1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright 2018-2021 NXP
4 *
5 * Crypto DSA interface implementation to enable HW driver.
6 */
7 #include <crypto/crypto.h>
8 #include <drvcrypt.h>
9 #include <drvcrypt_acipher.h>
10
11 /*
12 * Get the recommended L and N bits parameters corresponding
13 * respectively to the size of the Primes P and G (and so
14 * the Public Key and Private Key).
15 *
16 * Refer the NIST.FIPS 186-4 section 4.2
17 *
18 * @size_bits Maximum key size bits
19 * @l_bits [out] L size in bits
20 * @n_bits [out] N size in bits
21 */
get_keys_size(size_t size_bits,size_t * l_bits,size_t * n_bits)22 static TEE_Result get_keys_size(size_t size_bits, size_t *l_bits,
23 size_t *n_bits)
24 {
25 if (size_bits <= 1024)
26 *n_bits = 160;
27 else if (size_bits <= 3072)
28 *n_bits = 256;
29 else
30 return TEE_ERROR_NOT_IMPLEMENTED;
31
32 *l_bits = size_bits;
33
34 return TEE_SUCCESS;
35 }
36
crypto_acipher_alloc_dsa_keypair(struct dsa_keypair * key,size_t size_bits)37 TEE_Result crypto_acipher_alloc_dsa_keypair(struct dsa_keypair *key,
38 size_t size_bits)
39 {
40 TEE_Result ret = TEE_ERROR_NOT_IMPLEMENTED;
41 struct drvcrypt_dsa *dsa = NULL;
42 size_t l_bits = 0;
43 size_t n_bits = 0;
44
45 if (!key || !size_bits) {
46 CRYPTO_TRACE("Param error key @0x%" PRIxPTR " size %zu bits",
47 (uintptr_t)key, size_bits);
48 return TEE_ERROR_BAD_PARAMETERS;
49 }
50
51 ret = get_keys_size(size_bits, &l_bits, &n_bits);
52 if (ret == TEE_SUCCESS) {
53 dsa = drvcrypt_get_ops(CRYPTO_DSA);
54 if (dsa)
55 ret = dsa->alloc_keypair(key, l_bits, n_bits);
56 else
57 ret = TEE_ERROR_NOT_IMPLEMENTED;
58 }
59
60 CRYPTO_TRACE("DSA Keypair (%zu bits) alloc ret = 0x%" PRIx32, size_bits,
61 ret);
62 return ret;
63 }
64
crypto_acipher_alloc_dsa_public_key(struct dsa_public_key * key,size_t size_bits)65 TEE_Result crypto_acipher_alloc_dsa_public_key(struct dsa_public_key *key,
66 size_t size_bits)
67 {
68 TEE_Result ret = TEE_ERROR_NOT_IMPLEMENTED;
69 struct drvcrypt_dsa *dsa = NULL;
70 size_t l_bits = 0;
71 size_t n_bits = 0;
72
73 if (!key || !size_bits) {
74 CRYPTO_TRACE("Param error key @0x%" PRIxPTR " size %zu bits",
75 (uintptr_t)key, size_bits);
76 return TEE_ERROR_BAD_PARAMETERS;
77 }
78
79 ret = get_keys_size(size_bits, &l_bits, &n_bits);
80 if (ret == TEE_SUCCESS) {
81 dsa = drvcrypt_get_ops(CRYPTO_DSA);
82 if (dsa)
83 ret = dsa->alloc_publickey(key, l_bits, n_bits);
84 else
85 ret = TEE_ERROR_NOT_IMPLEMENTED;
86 }
87
88 CRYPTO_TRACE("DSA Public Key (%zu bits) alloc ret = 0x%" PRIx32,
89 size_bits, ret);
90 return ret;
91 }
92
crypto_acipher_gen_dsa_key(struct dsa_keypair * key,size_t key_size)93 TEE_Result crypto_acipher_gen_dsa_key(struct dsa_keypair *key, size_t key_size)
94 {
95 TEE_Result ret = TEE_ERROR_NOT_IMPLEMENTED;
96 struct drvcrypt_dsa *dsa = NULL;
97 size_t l_bits = 0;
98 size_t n_bits = 0;
99
100 if (!key || !key_size) {
101 CRYPTO_TRACE("Param error key @0x%" PRIxPTR " size %zu bits",
102 (uintptr_t)key, key_size);
103 return TEE_ERROR_BAD_PARAMETERS;
104 }
105
106 ret = get_keys_size(key_size, &l_bits, &n_bits);
107 if (ret == TEE_SUCCESS) {
108 dsa = drvcrypt_get_ops(CRYPTO_DSA);
109 if (dsa)
110 ret = dsa->gen_keypair(key, l_bits, n_bits);
111 else
112 ret = TEE_ERROR_NOT_IMPLEMENTED;
113 }
114
115 CRYPTO_TRACE("DSA Keypair (%zu bits) generate ret = 0x%" PRIx32,
116 key_size, ret);
117
118 return ret;
119 }
120
crypto_acipher_dsa_sign(uint32_t algo,struct dsa_keypair * key,const uint8_t * msg,size_t msg_len,uint8_t * sig,size_t * sig_len)121 TEE_Result crypto_acipher_dsa_sign(uint32_t algo, struct dsa_keypair *key,
122 const uint8_t *msg, size_t msg_len,
123 uint8_t *sig, size_t *sig_len)
124 {
125 TEE_Result ret = TEE_ERROR_BAD_PARAMETERS;
126 struct drvcrypt_dsa *dsa = NULL;
127 struct drvcrypt_sign_data sdata = { };
128 size_t l_bytes = 0;
129 size_t n_bytes = 0;
130
131 if (!key || !msg || !sig_len) {
132 CRYPTO_TRACE("Input parameters reference error");
133 return TEE_ERROR_BAD_PARAMETERS;
134 }
135
136 /*
137 * Verify the signature length function of the key size
138 *
139 * Prime number sizes are not stored but deducted from bignum size.
140 * This requires prime numbers p and q to have their MSB set otherwise
141 * crypto_bignum_num_bytes() will return a wrong size.
142 */
143 n_bytes = crypto_bignum_num_bytes(key->q);
144 l_bytes = crypto_bignum_num_bytes(key->p);
145 if (*sig_len < 2 * n_bytes) {
146 CRYPTO_TRACE("Length (%zu) too short expected %zu bytes",
147 *sig_len, 2 * n_bytes);
148 *sig_len = 2 * n_bytes;
149 return TEE_ERROR_SHORT_BUFFER;
150 }
151
152 if (!sig) {
153 CRYPTO_TRACE("Parameter \"sig\" reference error");
154 return TEE_ERROR_BAD_PARAMETERS;
155 }
156
157 dsa = drvcrypt_get_ops(CRYPTO_DSA);
158 if (dsa) {
159 sdata.algo = algo;
160 sdata.key = key;
161 sdata.size_sec = n_bytes;
162 sdata.message.data = (uint8_t *)msg;
163 sdata.message.length = msg_len;
164 sdata.signature.data = sig;
165 sdata.signature.length = *sig_len;
166
167 ret = dsa->sign(&sdata, l_bytes, n_bytes);
168
169 /* Set the signature length */
170 *sig_len = sdata.signature.length;
171 } else {
172 ret = TEE_ERROR_NOT_IMPLEMENTED;
173 }
174
175 CRYPTO_TRACE("Sign algo (0x%" PRIx32 ") returned 0x%" PRIx32, algo,
176 ret);
177
178 return ret;
179 }
180
crypto_acipher_dsa_verify(uint32_t algo,struct dsa_public_key * key,const uint8_t * msg,size_t msg_len,const uint8_t * sig,size_t sig_len)181 TEE_Result crypto_acipher_dsa_verify(uint32_t algo, struct dsa_public_key *key,
182 const uint8_t *msg, size_t msg_len,
183 const uint8_t *sig, size_t sig_len)
184 {
185 TEE_Result ret = TEE_ERROR_BAD_PARAMETERS;
186 struct drvcrypt_dsa *dsa = NULL;
187 struct drvcrypt_sign_data sdata = { };
188 size_t l_bytes = 0;
189 size_t n_bytes = 0;
190
191 if (!key || !msg || !sig) {
192 CRYPTO_TRACE("Input parameters reference error");
193 return TEE_ERROR_BAD_PARAMETERS;
194 }
195
196 /*
197 * Verify the signature length function of the key size
198 *
199 * Prime number sizes are not stored but deducted from bignum size.
200 * This requires prime numbers p and q to have their MSB set otherwise
201 * crypto_bignum_num_bytes() will return a wrong size.
202 */
203 n_bytes = crypto_bignum_num_bytes(key->q);
204 l_bytes = crypto_bignum_num_bytes(key->p);
205 if (sig_len != 2 * n_bytes) {
206 CRYPTO_TRACE("Length (%zu) is invalid expected %zu bytes",
207 sig_len, 2 * n_bytes);
208 return TEE_ERROR_SIGNATURE_INVALID;
209 }
210
211 dsa = drvcrypt_get_ops(CRYPTO_DSA);
212 if (dsa) {
213 sdata.algo = algo;
214 sdata.key = key;
215 sdata.size_sec = n_bytes;
216 sdata.message.data = (uint8_t *)msg;
217 sdata.message.length = msg_len;
218 sdata.signature.data = (uint8_t *)sig;
219 sdata.signature.length = sig_len;
220
221 ret = dsa->verify(&sdata, l_bytes, n_bytes);
222 } else {
223 ret = TEE_ERROR_NOT_IMPLEMENTED;
224 }
225
226 CRYPTO_TRACE("Verify algo (0x%" PRIx32 ") returned 0x%" PRIx32, algo,
227 ret);
228
229 return ret;
230 }
231