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