1 /* stm32.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 /* Generic STM32 Hashing Function */
23 /* Supports CubeMX HAL or Standard Peripheral Library */
24 
25 #ifdef HAVE_CONFIG_H
26     #include <config.h>
27 #endif
28 
29 #include <wolfssl/wolfcrypt/settings.h>
30 
31 #include <wolfssl/wolfcrypt/port/st/stm32.h>
32 #include <wolfssl/wolfcrypt/types.h>
33 #include <wolfssl/wolfcrypt/error-crypt.h>
34 
35 #ifdef NO_INLINE
36     #include <wolfssl/wolfcrypt/misc.h>
37 #else
38     #define WOLFSSL_MISC_INCLUDED
39     #include <wolfcrypt/src/misc.c>
40 #endif
41 
42 #ifndef NO_AES
43     #include <wolfssl/wolfcrypt/aes.h>
44 #endif
45 
46 
47 #ifdef STM32_HASH
48 
49 #ifdef WOLFSSL_STM32L4
50     #define HASH_STR_NBW HASH_STR_NBLW
51 #endif
52 
53 /* User can override STM32_HASH_CLOCK_ENABLE and STM32_HASH_CLOCK_DISABLE */
54 #ifndef STM32_HASH_CLOCK_ENABLE
wc_Stm32_Hash_Clock_Enable(STM32_HASH_Context * stmCtx)55     static WC_INLINE void wc_Stm32_Hash_Clock_Enable(STM32_HASH_Context* stmCtx)
56     {
57     #ifdef WOLFSSL_STM32_CUBEMX
58         __HAL_RCC_HASH_CLK_ENABLE();
59     #else
60         RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_HASH, ENABLE);
61     #endif
62         (void)stmCtx;
63     }
64     #define STM32_HASH_CLOCK_ENABLE(ctx) wc_Stm32_Hash_Clock_Enable(ctx)
65 #endif
66 
67 #ifndef STM32_HASH_CLOCK_DISABLE
wc_Stm32_Hash_Clock_Disable(STM32_HASH_Context * stmCtx)68     static WC_INLINE void wc_Stm32_Hash_Clock_Disable(STM32_HASH_Context* stmCtx)
69     {
70     #ifdef WOLFSSL_STM32_CUBEMX
71         __HAL_RCC_HASH_CLK_DISABLE();
72     #else
73         RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_HASH, DISABLE);
74     #endif
75         (void)stmCtx;
76     }
77     #define STM32_HASH_CLOCK_DISABLE(ctx) wc_Stm32_Hash_Clock_Disable(ctx)
78 #endif
79 
80 /* STM32 Port Internal Functions */
wc_Stm32_Hash_SaveContext(STM32_HASH_Context * ctx)81 static WC_INLINE void wc_Stm32_Hash_SaveContext(STM32_HASH_Context* ctx)
82 {
83     int i;
84 
85     /* save context registers */
86     ctx->HASH_IMR = HASH->IMR;
87     ctx->HASH_STR = HASH->STR;
88     ctx->HASH_CR  = HASH->CR;
89     for (i=0; i<HASH_CR_SIZE; i++) {
90         ctx->HASH_CSR[i] = HASH->CSR[i];
91     }
92 }
93 
wc_Stm32_Hash_RestoreContext(STM32_HASH_Context * ctx)94 static WC_INLINE int wc_Stm32_Hash_RestoreContext(STM32_HASH_Context* ctx)
95 {
96     int i;
97 
98     if (ctx->HASH_CR != 0) {
99         /* restore context registers */
100         HASH->IMR = ctx->HASH_IMR;
101         HASH->STR = ctx->HASH_STR;
102         HASH->CR = ctx->HASH_CR;
103 
104         /* Initialize the hash processor */
105         HASH->CR |= HASH_CR_INIT;
106 
107         /* continue restoring context registers */
108         for (i=0; i<HASH_CR_SIZE; i++) {
109             HASH->CSR[i] = ctx->HASH_CSR[i];
110         }
111         return 1;
112     }
113     return 0;
114 }
115 
wc_Stm32_Hash_GetDigest(byte * hash,int digestSize)116 static WC_INLINE void wc_Stm32_Hash_GetDigest(byte* hash, int digestSize)
117 {
118     word32 digest[HASH_MAX_DIGEST/sizeof(word32)];
119 
120     /* get digest result */
121     digest[0] = HASH->HR[0];
122     digest[1] = HASH->HR[1];
123     digest[2] = HASH->HR[2];
124     digest[3] = HASH->HR[3];
125     if (digestSize >= 20) {
126         digest[4] = HASH->HR[4];
127     #ifdef HASH_DIGEST
128         if (digestSize >= 28) {
129             digest[5] = HASH_DIGEST->HR[5];
130             digest[6] = HASH_DIGEST->HR[6];
131             if (digestSize == 32)
132                 digest[7] = HASH_DIGEST->HR[7];
133         }
134     #endif
135     }
136 
137     ByteReverseWords(digest, digest, digestSize);
138 
139     XMEMCPY(hash, digest, digestSize);
140 }
141 
142 
143 /* STM32 Port Exposed Functions */
wc_Stm32_Hash_WaitDone(void)144 static WC_INLINE int wc_Stm32_Hash_WaitDone(void)
145 {
146     /* wait until hash hardware is not busy */
147     int timeout = 0;
148     while ((HASH->SR & HASH_SR_BUSY) && ++timeout < STM32_HASH_TIMEOUT) {
149 
150     }
151     /* verify timeout did not occur */
152     if (timeout >= STM32_HASH_TIMEOUT) {
153         return WC_TIMEOUT_E;
154     }
155     return 0;
156 }
157 
158 
wc_Stm32_Hash_Init(STM32_HASH_Context * stmCtx)159 void wc_Stm32_Hash_Init(STM32_HASH_Context* stmCtx)
160 {
161     /* clear context */
162     XMEMSET(stmCtx, 0, sizeof(STM32_HASH_Context));
163 }
164 
wc_Stm32_Hash_Update(STM32_HASH_Context * stmCtx,word32 algo,const byte * data,int len)165 int wc_Stm32_Hash_Update(STM32_HASH_Context* stmCtx, word32 algo,
166     const byte* data, int len)
167 {
168     int ret = 0;
169     byte* local = (byte*)stmCtx->buffer;
170     int wroteToFifo = 0;
171 
172     /* check that internal buffLen is valid */
173     if (stmCtx->buffLen >= STM32_HASH_REG_SIZE) {
174         return BUFFER_E;
175     }
176 
177     /* turn on hash clock */
178     STM32_HASH_CLOCK_ENABLE(stmCtx);
179 
180     /* restore hash context or init as new hash */
181     if (wc_Stm32_Hash_RestoreContext(stmCtx) == 0) {
182         /* reset the control register */
183         HASH->CR &= ~(HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE);
184 
185         /* configure algorithm, mode and data type */
186         HASH->CR |= (algo | HASH_ALGOMODE_HASH | HASH_DATATYPE_8B);
187 
188         /* reset HASH processor */
189         HASH->CR |= HASH_CR_INIT;
190     }
191 
192     /* write 4-bytes at a time into FIFO */
193     while (len) {
194         word32 add = min(len, STM32_HASH_REG_SIZE - stmCtx->buffLen);
195         XMEMCPY(&local[stmCtx->buffLen], data, add);
196 
197         stmCtx->buffLen += add;
198         data            += add;
199         len             -= add;
200 
201         if (stmCtx->buffLen == STM32_HASH_REG_SIZE) {
202             wroteToFifo = 1;
203             HASH->DIN = *(word32*)stmCtx->buffer;
204 
205             stmCtx->loLen += STM32_HASH_REG_SIZE;
206             stmCtx->buffLen = 0;
207         }
208     }
209 
210     if (wroteToFifo) {
211         /* save hash state for next operation */
212         wc_Stm32_Hash_SaveContext(stmCtx);
213     }
214 
215     /* turn off hash clock */
216     STM32_HASH_CLOCK_DISABLE(stmCtx);
217 
218     return ret;
219 }
220 
wc_Stm32_Hash_Final(STM32_HASH_Context * stmCtx,word32 algo,byte * hash,int digestSize)221 int wc_Stm32_Hash_Final(STM32_HASH_Context* stmCtx, word32 algo,
222     byte* hash, int digestSize)
223 {
224     int ret = 0;
225     word32 nbvalidbitsdata = 0;
226 
227     /* turn on hash clock */
228     STM32_HASH_CLOCK_ENABLE(stmCtx);
229 
230     /* restore hash state */
231     wc_Stm32_Hash_RestoreContext(stmCtx);
232 
233     /* finish reading any trailing bytes into FIFO */
234     if (stmCtx->buffLen > 0) {
235         HASH->DIN = *(word32*)stmCtx->buffer;
236         stmCtx->loLen += stmCtx->buffLen;
237     }
238 
239     /* calculate number of valid bits in last word */
240     nbvalidbitsdata = 8 * (stmCtx->loLen % STM32_HASH_REG_SIZE);
241     HASH->STR &= ~HASH_STR_NBW;
242     HASH->STR |= nbvalidbitsdata;
243 
244     /* start hash processor */
245     HASH->STR |= HASH_STR_DCAL;
246 
247     /* wait for hash done */
248     ret = wc_Stm32_Hash_WaitDone();
249     if (ret == 0) {
250         /* read message digest */
251         wc_Stm32_Hash_GetDigest(hash, digestSize);
252     }
253 
254     /* turn off hash clock */
255     STM32_HASH_CLOCK_DISABLE(stmCtx);
256 
257     return ret;
258 }
259 
260 #endif /* STM32_HASH */
261 
262 
263 #ifdef STM32_CRYPTO
264 
265 #ifndef NO_AES
266 #ifdef WOLFSSL_STM32_CUBEMX
wc_Stm32_Aes_Init(Aes * aes,CRYP_HandleTypeDef * hcryp)267 int wc_Stm32_Aes_Init(Aes* aes, CRYP_HandleTypeDef* hcryp)
268 {
269     int ret;
270     word32 keySize;
271 
272     ret = wc_AesGetKeySize(aes, &keySize);
273     if (ret != 0)
274         return ret;
275 
276     XMEMSET(hcryp, 0, sizeof(CRYP_HandleTypeDef));
277     switch (keySize) {
278         case 16: /* 128-bit key */
279             hcryp->Init.KeySize = CRYP_KEYSIZE_128B;
280             break;
281     #ifdef CRYP_KEYSIZE_192B
282         case 24: /* 192-bit key */
283             hcryp->Init.KeySize = CRYP_KEYSIZE_192B;
284             break;
285     #endif
286         case 32: /* 256-bit key */
287             hcryp->Init.KeySize = CRYP_KEYSIZE_256B;
288             break;
289         default:
290             break;
291     }
292     hcryp->Instance = CRYP;
293     hcryp->Init.DataType = CRYP_DATATYPE_8B;
294     hcryp->Init.pKey = (STM_CRYPT_TYPE*)aes->key;
295 #ifdef STM32_HAL_V2
296     hcryp->Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
297     #ifdef CRYP_HEADERWIDTHUNIT_BYTE
298     hcryp->Init.HeaderWidthUnit = CRYP_HEADERWIDTHUNIT_BYTE;
299     #endif
300 #endif
301 
302     return 0;
303 }
304 
305 #else /* Standard Peripheral Library */
306 
wc_Stm32_Aes_Init(Aes * aes,CRYP_InitTypeDef * cryptInit,CRYP_KeyInitTypeDef * keyInit)307 int wc_Stm32_Aes_Init(Aes* aes, CRYP_InitTypeDef* cryptInit,
308     CRYP_KeyInitTypeDef* keyInit)
309 {
310     int ret;
311     word32 keySize;
312     word32* aes_key;
313 
314     ret = wc_AesGetKeySize(aes, &keySize);
315     if (ret != 0)
316         return ret;
317 
318     aes_key = aes->key;
319 
320     /* crypto structure initialization */
321     CRYP_KeyStructInit(keyInit);
322     CRYP_StructInit(cryptInit);
323 
324     /* load key into correct registers */
325     switch (keySize) {
326         case 16: /* 128-bit key */
327             cryptInit->CRYP_KeySize = CRYP_KeySize_128b;
328             keyInit->CRYP_Key2Left  = aes_key[0];
329             keyInit->CRYP_Key2Right = aes_key[1];
330             keyInit->CRYP_Key3Left  = aes_key[2];
331             keyInit->CRYP_Key3Right = aes_key[3];
332             break;
333 
334         case 24: /* 192-bit key */
335             cryptInit->CRYP_KeySize = CRYP_KeySize_192b;
336             keyInit->CRYP_Key1Left  = aes_key[0];
337             keyInit->CRYP_Key1Right = aes_key[1];
338             keyInit->CRYP_Key2Left  = aes_key[2];
339             keyInit->CRYP_Key2Right = aes_key[3];
340             keyInit->CRYP_Key3Left  = aes_key[4];
341             keyInit->CRYP_Key3Right = aes_key[5];
342             break;
343 
344         case 32: /* 256-bit key */
345             cryptInit->CRYP_KeySize = CRYP_KeySize_256b;
346             keyInit->CRYP_Key0Left  = aes_key[0];
347             keyInit->CRYP_Key0Right = aes_key[1];
348             keyInit->CRYP_Key1Left  = aes_key[2];
349             keyInit->CRYP_Key1Right = aes_key[3];
350             keyInit->CRYP_Key2Left  = aes_key[4];
351             keyInit->CRYP_Key2Right = aes_key[5];
352             keyInit->CRYP_Key3Left  = aes_key[6];
353             keyInit->CRYP_Key3Right = aes_key[7];
354             break;
355 
356         default:
357             break;
358     }
359     cryptInit->CRYP_DataType = CRYP_DataType_8b;
360 
361     return 0;
362 }
363 #endif /* WOLFSSL_STM32_CUBEMX */
364 #endif /* !NO_AES */
365 #endif /* STM32_CRYPTO */
366 
367 #ifdef WOLFSSL_STM32_PKA
368 #include <stdint.h>
369 
370 #if defined(WOLFSSL_STM32L5)
371 #include <stm32l5xx_hal_conf.h>
372 #include <stm32l5xx_hal_pka.h>
373 #else
374 #include <stm32wbxx_hal_conf.h>
375 #include <stm32wbxx_hal_pka.h>
376 #endif
377 extern PKA_HandleTypeDef hpka;
378 
379 /* Reverse array in memory (in place) */
380 #ifdef HAVE_ECC
381 #include <wolfssl/wolfcrypt/ecc.h>
382 
383 /* convert from mp_int to STM32 PKA HAL integer, as array of bytes of size sz.
384  * if mp_int has less bytes than sz, add zero bytes at most significant byte positions.
385  * This is when for example modulus is 32 bytes (P-256 curve)
386  * and mp_int has only 31 bytes, we add leading zeros
387  * so that result array has 32 bytes, same as modulus (sz).
388  */
stm32_get_from_mp_int(uint8_t * dst,const mp_int * a,int sz)389 static int stm32_get_from_mp_int(uint8_t *dst, const mp_int *a, int sz)
390 {
391     int res;
392     int szbin;
393     int offset;
394 
395     if (a == NULL || dst == NULL || sz < 0)
396         return BAD_FUNC_ARG;
397 
398     /* check how many bytes are in the mp_int */
399     szbin = mp_unsigned_bin_size(a);
400     if (szbin < 0 || szbin > sz)
401         return BUFFER_E;
402 
403     /* compute offset from dst */
404     offset = sz - szbin;
405     if (offset < 0)
406         offset = 0;
407     if (offset > sz)
408         offset = sz;
409 
410     /* add leading zeroes */
411     if (offset)
412         XMEMSET(dst, 0, offset);
413 
414     /* convert mp_int to array of bytes */
415     res = mp_to_unsigned_bin((mp_int*)a, dst + offset);
416     return res;
417 }
418 
419 /* ECC specs in lsbyte at lowest address format for direct use by STM32_PKA PKHA driver functions */
420 #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
421 #define ECC192
422 #endif
423 #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
424 #define ECC224
425 #endif
426 #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
427 #define ECC256
428 #endif
429 #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
430 #define ECC384
431 #endif
432 
433 /* STM32 PKA supports up to 640bit numbers */
434 #define STM32_MAX_ECC_SIZE (80)
435 
436 
437 /* P-192 */
438 #ifdef ECC192
439 #define ECC192_KEYSIZE (24)
440 static const uint8_t stm32_ecc192_prime[ECC192_KEYSIZE] = {
441     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
442     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
443     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
444 };
445 static const uint32_t stm32_ecc192_coef_sign = 1U;
446 static const uint8_t stm32_ecc192_coef[ECC192_KEYSIZE] = {
447     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
448     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
449     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
450 };
451 static const uint8_t stm32_ecc192_pointX[ECC192_KEYSIZE] =  {
452     0x18, 0x8D, 0xA8, 0x0E,  0xB0, 0x30, 0x90, 0xF6,
453     0x7C, 0xBF, 0x20, 0xEB,  0x43, 0xA1, 0x88, 0x00,
454     0xF4, 0xFF, 0x0A, 0xFD,  0x82, 0xFF, 0x10, 0x12
455 };
456 static const uint8_t stm32_ecc192_pointY[ECC192_KEYSIZE] = {
457     0x07, 0x19, 0x2B, 0x95,  0xFF, 0xC8, 0xDA, 0x78,
458     0x63, 0x10, 0x11, 0xED,  0x6B, 0x24, 0xCD, 0xD5,
459     0x73, 0xF9, 0x77, 0xA1,  0x1E, 0x79, 0x48, 0x11
460 };
461 static const uint8_t stm32_ecc192_order[ECC192_KEYSIZE] = {
462     0xFF, 0xFF, 0xFF, 0xFF,  0xFF, 0xFF, 0xFF, 0xFF,
463     0xFF, 0xFF, 0xFF, 0xFF,  0x99, 0xDE, 0xF8, 0x36,
464     0x14, 0x6B, 0xC9, 0xB1,  0xB4, 0xD2, 0x28, 0x31
465 };
466 #endif /* ECC192 */
467 
468 /* P-224 */
469 #ifdef ECC224
470 #define ECC224_KEYSIZE (28)
471 static const uint8_t stm32_ecc224_prime[ECC224_KEYSIZE] = {
472     0xFF, 0xFF, 0xFF, 0xFF,  0xFF, 0xFF, 0xFF, 0xFF,
473     0xFF, 0xFF, 0xFF, 0xFF,  0xFF, 0xFF, 0xFF, 0xFF,
474     0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
475     0x00, 0x00, 0x00, 0x01
476 };
477 static const uint32_t stm32_ecc224_coef_sign = 1U;
478 static const uint8_t stm32_ecc224_coef[ECC224_KEYSIZE] = {
479     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
480     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
481     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
482     0x00, 0x00, 0x00, 0x03
483 };
484 static const uint8_t stm32_ecc224_pointX[ECC224_KEYSIZE] =  {
485     0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F,
486     0x32, 0x13, 0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3,
487     0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
488     0x11, 0x5C, 0x1D, 0x21
489 };
490 static const uint8_t stm32_ecc224_pointY[ECC224_KEYSIZE] = {
491     0xBD, 0x37, 0x63, 0x88, 0xB5, 0xF7, 0x23, 0xFB,
492     0x4C, 0x22, 0xDF, 0xE6, 0xCD, 0x43, 0x75, 0xA0,
493     0x5A, 0x07, 0x47, 0x64, 0x44, 0xD5, 0x81, 0x99,
494     0x85, 0x00, 0x7E, 0x34
495 };
496 static const uint8_t stm32_ecc224_order[ECC224_KEYSIZE] = {
497     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
498     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x16, 0xA2,
499     0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
500     0x5C, 0x5C, 0x2A, 0x3D
501 };
502 #endif /* ECC224 */
503 
504 /* P-256 */
505 #ifdef ECC256
506 #define ECC256_KEYSIZE (32)
507 static const uint8_t stm32_ecc256_prime[ECC256_KEYSIZE] = {
508     0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
509     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
510     0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
511     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
512 };
513 static const uint32_t stm32_ecc256_coef_sign = 1U;
514 static const uint8_t stm32_ecc256_coef[ECC256_KEYSIZE] = {
515     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
516     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
517     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
518     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
519 };
520 static const uint8_t stm32_ecc256_pointX[ECC256_KEYSIZE] = {
521     0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47,
522     0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
523     0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
524     0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96
525 };
526 static const uint8_t stm32_ecc256_pointY[ECC256_KEYSIZE] = {
527     0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b,
528     0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
529     0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
530     0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5
531 };
532 static const uint8_t stm32_ecc256_order[ECC256_KEYSIZE] = {
533     0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
534     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
535     0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84,
536     0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51
537 };
538 #endif /* ECC256 */
539 
540 /* P-384 */
541 #ifdef ECC384
542 #define ECC384_KEYSIZE (48)
543 static const uint8_t stm32_ecc384_prime[ECC384_KEYSIZE] = {
544     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
545     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
546     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
547     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
548     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
549     0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF
550 };
551 static const uint32_t stm32_ecc384_coef_sign = 1U;
552 static const uint8_t stm32_ecc384_coef[ECC384_KEYSIZE] = {
553     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
554     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
559 };
560 static const uint8_t stm32_ecc384_pointX[ECC384_KEYSIZE] =  {
561     0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37,
562     0x8E, 0xB1, 0xC7, 0x1E, 0xF3, 0x20, 0xAD, 0x74,
563     0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
564     0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38,
565     0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, 0x6C,
566     0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
567 };
568 static const uint8_t stm32_ecc384_pointY[ECC384_KEYSIZE] = {
569     0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F,
570     0x5D, 0x9E, 0x98, 0xBF, 0x92, 0x92, 0xDC, 0x29,
571     0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C,
572     0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0,
573     0x0A, 0x60, 0xB1, 0xCE, 0x1D, 0x7E, 0x81, 0x9D,
574     0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F,
575 };
576 static const uint8_t stm32_ecc384_order[ECC384_KEYSIZE] = {
577     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
578     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
579     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
580     0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF,
581     0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A,
582     0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73
583 };
584 #endif /* ECC384 */
585 
stm32_get_ecc_specs(const uint8_t ** prime,const uint8_t ** coef,const uint32_t ** coef_sign,const uint8_t ** GenPointX,const uint8_t ** GenPointY,const uint8_t ** order,int size)586 static int stm32_get_ecc_specs(const uint8_t **prime, const uint8_t **coef,
587     const uint32_t **coef_sign, const uint8_t **GenPointX, const uint8_t **GenPointY,
588     const uint8_t **order, int size)
589 {
590     switch(size) {
591     case 32:
592         *prime = stm32_ecc256_prime;
593         *coef = stm32_ecc256_coef;
594         *GenPointX = stm32_ecc256_pointX;
595         *GenPointY = stm32_ecc256_pointY;
596         *coef_sign = &stm32_ecc256_coef_sign;
597         if (order) *order = stm32_ecc256_order;
598         break;
599 #ifdef ECC224
600     case 28:
601         *prime = stm32_ecc224_prime;
602         *coef = stm32_ecc224_coef;
603         *GenPointX = stm32_ecc224_pointX;
604         *GenPointY = stm32_ecc224_pointY;
605         *coef_sign = &stm32_ecc224_coef;
606         if (order) *order = stm32_ecc224_order;
607         break;
608 #endif
609 #ifdef ECC192
610     case 24:
611         *prime = stm32_ecc192_prime;
612         *coef = stm32_ecc192_coef;
613         *GenPointX = stm32_ecc192_pointX;
614         *GenPointY = stm32_ecc192_pointY;
615         *coef_sign = &stm32_ecc192_coef;
616         if (order) *order = stm32_ecc192_order;
617         break;
618 #endif
619 #ifdef ECC384
620     case 48:
621         *prime = stm32_ecc384_prime;
622         *coef = stm32_ecc384_coef;
623         *GenPointX = stm32_ecc384_pointX;
624         *GenPointY = stm32_ecc384_pointY;
625         *coef_sign = &stm32_ecc384_coef;
626         if (order) *order = stm32_ecc384_order;
627         break;
628 #endif
629     default:
630         return NOT_COMPILED_IN;
631     }
632     return 0;
633 }
634 
635 
636 /**
637    Perform a point multiplication  (timing resistant)
638    k    The scalar to multiply by
639    G    The base point
640    R    [out] Destination for kG
641    modulus  The modulus of the field the ECC curve is in
642    map      Boolean whether to map back to affine or not
643             (1==map, 0 == leave in projective)
644    return MP_OKAY on success
645 */
wc_ecc_mulmod_ex(const mp_int * k,ecc_point * G,ecc_point * R,mp_int * a,mp_int * modulus,int map,void * heap)646 int wc_ecc_mulmod_ex(const mp_int *k, ecc_point *G, ecc_point *R, mp_int* a,
647     mp_int *modulus, int map, void* heap)
648 {
649     PKA_ECCMulInTypeDef pka_mul;
650     PKA_ECCMulOutTypeDef pka_mul_res;
651     uint8_t size;
652     int szModulus;
653     int szkbin;
654     int status;
655     int res;
656     uint8_t Gxbin[STM32_MAX_ECC_SIZE];
657     uint8_t Gybin[STM32_MAX_ECC_SIZE];
658     uint8_t kbin[STM32_MAX_ECC_SIZE];
659     uint8_t PtXbin[STM32_MAX_ECC_SIZE];
660     uint8_t PtYbin[STM32_MAX_ECC_SIZE];
661     const uint8_t *prime, *coef, *gen_x, *gen_y;
662     const uint32_t *coef_sign;
663     (void)a;
664     (void)heap;
665     XMEMSET(&pka_mul, 0x00, sizeof(PKA_ECCMulInTypeDef));
666     XMEMSET(&pka_mul_res, 0x00, sizeof(PKA_ECCMulOutTypeDef));
667     pka_mul_res.ptX = PtXbin;
668     pka_mul_res.ptY = PtYbin;
669 
670     if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
671         return ECC_BAD_ARG_E;
672     }
673 
674     szModulus = mp_unsigned_bin_size(modulus);
675     szkbin = mp_unsigned_bin_size(k);
676 
677     res = stm32_get_from_mp_int(kbin, k, szkbin);
678     if (res == MP_OKAY)
679         res = stm32_get_from_mp_int(Gxbin, G->x, szModulus);
680     if (res == MP_OKAY)
681         res = stm32_get_from_mp_int(Gybin, G->y, szModulus);
682 
683     if (res != MP_OKAY)
684         return res;
685 
686     size = (uint8_t)szModulus;
687     /* find STM32_PKA friendly parameters for the selected curve */
688     if (0 != stm32_get_ecc_specs(&prime, &coef, &coef_sign, &gen_x, &gen_y, NULL, size)) {
689         return ECC_BAD_ARG_E;
690     }
691 
692     pka_mul.modulusSize = szModulus;
693     pka_mul.coefSign = *coef_sign;
694     pka_mul.coefA = coef;
695     pka_mul.modulus = prime;
696     pka_mul.pointX = Gxbin;
697     pka_mul.pointY = Gybin;
698     pka_mul.scalarMulSize = size;
699     pka_mul.scalarMul = kbin;
700 
701     status = HAL_PKA_ECCMul(&hpka, &pka_mul, HAL_MAX_DELAY);
702     if (status != HAL_OK) {
703         return WC_HW_E;
704     }
705     pka_mul_res.ptX = Gxbin;
706     pka_mul_res.ptY = Gybin;
707     HAL_PKA_ECCMul_GetResult(&hpka, &pka_mul_res);
708     res = mp_read_unsigned_bin(R->x, Gxbin, size);
709     if (res == MP_OKAY) {
710         res = mp_read_unsigned_bin(R->y, Gybin, size);
711 #ifndef WOLFSSL_SP_MATH
712         /* if k is negative, we compute the multiplication with abs(-k)
713          * with result (x, y) and modify the result to (x, -y)
714          */
715         R->y->sign = k->sign;
716 #endif
717     }
718     if (res == MP_OKAY)
719         res = mp_set(R->z, 1);
720     HAL_PKA_RAMReset(&hpka);
721     return res;
722 }
723 
wc_ecc_mulmod_ex2(const mp_int * k,ecc_point * G,ecc_point * R,mp_int * a,mp_int * modulus,mp_int * order,WC_RNG * rng,int map,void * heap)724 int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
725                       mp_int* modulus, mp_int* order, WC_RNG* rng, int map,
726                       void* heap)
727 {
728     (void)order;
729     (void)rng;
730     return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, heap);
731 }
732 
ecc_map_ex(ecc_point * P,mp_int * modulus,mp_digit mp,int ct)733 int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct)
734 {
735     /* this is handled in hardware, so no projective mapping needed */
736     (void)P;
737     (void)modulus;
738     (void)mp;
739     (void)ct;
740     return MP_OKAY;
741 }
742 
stm32_ecc_verify_hash_ex(mp_int * r,mp_int * s,const byte * hash,word32 hashlen,int * res,ecc_key * key)743 int stm32_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
744                     word32 hashlen, int* res, ecc_key* key)
745 {
746     PKA_ECDSAVerifInTypeDef pka_ecc;
747     uint8_t size;
748     int szModulus;
749     int szrbin;
750     int status;
751     uint8_t Rbin[STM32_MAX_ECC_SIZE];
752     uint8_t Sbin[STM32_MAX_ECC_SIZE];
753     uint8_t Qxbin[STM32_MAX_ECC_SIZE];
754     uint8_t Qybin[STM32_MAX_ECC_SIZE];
755     uint8_t Hashbin[STM32_MAX_ECC_SIZE];
756     uint8_t privKeybin[STM32_MAX_ECC_SIZE];
757     const uint8_t *prime, *coef, *gen_x, *gen_y, *order;
758     const uint32_t *coef_sign;
759     XMEMSET(&pka_ecc, 0x00, sizeof(PKA_ECDSAVerifInTypeDef));
760 
761     if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL) {
762         return ECC_BAD_ARG_E;
763     }
764     *res = 0;
765 
766     szModulus = mp_unsigned_bin_size(key->pubkey.x);
767     szrbin = mp_unsigned_bin_size(r);
768 
769     status = stm32_get_from_mp_int(Rbin, r, szrbin);
770     if (status == MP_OKAY)
771         status = stm32_get_from_mp_int(Sbin, s, szrbin);
772     if (status == MP_OKAY)
773         status = stm32_get_from_mp_int(Qxbin, key->pubkey.x, szModulus);
774     if (status == MP_OKAY)
775         status = stm32_get_from_mp_int(Qybin, key->pubkey.y, szModulus);
776     if (status == MP_OKAY)
777         status = stm32_get_from_mp_int(privKeybin, &key->k, szModulus);
778     if (status != MP_OKAY)
779         return status;
780 
781     size = (uint8_t)szModulus;
782     /* find parameters for the selected curve */
783     if (0 != stm32_get_ecc_specs(&prime, &coef, &coef_sign, &gen_x, &gen_y, &order, size)) {
784         return ECC_BAD_ARG_E;
785     }
786 
787 
788     pka_ecc.primeOrderSize =  size;
789     pka_ecc.modulusSize =     size;
790     pka_ecc.coefSign =        *coef_sign;
791     pka_ecc.coef =            coef;
792     pka_ecc.modulus =         prime;
793     pka_ecc.basePointX =      gen_x;
794     pka_ecc.basePointY =      gen_y;
795     pka_ecc.primeOrder =      order;
796 
797     pka_ecc.pPubKeyCurvePtX = Qxbin;
798     pka_ecc.pPubKeyCurvePtY = Qybin;
799     pka_ecc.RSign =           Rbin;
800     pka_ecc.SSign =           Sbin;
801     XMEMSET(Hashbin, 0, STM32_MAX_ECC_SIZE);
802     XMEMCPY(Hashbin + (size - hashlen), hash, hashlen);
803     pka_ecc.hash =            Hashbin;
804 
805     status = HAL_PKA_ECDSAVerif(&hpka, &pka_ecc, HAL_MAX_DELAY);
806     if (status != HAL_OK) {
807         HAL_PKA_RAMReset(&hpka);
808         return WC_HW_E;
809     }
810     *res = HAL_PKA_ECDSAVerif_IsValidSignature(&hpka);
811     HAL_PKA_RAMReset(&hpka);
812     return status;
813 }
814 
stm32_ecc_sign_hash_ex(const byte * hash,word32 hashlen,WC_RNG * rng,ecc_key * key,mp_int * r,mp_int * s)815 int stm32_ecc_sign_hash_ex(const byte* hash, word32 hashlen, WC_RNG* rng,
816                      ecc_key* key, mp_int *r, mp_int *s)
817 {
818     PKA_ECDSASignInTypeDef pka_ecc;
819     PKA_ECDSASignOutTypeDef pka_ecc_out;
820     int size;
821     int status;
822     mp_int gen_k;
823     mp_int order_mp;
824     uint8_t Keybin[STM32_MAX_ECC_SIZE];
825     uint8_t Intbin[STM32_MAX_ECC_SIZE];
826     uint8_t Rbin[STM32_MAX_ECC_SIZE];
827     uint8_t Sbin[STM32_MAX_ECC_SIZE];
828     uint8_t Hashbin[STM32_MAX_ECC_SIZE];
829     const uint8_t *prime, *coef, *gen_x, *gen_y, *order;
830     const uint32_t *coef_sign;
831     XMEMSET(&pka_ecc, 0x00, sizeof(PKA_ECDSASignInTypeDef));
832     XMEMSET(&pka_ecc_out, 0x00, sizeof(PKA_ECDSASignOutTypeDef));
833 
834     if (r == NULL || s == NULL || hash == NULL || key == NULL) {
835         return ECC_BAD_ARG_E;
836     }
837 
838     mp_init(&gen_k);
839     mp_init(&order_mp);
840 
841     size = mp_unsigned_bin_size(key->pubkey.x);
842 
843     status = stm32_get_from_mp_int(Keybin, &key->k, size);
844     if (status != MP_OKAY)
845         return status;
846 
847     /* find parameters for the selected curve */
848     if (0 != stm32_get_ecc_specs(&prime, &coef, &coef_sign, &gen_x, &gen_y, &order, size)) {
849         return ECC_BAD_ARG_E;
850     }
851 
852     status = mp_read_unsigned_bin(&order_mp, order, size);
853     if (status == MP_OKAY)
854         status = wc_ecc_gen_k(rng, size, &gen_k, &order_mp);
855     if (status == MP_OKAY)
856         status = stm32_get_from_mp_int(Intbin, &gen_k, size);
857     if (status != MP_OKAY)
858         return status;
859 
860     pka_ecc.primeOrderSize =  size;
861     pka_ecc.modulusSize =     size;
862     pka_ecc.coefSign =        *coef_sign;
863     pka_ecc.coef =            coef;
864     pka_ecc.modulus =         prime;
865     pka_ecc.basePointX =      gen_x;
866     pka_ecc.basePointY =      gen_y;
867     pka_ecc.primeOrder =      order;
868 
869     XMEMSET(Hashbin, 0, STM32_MAX_ECC_SIZE);
870     XMEMCPY(Hashbin + (size - hashlen), hash, hashlen);
871     pka_ecc.hash =            Hashbin;
872     pka_ecc.integer =         Intbin;
873     pka_ecc.privateKey =      Keybin;
874 
875     /* Assign R, S static buffers */
876     pka_ecc_out.RSign = Rbin;
877     pka_ecc_out.SSign = Sbin;
878 
879     status = HAL_PKA_ECDSASign(&hpka, &pka_ecc, HAL_MAX_DELAY);
880     if (status != HAL_OK) {
881         HAL_PKA_RAMReset(&hpka);
882         return WC_HW_E;
883     }
884     HAL_PKA_ECDSASign_GetResult(&hpka, &pka_ecc_out, NULL);
885     status = mp_read_unsigned_bin(r, pka_ecc_out.RSign, size);
886     if (status == MP_OKAY)
887         status = mp_read_unsigned_bin(s, pka_ecc_out.SSign, size);
888     HAL_PKA_RAMReset(&hpka);
889     return status;
890 }
891 
892 #endif /* HAVE_ECC */
893 #endif /* WOLFSSL_STM32_PKA */
894