1 /* se050_port.c
2 *
3 * Copyright (C) 2006-2021 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdint.h>
27
28 #include <wolfssl/wolfcrypt/settings.h>
29
30 #ifdef WOLFSSL_SE050
31
32 #include <wolfssl/wolfcrypt/types.h>
33 #include <wolfssl/wolfcrypt/wc_port.h>
34 #include <wolfssl/wolfcrypt/aes.h>
35 #include <wolfssl/wolfcrypt/error-crypt.h>
36 #include <wolfssl/wolfcrypt/ed25519.h>
37 #include <wolfssl/wolfcrypt/logging.h>
38 #include <wolfssl/wolfcrypt/curve25519.h>
39
40 #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
41
42 #ifdef WOLFSSL_SE050_INIT
43 #ifndef SE050_DEFAULT_PORT
44 #define SE050_DEFAULT_PORT "/dev/i2c-1"
45 #endif
46
47 #include "ex_sss_boot.h"
48 #endif
49
50 #ifdef WOLFSSL_SP_MATH
51 struct sp_int;
52 #define MATH_INT_T struct sp_int
53 #elif defined(USE_FAST_MATH)
54 struct fp_int;
55 #define MATH_INT_T struct fp_int
56 #else
57 struct mp_int;
58 #define MATH_INT_T struct mp_int
59 #endif
60 struct ecc_key;
61 #include <wolfssl/wolfcrypt/ecc.h>
62 #include <wolfssl/wolfcrypt/asn.h>
63
64 #ifndef SE050_ECC_DER_MAX
65 #define SE050_ECC_DER_MAX 256
66 #endif
67
68 /* enable for debugging */
69 /* #define SE050_DEBUG*/
70 /* enable to factory erase chip */
71 /* #define WOLFSSL_SE050_FACTORY_RESET */
72
73 /* Global variables */
74 static sss_session_t *cfg_se050_i2c_pi;
75 static sss_key_store_t *gHostKeyStore;
76 static sss_key_store_t *gHeyStore;
77
wc_se050_set_config(sss_session_t * pSession,sss_key_store_t * pHostKeyStore,sss_key_store_t * pKeyStore)78 int wc_se050_set_config(sss_session_t *pSession, sss_key_store_t *pHostKeyStore,
79 sss_key_store_t *pKeyStore)
80 {
81 WOLFSSL_MSG("Setting SE050 session configuration");
82
83 cfg_se050_i2c_pi = pSession;
84 gHostKeyStore = pHostKeyStore;
85 gHeyStore = pKeyStore;
86
87 return 0;
88 }
89
90 #ifdef WOLFSSL_SE050_INIT
wc_se050_init(const char * portName)91 int wc_se050_init(const char* portName)
92 {
93 int ret;
94 sss_status_t status;
95 static ex_sss_boot_ctx_t pCtx;
96
97 if (portName == NULL) {
98 portName = SE050_DEFAULT_PORT;
99 }
100
101 status = ex_sss_boot_open(&pCtx, portName);
102 if (status == kStatus_SSS_Success) {
103 ret = wc_se050_set_config(&pCtx.session,
104 #if SSS_HAVE_HOSTCRYPTO_ANY
105 &pCtx.host_ks,
106 #else
107 NULL,
108 #endif
109 &pCtx.ks);
110
111 #ifdef WOLFSSL_SE050_FACTORY_RESET
112 ex_sss_boot_factory_reset(&pCtx);
113 #endif
114 }
115 else {
116 ret = WC_HW_E;
117 }
118 return ret;
119 }
120 #endif
121
se050_allocate_key(int keyType)122 int se050_allocate_key(int keyType)
123 {
124 int keyId = -1;
125 static int keyId_allocator = 100;
126 switch (keyType) {
127 case SE050_AES_KEY:
128 case SE050_ECC_KEY:
129 case SE050_ED25519_KEY:
130 case SE050_CURVE25519_KEY:
131 case SE050_ANY_KEY:
132 keyId = keyId_allocator++;
133 break;
134 }
135 #ifdef SE050_DEBUG
136 printf("se050_allocate_key: keyId %d\n", keyId);
137 #endif
138 return keyId;
139 }
140
141 #ifndef WC_NO_RNG
se050_get_random_number(uint32_t count,uint8_t * rand_out)142 int se050_get_random_number(uint32_t count, uint8_t* rand_out)
143 {
144 int ret = 0;
145 sss_status_t status;
146 sss_rng_context_t rng;
147
148 #ifdef SE050_DEBUG
149 printf("se050_get_random_number: %p (%d)\n", rand_out, count);
150 #endif
151
152 if (cfg_se050_i2c_pi == NULL) {
153 return WC_HW_E;
154 }
155
156 if (wolfSSL_CryptHwMutexLock() != 0) {
157 return BAD_MUTEX_E;
158 }
159 status = sss_rng_context_init(&rng, cfg_se050_i2c_pi);
160 if (status == kStatus_SSS_Success) {
161 status = sss_rng_get_random(&rng, rand_out, count);
162 }
163 if (status == kStatus_SSS_Success) {
164 status = sss_rng_context_free(&rng);
165 }
166 if (status != kStatus_SSS_Success) {
167 ret = RNG_FAILURE_E;
168 }
169
170 wolfSSL_CryptHwMutexUnLock();
171
172 return ret;
173 }
174 #endif /* !WC_NO_RNG */
175
176 /* Used for sha/sha224/sha384/sha512 */
se050_hash_init(SE050_HASH_Context * se050Ctx,void * heap)177 int se050_hash_init(SE050_HASH_Context* se050Ctx, void* heap)
178 {
179 se050Ctx->heap = heap;
180 se050Ctx->len = 0;
181 se050Ctx->used = 0;
182 se050Ctx->msg = NULL;
183 return 0;
184 }
185
se050_hash_update(SE050_HASH_Context * se050Ctx,const byte * data,word32 len)186 int se050_hash_update(SE050_HASH_Context* se050Ctx, const byte* data, word32 len)
187 {
188 if (se050Ctx == NULL || (len > 0 && data == NULL)) {
189 return BAD_FUNC_ARG;
190 }
191
192 if (se050Ctx->len < se050Ctx->used + len) {
193 if (se050Ctx->msg == NULL) {
194 se050Ctx->msg = (byte*)XMALLOC(se050Ctx->used + len,
195 se050Ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
196 }
197 else {
198 se050Ctx->msg = (byte*)XREALLOC(se050Ctx->msg, se050Ctx->used + len,
199 se050Ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
200 }
201 if (se050Ctx->msg == NULL) {
202 return MEMORY_E;
203 }
204 se050Ctx->len = se050Ctx->used + len;
205 }
206
207 XMEMCPY(se050Ctx->msg + se050Ctx->used, data , len);
208 se050Ctx->used += len;
209
210 return 0;
211 }
212
se050_hash_final(SE050_HASH_Context * se050Ctx,byte * hash,size_t digestLen,sss_algorithm_t algo)213 int se050_hash_final(SE050_HASH_Context* se050Ctx, byte* hash, size_t digestLen,
214 sss_algorithm_t algo)
215 {
216 int ret;
217 sss_status_t status;
218 sss_digest_t digest_ctx;
219 const byte* data = se050Ctx->msg;
220 int size = (se050Ctx->len) / SSS_BLOCK_SIZE;
221 int leftover = (se050Ctx->len) % SSS_BLOCK_SIZE;
222 const byte* blocks = data;
223
224 if (cfg_se050_i2c_pi == NULL) {
225 return WC_HW_E;
226 }
227
228 if (wolfSSL_CryptHwMutexLock() != 0) {
229 return BAD_MUTEX_E;
230 }
231
232 status = sss_digest_context_init(&digest_ctx, cfg_se050_i2c_pi, algo,
233 kMode_SSS_Digest);
234 if (status == kStatus_SSS_Success) {
235 status = sss_digest_init(&digest_ctx);
236 }
237 if (status == kStatus_SSS_Success) {
238 /* used to send chunks of size 512 */
239 while (status == kStatus_SSS_Success && size--) {
240 status = sss_digest_update(&digest_ctx, blocks, SSS_BLOCK_SIZE);
241 blocks += SSS_BLOCK_SIZE;
242 }
243 if (status == kStatus_SSS_Success && leftover) {
244 status = sss_digest_update(&digest_ctx, blocks, leftover);
245 }
246 if (status == kStatus_SSS_Success) {
247 status = sss_digest_finish(&digest_ctx, hash, &digestLen);
248 }
249 sss_digest_context_free(&digest_ctx);
250 }
251
252 ret = (status == kStatus_SSS_Success) ? 0 : WC_HW_E;
253
254 wolfSSL_CryptHwMutexUnLock();
255
256 return ret;
257 }
258
se050_hash_free(SE050_HASH_Context * se050Ctx)259 void se050_hash_free(SE050_HASH_Context* se050Ctx)
260 {
261 (void)se050Ctx;
262 }
263
264 #ifndef NO_AES
se050_aes_set_key(Aes * aes,const byte * key,word32 keylen,const byte * iv,int dir)265 int se050_aes_set_key(Aes* aes, const byte* key, word32 keylen,
266 const byte* iv, int dir)
267 {
268 int ret = 0;
269 sss_status_t status;
270 sss_object_t newKey;
271 sss_key_store_t host_keystore;
272 int keyId;
273 int keyCreated = 0;
274
275 if (cfg_se050_i2c_pi == NULL) {
276 return WC_HW_E;
277 }
278
279 if (wolfSSL_CryptHwMutexLock() != 0) {
280 return BAD_MUTEX_E;
281 }
282
283 (void)dir;
284 (void)iv;
285
286 aes->rounds = keylen/4 + 6;
287
288 status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
289 if (status == kStatus_SSS_Success) {
290 status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_AES);
291 }
292 if (status == kStatus_SSS_Success) {
293 status = sss_key_object_init(&newKey, &host_keystore);
294 }
295 if (status == kStatus_SSS_Success) {
296 keyId = se050_allocate_key(SE050_AES_KEY);
297 status = sss_key_object_allocate_handle(&newKey, keyId,
298 kSSS_KeyPart_Default, kSSS_CipherType_AES, keylen,
299 kKeyObject_Mode_Transient);
300 }
301 if (status == kStatus_SSS_Success) {
302 keyCreated = 1;
303 status = sss_key_store_set_key(&host_keystore, &newKey, key, keylen,
304 keylen * 8, NULL, 0);
305 }
306
307 if (status == kStatus_SSS_Success) {
308 aes->keyId = keyId;
309 ret = 0;
310 }
311 else {
312 if (keyCreated) {
313 sss_key_store_erase_key(&host_keystore, &newKey);
314 sss_key_object_free(&newKey);
315 }
316 ret = WC_HW_E;
317 }
318
319 wolfSSL_CryptHwMutexUnLock();
320
321 return ret;
322 }
323
se050_aes_crypt(Aes * aes,const byte * in,byte * out,word32 sz,int dir,sss_algorithm_t algorithm)324 int se050_aes_crypt(Aes* aes, const byte* in, byte* out, word32 sz, int dir,
325 sss_algorithm_t algorithm)
326 {
327 int ret = 0;
328 sss_status_t status;
329 sss_object_t keyObject;
330 sss_key_store_t host_keystore;
331
332 if (cfg_se050_i2c_pi == NULL) {
333 return WC_HW_E;
334 }
335 if (aes->keyId <= 0) {
336 return BAD_FUNC_ARG;
337 }
338
339 if (wolfSSL_CryptHwMutexLock() != 0) {
340 return BAD_MUTEX_E;
341 }
342
343 status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
344 if (status == kStatus_SSS_Success) {
345 status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_AES);
346 }
347 if (status == kStatus_SSS_Success) {
348 status = sss_key_object_init(&keyObject, &host_keystore);
349 }
350 if (status == kStatus_SSS_Success) {
351 status = sss_key_object_get_handle(&keyObject, aes->keyId);
352 }
353
354 /* The first call to this function needs an initialization call,
355 * subsequent calls just need to call update */
356 if (status == kStatus_SSS_Success && aes->ctxInitDone == 0) {
357 sss_mode_t mode;
358
359 XMEMSET(&mode, 0, sizeof(mode));
360 if (dir == AES_DECRYPTION)
361 mode = kMode_SSS_Decrypt;
362 else if (dir == AES_ENCRYPTION)
363 mode = kMode_SSS_Encrypt;
364
365 if (status == kStatus_SSS_Success) {
366 status = sss_symmetric_context_init(&aes->aes_ctx,
367 cfg_se050_i2c_pi, &keyObject, algorithm, mode);
368 }
369 if (status == kStatus_SSS_Success) {
370 aes->ctxInitDone = 1;
371 status = sss_cipher_init(&aes->aes_ctx, (uint8_t*)aes->reg,
372 sizeof(aes->reg));
373 }
374 }
375 if (status == kStatus_SSS_Success) {
376 size_t outSz = (size_t)sz;
377 status = sss_cipher_update(&aes->aes_ctx, in, sz, out, &outSz);
378 }
379
380 ret = (status == kStatus_SSS_Success) ? 0 : WC_HW_E;
381
382 wolfSSL_CryptHwMutexUnLock();
383
384 return ret;
385 }
386
se050_aes_free(Aes * aes)387 void se050_aes_free(Aes* aes)
388 {
389 sss_status_t status;
390 sss_key_store_t host_keystore;
391 sss_object_t keyObject;
392
393 if (cfg_se050_i2c_pi == NULL) {
394 return;
395 }
396 if (aes->keyId <= 0) {
397 return;
398 }
399
400 if (wolfSSL_CryptHwMutexLock() != 0) {
401 return;
402 }
403
404 if (aes->ctxInitDone) {
405 sss_symmetric_context_free(&aes->aes_ctx);
406
407 /* sets back to zero to indicate that a free has been called */
408 aes->ctxInitDone = 0;
409 }
410
411 status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
412 if (status == kStatus_SSS_Success) {
413 status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_AES);
414 }
415 if (status == kStatus_SSS_Success) {
416 status = sss_key_object_init(&keyObject, &host_keystore);
417 }
418 if (status == kStatus_SSS_Success) {
419 status = sss_key_object_get_handle(&keyObject, aes->keyId);
420 aes->keyId = -1;
421 }
422 sss_key_store_erase_key(&host_keystore, &keyObject);
423 sss_key_object_free(&keyObject);
424
425 wolfSSL_CryptHwMutexUnLock();
426 }
427
428 #endif /* !NO_AES */
429
430 #ifdef HAVE_ECC
431
se050_map_curve(int curve_id,int keySize,int * keySizeBits,sss_cipher_type_t * pcurve_type)432 static int se050_map_curve(int curve_id, int keySize,
433 int* keySizeBits, sss_cipher_type_t* pcurve_type)
434 {
435 int ret = 0;
436 sss_cipher_type_t curve_type;
437 *keySizeBits = keySize * 8; /* set default */
438 switch (curve_id) {
439 case ECC_SECP160K1:
440 case ECC_SECP192K1:
441 case ECC_SECP224K1:
442 case ECC_SECP256K1:
443 #ifdef HAVE_ECC_KOBLITZ
444 curve_type = kSSS_CipherType_EC_NIST_K;
445 #else
446 ret = ECC_CURVE_OID_E;
447 #endif
448 break;
449 case ECC_BRAINPOOLP160R1:
450 case ECC_BRAINPOOLP192R1:
451 case ECC_BRAINPOOLP224R1:
452 case ECC_BRAINPOOLP256R1:
453 case ECC_BRAINPOOLP320R1:
454 case ECC_BRAINPOOLP384R1:
455 case ECC_BRAINPOOLP512R1:
456 #ifdef HAVE_ECC_BRAINPOOL
457 curve_type = kSSS_CipherType_EC_BRAINPOOL;
458 #else
459 ret = ECC_CURVE_OID_E;
460 #endif
461 break;
462 case ECC_SECP521R1:
463 curve_type = kSSS_CipherType_EC_NIST_P;
464 *keySizeBits = 521;
465 break;
466 case ECC_CURVE_DEF:
467 case ECC_SECP160R1:
468 case ECC_SECP192R1:
469 case ECC_SECP224R1:
470 case ECC_SECP256R1:
471 case ECC_SECP384R1:
472 curve_type = kSSS_CipherType_EC_NIST_P;
473 break;
474 case ECC_PRIME239V1:
475 case ECC_PRIME192V2:
476 case ECC_PRIME192V3:
477 default:
478 ret = ECC_CURVE_OID_E;
479 break;
480 }
481 if (pcurve_type)
482 *pcurve_type = curve_type;
483 return ret;
484 }
485
se050_map_hash_alg(int hashLen)486 static sss_algorithm_t se050_map_hash_alg(int hashLen)
487 {
488 sss_algorithm_t algorithm = kAlgorithm_None;
489 if (hashLen == 20) {
490 algorithm = kAlgorithm_SSS_SHA1;
491 } else if (hashLen == 28) {
492 algorithm = kAlgorithm_SSS_SHA224;
493 } else if (hashLen == 32) {
494 algorithm = kAlgorithm_SSS_SHA256;
495 } else if (hashLen == 48) {
496 algorithm = kAlgorithm_SSS_SHA384;
497 } else if (hashLen == 64) {
498 algorithm = kAlgorithm_SSS_SHA512;
499 }
500 return algorithm;
501 }
502
se050_ecc_sign_hash_ex(const byte * in,word32 inLen,byte * out,word32 * outLen,struct ecc_key * key)503 int se050_ecc_sign_hash_ex(const byte* in, word32 inLen, byte* out,
504 word32 *outLen, struct ecc_key* key)
505 {
506 int ret = 0;
507 sss_status_t status;
508 sss_asymmetric_t ctx_asymm;
509 sss_key_store_t host_keystore;
510 sss_object_t newKey;
511 sss_algorithm_t algorithm;
512 int keySize;
513 int keySizeBits;
514
515 #ifdef SE050_DEBUG
516 printf("se050_ecc_sign_hash_ex: key %p, in %p (%d), out %p (%d), keyId %d\n",
517 key, in, inLen, out, *outLen, key->keyId);
518 #endif
519
520 if (cfg_se050_i2c_pi == NULL) {
521 return WC_HW_E;
522 }
523 if (key->keyId <= 0) {
524 return BAD_FUNC_ARG;
525 }
526
527 keySize = key->dp->size;
528 ret = se050_map_curve(key->dp->id, keySize, &keySizeBits, NULL);
529 if (ret != 0) {
530 return ret;
531 }
532
533 /* truncate if digest is larger than key size */
534 if (inLen > (word32)keySize)
535 inLen = (word32)keySize;
536
537 algorithm = se050_map_hash_alg(inLen);
538 if (algorithm == kAlgorithm_None) {
539 inLen = keySize; /* try key size */
540 algorithm = se050_map_hash_alg(inLen);
541 }
542 if (algorithm == kAlgorithm_None) {
543 return ECC_CURVE_OID_E;
544 }
545
546 if (wolfSSL_CryptHwMutexLock() != 0) {
547 return BAD_MUTEX_E;
548 }
549
550 /* mark that key was used for signing */
551 key->flags |= WC_ECC_FLAG_DEC_SIGN;
552
553 status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
554 if (status == kStatus_SSS_Success) {
555 status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC);
556 }
557 if (status == kStatus_SSS_Success) {
558 status = sss_key_object_init(&newKey, &host_keystore);
559 }
560 if (status == kStatus_SSS_Success) {
561 status = sss_key_object_get_handle(&newKey, key->keyId);
562 }
563 if (status == kStatus_SSS_Success) {
564 status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi,
565 &newKey, algorithm, kMode_SSS_Sign);
566 if (status == kStatus_SSS_Success) {
567 byte sigBuf[ECC_MAX_SIG_SIZE];
568 size_t sigSz = sizeof(sigBuf);
569 status = sss_asymmetric_sign_digest(&ctx_asymm, (uint8_t*)in, inLen,
570 sigBuf, &sigSz);
571 if (status == kStatus_SSS_Success) {
572 /* SE050 returns ASN.1 encoded signature */
573 word32 rLen = keySize, sLen = keySize;
574 ret = DecodeECC_DSA_Sig_Bin(sigBuf, (word32)sigSz,
575 out, &rLen,
576 out+keySize, &sLen);
577 if (ret != 0) {
578 status = kStatus_SSS_Fail;
579 }
580 }
581 }
582 sss_asymmetric_context_free(&ctx_asymm);
583 }
584
585 if (status == kStatus_SSS_Success) {
586 ret = 0;
587 }
588 else {
589 if (ret == 0)
590 ret = WC_HW_E;
591 }
592
593 wolfSSL_CryptHwMutexUnLock();
594
595 #ifdef SE050_DEBUG
596 printf("se050_ecc_sign_hash_ex: ret %d, outLen %d\n", ret, *outLen);
597 #endif
598
599 (void)outLen; /* caller sets outLen */
600
601 return ret;
602 }
603
se050_ecc_verify_hash_ex(const byte * hash,word32 hashLen,byte * sigRS,word32 sigRSLen,struct ecc_key * key,int * res)604 int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* sigRS,
605 word32 sigRSLen, struct ecc_key* key, int* res)
606 {
607 int ret = 0;
608 sss_status_t status;
609 sss_asymmetric_t ctx_asymm;
610 sss_object_t newKey;
611 sss_key_store_t host_keystore;
612 sss_algorithm_t algorithm;
613 int keyId;
614 int keySize;
615 int keySizeBits;
616 sss_cipher_type_t curveType;
617 int keyCreated = 0;
618
619 #ifdef SE050_DEBUG
620 printf("se050_ecc_verify_hash_ex: key %p, hash %p (%d), sig %p (%d)\n",
621 key, hash, hashLen, sigRS, sigRSLen);
622 #endif
623
624 *res = 0;
625 (void)sigRSLen;
626
627 if (cfg_se050_i2c_pi == NULL) {
628 return WC_HW_E;
629 }
630
631 keySize = key->dp->size;
632 ret = se050_map_curve(key->dp->id, keySize, &keySizeBits, &curveType);
633 if (ret != 0) {
634 return ret;
635 }
636
637 /* truncate hash if larger than key size */
638 if (hashLen > (word32)keySize)
639 hashLen = (word32)keySize;
640
641 algorithm = se050_map_hash_alg(hashLen);
642 if (algorithm == kAlgorithm_None) {
643 hashLen = keySize; /* try key size */
644 algorithm = se050_map_hash_alg(hashLen);
645 }
646 if (algorithm == kAlgorithm_None) {
647 return ECC_CURVE_OID_E;
648 }
649
650 if (wolfSSL_CryptHwMutexLock() != 0) {
651 return BAD_MUTEX_E;
652 }
653
654 status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
655 if (status == kStatus_SSS_Success) {
656 status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC);
657 }
658 if (status == kStatus_SSS_Success) {
659 status = sss_key_object_init(&newKey, &host_keystore);
660 }
661
662 /* this is run when a key was not generated and was instead passed in */
663 if (status == kStatus_SSS_Success) {
664 keyId = key->keyId;
665 if (keyId <= 0) {
666 byte derBuf[SE050_ECC_DER_MAX];
667 word32 derSz;
668
669 ret = wc_EccPublicKeyToDer(key, derBuf, (word32)sizeof(derBuf), 1);
670 if (ret >= 0) {
671 derSz = ret;
672 ret = 0;
673 }
674 else {
675 status = kStatus_SSS_Fail;
676 }
677 if (status == kStatus_SSS_Success) {
678 keyId = se050_allocate_key(SE050_ECC_KEY);
679 status = sss_key_object_allocate_handle(&newKey, keyId,
680 kSSS_KeyPart_Public, curveType, keySize,
681 kKeyObject_Mode_Transient);
682 }
683 if (status == kStatus_SSS_Success) {
684 keyCreated = 1;
685 status = sss_key_store_set_key(&host_keystore, &newKey, derBuf,
686 derSz, keySizeBits, NULL, 0);
687 }
688 }
689 else {
690 status = sss_key_object_get_handle(&newKey, keyId);
691 }
692 }
693
694 if (status == kStatus_SSS_Success) {
695 status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi,
696 &newKey, algorithm, kMode_SSS_Verify);
697 if (status == kStatus_SSS_Success) {
698 /* SE050 expects ASN.1 encoded signature */
699 byte sigBuf[ECC_MAX_SIG_SIZE];
700 word32 sigSz = (word32)sizeof(sigBuf);
701 ret = StoreECC_DSA_Sig_Bin(sigBuf, &sigSz,
702 sigRS, keySize,
703 sigRS+keySize, keySize);
704 if (ret == 0) {
705 status = sss_asymmetric_verify_digest(&ctx_asymm,
706 (uint8_t*)hash, hashLen, sigBuf, sigSz);
707 }
708 else {
709 status = kStatus_SSS_Fail;
710 }
711 }
712
713 sss_asymmetric_context_free(&ctx_asymm);
714 }
715
716 if (status == kStatus_SSS_Success) {
717 key->keyId = keyId;
718 *res = 1;
719 ret = 0;
720 }
721 else {
722 if (keyCreated) {
723 sss_key_store_erase_key(&host_keystore, &newKey);
724 sss_key_object_free(&newKey);
725 }
726 if (ret == 0)
727 ret = WC_HW_E;
728 }
729
730 wolfSSL_CryptHwMutexUnLock();
731
732 #ifdef SE050_DEBUG
733 printf("se050_ecc_verify_hash_ex: key %p, ret %d, res %d\n",
734 key, ret, *res);
735 #endif
736
737 return ret;
738 }
739
740
se050_ecc_free_key(struct ecc_key * key)741 void se050_ecc_free_key(struct ecc_key* key)
742 {
743 sss_status_t status = kStatus_SSS_Success;
744 sss_object_t keyObject;
745 sss_key_store_t host_keystore;
746
747 #ifdef SE050_DEBUG
748 printf("se050_ecc_free_key: key %p, keyId %d\n", key, key->keyId);
749 #endif
750
751 if (cfg_se050_i2c_pi == NULL) {
752 return;
753 }
754 if (key->keyId <= 0) {
755 return;
756 }
757
758 if (wolfSSL_CryptHwMutexLock() != 0) {
759 return;
760 }
761
762 status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
763 if (status == kStatus_SSS_Success) {
764 status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC);
765 }
766 if (status == kStatus_SSS_Success) {
767 status = sss_key_object_init(&keyObject, &host_keystore);
768 }
769 if (status == kStatus_SSS_Success) {
770 status = sss_key_object_get_handle(&keyObject, key->keyId);
771 }
772 if (status == kStatus_SSS_Success) {
773 if ((key->flags & WC_ECC_FLAG_DEC_SIGN) == 0) {
774 /* key was not used for signing, so release it */
775 sss_key_store_erase_key(&host_keystore, &keyObject);
776 }
777 sss_key_object_free(&keyObject);
778 key->keyId = -1;
779 }
780 wolfSSL_CryptHwMutexUnLock();
781 }
782
se050_ecc_create_key(struct ecc_key * key,int curve_id,int keySize)783 int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize)
784 {
785 int ret = 0;
786 sss_status_t status = kStatus_SSS_Success;
787 sss_object_t keyPair;
788 sss_key_store_t host_keystore;
789 uint8_t derBuf[SE050_ECC_DER_MAX];
790 size_t derSz = sizeof(derBuf);
791 int keyId;
792 int keySizeBits;
793 sss_cipher_type_t curveType;
794 int keyCreated = 0;
795
796 #ifdef SE050_DEBUG
797 printf("se050_ecc_create_key: key %p, curve %d, keySize %d\n",
798 key, curve_id, keySize);
799 #endif
800
801 if (cfg_se050_i2c_pi == NULL) {
802 return WC_HW_E;
803 }
804
805 ret = se050_map_curve(curve_id, keySize, &keySizeBits, &curveType);
806 if (ret != 0) {
807 return ret;
808 }
809
810 if (wolfSSL_CryptHwMutexLock() != 0) {
811 return BAD_MUTEX_E;
812 }
813
814 status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
815 if (status == kStatus_SSS_Success) {
816 status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC);
817 }
818 if (status == kStatus_SSS_Success) {
819 status = sss_key_object_init(&keyPair, &host_keystore);
820 }
821 if (status == kStatus_SSS_Success) {
822 keyId = se050_allocate_key(SE050_ECC_KEY);
823 status = sss_key_object_allocate_handle(&keyPair, keyId,
824 kSSS_KeyPart_Pair, curveType, keySize,
825 kKeyObject_Mode_Transient);
826 }
827 if (status == kStatus_SSS_Success) {
828 keyCreated = 1;
829 status = sss_key_store_generate_key(&host_keystore, &keyPair,
830 keySizeBits, NULL);
831 }
832 if (status == kStatus_SSS_Success) {
833 size_t derSzBits = derSz * 8;
834 status = sss_key_store_get_key(&host_keystore, &keyPair,
835 derBuf, &derSz, &derSzBits);
836 (void)derSzBits; /* not used */
837 }
838 if (status == kStatus_SSS_Success) {
839 word32 idx = 0;
840 ret = wc_EccPublicKeyDecode(derBuf, &idx, key, (word32)derSz);
841 if (ret != 0) {
842 status = kStatus_SSS_Fail;
843 }
844 }
845 if (status == kStatus_SSS_Success) {
846 key->keyId = keyId;
847 ret = 0;
848 }
849 else {
850 if (keyCreated) {
851 sss_key_store_erase_key(&host_keystore, &keyPair);
852 sss_key_object_free(&keyPair);
853 }
854 if (ret == 0)
855 ret = WC_HW_E;
856 }
857
858 wolfSSL_CryptHwMutexUnLock();
859
860 #ifdef SE050_DEBUG
861 printf("se050_ecc_create_key: key %p, ret %d, keyId %d\n",
862 key, ret, key->keyId);
863 #endif
864
865 return ret;
866 }
867
868
se050_ecc_shared_secret(ecc_key * private_key,ecc_key * public_key,byte * out,word32 * outlen)869 int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key,
870 byte* out, word32* outlen)
871 {
872 int ret;
873 sss_status_t status = kStatus_SSS_Success;
874 sss_key_store_t host_keystore;
875 sss_object_t ref_private_key;
876 sss_object_t ref_public_key;
877 sss_object_t deriveKey;
878 sss_derive_key_t ctx_derive_key;
879 int keyId;
880 int keySize;
881 int keySizeBits;
882 sss_cipher_type_t curveType;
883 int keyCreated = 0;
884 int deriveKeyCreated = 0;
885
886 #ifdef SE050_DEBUG
887 printf("se050_ecc_shared_secret: priv %p, pub %p, out %p (%d)\n",
888 private_key, public_key, out, *outlen);
889 #endif
890
891 if (cfg_se050_i2c_pi == NULL) {
892 return WC_HW_E;
893 }
894 if (private_key->keyId <= 0) {
895 return BAD_FUNC_ARG;
896 }
897
898 keySize = private_key->dp->size;
899 ret = se050_map_curve(private_key->dp->id, keySize, &keySizeBits, &curveType);
900 if (ret != 0) {
901 return ret;
902 }
903
904 if (wolfSSL_CryptHwMutexLock() != 0) {
905 return BAD_MUTEX_E;
906 }
907
908 status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
909 if (status == kStatus_SSS_Success) {
910 status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC);
911 }
912 if (status == kStatus_SSS_Success) {
913 status = sss_key_object_init(&ref_private_key, &host_keystore);
914 }
915 if (status == kStatus_SSS_Success) {
916 status = sss_key_object_get_handle(&ref_private_key, private_key->keyId);
917 }
918 if (status == kStatus_SSS_Success) {
919 status = sss_key_object_init(&ref_public_key, &host_keystore);
920 }
921 if (status == kStatus_SSS_Success) {
922 keyId = public_key->keyId;
923 if (keyId <= 0) {
924 byte derBuf[SE050_ECC_DER_MAX];
925 word32 derSz;
926
927 ret = wc_EccPublicKeyToDer(public_key, derBuf,
928 (word32)sizeof(derBuf), 1);
929 if (ret >= 0) {
930 derSz = ret;
931 ret = 0;
932 }
933 else {
934 status = kStatus_SSS_Fail;
935 }
936 if (status == kStatus_SSS_Success) {
937 keyId = se050_allocate_key(SE050_ECC_KEY);
938 status = sss_key_object_allocate_handle(&ref_public_key,
939 keyId, kSSS_KeyPart_Public, curveType, keySize,
940 kKeyObject_Mode_Transient);
941 }
942 if (status == kStatus_SSS_Success) {
943 keyCreated = 1;
944 status = sss_key_store_set_key(&host_keystore, &ref_public_key,
945 derBuf, derSz, keySizeBits, NULL, 0);
946 }
947 }
948 else {
949 status = sss_key_object_get_handle(&ref_public_key, keyId);
950 }
951 }
952 if (status == kStatus_SSS_Success) {
953 status = sss_key_object_init(&deriveKey, &host_keystore);
954 }
955 if (status == kStatus_SSS_Success) {
956 int keyIdAes = se050_allocate_key(SE050_AES_KEY);
957 deriveKeyCreated = 1;
958 status = sss_key_object_allocate_handle(&deriveKey,
959 keyIdAes,
960 kSSS_KeyPart_Default,
961 kSSS_CipherType_Binary,
962 keySize,
963 kKeyObject_Mode_Transient);
964 }
965 if (status == kStatus_SSS_Success) {
966 status = sss_derive_key_context_init(&ctx_derive_key, cfg_se050_i2c_pi,
967 &ref_private_key, kAlgorithm_SSS_ECDH,
968 kMode_SSS_ComputeSharedSecret);
969 if (status == kStatus_SSS_Success) {
970 status = sss_derive_key_dh(&ctx_derive_key, &ref_public_key,
971 &deriveKey);
972 }
973 if (status == kStatus_SSS_Success) {
974 size_t outlenSz = (size_t)*outlen;
975 size_t outlenSzBits = outlenSz * 8;
976 /* derived key export */
977 status = sss_key_store_get_key(&host_keystore, &deriveKey, out,
978 &outlenSz, &outlenSzBits);
979 *outlen = (word32)outlenSz;
980 (void)outlenSzBits; /* not used */
981 }
982
983 sss_derive_key_context_free(&ctx_derive_key);
984 }
985 if (deriveKeyCreated) {
986 sss_key_store_erase_key(&host_keystore, &deriveKey);
987 sss_key_object_free(&deriveKey);
988 }
989
990 if (status == kStatus_SSS_Success) {
991 public_key->keyId = keyId;
992 ret = 0;
993 }
994 else {
995 if (keyCreated) {
996 sss_key_store_erase_key(&host_keystore, &public_key);
997 sss_key_object_free(&public_key);
998 }
999 if (ret == 0)
1000 ret = WC_HW_E;
1001 }
1002
1003 wolfSSL_CryptHwMutexUnLock();
1004
1005 #ifdef SE050_DEBUG
1006 printf("se050_ecc_shared_secret: ret %d, outlen %d\n", ret, *outlen);
1007 #endif
1008
1009 return ret;
1010 }
1011 #endif /* HAVE_ECC */
1012
1013 #ifdef HAVE_ED25519
1014
se050_ed25519_create_key(ed25519_key * key)1015 int se050_ed25519_create_key(ed25519_key* key)
1016 {
1017 int ret = 0;
1018 sss_status_t status;
1019 sss_key_store_t host_keystore;
1020 sss_object_t newKey;
1021 int keyId;
1022 int keySize = ED25519_KEY_SIZE;
1023 int keyCreated = 0;
1024
1025 #ifdef SE050_DEBUG
1026 printf("se050_ed25519_create_key: %p\n", key);
1027 #endif
1028
1029 if (cfg_se050_i2c_pi == NULL) {
1030 return WC_HW_E;
1031 }
1032
1033 if (wolfSSL_CryptHwMutexLock() != 0) {
1034 return BAD_MUTEX_E;
1035 }
1036
1037 status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
1038 if (status == kStatus_SSS_Success) {
1039 status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ED25519);
1040 }
1041 if (status == kStatus_SSS_Success) {
1042 status = sss_key_object_init(&newKey, &host_keystore);
1043 }
1044 if (status == kStatus_SSS_Success) {
1045 keyId = se050_allocate_key(SE050_ED25519_KEY);
1046 status = sss_key_object_allocate_handle(&newKey, keyId,
1047 kSSS_KeyPart_Pair, kSSS_CipherType_EC_TWISTED_ED, keySize,
1048 kKeyObject_Mode_Transient);
1049 }
1050 if (status == kStatus_SSS_Success) {
1051 keyCreated = 1;
1052 status = sss_key_store_generate_key(&host_keystore, &newKey,
1053 keySize * 8, NULL);
1054 }
1055
1056 if (status == kStatus_SSS_Success) {
1057 key->keyId = keyId;
1058 ret = 0;
1059 }
1060 else {
1061 if (keyCreated) {
1062 sss_key_store_erase_key(&host_keystore, &newKey);
1063 sss_key_object_free(&newKey);
1064 }
1065 ret = WC_HW_E;
1066 }
1067
1068 wolfSSL_CryptHwMutexUnLock();
1069
1070 #ifdef SE050_DEBUG
1071 printf("se050_ed25519_create_key: ret %d, keyId %d\n", ret, key->keyId);
1072 #endif
1073
1074 return ret;
1075 }
1076
se050_ed25519_free_key(ed25519_key * key)1077 void se050_ed25519_free_key(ed25519_key* key)
1078 {
1079 sss_status_t status;
1080 sss_object_t newKey;
1081 sss_key_store_t host_keystore;
1082
1083 #ifdef SE050_DEBUG
1084 printf("se050_ed25519_free_key: %p, id %d\n", key, key->keyId);
1085 #endif
1086
1087 if (cfg_se050_i2c_pi == NULL) {
1088 return;
1089 }
1090 if (key->keyId <= 0) {
1091 return;
1092 }
1093
1094 if (wolfSSL_CryptHwMutexLock() != 0) {
1095 return;
1096 }
1097
1098 status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
1099
1100 if (status == kStatus_SSS_Success) {
1101 status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ED25519);
1102 }
1103 if (status == kStatus_SSS_Success) {
1104 status = sss_key_object_init(&newKey, &host_keystore);
1105 }
1106 if (status == kStatus_SSS_Success) {
1107 status = sss_key_object_get_handle(&newKey, key->keyId);
1108 }
1109 if (status == kStatus_SSS_Success) {
1110 sss_key_object_free(&newKey);
1111 key->keyId = -1;
1112 }
1113 wolfSSL_CryptHwMutexUnLock();
1114 }
1115
se050_ed25519_sign_msg(const byte * in,word32 inLen,byte * out,word32 * outLen,ed25519_key * key)1116 int se050_ed25519_sign_msg(const byte* in, word32 inLen, byte* out,
1117 word32 *outLen, ed25519_key* key)
1118 {
1119 int ret = 0;
1120 sss_status_t status = kStatus_SSS_Success;
1121 sss_asymmetric_t ctx_asymm;
1122 sss_key_store_t host_keystore;
1123 sss_object_t newKey;
1124
1125 #ifdef SE050_DEBUG
1126 printf("se050_ed25519_sign_msg: key %p, in %p (%d), out %p (%d), keyId %d\n",
1127 key, in, inLen, out, *outLen, key->keyId);
1128 #endif
1129
1130 if (cfg_se050_i2c_pi == NULL) {
1131 return WC_HW_E;
1132 }
1133 if (key->keyId <= 0) {
1134 return BAD_FUNC_ARG;
1135 }
1136
1137 if (wolfSSL_CryptHwMutexLock() != 0) {
1138 return BAD_MUTEX_E;
1139 }
1140
1141 status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
1142 if (status == kStatus_SSS_Success) {
1143 status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ED25519);
1144 }
1145 if (status == kStatus_SSS_Success) {
1146 status = sss_key_object_init(&newKey, &host_keystore);
1147 }
1148 if (status == kStatus_SSS_Success) {
1149 status = sss_key_object_get_handle(&newKey, key->keyId);
1150 }
1151 if (status == kStatus_SSS_Success) {
1152 status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi,
1153 &newKey, kAlgorithm_SSS_SHA512, kMode_SSS_Sign);
1154 if (status == kStatus_SSS_Success) {
1155 size_t outlenSz = (size_t)*outLen;
1156 status = sss_se05x_asymmetric_sign((sss_se05x_asymmetric_t *)&ctx_asymm,
1157 (uint8_t *)in, inLen, out, &outlenSz);
1158 *outLen = (word32)outlenSz;
1159 }
1160
1161 sss_asymmetric_context_free(&ctx_asymm);
1162 }
1163
1164 if (status != kStatus_SSS_Success) {
1165 ret = WC_HW_E;
1166 }
1167
1168 wolfSSL_CryptHwMutexUnLock();
1169
1170 #ifdef SE050_DEBUG
1171 printf("se050_ed25519_sign_msg: ret %d, outLen %d\n", ret, *outLen);
1172 #endif
1173
1174 return ret;
1175 }
1176
se050_ed25519_verify_msg(const byte * signature,word32 signatureLen,const byte * msg,word32 msgLen,struct ed25519_key * key,int * res)1177 int se050_ed25519_verify_msg(const byte* signature, word32 signatureLen,
1178 const byte* msg, word32 msgLen, struct ed25519_key* key, int* res)
1179 {
1180 int ret = 0;
1181 sss_status_t status = kStatus_SSS_Success;
1182 sss_asymmetric_t ctx_asymm;
1183 sss_object_t newKey;
1184 sss_key_store_t host_keystore;
1185 int keyId;
1186 int keySize = ED25519_KEY_SIZE;
1187 int keyCreated = 0;
1188
1189 #ifdef SE050_DEBUG
1190 printf("se050_ed25519_verify_msg: key %p, sig %p (%d), msg %p (%d)\n",
1191 key, signature, signatureLen, msg, msgLen);
1192 #endif
1193
1194 if (cfg_se050_i2c_pi == NULL) {
1195 return WC_HW_E;
1196 }
1197
1198 if (wolfSSL_CryptHwMutexLock() != 0) {
1199 return BAD_MUTEX_E;
1200 }
1201
1202 status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
1203 if (status == kStatus_SSS_Success) {
1204 status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ED25519);
1205 }
1206 if (status == kStatus_SSS_Success) {
1207 status = sss_key_object_init(&newKey, &host_keystore);
1208 }
1209 if (status == kStatus_SSS_Success) {
1210 keyId = key->keyId;
1211 if (keyId <= 0) {
1212 byte derBuf[48];
1213 word32 derSz = 0, idx = 0;
1214
1215 ret = wc_Ed25519PublicKeyDecode(derBuf, &idx, key,
1216 (word32)sizeof(derBuf));
1217 if (ret >= 0) {
1218 derSz = ret;
1219 ret = 0;
1220 }
1221 else {
1222 status = kStatus_SSS_Fail;
1223 }
1224 if (status == kStatus_SSS_Success) {
1225 keyId = se050_allocate_key(SE050_ED25519_KEY);
1226 status = sss_key_object_allocate_handle(&newKey, keyId,
1227 kSSS_KeyPart_Pair, kSSS_CipherType_EC_TWISTED_ED, keySize,
1228 kKeyObject_Mode_Transient);
1229 }
1230 if (status == kStatus_SSS_Success) {
1231 keyCreated = 1;
1232 status = sss_key_store_set_key(&host_keystore, &newKey, derBuf,
1233 derSz, keySize * 8, NULL, 0);
1234 }
1235 }
1236 else {
1237 status = sss_key_object_get_handle(&newKey, keyId);
1238 }
1239 }
1240
1241 if (status == kStatus_SSS_Success) {
1242 status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi,
1243 &newKey, kAlgorithm_SSS_SHA512, kMode_SSS_Verify);
1244 if (status == kStatus_SSS_Success) {
1245 status = sss_se05x_asymmetric_verify(
1246 (sss_se05x_asymmetric_t*)&ctx_asymm, (uint8_t*)msg, msgLen,
1247 (uint8_t*)signature, (size_t)signatureLen);
1248 }
1249 sss_asymmetric_context_free(&ctx_asymm);
1250 }
1251
1252 if (status == kStatus_SSS_Success) {
1253 key->keyId = keyId;
1254 *res = 1;
1255 ret = 0;
1256 }
1257 else {
1258 if (keyCreated) {
1259 sss_key_store_erase_key(&host_keystore, &newKey);
1260 sss_key_object_free(&newKey);
1261 }
1262 if (ret == 0)
1263 ret = WC_HW_E;
1264 }
1265
1266 wolfSSL_CryptHwMutexUnLock();
1267
1268 #ifdef SE050_DEBUG
1269 printf("se050_ed25519_verify_msg: ret %d, res %d\n", ret, *res);
1270 #endif
1271
1272 return ret;
1273 }
1274
1275 #endif /* HAVE_ED25519 */
1276
1277
1278 #ifdef HAVE_CURVE25519
1279
se050_curve25519_create_key(curve25519_key * key,int keySize)1280 int se050_curve25519_create_key(curve25519_key* key, int keySize)
1281 {
1282 int ret;
1283 sss_status_t status = kStatus_SSS_Success;
1284 sss_object_t keyPair;
1285 sss_key_store_t host_keystore;
1286 uint8_t derBuf[SE050_ECC_DER_MAX];
1287 size_t derSz = sizeof(derBuf);
1288 int keyId;
1289 int keyCreated = 0;
1290
1291 #ifdef SE050_DEBUG
1292 printf("se050_curve25519_create_key: key %p, keySize %d\n",
1293 key, keySize);
1294 #endif
1295
1296 if (cfg_se050_i2c_pi == NULL) {
1297 return WC_HW_E;
1298 }
1299 if (wolfSSL_CryptHwMutexLock() != 0) {
1300 return BAD_MUTEX_E;
1301 }
1302
1303 status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
1304 if (status == kStatus_SSS_Success) {
1305 status = sss_key_store_allocate(&host_keystore,
1306 SE050_KEYSTOREID_CURVE25519);
1307 }
1308 if (status == kStatus_SSS_Success) {
1309 status = sss_key_object_init(&keyPair, &host_keystore);
1310 }
1311 if (status == kStatus_SSS_Success) {
1312 keyId = se050_allocate_key(SE050_CURVE25519_KEY);
1313 status = sss_key_object_allocate_handle(&keyPair, keyId,
1314 kSSS_KeyPart_Pair, kSSS_CipherType_EC_MONTGOMERY, keySize,
1315 kKeyObject_Mode_None);
1316 }
1317 if (status == kStatus_SSS_Success) {
1318 keyCreated = 1;
1319 status = sss_key_store_generate_key(&host_keystore, &keyPair,
1320 keySize * 8, NULL);
1321 }
1322 if (status == kStatus_SSS_Success) {
1323 size_t derSzBits = derSz * 8;
1324 status = sss_key_store_get_key(&host_keystore, &keyPair,
1325 derBuf, &derSz, &derSzBits);
1326 (void)derSzBits; /* not used */
1327 }
1328 if (status == kStatus_SSS_Success) {
1329 word32 idx = 0;
1330 ret = wc_Curve25519PublicKeyDecode(derBuf, &idx, key, (word32)derSz);
1331 if (ret == 0) {
1332 key->p.point[CURVE25519_KEYSIZE-1] &= ~0x80; /* clear MSB */
1333 }
1334 else {
1335 status = kStatus_SSS_Fail;
1336 }
1337 }
1338
1339 if (status == kStatus_SSS_Success) {
1340 key->keyId = keyId;
1341 ret = 0;
1342 }
1343 else {
1344 if (keyCreated) {
1345 sss_key_store_erase_key(&host_keystore, &keyPair);
1346 sss_key_object_free(&keyPair);
1347 }
1348 ret = WC_HW_E;
1349 }
1350 wolfSSL_CryptHwMutexUnLock();
1351
1352 #ifdef SE050_DEBUG
1353 printf("se050_curve25519_create_key: key %p, ret %d, keyId %d\n",
1354 key, ret, key->keyId);
1355 #endif
1356
1357 return ret;
1358 }
1359
se050_curve25519_shared_secret(curve25519_key * private_key,curve25519_key * public_key,ECPoint * out)1360 int se050_curve25519_shared_secret(curve25519_key* private_key,
1361 curve25519_key* public_key, ECPoint* out)
1362 {
1363 int ret;
1364 sss_status_t status = kStatus_SSS_Success;
1365 sss_key_store_t host_keystore;
1366 sss_object_t ref_private_key;
1367 sss_object_t ref_public_key;
1368 sss_object_t deriveKey;
1369 sss_derive_key_t ctx_derive_key;
1370 int keyId;
1371 int keySize = CURVE25519_KEYSIZE;
1372 int keyCreated = 0;
1373 int deriveKeyCreated = 0;
1374
1375 #ifdef SE050_DEBUG
1376 printf("se050_curve25519_shared_secret: priv %p, pub %p, out %p (%d)\n",
1377 private_key, public_key, out, out->pointSz);
1378 #endif
1379
1380 if (cfg_se050_i2c_pi == NULL) {
1381 return WC_HW_E;
1382 }
1383 if (private_key->keyId <= 0) {
1384 return BAD_FUNC_ARG;
1385 }
1386
1387 if (wolfSSL_CryptHwMutexLock() != 0) {
1388 return BAD_MUTEX_E;
1389 }
1390
1391 status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
1392 if (status == kStatus_SSS_Success) {
1393 status = sss_key_store_allocate(&host_keystore,
1394 SE050_KEYSTOREID_CURVE25519);
1395 }
1396 if (status == kStatus_SSS_Success) {
1397 status = sss_key_object_init(&ref_private_key, &host_keystore);
1398 }
1399 if (status == kStatus_SSS_Success) {
1400 status = sss_key_object_get_handle(&ref_private_key, private_key->keyId);
1401 }
1402 if (status == kStatus_SSS_Success) {
1403 status = sss_key_object_init(&ref_public_key, &host_keystore);
1404 }
1405 if (status == kStatus_SSS_Success) {
1406 keyId = public_key->keyId;
1407 if (keyId <= 0) {
1408 byte derBuf[SE050_ECC_DER_MAX];
1409 word32 derSz;
1410
1411 ret = wc_Curve25519PublicKeyToDer(public_key, derBuf,
1412 (word32)sizeof(derBuf), 1);
1413 if (ret >= 0) {
1414 derSz = ret;
1415 ret = 0;
1416 }
1417 else {
1418 status = kStatus_SSS_Fail;
1419 }
1420 if (status == kStatus_SSS_Success) {
1421 keyId = se050_allocate_key(SE050_CURVE25519_KEY);
1422 status = sss_key_object_allocate_handle(&ref_public_key,
1423 keyId, kSSS_KeyPart_Public, kSSS_CipherType_EC_MONTGOMERY,
1424 keySize, kKeyObject_Mode_Transient);
1425 }
1426 if (status == kStatus_SSS_Success) {
1427 keyCreated = 1;
1428 status = sss_key_store_set_key(&host_keystore, &ref_public_key,
1429 derBuf, derSz, keySize * 8, NULL, 0);
1430 }
1431 }
1432 else {
1433 status = sss_key_object_get_handle(&ref_public_key, keyId);
1434 }
1435 }
1436 if (status == kStatus_SSS_Success) {
1437 status = sss_key_object_init(&deriveKey, &host_keystore);
1438 }
1439 if (status == kStatus_SSS_Success) {
1440 int keyIdAes = se050_allocate_key(SE050_AES_KEY);
1441 deriveKeyCreated = 1;
1442 status = sss_key_object_allocate_handle(&deriveKey,
1443 keyIdAes,
1444 kSSS_KeyPart_Default,
1445 kSSS_CipherType_Binary,
1446 keySize,
1447 kKeyObject_Mode_Transient);
1448 }
1449 if (status == kStatus_SSS_Success) {
1450 status = sss_derive_key_context_init(&ctx_derive_key, cfg_se050_i2c_pi,
1451 &ref_private_key, kAlgorithm_SSS_ECDH,
1452 kMode_SSS_ComputeSharedSecret);
1453 if (status == kStatus_SSS_Success) {
1454 status = sss_derive_key_dh(&ctx_derive_key, &ref_public_key,
1455 &deriveKey);
1456 }
1457 if (status == kStatus_SSS_Success) {
1458 size_t outlenSz = sizeof(out->point);
1459 size_t outlenSzBits = outlenSz * 8;
1460 /* derived key export */
1461 status = sss_key_store_get_key(&host_keystore, &deriveKey,
1462 out->point, &outlenSz, &outlenSzBits);
1463 out->pointSz = (word32)outlenSz;
1464 (void)outlenSzBits; /* not used */
1465 }
1466
1467 sss_derive_key_context_free(&ctx_derive_key);
1468 }
1469 if (deriveKeyCreated) {
1470 sss_key_store_erase_key(&host_keystore, &deriveKey);
1471 sss_key_object_free(&deriveKey);
1472 }
1473
1474 if (status == kStatus_SSS_Success) {
1475 public_key->keyId = keyId;
1476 ret = 0;
1477 }
1478 else {
1479 if (keyCreated) {
1480 sss_key_store_erase_key(&host_keystore, &public_key);
1481 sss_key_object_free(&public_key);
1482 }
1483 if (ret == 0)
1484 ret = WC_HW_E;
1485 }
1486
1487 wolfSSL_CryptHwMutexUnLock();
1488
1489 #ifdef SE050_DEBUG
1490 printf("se050_curve25519_shared_secret: ret %d, outlen %d\n",
1491 ret, out->pointSz);
1492 #endif
1493
1494 return ret;
1495 }
1496
se050_curve25519_free_key(struct curve25519_key * key)1497 void se050_curve25519_free_key(struct curve25519_key* key)
1498 {
1499 sss_status_t status;
1500 sss_object_t newKey;
1501 sss_key_store_t host_keystore;
1502
1503 #ifdef SE050_DEBUG
1504 printf("se050_curve25519_free_key: %p, id %d\n", key, key->keyId);
1505 #endif
1506
1507 if (cfg_se050_i2c_pi == NULL) {
1508 return;
1509 }
1510 if (key->keyId <= 0) {
1511 return;
1512 }
1513
1514 if (wolfSSL_CryptHwMutexLock() != 0) {
1515 return;
1516 }
1517
1518 status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
1519
1520 if (status == kStatus_SSS_Success) {
1521 status = sss_key_store_allocate(&host_keystore,
1522 SE050_KEYSTOREID_CURVE25519);
1523 }
1524 if (status == kStatus_SSS_Success) {
1525 status = sss_key_object_init(&newKey, &host_keystore);
1526 }
1527 if (status == kStatus_SSS_Success) {
1528 status = sss_key_object_get_handle(&newKey, key->keyId);
1529 }
1530 if (status == kStatus_SSS_Success) {
1531 sss_key_object_free(&newKey);
1532 key->keyId = -1;
1533 }
1534 wolfSSL_CryptHwMutexUnLock();
1535 }
1536 #endif /* HAVE_CURVE25519 */
1537
1538 #endif /* WOLFSSL_SE050 */
1539