1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (C) Foundries Ltd. 2022.
4 * Author: Jorge Ramirez <jorge@foundries.io>
5 */
6
7 #include <drvcrypt.h>
8 #include <drvcrypt_acipher.h>
9 #include <crypto/crypto_impl.h>
10 #include <initcall.h>
11 #include <ipi.h>
12 #include <kernel/panic.h>
13 #include <mm/core_memprot.h>
14 #include <string.h>
15 #include <tee/cache.h>
16 #include <tee/tee_cryp_utl.h>
17 #include <util.h>
18
19 /* AMD/Xilinx Versal's Known Answer Tests */
20 #define XSECURE_ECDSA_KAT_NIST_P384 0
21 #define XSECURE_ECDSA_KAT_NIST_P521 2
22
23 /* Software based ECDSA operations */
24 static const struct crypto_ecc_keypair_ops *keypair_ops;
25 static const struct crypto_ecc_public_ops *pub_ops;
26
27 enum versal_ecc_err {
28 KAT_KEY_NOTVALID_ERROR = 0xC0,
29 KAT_FAILED_ERROR,
30 NON_SUPPORTED_CURVE,
31 KEY_ZERO,
32 KEY_WRONG_ORDER,
33 KEY_NOT_ON_CURVE,
34 BAD_SIGN,
35 GEN_SIGN_INCORRECT_HASH_LEN,
36 VER_SIGN_INCORRECT_HASH_LEN,
37 GEN_SIGN_BAD_RAND_NUM,
38 GEN_KEY_ERR,
39 INVALID_PARAM,
40 VER_SIGN_R_ZERO,
41 VER_SIGN_S_ZERO,
42 VER_SIGN_R_ORDER_ERROR,
43 VER_SIGN_S_ORDER_ERROR,
44 KAT_INVLD_CRV_ERROR,
45 };
46
47 #define VERSAL_ECC_ERROR(m) { .error = (m), .name = TO_STR(m) }
48
versal_ecc_error(uint8_t err)49 static const char *versal_ecc_error(uint8_t err)
50 {
51 struct {
52 enum versal_ecc_err error;
53 const char *name;
54 } elist[] = {
55 VERSAL_ECC_ERROR(KAT_KEY_NOTVALID_ERROR),
56 VERSAL_ECC_ERROR(KAT_FAILED_ERROR),
57 VERSAL_ECC_ERROR(NON_SUPPORTED_CURVE),
58 VERSAL_ECC_ERROR(KEY_ZERO),
59 VERSAL_ECC_ERROR(KEY_WRONG_ORDER),
60 VERSAL_ECC_ERROR(KEY_NOT_ON_CURVE),
61 VERSAL_ECC_ERROR(BAD_SIGN),
62 VERSAL_ECC_ERROR(GEN_SIGN_INCORRECT_HASH_LEN),
63 VERSAL_ECC_ERROR(VER_SIGN_INCORRECT_HASH_LEN),
64 VERSAL_ECC_ERROR(GEN_SIGN_BAD_RAND_NUM),
65 VERSAL_ECC_ERROR(GEN_KEY_ERR),
66 VERSAL_ECC_ERROR(INVALID_PARAM),
67 VERSAL_ECC_ERROR(VER_SIGN_R_ZERO),
68 VERSAL_ECC_ERROR(VER_SIGN_S_ZERO),
69 VERSAL_ECC_ERROR(VER_SIGN_R_ORDER_ERROR),
70 VERSAL_ECC_ERROR(VER_SIGN_S_ORDER_ERROR),
71 VERSAL_ECC_ERROR(KAT_INVLD_CRV_ERROR),
72 };
73
74 if (err <= KAT_INVLD_CRV_ERROR && err >= KAT_KEY_NOTVALID_ERROR) {
75 if (elist[err - KAT_KEY_NOTVALID_ERROR].name)
76 return elist[err - KAT_KEY_NOTVALID_ERROR].name;
77
78 return "Invalid";
79 }
80
81 return "Unknown";
82 }
83
ecc_get_key_size(uint32_t curve,size_t * bytes,size_t * bits)84 static TEE_Result ecc_get_key_size(uint32_t curve, size_t *bytes, size_t *bits)
85 {
86 switch (curve) {
87 case TEE_ECC_CURVE_NIST_P384:
88 *bits = 384;
89 *bytes = 48;
90 break;
91 case TEE_ECC_CURVE_NIST_P521:
92 *bits = 521;
93 *bytes = 66;
94 break;
95 default:
96 return TEE_ERROR_NOT_SUPPORTED;
97 }
98
99 return TEE_SUCCESS;
100 }
101
crypto_bignum_bn2bin_eswap(uint32_t curve,struct bignum * from,uint8_t * to)102 static void crypto_bignum_bn2bin_eswap(uint32_t curve,
103 struct bignum *from, uint8_t *to)
104 {
105 uint8_t pad[66] = { 0 };
106 uint8_t tmp = 0;
107 size_t i = 0;
108 size_t j = 0;
109 size_t len = crypto_bignum_num_bytes(from);
110 size_t bytes = 0;
111 size_t bits = 0;
112
113 if (ecc_get_key_size(curve, &bytes, &bits))
114 panic();
115
116 crypto_bignum_bn2bin(from, pad + bytes - len);
117 for (i = 0, j = bytes - 1; i < j; i++, j--) {
118 tmp = pad[i];
119 pad[i] = pad[j];
120 pad[j] = tmp;
121 }
122 memcpy(to, pad, bytes);
123 }
124
ecc_prepare_msg(uint32_t algo,const uint8_t * msg,size_t msg_len,struct versal_mbox_mem * p)125 static TEE_Result ecc_prepare_msg(uint32_t algo, const uint8_t *msg,
126 size_t msg_len, struct versal_mbox_mem *p)
127 {
128 uint8_t buf[TEE_SHA512_HASH_SIZE + 2] = { 0 };
129 TEE_Result ret = TEE_SUCCESS;
130 size_t len = 0;
131
132 switch (algo) {
133 case TEE_ALG_ECDSA_P384:
134 len = TEE_SHA384_HASH_SIZE;
135
136 if (msg_len == len)
137 return versal_mbox_alloc(len, msg, p);
138
139 ret = tee_hash_createdigest(TEE_ALG_SHA384, msg, msg_len,
140 buf, sizeof(buf));
141 if (ret)
142 return ret;
143 break;
144 case TEE_ALG_ECDSA_P521:
145 len = TEE_SHA512_HASH_SIZE + 2;
146
147 if (msg_len == len)
148 return versal_mbox_alloc(len, msg, p);
149
150 ret = tee_hash_createdigest(TEE_ALG_SHA512, msg, msg_len, buf,
151 sizeof(buf));
152 if (ret)
153 return ret;
154 break;
155 default:
156 return TEE_ERROR_GENERIC;
157 }
158
159 /* provide the hash */
160 versal_mbox_alloc(len, buf, p);
161
162 return TEE_SUCCESS;
163 }
164
verify(uint32_t algo,struct ecc_public_key * key,const uint8_t * msg,size_t msg_len,const uint8_t * sig,size_t sig_len)165 static TEE_Result verify(uint32_t algo, struct ecc_public_key *key,
166 const uint8_t *msg, size_t msg_len,
167 const uint8_t *sig, size_t sig_len)
168 {
169 TEE_Result ret = TEE_SUCCESS;
170 struct versal_ecc_verify_param *cmd = NULL;
171 struct versal_cmd_args arg = { };
172 struct versal_mbox_mem x = { };
173 struct versal_mbox_mem s = { };
174 struct versal_mbox_mem p = { };
175 struct versal_mbox_mem cmd_buf = { };
176 uint32_t err = 0;
177 size_t bytes = 0;
178 size_t bits = 0;
179
180 ret = ecc_get_key_size(key->curve, &bytes, &bits);
181 if (ret != TEE_SUCCESS) {
182 if (ret != TEE_ERROR_NOT_SUPPORTED)
183 return ret;
184
185 /* Fallback to software */
186 return pub_ops->verify(algo, key, msg, msg_len, sig, sig_len);
187 }
188
189 ret = ecc_prepare_msg(algo, msg, msg_len, &p);
190 if (ret)
191 return ret;
192
193 versal_mbox_alloc(bytes * 2, NULL, &x);
194 crypto_bignum_bn2bin_eswap(key->curve, key->x, x.buf);
195 crypto_bignum_bn2bin_eswap(key->curve, key->y,
196 (uint8_t *)x.buf + bytes);
197 /* Validate the public key for the curve */
198 arg.data[0] = key->curve;
199 arg.dlen = 1;
200 arg.ibuf[0].mem = x;
201 if (versal_crypto_request(VERSAL_ELLIPTIC_VALIDATE_PUBLIC_KEY,
202 &arg, &err)) {
203 EMSG("Versal ECC: %s", versal_ecc_error(err));
204 ret = TEE_ERROR_GENERIC;
205 goto out;
206 }
207 memset(&arg, 0, sizeof(arg));
208
209 /* Verify the message with the validated key */
210 versal_mbox_alloc(sig_len, sig, &s);
211 versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf);
212
213 cmd = cmd_buf.buf;
214 cmd->signature_addr = virt_to_phys(s.buf);
215 cmd->pub_key_addr = virt_to_phys(x.buf);
216 cmd->hash_addr = virt_to_phys(p.buf);
217 cmd->hash_len = p.len;
218 cmd->curve = key->curve;
219
220 arg.ibuf[0].mem = cmd_buf;
221 arg.ibuf[1].mem = p;
222 arg.ibuf[1].only_cache = true;
223 arg.ibuf[2].mem = x;
224 arg.ibuf[3].mem = s;
225
226 if (versal_crypto_request(VERSAL_ELLIPTIC_VERIFY_SIGN, &arg, &err)) {
227 EMSG("Versal ECC: %s", versal_ecc_error(err));
228 ret = TEE_ERROR_GENERIC;
229 }
230 out:
231 free(p.buf);
232 free(x.buf);
233 free(s.buf);
234 free(cmd);
235
236 return ret;
237 }
238
sign(uint32_t algo,struct ecc_keypair * key,const uint8_t * msg,size_t msg_len,uint8_t * sig,size_t * sig_len)239 static TEE_Result sign(uint32_t algo, struct ecc_keypair *key,
240 const uint8_t *msg, size_t msg_len,
241 uint8_t *sig, size_t *sig_len)
242 {
243 struct versal_ecc_sign_param *cmd = NULL;
244 struct versal_mbox_mem cmd_buf = { };
245 struct ecc_keypair ephemeral = { };
246 struct versal_cmd_args arg = { };
247 struct versal_mbox_mem p = { };
248 struct versal_mbox_mem k = { };
249 struct versal_mbox_mem d = { };
250 struct versal_mbox_mem s = { };
251 TEE_Result ret = TEE_SUCCESS;
252 uint32_t err = 0;
253 size_t bytes = 0;
254 size_t bits = 0;
255
256 ret = ecc_get_key_size(key->curve, &bytes, &bits);
257 if (ret != TEE_SUCCESS) {
258 if (ret != TEE_ERROR_NOT_SUPPORTED)
259 return ret;
260
261 /* Fallback to software */
262 return keypair_ops->sign(algo, key, msg, msg_len, sig, sig_len);
263 }
264
265 /* Hash and update the length */
266 ret = ecc_prepare_msg(algo, msg, msg_len, &p);
267 if (ret)
268 return ret;
269
270 /* Ephemeral private key */
271 ret = drvcrypt_asym_alloc_ecc_keypair(&ephemeral,
272 TEE_TYPE_ECDSA_KEYPAIR, bits);
273 if (ret) {
274 EMSG("Versal, can't allocate the ephemeral key");
275 return ret;
276 }
277
278 ephemeral.curve = key->curve;
279 ret = crypto_acipher_gen_ecc_key(&ephemeral, bits);
280 if (ret) {
281 EMSG("Versal, can't generate the ephemeral key");
282 return ret;
283 }
284
285 versal_mbox_alloc(bytes, NULL, &k);
286 crypto_bignum_bn2bin_eswap(key->curve, ephemeral.d, k.buf);
287 crypto_bignum_free(ephemeral.d);
288 crypto_bignum_free(ephemeral.x);
289 crypto_bignum_free(ephemeral.y);
290
291 /* Private key*/
292 versal_mbox_alloc(bytes, NULL, &d);
293 crypto_bignum_bn2bin_eswap(key->curve, key->d, d.buf);
294
295 /* Signature */
296 versal_mbox_alloc(*sig_len, NULL, &s);
297
298 /* IPI command */
299 versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf);
300
301 cmd = cmd_buf.buf;
302 cmd->priv_key_addr = virt_to_phys(d.buf);
303 cmd->epriv_key_addr = virt_to_phys(k.buf);
304 cmd->hash_addr = virt_to_phys(p.buf);
305 cmd->hash_len = p.len;
306 cmd->curve = key->curve;
307
308 arg.ibuf[0].mem = cmd_buf;
309 arg.ibuf[1].mem = s;
310 arg.ibuf[2].mem = k;
311 arg.ibuf[3].mem = d;
312 arg.ibuf[4].mem = p;
313
314 if (versal_crypto_request(VERSAL_ELLIPTIC_GENERATE_SIGN, &arg, &err)) {
315 EMSG("Versal ECC: %s", versal_ecc_error(err));
316 ret = TEE_ERROR_GENERIC;
317 goto out;
318 }
319
320 *sig_len = 2 * bytes;
321 memcpy(sig, s.buf, *sig_len);
322 out:
323 free(cmd);
324 free(k.buf);
325 free(p.buf);
326 free(s.buf);
327 free(d.buf);
328
329 return ret;
330 }
331
shared_secret(struct ecc_keypair * private_key,struct ecc_public_key * public_key,void * secret,size_t * secret_len)332 static TEE_Result shared_secret(struct ecc_keypair *private_key,
333 struct ecc_public_key *public_key,
334 void *secret, size_t *secret_len)
335 {
336 return keypair_ops->shared_secret(private_key, public_key,
337 secret, secret_len);
338 }
339
do_shared_secret(struct drvcrypt_secret_data * sdata)340 static TEE_Result do_shared_secret(struct drvcrypt_secret_data *sdata)
341 {
342 return shared_secret(sdata->key_priv,
343 sdata->key_pub,
344 sdata->secret.data,
345 &sdata->secret.length);
346 }
347
do_sign(struct drvcrypt_sign_data * sdata)348 static TEE_Result do_sign(struct drvcrypt_sign_data *sdata)
349 {
350 return sign(sdata->algo,
351 sdata->key,
352 sdata->message.data,
353 sdata->message.length,
354 sdata->signature.data,
355 &sdata->signature.length);
356 }
357
do_verify(struct drvcrypt_sign_data * sdata)358 static TEE_Result do_verify(struct drvcrypt_sign_data *sdata)
359 {
360 return verify(sdata->algo,
361 sdata->key,
362 sdata->message.data,
363 sdata->message.length,
364 sdata->signature.data,
365 sdata->signature.length);
366 }
367
do_gen_keypair(struct ecc_keypair * s,size_t size_bits)368 static TEE_Result do_gen_keypair(struct ecc_keypair *s, size_t size_bits)
369 {
370 /*
371 * Versal requires little endian so need to eswap on Versal IP ops.
372 * We chose not to do it here because some tests might be using
373 * their own keys
374 */
375 return keypair_ops->generate(s, size_bits);
376 }
377
do_alloc_keypair(struct ecc_keypair * s,size_t size_bits)378 static TEE_Result do_alloc_keypair(struct ecc_keypair *s, size_t size_bits)
379 {
380 TEE_Result ret = TEE_SUCCESS;
381
382 ret = crypto_asym_alloc_ecc_keypair(s, TEE_TYPE_ECDSA_KEYPAIR,
383 size_bits);
384 if (ret)
385 return TEE_ERROR_NOT_IMPLEMENTED;
386
387 s->ops = NULL;
388
389 return TEE_SUCCESS;
390 }
391
do_alloc_publickey(struct ecc_public_key * s,size_t size_bits)392 static TEE_Result do_alloc_publickey(struct ecc_public_key *s, size_t size_bits)
393 {
394 TEE_Result ret = TEE_SUCCESS;
395
396 ret = crypto_asym_alloc_ecc_public_key(s, TEE_TYPE_ECDSA_PUBLIC_KEY,
397 size_bits);
398 if (ret)
399 return TEE_ERROR_NOT_IMPLEMENTED;
400
401 s->ops = NULL;
402
403 return TEE_SUCCESS;
404 }
405
do_free_publickey(struct ecc_public_key * s)406 static void do_free_publickey(struct ecc_public_key *s)
407 {
408 return pub_ops->free(s);
409 }
410
411 static struct drvcrypt_ecc driver_ecc = {
412 .shared_secret = do_shared_secret,
413 .alloc_publickey = do_alloc_publickey,
414 .free_publickey = do_free_publickey,
415 .alloc_keypair = do_alloc_keypair,
416 .gen_keypair = do_gen_keypair,
417 .verify = do_verify,
418 .sign = do_sign,
419 };
420
ecc_init(void)421 static TEE_Result ecc_init(void)
422 {
423 struct versal_cmd_args arg = { };
424 uint32_t err = 0;
425
426 arg.data[arg.dlen++] = XSECURE_ECDSA_KAT_NIST_P384;
427 if (versal_crypto_request(VERSAL_ELLIPTIC_KAT, &arg, &err)) {
428 EMSG("Versal KAG NIST_P384: %s", versal_ecc_error(err));
429 return TEE_ERROR_GENERIC;
430 }
431
432 /* Clean previous request */
433 arg.dlen = 0;
434
435 arg.data[arg.dlen++] = XSECURE_ECDSA_KAT_NIST_P521;
436 if (versal_crypto_request(VERSAL_ELLIPTIC_KAT, &arg, &err)) {
437 EMSG("Versal KAG NIST_P521 %s", versal_ecc_error(err));
438 return TEE_ERROR_GENERIC;
439 }
440
441 keypair_ops = crypto_asym_get_ecc_keypair_ops(TEE_TYPE_ECDSA_KEYPAIR);
442 if (!keypair_ops)
443 return TEE_ERROR_GENERIC;
444
445 pub_ops = crypto_asym_get_ecc_public_ops(TEE_TYPE_ECDSA_PUBLIC_KEY);
446 if (!pub_ops)
447 return TEE_ERROR_GENERIC;
448
449 return drvcrypt_register_ecc(&driver_ecc);
450 }
451
452 driver_init(ecc_init);
453