crypto_mod.c 4.3 KB
Newer Older
1
/*
2
 * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
3
 *
dp-arm's avatar
dp-arm committed
4
 * SPDX-License-Identifier: BSD-3-Clause
5
6
7
 */

#include <assert.h>
8
9
10

#include <common/debug.h>
#include <drivers/auth/crypto_mod.h>
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

/* Variable exported by the crypto library through REGISTER_CRYPTO_LIB() */

/*
 * The crypto module is responsible for verifying digital signatures and hashes.
 * It relies on a crypto library to perform the cryptographic operations.
 *
 * The crypto module itself does not impose any specific format on signatures,
 * signature algorithm, keys or hashes, but most cryptographic libraries will
 * take the parameters as the following DER encoded ASN.1 structures:
 *
 *     AlgorithmIdentifier ::= SEQUENCE  {
 *         algorithm        OBJECT IDENTIFIER,
 *         parameters       ANY DEFINED BY algorithm OPTIONAL
 *     }
 *
 *     DigestInfo ::= SEQUENCE {
 *         digestAlgorithm  AlgorithmIdentifier,
 *         digest           OCTET STRING
 *     }
 *
 *     SubjectPublicKeyInfo ::= SEQUENCE  {
 *         algorithm        AlgorithmIdentifier,
 *         subjectPublicKey BIT STRING
 *     }
 *
 *     SignatureAlgorithm ::= AlgorithmIdentifier
 *
 *     SignatureValue ::= BIT STRING
 */

/*
 * Perform some static checking and call the library initialization function
 */
void crypto_mod_init(void)
{
	assert(crypto_lib_desc.name != NULL);
	assert(crypto_lib_desc.init != NULL);
	assert(crypto_lib_desc.verify_signature != NULL);
	assert(crypto_lib_desc.verify_hash != NULL);

	/* Initialize the cryptographic library */
	crypto_lib_desc.init();
	INFO("Using crypto library '%s'\n", crypto_lib_desc.name);
}

/*
 * Function to verify a digital signature
 *
 * Parameters:
 *
 *   data_ptr, data_len: signed data
 *   sig_ptr, sig_len: the digital signature
 *   sig_alg_ptr, sig_alg_len: the digital signature algorithm
 *   pk_ptr, pk_len: the public key
 */
int crypto_mod_verify_signature(void *data_ptr, unsigned int data_len,
				void *sig_ptr, unsigned int sig_len,
				void *sig_alg_ptr, unsigned int sig_alg_len,
				void *pk_ptr, unsigned int pk_len)
{
	assert(data_ptr != NULL);
	assert(data_len != 0);
	assert(sig_ptr != NULL);
	assert(sig_len != 0);
	assert(sig_alg_ptr != NULL);
	assert(sig_alg_len != 0);
	assert(pk_ptr != NULL);
	assert(pk_len != 0);

	return crypto_lib_desc.verify_signature(data_ptr, data_len,
						sig_ptr, sig_len,
						sig_alg_ptr, sig_alg_len,
						pk_ptr, pk_len);
}

/*
 * Verify a hash by comparison
 *
 * Parameters:
 *
 *   data_ptr, data_len: data to be hashed
 *   digest_info_ptr, digest_info_len: hash to be compared
 */
int crypto_mod_verify_hash(void *data_ptr, unsigned int data_len,
			   void *digest_info_ptr, unsigned int digest_info_len)
{
	assert(data_ptr != NULL);
	assert(data_len != 0);
	assert(digest_info_ptr != NULL);
	assert(digest_info_len != 0);

	return crypto_lib_desc.verify_hash(data_ptr, data_len,
					   digest_info_ptr, digest_info_len);
}
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

#if MEASURED_BOOT
/*
 * Calculate a hash
 *
 * Parameters:
 *
 *   alg: message digest algorithm
 *   data_ptr, data_len: data to be hashed
 *   output: resulting hash
 */
int crypto_mod_calc_hash(unsigned int alg, void *data_ptr,
			 unsigned int data_len, unsigned char *output)
{
	assert(data_ptr != NULL);
	assert(data_len != 0);
	assert(output != NULL);

	return crypto_lib_desc.calc_hash(alg, data_ptr, data_len, output);
}
#endif	/* MEASURED_BOOT */
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

/*
 * Authenticated decryption of data
 *
 * Parameters:
 *
 *   dec_algo: authenticated decryption algorithm
 *   data_ptr, len: data to be decrypted (inout param)
 *   key, key_len, key_flags: symmetric decryption key
 *   iv, iv_len: initialization vector
 *   tag, tag_len: authentication tag
 */
int crypto_mod_auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
			    size_t len, const void *key, unsigned int key_len,
			    unsigned int key_flags, const void *iv,
			    unsigned int iv_len, const void *tag,
			    unsigned int tag_len)
{
	assert(crypto_lib_desc.auth_decrypt != NULL);
	assert(data_ptr != NULL);
	assert(len != 0U);
	assert(key != NULL);
	assert(key_len != 0U);
	assert(iv != NULL);
	assert((iv_len != 0U) && (iv_len <= CRYPTO_MAX_IV_SIZE));
	assert(tag != NULL);
	assert((tag_len != 0U) && (tag_len <= CRYPTO_MAX_TAG_SIZE));

	return crypto_lib_desc.auth_decrypt(dec_algo, data_ptr, len, key,
					    key_len, key_flags, iv, iv_len, tag,
					    tag_len);
}