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