1 /**************************************************************************//**
2 * @file crypto.c
3 * @version V3.00
4 * @brief Cryptographic Accelerator driver source file
5 *
6 * @copyright SPDX-License-Identifier: Apache-2.0
7 * @copyright Copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
8 *****************************************************************************/
9
10 #include <stdio.h>
11 #include <string.h>
12 #include "NuMicro.h"
13
14 #define ENABLE_DEBUG 0
15
16 #define ECC_SCA_PROTECT 1 // Enable Side-Channel Protection
17
18 #if ENABLE_DEBUG
19 #define CRPT_DBGMSG printf
20 #else
21 #define CRPT_DBGMSG(...) do { } while (0) /* disable debug */
22 #endif
23
24 #if defined(__ICCARM__)
25 # pragma diag_suppress=Pm073, Pm143 /* Misra C rule 14.7 */
26 #endif
27
28 #define TIMEOUT_ECC SystemCoreClock /* 1 second time-out */
29
30 /** @addtogroup Standard_Driver Standard Driver
31 @{
32 */
33
34 /** @addtogroup CRYPTO_Driver CRYPTO Driver
35 @{
36 */
37
38
39 /** @addtogroup CRYPTO_EXPORTED_FUNCTIONS CRYPTO Exported Functions
40 @{
41 */
42
43 /* // @cond HIDDEN_SYMBOLS */
44
45
46 static char hex_char_tbl[] = "0123456789abcdef";
47
48 static void dump_ecc_reg(char *str, uint32_t volatile regs[], int32_t count);
49 static char get_Nth_nibble_char(uint32_t val32, uint32_t idx);
50 static void Hex2Reg(char input[], uint32_t volatile reg[]);
51 static void Reg2Hex(int32_t count, uint32_t volatile reg[], char output[]);
52 static char ch2hex(char ch);
53 static void Hex2RegEx(char input[], uint32_t volatile reg[], int shift);
54 static int get_nibble_value(char c);
55 int32_t ECC_Mutiply(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char x1[], char y1[], char *k, char x2[], char y2[]);
56 void ECC_Complete(CRPT_T *crpt);
57
58
59 /* // @endcond HIDDEN_SYMBOLS */
60
61 /**
62 * @brief Open PRNG function
63 * @param[in] crpt The pointer of CRYPTO module
64 * @param[in] u32KeySize it is PRNG key size, including:
65 * - \ref PRNG_KEY_SIZE_128
66 * - \ref PRNG_KEY_SIZE_192
67 * - \ref PRNG_KEY_SIZE_224
68 * - \ref PRNG_KEY_SIZE_255
69 * - \ref PRNG_KEY_SIZE_256
70 * - \ref PRNG_KEY_SIZE_283
71 * - \ref PRNG_KEY_SIZE_384
72 * - \ref PRNG_KEY_SIZE_409
73 * - \ref PRNG_KEY_SIZE_512
74 * - \ref PRNG_KEY_SIZE_521
75 * - \ref PRNG_KEY_SIZE_571
76 * @param[in] u32SeedReload is PRNG seed reload or not, including:
77 * - \ref PRNG_SEED_CONT
78 * - \ref PRNG_SEED_RELOAD
79 * @param[in] u32Seed The new seed. Only valid when u32SeedReload is PRNG_SEED_RELOAD.
80 * @return None
81 */
PRNG_Open(CRPT_T * crpt,uint32_t u32KeySize,uint32_t u32SeedReload,uint32_t u32Seed)82 void PRNG_Open(CRPT_T *crpt, uint32_t u32KeySize, uint32_t u32SeedReload, uint32_t u32Seed)
83 {
84 if(u32SeedReload)
85 {
86 crpt->PRNG_SEED = u32Seed;
87 }
88
89 crpt->PRNG_CTL = (u32KeySize << CRPT_PRNG_CTL_KEYSZ_Pos) | PRNG_CTL_SEEDSRC_SEEDREG |
90 (u32SeedReload << CRPT_PRNG_CTL_SEEDRLD_Pos);
91 }
92
93 /**
94 * @brief Start to generate one PRNG key.
95 * @param[in] crpt The pointer of CRYPTO module
96 * @retval 0 Generate PRNG key success.
97 * @retval -1 Generate PRNG key time-out.
98 */
PRNG_Start(CRPT_T * crpt)99 int32_t PRNG_Start(CRPT_T *crpt)
100 {
101 int32_t i32TimeOutCnt = SystemCoreClock; /* 1 second time-out */
102
103 crpt->PRNG_CTL = (crpt->PRNG_CTL & (~CRPT_PRNG_CTL_SEEDRLD_Msk));
104 crpt->PRNG_CTL |= CRPT_PRNG_CTL_START_Msk;
105
106 /* Waiting for PRNG Busy */
107 while(crpt->PRNG_CTL & CRPT_PRNG_CTL_BUSY_Msk)
108 {
109 if( i32TimeOutCnt-- <= 0)
110 {
111 return -1;
112 }
113 }
114
115 return 0;
116 }
117
118 /**
119 * @brief Read the PRNG key.
120 * @param[in] crpt The pointer of CRYPTO module
121 * @param[out] u32RandKey The key buffer to store newly generated PRNG key.
122 * @return None
123 */
PRNG_Read(CRPT_T * crpt,uint32_t u32RandKey[])124 void PRNG_Read(CRPT_T *crpt, uint32_t u32RandKey[])
125 {
126 uint32_t i, wcnt;
127 uint32_t au32WcntTbl[7] = {4, 6, 6, 7, 8, 8, 8};
128
129 wcnt = ((crpt->PRNG_CTL & CRPT_PRNG_CTL_KEYSZ_Msk) >> CRPT_PRNG_CTL_KEYSZ_Pos);
130 if( wcnt > 6 ) return;
131 else wcnt = au32WcntTbl[wcnt];
132
133 for(i = 0U; i < wcnt; i++)
134 {
135 u32RandKey[i] = crpt->PRNG_KEY[i];
136 }
137
138 crpt->PRNG_CTL &= ~CRPT_PRNG_CTL_SEEDRLD_Msk;
139 }
140
141
142 /**
143 * @brief Open AES encrypt/decrypt function.
144 * @param[in] crpt The pointer of CRYPTO module
145 * @param[in] u32Channel AES channel. Must be 0~3.
146 * @param[in] u32EncDec 1: AES encode; 0: AES decode
147 * @param[in] u32OpMode AES operation mode, including:
148 * - \ref AES_MODE_ECB
149 * - \ref AES_MODE_CBC
150 * - \ref AES_MODE_CFB
151 * - \ref AES_MODE_OFB
152 * - \ref AES_MODE_CTR
153 * - \ref AES_MODE_CBC_CS1
154 * - \ref AES_MODE_CBC_CS2
155 * - \ref AES_MODE_CBC_CS3
156 * @param[in] u32KeySize is AES key size, including:
157 * - \ref AES_KEY_SIZE_128
158 * - \ref AES_KEY_SIZE_192
159 * - \ref AES_KEY_SIZE_256
160 * @param[in] u32SwapType is AES input/output data swap control, including:
161 * - \ref AES_NO_SWAP
162 * - \ref AES_OUT_SWAP
163 * - \ref AES_IN_SWAP
164 * - \ref AES_IN_OUT_SWAP
165 * @return None
166 */
AES_Open(CRPT_T * crpt,uint32_t u32Channel,uint32_t u32EncDec,uint32_t u32OpMode,uint32_t u32KeySize,uint32_t u32SwapType)167 void AES_Open(CRPT_T *crpt, uint32_t u32Channel, uint32_t u32EncDec,
168 uint32_t u32OpMode, uint32_t u32KeySize, uint32_t u32SwapType)
169 {
170 (void)u32Channel;
171
172 crpt->AES_CTL = (u32EncDec << CRPT_AES_CTL_ENCRPT_Pos) |
173 (u32OpMode << CRPT_AES_CTL_OPMODE_Pos) |
174 (u32KeySize << CRPT_AES_CTL_KEYSZ_Pos) |
175 (u32SwapType << CRPT_AES_CTL_OUTSWAP_Pos);
176
177 }
178
179 /**
180 * @brief Start AES encrypt/decrypt
181 * @param[in] crpt The pointer of CRYPTO module
182 * @param[in] u32Channel AES channel. Must be 0~3.
183 * @param[in] u32DMAMode AES DMA control, including:
184 * - \ref CRYPTO_DMA_ONE_SHOT One shot AES encrypt/decrypt.
185 * - \ref CRYPTO_DMA_CONTINUE Continuous AES encrypt/decrypt.
186 * - \ref CRYPTO_DMA_LAST Last AES encrypt/decrypt of a series of AES_Start.
187 * @return None
188 */
AES_Start(CRPT_T * crpt,int32_t u32Channel,uint32_t u32DMAMode)189 void AES_Start(CRPT_T *crpt, int32_t u32Channel, uint32_t u32DMAMode)
190 {
191 (void)u32Channel;
192
193 crpt->AES_CTL |= CRPT_AES_CTL_START_Msk | (u32DMAMode << CRPT_AES_CTL_DMALAST_Pos);
194 }
195
196 /**
197 * @brief Set AES keys
198 * @param[in] crpt The pointer of CRYPTO module
199 * @param[in] u32Channel AES channel. Must be 0~3.
200 * @param[in] au32Keys An word array contains AES keys.
201 * @param[in] u32KeySize is AES key size, including:
202 * - \ref AES_KEY_SIZE_128
203 * - \ref AES_KEY_SIZE_192
204 * - \ref AES_KEY_SIZE_256
205 * @return None
206 */
AES_SetKey(CRPT_T * crpt,uint32_t u32Channel,uint32_t au32Keys[],uint32_t u32KeySize)207 void AES_SetKey(CRPT_T *crpt, uint32_t u32Channel, uint32_t au32Keys[], uint32_t u32KeySize)
208 {
209 uint32_t i, wcnt, key_reg_addr;
210
211 (void) u32Channel;
212
213 key_reg_addr = (uint32_t)&crpt->AES_KEY[0];
214 wcnt = 4UL + u32KeySize * 2UL;
215
216 for(i = 0U; i < wcnt; i++)
217 {
218 outpw(key_reg_addr, au32Keys[i]);
219 key_reg_addr += 4UL;
220 }
221 }
222
223
224
225 /**
226 * @brief Set AES keys index of Key Store
227 * @param[in] crpt The pointer of CRYPTO module
228 * @param[in] mem Memory type of Key Store key. it could be:
229 * - \ref KS_SRAM
230 * - \ref KS_FLASH
231 * - \ref KS_OTP
232 * @param[in] i32KeyIdx Index of the key in Key Store.
233 * @details AES could use the key in Key Store. This function is used to set the key index of Key Store.
234 */
AES_SetKey_KS(CRPT_T * crpt,KS_MEM_Type mem,int32_t i32KeyIdx)235 void AES_SetKey_KS(CRPT_T *crpt, KS_MEM_Type mem, int32_t i32KeyIdx)
236 {
237 /* Use key in key store */
238 crpt->AES_KSCTL = CRPT_AES_KSCTL_RSRC_Msk /* use KS */ |
239 (uint32_t)((int)mem << CRPT_AES_KSCTL_RSSRC_Pos) /* KS Memory type */ |
240 (uint32_t)i32KeyIdx /* key num */ ;
241
242 }
243
244
245 /**
246 * @brief Set AES initial vectors
247 * @param[in] crpt The pointer of CRYPTO module
248 * @param[in] u32Channel AES channel. Must be 0~3.
249 * @param[in] au32IV A four entry word array contains AES initial vectors.
250 * @return None
251 */
AES_SetInitVect(CRPT_T * crpt,uint32_t u32Channel,uint32_t au32IV[])252 void AES_SetInitVect(CRPT_T *crpt, uint32_t u32Channel, uint32_t au32IV[])
253 {
254 uint32_t i, key_reg_addr;
255
256 (void) u32Channel;
257
258 key_reg_addr = (uint32_t)&crpt->AES_IV[0];
259
260 for(i = 0U; i < 4U; i++)
261 {
262 outpw(key_reg_addr, au32IV[i]);
263 key_reg_addr += 4UL;
264 }
265 }
266
267 /**
268 * @brief Set AES DMA transfer configuration.
269 * @param[in] crpt The pointer of CRYPTO module
270 * @param[in] u32Channel AES channel. Must be 0~3.
271 * @param[in] u32SrcAddr AES DMA source address
272 * @param[in] u32DstAddr AES DMA destination address
273 * @param[in] u32TransCnt AES DMA transfer byte count
274 * @return None
275 */
AES_SetDMATransfer(CRPT_T * crpt,uint32_t u32Channel,uint32_t u32SrcAddr,uint32_t u32DstAddr,uint32_t u32TransCnt)276 void AES_SetDMATransfer(CRPT_T *crpt, uint32_t u32Channel, uint32_t u32SrcAddr,
277 uint32_t u32DstAddr, uint32_t u32TransCnt)
278 {
279 (void) u32Channel;
280
281 crpt->AES_SADDR = u32SrcAddr;
282 crpt->AES_DADDR = u32DstAddr;
283 crpt->AES_CNT = u32TransCnt;
284
285 }
286
287 /**
288 * @brief Open SHA encrypt function.
289 * @param[in] crpt The pointer of CRYPTO module
290 * @param[in] u32OpMode SHA operation mode, including:
291 * - \ref SHA_MODE_SHA1
292 * - \ref SHA_MODE_SHA224
293 * - \ref SHA_MODE_SHA256
294 * @param[in] u32SwapType is SHA input/output data swap control, including:
295 * - \ref SHA_NO_SWAP
296 * - \ref SHA_OUT_SWAP
297 * - \ref SHA_IN_SWAP
298 * - \ref SHA_IN_OUT_SWAP
299 * @param[in] hmac_key_len HMAC key byte count
300 * @return None
301 */
SHA_Open(CRPT_T * crpt,uint32_t u32OpMode,uint32_t u32SwapType,uint32_t hmac_key_len)302 void SHA_Open(CRPT_T *crpt, uint32_t u32OpMode, uint32_t u32SwapType, uint32_t hmac_key_len)
303 {
304 crpt->HMAC_CTL = (u32OpMode << CRPT_HMAC_CTL_OPMODE_Pos) |
305 (u32SwapType << CRPT_HMAC_CTL_OUTSWAP_Pos);
306
307 if(hmac_key_len != 0UL)
308 {
309 crpt->HMAC_KEYCNT = hmac_key_len;
310 }
311 }
312
313 /**
314 * @brief Start SHA encrypt
315 * @param[in] crpt The pointer of CRYPTO module
316 * @param[in] u32DMAMode DMA control, including:
317 * - \ref CRYPTO_DMA_ONE_SHOT One shop SHA encrypt.
318 * - \ref CRYPTO_DMA_CONTINUE Continuous SHA encrypt.
319 * - \ref CRYPTO_DMA_LAST Last SHA encrypt of a series of SHA_Start.
320 * @return None
321 */
SHA_Start(CRPT_T * crpt,uint32_t u32DMAMode)322 void SHA_Start(CRPT_T *crpt, uint32_t u32DMAMode)
323 {
324 crpt->HMAC_CTL &= ~(0x7UL << CRPT_HMAC_CTL_DMALAST_Pos);
325 crpt->HMAC_CTL |= CRPT_HMAC_CTL_START_Msk | (u32DMAMode << CRPT_HMAC_CTL_DMALAST_Pos);
326 }
327
328 /**
329 * @brief Set SHA DMA transfer
330 * @param[in] crpt The pointer of CRYPTO module
331 * @param[in] u32SrcAddr SHA DMA source address
332 * @param[in] u32TransCnt SHA DMA transfer byte count
333 * @return None
334 */
SHA_SetDMATransfer(CRPT_T * crpt,uint32_t u32SrcAddr,uint32_t u32TransCnt)335 void SHA_SetDMATransfer(CRPT_T *crpt, uint32_t u32SrcAddr, uint32_t u32TransCnt)
336 {
337 crpt->HMAC_SADDR = u32SrcAddr;
338 crpt->HMAC_DMACNT = u32TransCnt;
339 }
340
341 /**
342 * @brief Read the SHA digest.
343 * @param[in] crpt The pointer of CRYPTO module
344 * @param[out] u32Digest The SHA encrypt output digest.
345 * @return None
346 */
SHA_Read(CRPT_T * crpt,uint32_t u32Digest[])347 void SHA_Read(CRPT_T *crpt, uint32_t u32Digest[])
348 {
349 uint32_t i, wcnt, reg_addr;
350
351 i = (crpt->HMAC_CTL & CRPT_HMAC_CTL_OPMODE_Msk) >> CRPT_HMAC_CTL_OPMODE_Pos;
352
353 if(i == SHA_MODE_SHA1)
354 {
355 wcnt = 5UL;
356 }
357 else if(i == SHA_MODE_SHA224)
358 {
359 wcnt = 7UL;
360 }
361 else if(i == SHA_MODE_SHA256)
362 {
363 wcnt = 8UL;
364 }
365 else if(i == SHA_MODE_SHA384)
366 {
367 wcnt = 12UL;
368 }
369 else
370 {
371 /* SHA_MODE_SHA512 */
372 wcnt = 16UL;
373 }
374
375 reg_addr = (uint32_t) & (crpt->HMAC_DGST[0]);
376 for(i = 0UL; i < wcnt; i++)
377 {
378 u32Digest[i] = inpw(reg_addr);
379 reg_addr += 4UL;
380 }
381 }
382
383
384 /*-----------------------------------------------------------------------------------------------*/
385 /* */
386 /* ECC */
387 /* */
388 /*-----------------------------------------------------------------------------------------------*/
389
390 #define ECCOP_POINT_MUL (0x0UL << CRPT_ECC_CTL_ECCOP_Pos)
391 #define ECCOP_MODULE (0x1UL << CRPT_ECC_CTL_ECCOP_Pos)
392 #define ECCOP_POINT_ADD (0x2UL << CRPT_ECC_CTL_ECCOP_Pos)
393 #define ECCOP_POINT_DOUBLE (0x0UL << CRPT_ECC_CTL_ECCOP_Pos)
394
395 #define MODOP_DIV (0x0UL << CRPT_ECC_CTL_MODOP_Pos)
396 #define MODOP_MUL (0x1UL << CRPT_ECC_CTL_MODOP_Pos)
397 #define MODOP_ADD (0x2UL << CRPT_ECC_CTL_MODOP_Pos)
398 #define MODOP_SUB (0x3UL << CRPT_ECC_CTL_MODOP_Pos)
399
400 #define OP_ECDSAS (0x1UL << CRPT_ECC_CTL_ECDSAS_Pos)
401 #define OP_ECDSAR (0x1UL << CRPT_ECC_CTL_ECDSAR_Pos)
402
403 enum
404 {
405 CURVE_GF_P,
406 CURVE_GF_2M,
407 };
408
409 /*-----------------------------------------------------*/
410 /* Define elliptic curve (EC): */
411 /*-----------------------------------------------------*/
412 static const ECC_CURVE _Curve[] =
413 {
414 {
415 /* NIST: Curve P-192 : y^2=x^3-ax+b (mod p) */
416 CURVE_P_192,
417 48, /* Echar */
418 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* "000000000000000000000000000000000000000000000003" */
419 "64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
420 "188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
421 "07192b95ffc8da78631011ed6b24cdd573f977a11e794811",
422 58, /* Epl */
423 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* "6277101735386680763835789423207666416083908700390324961279" */
424 58, /* Eol */
425 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* "6277101735386680763835789423176059013767194773182842284081" */
426 192, /* key_len */
427 7,
428 2,
429 1,
430 CURVE_GF_P
431 },
432 {
433 /* NIST: Curve P-224 : y^2=x^3-ax+b (mod p) */
434 CURVE_P_224,
435 56, /* Echar */
436 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* "00000000000000000000000000000000000000000000000000000003" */
437 "b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
438 "b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
439 "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
440 70, /* Epl */
441 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "0026959946667150639794667015087019630673557916260026308143510066298881" */
442 70, /* Eol */
443 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* "0026959946667150639794667015087019625940457807714424391721682722368061" */
444 224, /* key_len */
445 9,
446 8,
447 3,
448 CURVE_GF_P
449 },
450 {
451 /* NIST: Curve P-256 : y^2=x^3-ax+b (mod p) */
452 CURVE_P_256,
453 64, /* Echar */
454 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* "0000000000000000000000000000000000000000000000000000000000000003" */
455 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
456 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
457 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
458 78, /* Epl */
459 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* "115792089210356248762697446949407573530086143415290314195533631308867097853951" */
460 78, /* Eol */
461 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* "115792089210356248762697446949407573529996955224135760342422259061068512044369" */
462 256, /* key_len */
463 10,
464 5,
465 2,
466 CURVE_GF_P
467 },
468 {
469 /* NIST: Curve P-384 : y^2=x^3-ax+b (mod p) */
470 CURVE_P_384,
471 96, /* Echar */
472 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003" */
473 "b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef",
474 "aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7",
475 "3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f",
476 116, /* Epl */
477 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* "39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319" */
478 116, /* Eol */
479 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* "39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643" */
480 384, /* key_len */
481 12,
482 3,
483 2,
484 CURVE_GF_P
485 },
486 {
487 /* NIST: Curve P-521 : y^2=x^3-ax+b (mod p)*/
488 CURVE_P_521,
489 131, /* Echar */
490 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003" */
491 "051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
492 "0c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
493 "11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
494 157, /* Epl */
495 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151" */
496 157, /* Eol */
497 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* "6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449" */
498 521, /* key_len */
499 32,
500 32,
501 32,
502 CURVE_GF_P
503 },
504 {
505 /* NIST: Curve B-163 : y^2+xy=x^3+ax^2+b */
506 CURVE_B_163,
507 41, /* Echar */
508 "00000000000000000000000000000000000000001",
509 "20a601907b8c953ca1481eb10512f78744a3205fd",
510 "3f0eba16286a2d57ea0991168d4994637e8343e36",
511 "0d51fbc6c71a0094fa2cdd545b11c5c0c797324f1",
512 68, /* Epl */
513 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
514 49, /* Eol */
515 "40000000000000000000292FE77E70C12A4234C33", /* "5846006549323611672814742442876390689256843201587" */
516 163, /* key_len */
517 7,
518 6,
519 3,
520 CURVE_GF_2M
521 },
522 {
523 /* NIST: Curve B-233 : y^2+xy=x^3+ax^2+b */
524 CURVE_B_233,
525 59, /* Echar 59 */
526 "00000000000000000000000000000000000000000000000000000000001",
527 "066647ede6c332c7f8c0923bb58213b333b20e9ce4281fe115f7d8f90ad",
528 "0fac9dfcbac8313bb2139f1bb755fef65bc391f8b36f8f8eb7371fd558b",
529 "1006a08a41903350678e58528bebf8a0beff867a7ca36716f7e01f81052",
530 68, /* Epl */
531 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
532 70, /* Eol */
533 "1000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", /* "6901746346790563787434755862277025555839812737345013555379383634485463" */
534 233, /* key_len */
535 74,
536 74,
537 74,
538 CURVE_GF_2M
539 },
540 {
541 /* NIST: Curve B-283 : y^2+xy=x^3+ax^2+b */
542 CURVE_B_283,
543 71, /* Echar */
544 "00000000000000000000000000000000000000000000000000000000000000000000001",
545 "27b680ac8b8596da5a4af8a19a0303fca97fd7645309fa2a581485af6263e313b79a2f5",
546 "5f939258db7dd90e1934f8c70b0dfec2eed25b8557eac9c80e2e198f8cdbecd86b12053",
547 "3676854fe24141cb98fe6d4b20d02b4516ff702350eddb0826779c813f0df45be8112f4",
548 68, /* Epl */
549 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
550 85, /* Eol */
551 "3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", /* "7770675568902916283677847627294075626569625924376904889109196526770044277787378692871" */
552 283, /* key_len */
553 12,
554 7,
555 5,
556 CURVE_GF_2M
557 },
558 {
559 /* NIST: Curve B-409 : y^2+xy=x^3+ax^2+b */
560 CURVE_B_409,
561 103, /* Echar */
562 "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
563 "021a5c2c8ee9feb5c4b9a753b7b476b7fd6422ef1f3dd674761fa99d6ac27c8a9a197b272822f6cd57a55aa4f50ae317b13545f",
564 "15d4860d088ddb3496b0c6064756260441cde4af1771d4db01ffe5b34e59703dc255a868a1180515603aeab60794e54bb7996a7",
565 "061b1cfab6be5f32bbfa78324ed106a7636b9c5a7bd198d0158aa4f5488d08f38514f1fdf4b4f40d2181b3681c364ba0273c706",
566 68, /* Epl */
567 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
568 123, /* Eol */
569 "10000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173", /* "661055968790248598951915308032771039828404682964281219284648798304157774827374805208143723762179110965979867288366567526771" */
570 409, /* key_len */
571 87,
572 87,
573 87,
574 CURVE_GF_2M
575 },
576 {
577 /* NIST: Curve B-571 : y^2+xy=x^3+ax^2+b */
578 CURVE_B_571,
579 143, /* Echar */
580 "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
581 "2f40e7e2221f295de297117b7f3d62f5c6a97ffcb8ceff1cd6ba8ce4a9a18ad84ffabbd8efa59332be7ad6756a66e294afd185a78ff12aa520e4de739baca0c7ffeff7f2955727a",
582 "303001d34b856296c16c0d40d3cd7750a93d1d2955fa80aa5f40fc8db7b2abdbde53950f4c0d293cdd711a35b67fb1499ae60038614f1394abfa3b4c850d927e1e7769c8eec2d19",
583 "37bf27342da639b6dccfffeb73d69d78c6c27a6009cbbca1980f8533921e8a684423e43bab08a576291af8f461bb2a8b3531d2f0485c19b16e2f1516e23dd3c1a4827af1b8ac15b",
584 68, /* Epl */
585 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
586 172, /* Eol */
587 "3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47", /* "3864537523017258344695351890931987344298927329706434998657235251451519142289560424536143999389415773083133881121926944486246872462816813070234528288303332411393191105285703" */
588 571, /* key_len */
589 10,
590 5,
591 2,
592 CURVE_GF_2M
593 },
594 {
595 /* NIST: Curve K-163 : y^2+xy=x^3+ax^2+b */
596 CURVE_K_163,
597 41, /* Echar */
598 "00000000000000000000000000000000000000001",
599 "00000000000000000000000000000000000000001",
600 "2fe13c0537bbc11acaa07d793de4e6d5e5c94eee8",
601 "289070fb05d38ff58321f2e800536d538ccdaa3d9",
602 68, /* Epl */
603 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
604 49, /* Eol */
605 "4000000000000000000020108A2E0CC0D99F8A5EF", /* "5846006549323611672814741753598448348329118574063" */
606 163, /* key_len */
607 7,
608 6,
609 3,
610 CURVE_GF_2M
611 },
612 {
613 /* NIST: Curve K-233 : y^2+xy=x^3+ax^2+b */
614 CURVE_K_233,
615 59, /* Echar 59 */
616 "00000000000000000000000000000000000000000000000000000000000",
617 "00000000000000000000000000000000000000000000000000000000001",
618 "17232ba853a7e731af129f22ff4149563a419c26bf50a4c9d6eefad6126",
619 "1db537dece819b7f70f555a67c427a8cd9bf18aeb9b56e0c11056fae6a3",
620 68, /* Epl */
621 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
622 70, /* Eol */
623 "8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", /* "3450873173395281893717377931138512760570940988862252126328087024741343" */
624 233, /* key_len */
625 74,
626 74,
627 74,
628 CURVE_GF_2M
629 },
630 {
631 /* NIST: Curve K-283 : y^2+xy=x^3+ax^2+b */
632 CURVE_K_283,
633 71, /* Echar */
634 "00000000000000000000000000000000000000000000000000000000000000000000000",
635 "00000000000000000000000000000000000000000000000000000000000000000000001",
636 "503213f78ca44883f1a3b8162f188e553cd265f23c1567a16876913b0c2ac2458492836",
637 "1ccda380f1c9e318d90f95d07e5426fe87e45c0e8184698e45962364e34116177dd2259",
638 68, /* Epl */
639 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
640 85, /* Eol */
641 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61", /* "3885337784451458141838923813647037813284811733793061324295874997529815829704422603873" */
642 283, /* key_len */
643 12,
644 7,
645 5,
646 CURVE_GF_2M
647 },
648 {
649 /* NIST: Curve K-409 : y^2+xy=x^3+ax^2+b */
650 CURVE_K_409,
651 103, /* Echar */
652 "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
653 "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
654 "060f05f658f49c1ad3ab1890f7184210efd0987e307c84c27accfb8f9f67cc2c460189eb5aaaa62ee222eb1b35540cfe9023746",
655 "1e369050b7c4e42acba1dacbf04299c3460782f918ea427e6325165e9ea10e3da5f6c42e9c55215aa9ca27a5863ec48d8e0286b",
656 68, /* Epl */
657 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
658 123, /* Eol */
659 "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", /* "330527984395124299475957654016385519914202341482140609642324395022880711289249191050673258457777458014096366590617731358671" */
660 409, /* key_len */
661 87,
662 87,
663 87,
664 CURVE_GF_2M
665 },
666 {
667 /* NIST: Curve K-571 : y^2+xy=x^3+ax^2+b */
668 CURVE_K_571,
669 143, /* Echar */
670 "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
671 "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
672 "26eb7a859923fbc82189631f8103fe4ac9ca2970012d5d46024804801841ca44370958493b205e647da304db4ceb08cbbd1ba39494776fb988b47174dca88c7e2945283a01c8972",
673 "349dc807f4fbf374f4aeade3bca95314dd58cec9f307a54ffc61efc006d8a2c9d4979c0ac44aea74fbebbb9f772aedcb620b01a7ba7af1b320430c8591984f601cd4c143ef1c7a3",
674 68, /* Epl */
675 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
676 172, /* Eol */
677 "20000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001", /* "1932268761508629172347675945465993672149463664853217499328617625725759571144780212268133978522706711834706712800825351461273674974066617311929682421617092503555733685276673" */
678 571, /* key_len */
679 10,
680 5,
681 2,
682 CURVE_GF_2M
683 },
684 {
685 /* Koblitz: Curve secp192k1 : y2 = x3+ax+b over Fp */
686 CURVE_KO_192,
687 48, /* Echar */
688 "00000000000000000000000000000000000000000",
689 "00000000000000000000000000000000000000003",
690 "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D",
691 "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D",
692 58, /* Epl */
693 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* p */
694 58, /* Eol */
695 "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* n */
696 192, /* key_len */
697 7,
698 2,
699 1,
700 CURVE_GF_P
701 },
702 {
703 /* Koblitz: Curve secp224k1 : y2 = x3+ax+b over Fp */
704 CURVE_KO_224,
705 56, /* Echar */
706 "00000000000000000000000000000000000000000000000000000000",
707 "00000000000000000000000000000000000000000000000000000005",
708 "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C",
709 "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5",
710 70, /* Epl */
711 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* p */
712 70, /* Eol */
713 "0000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", /* n */
714 224, /* key_len */
715 7,
716 2,
717 1,
718 CURVE_GF_P
719 },
720 {
721 /* Koblitz: Curve secp256k1 : y2 = x3+ax+b over Fp */
722 CURVE_KO_256,
723 64, /* Echar */
724 "0000000000000000000000000000000000000000000000000000000000000000",
725 "0000000000000000000000000000000000000000000000000000000000000007",
726 "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
727 "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
728 78, /* Epl */
729 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* p */
730 78, /* Eol */
731 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* n */
732 256, /* key_len */
733 7,
734 2,
735 1,
736 CURVE_GF_P
737 },
738 {
739 /* Brainpool: Curve brainpoolP256r1 */
740 CURVE_BP_256,
741 64, /* Echar */
742 "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A */
743 "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B */
744 "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* x */
745 "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* y */
746 78, /* Epl */
747 "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* p */
748 78, /* Eol */
749 "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* q */
750 256, /* key_len */
751 7,
752 2,
753 1,
754 CURVE_GF_P
755 },
756 {
757 /* Brainpool: Curve brainpoolP384r1 */
758 CURVE_BP_384,
759 96, /* Echar */
760 "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A */
761 "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B */
762 "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* x */
763 "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* y */
764 116, /* Epl */
765 "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* p */
766 116, /* Eol */
767 "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* q */
768 384, /* key_len */
769 7,
770 2,
771 1,
772 CURVE_GF_P
773 },
774 {
775 /* Brainpool: Curve brainpoolP512r1 */
776 CURVE_BP_512,
777 128, /* Echar */
778 "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A */
779 "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B */
780 "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* x */
781 "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* y */
782 156, /* Epl */
783 "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* p */
784 156, /* Eol */
785 "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* q */
786 512, /* key_len */
787 7,
788 2,
789 1,
790 CURVE_GF_P
791 },
792 {
793 CURVE_25519,
794 64, // Echar
795 "0000000000000000000000000000000000000000000000000000000000076D06", // "0000000000000000000000000000000000000000000000000000000000000003",
796 "0000000000000000000000000000000000000000000000000000000000000001",
797 "0000000000000000000000000000000000000000000000000000000000000009",
798 "20ae19a1b8a086b4e01edd2c7748d14c923d4d7e6d7c61b229e9c5a27eced3d9",
799 78, // Epl
800 "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed", // "115792089210356248762697446949407573530086143415290314195533631308867097853951",
801 78, // Eol
802 "1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed", // "115792089210356248762697446949407573529996955224135760342422259061068512044369",
803 255, // key_len
804 10,
805 5,
806 2,
807 CURVE_GF_P
808 },
809 {
810 /* NIST: Curve P-256 : y^2=x^3-ax+b (mod p) */
811 CURVE_SM2_256,
812 64, /* Echar */
813 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", /* a */
814 "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", /* b */
815 "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", /* x */
816 "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", /* y */
817 78, /* Epl */
818 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", /* p */
819 78, /* Eol */
820 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", /* n */
821 256, /* key_len */
822 10,
823 5,
824 2,
825 CURVE_GF_P
826 },
827
828 };
829
830
831 static ECC_CURVE *pCurve;
832 static ECC_CURVE Curve_Copy;
833
834 static ECC_CURVE * get_curve(E_ECC_CURVE ecc_curve);
835 static int32_t ecc_init_curve(CRPT_T *crpt, E_ECC_CURVE ecc_curve);
836 static int32_t run_ecc_codec(CRPT_T *crpt, uint32_t mode);
837
838 static char temp_hex_str[160];
839
840 static volatile uint32_t g_ECC_done, g_ECCERR_done;
841
ECC_DriverISR(CRPT_T * crpt)842 void ECC_DriverISR(CRPT_T *crpt)
843 {
844 if(crpt->INTSTS & CRPT_INTSTS_ECCIF_Msk)
845 {
846 g_ECC_done = 1UL;
847 crpt->INTSTS = CRPT_INTSTS_ECCIF_Msk;
848 /* printf("ECC done IRQ.\n"); */
849 }
850
851 if(crpt->INTSTS & CRPT_INTSTS_ECCEIF_Msk)
852 {
853 g_ECCERR_done = 1UL;
854 crpt->INTSTS = CRPT_INTSTS_ECCEIF_Msk;
855 /* printf("ECCERRIF is set!!\n"); */
856 }
857 }
858
859
860 #if ENABLE_DEBUG
dump_ecc_reg(char * str,uint32_t volatile regs[],int32_t count)861 static void dump_ecc_reg(char *str, uint32_t volatile regs[], int32_t count)
862 {
863 int32_t i;
864
865 printf("%s => ", str);
866 for(i = 0; i < count; i++)
867 {
868 printf("0x%08x ", regs[i]);
869 }
870 printf("\n");
871 }
872 #else
dump_ecc_reg(char * str,uint32_t volatile regs[],int32_t count)873 static void dump_ecc_reg(char *str, uint32_t volatile regs[], int32_t count)
874 {
875 (void)str;
876 (void)regs;
877 (void)count;
878 }
879 #endif
ch2hex(char ch)880 static char ch2hex(char ch)
881 {
882 if(ch <= '9')
883 {
884 return ch - '0';
885 }
886 else if((ch <= 'z') && (ch >= 'a'))
887 {
888 return ch - 'a' + 10U;
889 }
890 else
891 {
892 return ch - 'A' + 10U;
893 }
894 }
895
Hex2Reg(char input[],uint32_t volatile reg[])896 static void Hex2Reg(char input[], uint32_t volatile reg[])
897 {
898 char hex;
899 int si, ri;
900 uint32_t i, val32;
901
902 si = (int)strlen(input) - 1;
903 ri = 0;
904
905 while(si >= 0)
906 {
907 val32 = 0UL;
908 for(i = 0UL; (i < 8UL) && (si >= 0); i++)
909 {
910 hex = ch2hex(input[si]);
911 val32 |= (uint32_t)hex << (i * 4UL);
912 si--;
913 }
914 reg[ri++] = val32;
915 }
916 }
917
Hex2RegEx(char input[],uint32_t volatile reg[],int shift)918 static void Hex2RegEx(char input[], uint32_t volatile reg[], int shift)
919 {
920 uint32_t hex, carry;
921 int si, ri;
922 uint32_t i, val32;
923
924 si = (int)strlen(input) - 1;
925 ri = 0;
926 carry = 0U;
927 while(si >= 0)
928 {
929 val32 = 0UL;
930 for(i = 0UL; (i < 8UL) && (si >= 0); i++)
931 {
932 hex = (uint32_t)ch2hex(input[si]);
933 hex <<= shift;
934
935 val32 |= (uint32_t)((hex & 0xFU) | carry) << (i * 4UL);
936 carry = (hex >> 4) & 0xFU;
937 si--;
938 }
939 reg[ri++] = val32;
940 }
941 if(carry != 0U)
942 {
943 reg[ri] = carry;
944 }
945 }
946
947 /**
948 * @brief Extract specified nibble from an unsigned word in character format.
949 * For example:
950 * Suppose val32 is 0x786543210, get_Nth_nibble_char(val32, 3) will return a '3'.
951 * @param[in] val32 The input unsigned word
952 * @param[in] idx The Nth nibble to be extracted.
953 * @return The nibble in character format.
954 */
get_Nth_nibble_char(uint32_t val32,uint32_t idx)955 static char get_Nth_nibble_char(uint32_t val32, uint32_t idx)
956 {
957 return hex_char_tbl[(val32 >> (idx * 4U)) & 0xfU ];
958 }
959
960
Reg2Hex(int32_t count,uint32_t volatile reg[],char output[])961 static void Reg2Hex(int32_t count, uint32_t volatile reg[], char output[])
962 {
963 int32_t idx, ri;
964 uint32_t i;
965
966 output[count] = 0U;
967 idx = count - 1;
968
969 for(ri = 0; idx >= 0; ri++)
970 {
971 for(i = 0UL; (i < 8UL) && (idx >= 0); i++)
972 {
973 output[idx] = get_Nth_nibble_char(reg[ri], i);
974 idx--;
975 }
976 }
977 }
978
979 /**
980 * @brief Translate registers value into hex string
981 * @param[in] count The string length of ouptut hex string.
982 * @param[in] reg Register array.
983 * @param[in] output String buffer for output hex string.
984 */
CRPT_Reg2Hex(int32_t count,volatile uint32_t reg[],char output[])985 void CRPT_Reg2Hex(int32_t count, volatile uint32_t reg[], char output[])
986 {
987 Reg2Hex(count, reg, output);
988 }
989
990 /**
991 * @brief Translate hex string to registers value
992 * @param[in] input hex string.
993 * @param[in] reg Register array.
994 */
CRPT_Hex2Reg(char input[],uint32_t volatile reg[])995 void CRPT_Hex2Reg(char input[], uint32_t volatile reg[])
996 {
997 Hex2Reg(input, reg);
998 }
999
1000
ecc_init_curve(CRPT_T * crpt,E_ECC_CURVE ecc_curve)1001 static int32_t ecc_init_curve(CRPT_T *crpt, E_ECC_CURVE ecc_curve)
1002 {
1003 int32_t i, ret = 0;
1004
1005 pCurve = get_curve(ecc_curve);
1006 if(pCurve == NULL)
1007 {
1008 CRPT_DBGMSG("Cannot find curve %d!!\n", ecc_curve);
1009 ret = -1;
1010 }
1011
1012 if(ret == 0)
1013 {
1014 for(i = 0; i < 18; i++)
1015 {
1016 crpt->ECC_A[i] = 0UL;
1017 crpt->ECC_B[i] = 0UL;
1018 crpt->ECC_X1[i] = 0UL;
1019 crpt->ECC_Y1[i] = 0UL;
1020 crpt->ECC_N[i] = 0UL;
1021 }
1022
1023 Hex2Reg(pCurve->Ea, crpt->ECC_A);
1024 Hex2Reg(pCurve->Eb, crpt->ECC_B);
1025 Hex2Reg(pCurve->Px, crpt->ECC_X1);
1026 Hex2Reg(pCurve->Py, crpt->ECC_Y1);
1027
1028 CRPT_DBGMSG("Key length = %d\n", pCurve->key_len);
1029 dump_ecc_reg("CRPT_ECC_CURVE_A", crpt->ECC_A, 10);
1030 dump_ecc_reg("CRPT_ECC_CURVE_B", crpt->ECC_B, 10);
1031 dump_ecc_reg("CRPT_ECC_POINT_X1", crpt->ECC_X1, 10);
1032 dump_ecc_reg("CRPT_ECC_POINT_Y1", crpt->ECC_Y1, 10);
1033
1034 if(pCurve->GF == (int)CURVE_GF_2M)
1035 {
1036 crpt->ECC_N[0] = 0x1UL;
1037 crpt->ECC_N[(pCurve->key_len) / 32] |= (1UL << ((pCurve->key_len) % 32));
1038 crpt->ECC_N[(pCurve->irreducible_k1) / 32] |= (1UL << ((pCurve->irreducible_k1) % 32));
1039 crpt->ECC_N[(pCurve->irreducible_k2) / 32] |= (1UL << ((pCurve->irreducible_k2) % 32));
1040 crpt->ECC_N[(pCurve->irreducible_k3) / 32] |= (1UL << ((pCurve->irreducible_k3) % 32));
1041 }
1042 else
1043 {
1044 Hex2Reg(pCurve->Pp, crpt->ECC_N);
1045 }
1046 }
1047 dump_ecc_reg("CRPT_ECC_CURVE_N", crpt->ECC_N, 10);
1048 return ret;
1049 }
1050
1051
get_nibble_value(char c)1052 static int get_nibble_value(char c)
1053 {
1054 char ch;
1055
1056 if((c >= '0') && (c <= '9'))
1057 {
1058 ch = '0';
1059 return ((int)c - (int)ch);
1060 }
1061
1062 if((c >= 'a') && (c <= 'f'))
1063 {
1064 ch = 'a';
1065 return ((int)c - (int)ch + 10);
1066 }
1067
1068 if((c >= 'A') && (c <= 'F'))
1069 {
1070 ch = 'A';
1071 return ((int)c - (int)ch + 10);
1072 }
1073 return 0;
1074 }
1075
1076
1077 /**
1078 * @brief Check if the private key is located in valid range of curve.
1079 * @param[in] crpt The pointer of CRYPTO module
1080 * @param[in] ecc_curve The pre-defined ECC curve.
1081 * @param[in] private_k The input private key.
1082 * @return 1 Is valid.
1083 * @return 0 Is not valid.
1084 * @return -1 Invalid curve.
1085 */
ECC_IsPrivateKeyValid(CRPT_T * crpt,E_ECC_CURVE ecc_curve,char private_k[])1086 int ECC_IsPrivateKeyValid(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char private_k[])
1087 {
1088 uint32_t i;
1089
1090 (void)crpt;
1091 pCurve = get_curve(ecc_curve);
1092 if(pCurve == NULL)
1093 {
1094 return -1;
1095 }
1096
1097 if(strlen(private_k) < strlen(pCurve->Eorder))
1098 {
1099 return 1;
1100 }
1101
1102 if(strlen(private_k) > strlen(pCurve->Eorder))
1103 {
1104 return 0;
1105 }
1106
1107 for(i = 0U; i < strlen(private_k); i++)
1108 {
1109 if(get_nibble_value(private_k[i]) < get_nibble_value(pCurve->Eorder[i]))
1110 {
1111 return 1;
1112 }
1113
1114 if(get_nibble_value(private_k[i]) > get_nibble_value(pCurve->Eorder[i]))
1115 {
1116 return 0;
1117 }
1118 }
1119 return 0;
1120 }
1121
1122
1123 /**
1124 * @brief Given a private key and curve to generate the public key pair.
1125 * @param[in] crpt The pointer of CRYPTO module
1126 * @param[in] private_k The input private key.
1127 * @param[in] ecc_curve The pre-defined ECC curve.
1128 * @param[out] public_k1 The output publick key 1.
1129 * @param[out] public_k2 The output publick key 2.
1130 * @return 0 Success.
1131 * @return -1 Hardware error or time-out.
1132 * @return -2 "ecc_curve" value is invalid.
1133 */
ECC_GeneratePublicKey(CRPT_T * crpt,E_ECC_CURVE ecc_curve,char * private_k,char public_k1[],char public_k2[])1134 int32_t ECC_GeneratePublicKey(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char *private_k, char public_k1[], char public_k2[])
1135 {
1136 int32_t ret = 0, i, i32TimeOutCnt;
1137
1138 if(ecc_init_curve(crpt, ecc_curve) != 0)
1139 {
1140 ret = -2;
1141 }
1142
1143 if(ret == 0)
1144 {
1145 CRPT->ECC_KSCTL = 0;
1146
1147 for(i = 0; i < 18; i++)
1148 {
1149 crpt->ECC_K[i] = 0UL;
1150 }
1151
1152 Hex2Reg(private_k, crpt->ECC_K);
1153
1154 /* set FSEL (Field selection) */
1155 if(pCurve->GF == (int)CURVE_GF_2M)
1156 {
1157 crpt->ECC_CTL = 0UL;
1158 }
1159 else /* CURVE_GF_P */
1160 {
1161 crpt->ECC_CTL = CRPT_ECC_CTL_FSEL_Msk;
1162 }
1163
1164 g_ECC_done = g_ECCERR_done = 0UL;
1165 crpt->ECC_CTL |= ((uint32_t)pCurve->key_len << CRPT_ECC_CTL_CURVEM_Pos) |
1166 ECCOP_POINT_MUL | CRPT_ECC_CTL_START_Msk;
1167
1168 i32TimeOutCnt = TIMEOUT_ECC;
1169 while(g_ECC_done == 0UL)
1170 {
1171 if( (i32TimeOutCnt-- <= 0) || g_ECCERR_done )
1172 {
1173 ret = -1;
1174 break;
1175 }
1176 }
1177 }
1178
1179 if(ret == 0)
1180 {
1181 Reg2Hex(pCurve->Echar, crpt->ECC_X1, public_k1);
1182 Reg2Hex(pCurve->Echar, crpt->ECC_Y1, public_k2);
1183 }
1184
1185 return ret;
1186 }
1187
1188
1189
1190
1191 /**
1192 * @brief Given a private key and curve to generate the public key pair.
1193 * @param[in] crpt The pointer of CRYPTO module
1194 * @param[in] ecc_curve The pre-defined ECC curve.
1195 * @param[in] mem Memory type of Key Store. It could be KS_SRAM, KS_FLASH or KS_OTP.
1196 * @param[in] i32KeyIdx Index of the key in Key Store.
1197 * @param[out] public_k1 The output publick key 1.
1198 * @param[out] public_k2 The output publick key 2.
1199 * @param[in] u32ExtraOp Extra options for ECC_KSCTL register.
1200 * @return 0 Success.
1201 * @return -1 Hardware error or time-out.
1202 * @return -2 "ecc_curve" value is invalid.
1203 */
ECC_GeneratePublicKey_KS(CRPT_T * crpt,E_ECC_CURVE ecc_curve,KS_MEM_Type mem,int32_t i32KeyIdx,char public_k1[],char public_k2[],uint32_t u32ExtraOp)1204 int32_t ECC_GeneratePublicKey_KS(CRPT_T *crpt, E_ECC_CURVE ecc_curve, KS_MEM_Type mem, int32_t i32KeyIdx, char public_k1[], char public_k2[], uint32_t u32ExtraOp)
1205 {
1206 int32_t ret = 0, i32TimeOutCnt;
1207
1208 if(ecc_init_curve(crpt, ecc_curve) != 0)
1209 {
1210 ret = -2;
1211 }
1212
1213 if(ret == 0)
1214 {
1215
1216 // key from key store
1217 crpt->ECC_KSCTL = (uint32_t)(mem << 6)/* KS Memory Type */ |
1218 (CRPT_ECC_KSCTL_RSRCK_Msk)/* Key from KS */ |
1219 u32ExtraOp |
1220 (uint32_t)i32KeyIdx;
1221
1222 /* set FSEL (Field selection) */
1223 if(pCurve->GF == (int)CURVE_GF_2M)
1224 {
1225 crpt->ECC_CTL = 0UL;
1226 }
1227 else /* CURVE_GF_P */
1228 {
1229 crpt->ECC_CTL = CRPT_ECC_CTL_FSEL_Msk;
1230 }
1231
1232 g_ECC_done = g_ECCERR_done = 0UL;
1233 crpt->ECC_CTL |= ((uint32_t)pCurve->key_len << CRPT_ECC_CTL_CURVEM_Pos) |
1234 ECCOP_POINT_MUL | CRPT_ECC_CTL_START_Msk;
1235
1236 i32TimeOutCnt = TIMEOUT_ECC;
1237 while(g_ECC_done == 0UL)
1238 {
1239 if( (i32TimeOutCnt-- <= 0) || g_ECCERR_done )
1240 {
1241 ret = -1;
1242 break;
1243 }
1244 }
1245 }
1246
1247 if(ret == 0)
1248 {
1249 Reg2Hex(pCurve->Echar, crpt->ECC_X1, public_k1);
1250 Reg2Hex(pCurve->Echar, crpt->ECC_Y1, public_k2);
1251 }
1252
1253 return ret;
1254 }
1255
1256 /**
1257 * @brief Given a private key and curve to generate the public key pair.
1258 * @param[in] crpt Reference to Crypto module.
1259 * @param[out] x1 The x-coordinate of input point.
1260 * @param[out] y1 The y-coordinate of input point.
1261 * @param[in] k The private key
1262 * @param[in] ecc_curve The pre-defined ECC curve.
1263 * @param[out] x2 The x-coordinate of output point.
1264 * @param[out] y2 The y-coordinate of output point.
1265 * @return 0 Success.
1266 * @return -1 Hardware error or time-out.
1267 * @return -2 "ecc_curve" value is invalid.
1268 */
ECC_Mutiply(CRPT_T * crpt,E_ECC_CURVE ecc_curve,char x1[],char y1[],char * k,char x2[],char y2[])1269 int32_t ECC_Mutiply(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char x1[], char y1[], char *k, char x2[], char y2[])
1270 {
1271 int32_t i, ret = 0, i32TimeOutCnt;
1272
1273 if(ecc_init_curve(crpt, ecc_curve) != 0)
1274 {
1275 ret = -2;
1276 }
1277
1278 if(ret == 0)
1279 {
1280 for(i = 0; i < 9; i++)
1281 {
1282 crpt->ECC_X1[i] = 0UL;
1283 crpt->ECC_Y1[i] = 0UL;
1284 crpt->ECC_K[i] = 0UL;
1285 }
1286
1287 Hex2Reg(x1, crpt->ECC_X1);
1288 Hex2Reg(y1, crpt->ECC_Y1);
1289 Hex2Reg(k, crpt->ECC_K);
1290
1291 /* set FSEL (Field selection) */
1292 if(pCurve->GF == (int)CURVE_GF_2M)
1293 {
1294 crpt->ECC_CTL = 0UL;
1295 }
1296 else
1297 {
1298 /* CURVE_GF_P */
1299 crpt->ECC_CTL = CRPT_ECC_CTL_FSEL_Msk;
1300 }
1301
1302 g_ECC_done = g_ECCERR_done = 0UL;
1303
1304 if(ecc_curve == CURVE_25519)
1305 {
1306 crpt->ECC_CTL |= CRPT_ECC_CTL_CSEL_Msk;
1307 }
1308
1309 crpt->ECC_CTL |= ((uint32_t)pCurve->key_len << CRPT_ECC_CTL_CURVEM_Pos) |
1310 ECCOP_POINT_MUL | CRPT_ECC_CTL_START_Msk;
1311
1312 i32TimeOutCnt = TIMEOUT_ECC;
1313 while(g_ECC_done == 0UL)
1314 {
1315 if( (i32TimeOutCnt-- <= 0) || g_ECCERR_done )
1316 {
1317 ret = -1;
1318 break;
1319 }
1320 }
1321 }
1322
1323 if(ret == 0)
1324 {
1325 Reg2Hex(pCurve->Echar, crpt->ECC_X1, x2);
1326 Reg2Hex(pCurve->Echar, crpt->ECC_Y1, y2);
1327 }
1328
1329 return ret;
1330 }
1331
1332
1333 /**
1334 * @brief Given a curve parameter, the other party's public key, and one's own private key to generate the secret Z.
1335 * @param[in] crpt The pointer of CRYPTO module
1336 * @param[in] ecc_curve The pre-defined ECC curve.
1337 * @param[in] private_k One's own private key.
1338 * @param[in] public_k1 The other party's publick key 1.
1339 * @param[in] public_k2 The other party's publick key 2.
1340 * @param[out] secret_z The ECC CDH secret Z.
1341 * @return 0 Success.
1342 * @return -1 Hardware error or time-out.
1343 * @return -2 "ecc_curve" value is invalid.
1344 */
ECC_GenerateSecretZ(CRPT_T * crpt,E_ECC_CURVE ecc_curve,char * private_k,char public_k1[],char public_k2[],char secret_z[])1345 int32_t ECC_GenerateSecretZ(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char *private_k, char public_k1[], char public_k2[], char secret_z[])
1346 {
1347 int32_t i, ret = 0, i32TimeOutCnt;
1348
1349 if(ecc_init_curve(crpt, ecc_curve) != 0)
1350 {
1351 ret = -2;
1352 }
1353
1354 if(ret == 0)
1355 {
1356 for(i = 0; i < 18; i++)
1357 {
1358 crpt->ECC_K[i] = 0UL;
1359 crpt->ECC_X1[i] = 0UL;
1360 crpt->ECC_Y1[i] = 0UL;
1361 }
1362
1363 if((ecc_curve == CURVE_B_163) || (ecc_curve == CURVE_B_233) || (ecc_curve == CURVE_B_283) ||
1364 (ecc_curve == CURVE_B_409) || (ecc_curve == CURVE_B_571) || (ecc_curve == CURVE_K_163))
1365 {
1366 Hex2RegEx(private_k, crpt->ECC_K, 1);
1367 }
1368 else if((ecc_curve == CURVE_K_233) || (ecc_curve == CURVE_K_283) ||
1369 (ecc_curve == CURVE_K_409) || (ecc_curve == CURVE_K_571))
1370 {
1371 Hex2RegEx(private_k, crpt->ECC_K, 2);
1372 }
1373 else
1374 {
1375 Hex2Reg(private_k, crpt->ECC_K);
1376 }
1377
1378 Hex2Reg(public_k1, crpt->ECC_X1);
1379 Hex2Reg(public_k2, crpt->ECC_Y1);
1380
1381 /* set FSEL (Field selection) */
1382 if(pCurve->GF == (int)CURVE_GF_2M)
1383 {
1384 crpt->ECC_CTL = 0UL;
1385 }
1386 else /* CURVE_GF_P */
1387 {
1388 crpt->ECC_CTL = CRPT_ECC_CTL_FSEL_Msk;
1389 }
1390 g_ECC_done = g_ECCERR_done = 0UL;
1391 crpt->ECC_CTL |= ((uint32_t)pCurve->key_len << CRPT_ECC_CTL_CURVEM_Pos) |
1392 ECCOP_POINT_MUL | CRPT_ECC_CTL_START_Msk;
1393
1394 i32TimeOutCnt = TIMEOUT_ECC;
1395 while(g_ECC_done == 0UL)
1396 {
1397 if( (i32TimeOutCnt-- <= 0) || g_ECCERR_done )
1398 {
1399 ret = -1;
1400 break;
1401 }
1402 }
1403 }
1404
1405 if(ret == 0)
1406 {
1407 Reg2Hex(pCurve->Echar, crpt->ECC_X1, secret_z);
1408 }
1409
1410 return ret;
1411 }
1412
1413
1414 /**
1415 * @brief Given a curve parameter, the other party's public key, and one's own private key to generate the secret Z.
1416 * @param[in] crpt The pointer of CRYPTO module
1417 * @param[in] ecc_curve The pre-defined ECC curve.
1418 * @param[in] private_k One's own private key.
1419 * @param[in] public_k1 The other party's publick key 1.
1420 * @param[in] public_k2 The other party's publick key 2.
1421 * @param[out] secret_z The ECC CDH secret Z.
1422 * @return 0 Success.
1423 * @return -1 Hardware error or time-out.
1424 * @return -2 "ecc_curve" value is invalid.
1425 */
ECC_GenerateSecretZ_KS(CRPT_T * crpt,E_ECC_CURVE ecc_curve,KS_MEM_Type mem,int32_t i32KeyIdx,char public_k1[],char public_k2[])1426 int32_t ECC_GenerateSecretZ_KS(CRPT_T *crpt, E_ECC_CURVE ecc_curve, KS_MEM_Type mem, int32_t i32KeyIdx, char public_k1[], char public_k2[])
1427 {
1428 int32_t i, i32TimeOutCnt;
1429
1430 if(ecc_init_curve(crpt, ecc_curve) != 0)
1431 {
1432 return -2;
1433 }
1434
1435 for(i = 0; i < 18; i++)
1436 {
1437 crpt->ECC_K[i] = 0UL;
1438 crpt->ECC_X1[i] = 0UL;
1439 crpt->ECC_Y1[i] = 0UL;
1440 }
1441
1442 crpt->ECC_KSCTL = CRPT_ECC_KSCTL_ECDH_Msk | CRPT_ECC_KSCTL_RSRCK_Msk | CRPT_ECC_KSCTL_WDST_Msk |
1443 (uint32_t)(mem << CRPT_ECC_KSCTL_RSSRCK_Pos)/* KS Memory Type */ |
1444 (uint32_t)i32KeyIdx;
1445
1446 Hex2Reg(public_k1, crpt->ECC_X1);
1447 Hex2Reg(public_k2, crpt->ECC_Y1);
1448
1449 /* set FSEL (Field selection) */
1450 if(pCurve->GF == (int)CURVE_GF_2M)
1451 {
1452 crpt->ECC_CTL = 0UL;
1453 }
1454 else /* CURVE_GF_P */
1455 {
1456 crpt->ECC_CTL = CRPT_ECC_CTL_FSEL_Msk;
1457 }
1458
1459 g_ECC_done = g_ECCERR_done = 0UL;
1460
1461 crpt->ECC_CTL |= ((uint32_t)pCurve->key_len << CRPT_ECC_CTL_CURVEM_Pos) |
1462 ECCOP_POINT_MUL | CRPT_ECC_CTL_START_Msk;
1463
1464 i32TimeOutCnt = TIMEOUT_ECC;
1465 while(g_ECC_done == 0UL)
1466 {
1467 if( (i32TimeOutCnt-- <= 0) || g_ECCERR_done )
1468 {
1469 return -1;
1470 }
1471 }
1472
1473 return (crpt->ECC_KSSTS & 0x1f);
1474
1475 }
1476
1477
run_ecc_codec(CRPT_T * crpt,uint32_t mode)1478 static int32_t run_ecc_codec(CRPT_T *crpt, uint32_t mode)
1479 {
1480 uint32_t eccop;
1481 int32_t i32TimeOutCnt;
1482 #ifdef ECC_SCA_PROTECT
1483 uint32_t x1[18], y1[18], ctl;
1484 int32_t i;
1485 #endif
1486
1487 eccop = mode & CRPT_ECC_CTL_ECCOP_Msk;
1488 if(eccop == ECCOP_MODULE)
1489 {
1490 crpt->ECC_CTL = CRPT_ECC_CTL_FSEL_Msk;
1491 }
1492 else
1493 {
1494 if(pCurve->GF == (int)CURVE_GF_2M)
1495 {
1496 /* point */
1497 crpt->ECC_CTL = 0UL;
1498 }
1499 else
1500 {
1501 /* CURVE_GF_P */
1502 crpt->ECC_CTL = CRPT_ECC_CTL_FSEL_Msk;
1503 }
1504
1505 #ifdef ECC_SCA_PROTECT
1506 if(eccop == ECCOP_POINT_MUL)
1507 {
1508 /* Backup ctrl */
1509 ctl = crpt->ECC_CTL;
1510
1511 /* Enable side-channel protection in some operation */
1512 crpt->ECC_CTL |= CRPT_ECC_CTL_SCAP_Msk;
1513 /* If SCAP enabled, the curve order must be written to ECC_X2 */
1514 Hex2Reg(pCurve->Eorder, crpt->ECC_X2);
1515
1516 /* Backeup x1, y1 for retry */
1517 for(i = 0; i < 18; i++)
1518 {
1519 x1[i] = crpt->ECC_X1[i];
1520 y1[i] = crpt->ECC_Y1[i];
1521 }
1522
1523 }
1524 #endif
1525
1526 }
1527
1528 g_ECC_done = g_ECCERR_done = 0UL;
1529
1530 crpt->ECC_CTL |= ((uint32_t)pCurve->key_len << CRPT_ECC_CTL_CURVEM_Pos) | mode | CRPT_ECC_CTL_START_Msk;
1531
1532 i32TimeOutCnt = TIMEOUT_ECC;
1533 while(g_ECC_done == 0UL)
1534 {
1535 if( (i32TimeOutCnt-- <= 0) || g_ECCERR_done )
1536 {
1537 goto lexit;
1538 }
1539 }
1540
1541 i32TimeOutCnt = TIMEOUT_ECC;
1542 while(crpt->ECC_STS & CRPT_ECC_STS_BUSY_Msk)
1543 {
1544 if( i32TimeOutCnt-- <= 0)
1545 {
1546 goto lexit;
1547 }
1548 }
1549
1550 lexit:
1551 #ifdef ECC_SCA_PROTECT
1552 if(i32TimeOutCnt <= 0)
1553 {
1554 /* Retry if ECCOP_POINT_MUL */
1555 if(eccop == ECCOP_POINT_MUL)
1556 {
1557 crpt->ECC_CTL = CRPT_ECC_CTL_STOP_Msk;
1558 crpt->ECC_CTL = ctl;
1559
1560 /* Try again */
1561 for(i = 0; i < 18; i++)
1562 {
1563 crpt->ECC_X1[i] = x1[i];
1564 crpt->ECC_Y1[i] = y1[i];
1565 }
1566
1567 g_ECC_done = g_ECCERR_done = 0UL;
1568
1569 crpt->ECC_CTL |= ((uint32_t)pCurve->key_len << CRPT_ECC_CTL_CURVEM_Pos) | mode | CRPT_ECC_CTL_START_Msk;
1570
1571 i32TimeOutCnt = TIMEOUT_ECC;
1572 while(g_ECC_done == 0UL)
1573 {
1574 if((i32TimeOutCnt-- <= 0) || g_ECCERR_done)
1575 {
1576 return -1;
1577 }
1578 }
1579 }
1580 else
1581 {
1582 return -1;
1583 }
1584 }
1585
1586 #else
1587 if(i32TimeOutCnt <= 0)
1588 {
1589 return -1;
1590 }
1591 #endif
1592
1593 return 0;
1594 }
1595
1596 /**
1597 * @brief ECDSA digital signature generation.
1598 * @param[in] crpt The pointer of CRYPTO module
1599 * @param[in] ecc_curve The pre-defined ECC curve.
1600 * @param[in] message The hash value of source context.
1601 * @param[in] d The private key.
1602 * @param[in] k The selected random integer.
1603 * @param[out] R R of the (R,S) pair digital signature
1604 * @param[out] S S of the (R,S) pair digital signature
1605 * @return 0 Success.
1606 * @return -1 "ecc_curve" value is invalid.
1607 */
ECC_GenerateSignature(CRPT_T * crpt,E_ECC_CURVE ecc_curve,char * message,char * d,char * k,char * R,char * S)1608 int32_t ECC_GenerateSignature(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char *message,
1609 char *d, char *k, char *R, char *S)
1610 {
1611 uint32_t volatile temp_result1[18], temp_result2[18];
1612 int32_t i, ret = 0;
1613
1614 if(ecc_init_curve(crpt, ecc_curve) != 0)
1615 {
1616 ret = -1;
1617 }
1618
1619 if(ret == 0)
1620 {
1621 CRPT->ECC_KSCTL = 0;
1622
1623 /*
1624 * 1. Calculate e = HASH(m), where HASH is a cryptographic hashing algorithm, (i.e. SHA-1)
1625 * (1) Use SHA to calculate e
1626 */
1627
1628 /* 2. Select a random integer k form [1, n-1]
1629 * (1) Notice that n is order, not prime modulus or irreducible polynomial function
1630 */
1631
1632 /*
1633 * 3. Compute r = x1 (mod n), where (x1, y1) = k * G. If r = 0, go to step 2
1634 * (1) Write the curve parameter A, B, and curve length M to corresponding registers
1635 * (2) Write the prime modulus or irreducible polynomial function to N registers according
1636 * (3) Write the point G(x, y) to X1, Y1 registers
1637 * (4) Write the random integer k to K register
1638 * (5) Set ECCOP(CRPT_ECC_CTL[10:9]) to 00
1639 * (6) Set FSEL(CRPT_ECC_CTL[8]) according to used curve of prime field or binary field
1640 * (7) Set START(CRPT_ECC_CTL[0]) to 1
1641 * (8) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1642 * (9) Write the curve order and curve length to N ,M registers according
1643 * (10) Write 0x0 to Y1 registers
1644 * (11) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1645 * (12) Set MOPOP(CRPT_ECC_CTL[12:11]) to 10
1646 * (13) Set START(CRPT_ECC_CTL[0]) to 1 *
1647 * (14) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1648 * (15) Read X1 registers to get r
1649 */
1650
1651 /* 3-(4) Write the random integer k to K register */
1652 for(i = 0; i < 18; i++)
1653 {
1654 crpt->ECC_K[i] = 0UL;
1655 }
1656 Hex2Reg(k, crpt->ECC_K);
1657
1658 run_ecc_codec(crpt, ECCOP_POINT_MUL);
1659
1660 /* 3-(9) Write the curve order to N registers */
1661 for(i = 0; i < 18; i++)
1662 {
1663 crpt->ECC_N[i] = 0UL;
1664 }
1665 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
1666
1667 /* 3-(10) Write 0x0 to Y1 registers */
1668 for(i = 0; i < 18; i++)
1669 {
1670 crpt->ECC_Y1[i] = 0UL;
1671 }
1672
1673 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_ADD);
1674
1675 /* 3-(15) Read X1 registers to get r */
1676 for(i = 0; i < 18; i++)
1677 {
1678 temp_result1[i] = crpt->ECC_X1[i];
1679 }
1680
1681 Reg2Hex(pCurve->Echar, temp_result1, R);
1682
1683 /*
1684 * 4. Compute s = k^-1 * (e + d * r)(mod n). If s = 0, go to step 2
1685 * (1) Write the curve order to N registers according
1686 * (2) Write 0x1 to Y1 registers
1687 * (3) Write the random integer k to X1 registers according
1688 * (4) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1689 * (5) Set MOPOP(CRPT_ECC_CTL[12:11]) to 00
1690 * (6) Set START(CRPT_ECC_CTL[0]) to 1
1691 * (7) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1692 * (8) Read X1 registers to get k^-1
1693 * (9) Write the curve order and curve length to N ,M registers
1694 * (10) Write r, d to X1, Y1 registers
1695 * (11) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1696 * (12) Set MOPOP(CRPT_ECC_CTL[12:11]) to 01
1697 * (13) Set START(CRPT_ECC_CTL[0]) to 1
1698 * (14) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1699 * (15) Write the curve order to N registers
1700 * (16) Write e to Y1 registers
1701 * (17) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1702 * (18) Set MOPOP(CRPT_ECC_CTL[12:11]) to 10
1703 * (19) Set START(CRPT_ECC_CTL[0]) to 1
1704 * (20) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1705 * (21) Write the curve order and curve length to N ,M registers
1706 * (22) Write k^-1 to Y1 registers
1707 * (23) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1708 * (24) Set MOPOP(CRPT_ECC_CTL[12:11]) to 01
1709 * (25) Set START(CRPT_ECC_CTL[0]) to 1
1710 * (26) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1711 * (27) Read X1 registers to get s
1712 */
1713
1714 /* S/W: GFp_add_mod_order(pCurve->key_len+2, 0, x1, a, R); */
1715
1716 /* 4-(1) Write the curve order to N registers */
1717 for(i = 0; i < 18; i++)
1718 {
1719 crpt->ECC_N[i] = 0UL;
1720 }
1721 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
1722
1723 /* 4-(2) Write 0x1 to Y1 registers */
1724 for(i = 0; i < 18; i++)
1725 {
1726 crpt->ECC_Y1[i] = 0UL;
1727 }
1728 crpt->ECC_Y1[0] = 0x1UL;
1729
1730 /* 4-(3) Write the random integer k to X1 registers */
1731 for(i = 0; i < 18; i++)
1732 {
1733 crpt->ECC_X1[i] = 0UL;
1734 }
1735 Hex2Reg(k, crpt->ECC_X1);
1736
1737 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_DIV);
1738
1739 #if ENABLE_DEBUG
1740 Reg2Hex(pCurve->Echar, crpt->ECC_X1, temp_hex_str);
1741 CRPT_DBGMSG("(7) output = %s\n", temp_hex_str);
1742 #endif
1743
1744 /* 4-(8) Read X1 registers to get k^-1 */
1745
1746 for(i = 0; i < 18; i++)
1747 {
1748 temp_result2[i] = crpt->ECC_X1[i];
1749 }
1750
1751 #if ENABLE_DEBUG
1752 Reg2Hex(pCurve->Echar, temp_result2, temp_hex_str);
1753 CRPT_DBGMSG("k^-1 = %s\n", temp_hex_str);
1754 #endif
1755
1756 /* 4-(9) Write the curve order and curve length to N ,M registers */
1757 for(i = 0; i < 18; i++)
1758 {
1759 crpt->ECC_N[i] = 0UL;
1760 }
1761 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
1762
1763 /* 4-(10) Write r, d to X1, Y1 registers */
1764 for(i = 0; i < 18; i++)
1765 {
1766 crpt->ECC_X1[i] = temp_result1[i];
1767 }
1768
1769 for(i = 0; i < 18; i++)
1770 {
1771 crpt->ECC_Y1[i] = 0UL;
1772 }
1773 Hex2Reg(d, crpt->ECC_Y1);
1774
1775 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_MUL);
1776
1777 #if ENABLE_DEBUG
1778 Reg2Hex(pCurve->Echar, crpt->ECC_X1, temp_hex_str);
1779 CRPT_DBGMSG("(14) output = %s\n", temp_hex_str);
1780 #endif
1781
1782 /* 4-(15) Write the curve order to N registers */
1783 for(i = 0; i < 18; i++)
1784 {
1785 crpt->ECC_N[i] = 0UL;
1786 }
1787 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
1788
1789 /* 4-(16) Write e to Y1 registers */
1790 for(i = 0; i < 18; i++)
1791 {
1792 crpt->ECC_Y1[i] = 0UL;
1793 }
1794
1795 Hex2Reg(message, crpt->ECC_Y1);
1796
1797 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_ADD);
1798
1799 #if ENABLE_DEBUG
1800 Reg2Hex(pCurve->Echar, crpt->ECC_X1, temp_hex_str);
1801 CRPT_DBGMSG("(20) output = %s\n", temp_hex_str);
1802 #endif
1803
1804 /* 4-(21) Write the curve order and curve length to N ,M registers */
1805 for(i = 0; i < 18; i++)
1806 {
1807 crpt->ECC_N[i] = 0UL;
1808 }
1809 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
1810
1811 /* 4-(22) Write k^-1 to Y1 registers */
1812 for(i = 0; i < 18; i++)
1813 {
1814 crpt->ECC_Y1[i] = temp_result2[i];
1815 }
1816
1817 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_MUL);
1818
1819 /* 4-(27) Read X1 registers to get s */
1820 for(i = 0; i < 18; i++)
1821 {
1822 temp_result2[i] = crpt->ECC_X1[i];
1823 }
1824
1825 Reg2Hex(pCurve->Echar, temp_result2, S);
1826
1827 } /* ret == 0 */
1828
1829 return ret;
1830 }
1831
1832
1833
1834 /**
1835 * @brief ECDSA digital signature generation.
1836 * @param[in] crpt The pointer of CRYPTO module
1837 * @param[in] ecc_curve The pre-defined ECC curve.
1838 * @param[in] message The hash value of source context.
1839 * @param[in] d The private key.
1840 * @param[in] k The selected random integer.
1841 * @param[out] R R of the (R,S) pair digital signature
1842 * @param[out] S S of the (R,S) pair digital signature
1843 * @return 0 Success.
1844 * @return -1 "ecc_curve" value is invalid.
1845 */
ECC_GenerateSignature_KS(CRPT_T * crpt,E_ECC_CURVE ecc_curve,char * message,KS_MEM_Type mem_d,int32_t i32KeyIdx_d,KS_MEM_Type mem_k,int32_t i32KeyIdx_k,char * R,char * S)1846 int32_t ECC_GenerateSignature_KS(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char *message, KS_MEM_Type mem_d, int32_t i32KeyIdx_d, KS_MEM_Type mem_k, int32_t i32KeyIdx_k, char *R, char *S)
1847 {
1848 uint32_t volatile temp_result1[18], temp_result2[18];
1849 int32_t i, ret = 0;
1850
1851 if(ecc_init_curve(crpt, ecc_curve) != 0)
1852 {
1853 ret = -1;
1854 }
1855
1856 if(ret == 0)
1857 {
1858 CRPT->ECC_KSCTL = 0;
1859 CRPT->ECC_KSXY = 0;
1860
1861 /*
1862 * 1. Calculate e = HASH(m), where HASH is a cryptographic hashing algorithm, (i.e. SHA-1)
1863 * (1) Use SHA to calculate e
1864 */
1865
1866 /* 2. Select a random integer k form [1, n-1]
1867 * (1) Notice that n is order, not prime modulus or irreducible polynomial function
1868 */
1869
1870 /*
1871 * 3. Compute r = x1 (mod n), where (x1, y1) = k * G. If r = 0, go to step 2
1872 * (1) Write the curve parameter A, B, and curve length M to corresponding registers
1873 * (2) Write the prime modulus or irreducible polynomial function to N registers according
1874 * (3) Write the point G(x, y) to X1, Y1 registers
1875 * (4) Write the random integer k to K register
1876 * (5) Set ECCOP(CRPT_ECC_CTL[10:9]) to 00
1877 * (6) Set FSEL(CRPT_ECC_CTL[8]) according to used curve of prime field or binary field
1878 * (7) Set START(CRPT_ECC_CTL[0]) to 1
1879 * (8) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1880 * (9) Write the curve order and curve length to N ,M registers according
1881 * (10) Write 0x0 to Y1 registers
1882 * (11) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1883 * (12) Set MOPOP(CRPT_ECC_CTL[12:11]) to 10
1884 * (13) Set START(CRPT_ECC_CTL[0]) to 1 *
1885 * (14) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1886 * (15) Read X1 registers to get r
1887 */
1888
1889 /* 3-(4) Use k in Key Store */
1890 crpt->ECC_KSCTL = (uint32_t)(mem_k << CRPT_ECC_KSCTL_RSSRCK_Pos)/* KS Memory Type */ |
1891 CRPT_ECC_KSCTL_RSRCK_Msk/* Key from KS */ |
1892 (uint32_t)i32KeyIdx_k;
1893
1894 run_ecc_codec(crpt, ECCOP_POINT_MUL | OP_ECDSAR);
1895
1896 /* 3-(9) Write the curve order to N registers */
1897 for(i = 0; i < 18; i++)
1898 {
1899 crpt->ECC_N[i] = 0UL;
1900 }
1901 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
1902
1903 /* 3-(10) Write 0x0 to Y1 registers */
1904 for(i = 0; i < 18; i++)
1905 {
1906 crpt->ECC_Y1[i] = 0UL;
1907 }
1908
1909 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_ADD);
1910
1911 /* 3-(15) Read X1 registers to get r */
1912 for(i = 0; i < 18; i++)
1913 {
1914 temp_result1[i] = crpt->ECC_X1[i];
1915 }
1916
1917 Reg2Hex(pCurve->Echar, temp_result1, R);
1918
1919
1920 /*
1921 * 4. Compute s = k ^-1 * (e + d * r)(mod n). If s = 0, go to step 2
1922 * (1) Write the curve order to N registers according
1923 * (2) Write 0x1 to Y1 registers
1924 * (3) Write the random integer k to X1 registers according
1925 * (4) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1926 * (5) Set MOPOP(CRPT_ECC_CTL[12:11]) to 00
1927 * (6) Set START(CRPT_ECC_CTL[0]) to 1
1928 * (7) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1929 * (8) Read X1 registers to get k^-1
1930 * (9) Write the curve order and curve length to N ,M registers
1931 * (10) Write r, d to X1, Y1 registers
1932 * (11) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1933 * (12) Set MOPOP(CRPT_ECC_CTL[12:11]) to 01
1934 * (13) Set START(CRPT_ECC_CTL[0]) to 1
1935 * (14) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1936 * (15) Write the curve order to N registers
1937 * (16) Write e to Y1 registers
1938 * (17) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1939 * (18) Set MOPOP(CRPT_ECC_CTL[12:11]) to 10
1940 * (19) Set START(CRPT_ECC_CTL[0]) to 1
1941 * (20) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1942 * (21) Write the curve order and curve length to N ,M registers
1943 * (22) Write k^-1 to Y1 registers
1944 * (23) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1945 * (24) Set MOPOP(CRPT_ECC_CTL[12:11]) to 01
1946 * (25) Set START(CRPT_ECC_CTL[0]) to 1
1947 * (26) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1948 * (27) Read X1 registers to get s
1949 */
1950
1951 /* S/W: GFp_add_mod_order(pCurve->key_len+2, 0, x1, a, R); */
1952
1953 /* 4-(1) Write the curve order to N registers */
1954 for(i = 0; i < 18; i++)
1955 {
1956 crpt->ECC_N[i] = 0UL;
1957 }
1958 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
1959
1960 /* 4-(2)(3)(4)(5) Use d, k in Key Store */
1961 crpt->ECC_CTL = 0;
1962 crpt->ECC_KSXY = CRPT_ECC_KSXY_RSRCXY_Msk |
1963 (uint32_t)(mem_k << CRPT_ECC_KSXY_RSSRCX_Pos) | ((uint32_t)i32KeyIdx_k << CRPT_ECC_KSXY_NUMX_Pos) | // Key Store index of k
1964 (uint32_t)(mem_d << CRPT_ECC_KSXY_RSSRCY_Pos) | ((uint32_t)i32KeyIdx_d << CRPT_ECC_KSXY_NUMY_Pos); // Key Store index of d
1965
1966 // 4-5
1967 for(i = 0; i < 18; i++)
1968 {
1969 crpt->ECC_X2[i] = temp_result1[i];
1970 crpt->ECC_Y2[i] = 0;
1971 }
1972 Hex2Reg(message, crpt->ECC_Y2);
1973
1974 run_ecc_codec(crpt, ECCOP_MODULE | OP_ECDSAS);
1975
1976 /* 4-11 Read X1 registers to get s */
1977 for(i = 0; i < 18; i++)
1978 {
1979 temp_result2[i] = crpt->ECC_X1[i];
1980 }
1981 Reg2Hex(pCurve->Echar, temp_result2, S);
1982
1983 /* Clear KS Control */
1984 CRPT->ECC_KSCTL = 0;
1985 CRPT->ECC_KSXY = 0;
1986
1987 } /* ret == 0 */
1988
1989 return ret;
1990 }
1991
1992
1993 /**
1994 * @brief ECDSA digital signature verification.
1995 * @param[in] crpt The pointer of CRYPTO module
1996 * @param[in] ecc_curve The pre-defined ECC curve.
1997 * @param[in] message The hash value of source context.
1998 * @param[in] public_k1 The public key 1.
1999 * @param[in] public_k2 The public key 2.
2000 * @param[in] R R of the (R,S) pair digital signature
2001 * @param[in] S S of the (R,S) pair digital signature
2002 * @return 0 Success.
2003 * @return -1 "ecc_curve" value is invalid.
2004 * @return -2 Verification failed.
2005 */
ECC_VerifySignature(CRPT_T * crpt,E_ECC_CURVE ecc_curve,char * message,char * public_k1,char * public_k2,char * R,char * S)2006 int32_t ECC_VerifySignature(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char *message,
2007 char *public_k1, char *public_k2, char *R, char *S)
2008 {
2009 uint32_t temp_result1[18], temp_result2[18];
2010 uint32_t temp_x[18], temp_y[18];
2011 int32_t i, ret = 0;
2012
2013 /*
2014 * 1. Verify that r and s are integers in the interval [1, n-1]. If not, the signature is invalid
2015 * 2. Compute e = HASH (m), where HASH is the hashing algorithm in signature generation
2016 * (1) Use SHA to calculate e
2017 */
2018
2019 /*
2020 * 3. Compute w = s^-1 (mod n)
2021 * (1) Write the curve order to N registers
2022 * (2) Write 0x1 to Y1 registers
2023 * (3) Write s to X1 registers
2024 * (4) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
2025 * (5) Set MOPOP(CRPT_ECC_CTL[12:11]) to 00
2026 * (6) Set FSEL(CRPT_ECC_CTL[8]) according to used curve of prime field or binary field
2027 * (7) Set START(CRPT_ECC_CTL[0]) to 1
2028 * (8) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
2029 * (9) Read X1 registers to get w
2030 */
2031
2032 if(ecc_init_curve(crpt, ecc_curve) != 0)
2033 {
2034 ret = -1;
2035 }
2036
2037 if(ret == 0)
2038 {
2039
2040 /* 3-(1) Write the curve order to N registers */
2041 for(i = 0; i < 18; i++)
2042 {
2043 crpt->ECC_N[i] = 0UL;
2044 }
2045 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
2046
2047 /* 3-(2) Write 0x1 to Y1 registers */
2048 for(i = 0; i < 18; i++)
2049 {
2050 crpt->ECC_Y1[i] = 0UL;
2051 }
2052 crpt->ECC_Y1[0] = 0x1UL;
2053
2054 /* 3-(3) Write s to X1 registers */
2055 for(i = 0; i < 18; i++)
2056 {
2057 CRPT->ECC_X1[i] = 0UL;
2058 }
2059 Hex2Reg(S, crpt->ECC_X1);
2060
2061 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_DIV);
2062
2063 /* 3-(9) Read X1 registers to get w */
2064 for(i = 0; i < 18; i++)
2065 {
2066 temp_result2[i] = crpt->ECC_X1[i];
2067 }
2068
2069 #if ENABLE_DEBUG
2070 CRPT_DBGMSG("e = %s\n", message);
2071 Reg2Hex(pCurve->Echar, temp_result2, temp_hex_str);
2072 CRPT_DBGMSG("w = %s\n", temp_hex_str);
2073 CRPT_DBGMSG("o = %s (order)\n", pCurve->Eorder);
2074 #endif
2075
2076 /*
2077 * 4. Compute u1 = e * w (mod n) and u2 = r * w (mod n)
2078 * (1) Write the curve order and curve length to N ,M registers
2079 * (2) Write e, w to X1, Y1 registers
2080 * (3) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
2081 * (4) Set MOPOP(CRPT_ECC_CTL[12:11]) to 01
2082 * (5) Set START(CRPT_ECC_CTL[0]) to 1
2083 * (6) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
2084 * (7) Read X1 registers to get u1
2085 * (8) Write the curve order and curve length to N ,M registers
2086 * (9) Write r, w to X1, Y1 registers
2087 * (10) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
2088 * (11) Set MOPOP(CRPT_ECC_CTL[12:11]) to 01
2089 * (12) Set START(CRPT_ECC_CTL[0]) to 1
2090 * (13) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
2091 * (14) Read X1 registers to get u2
2092 */
2093
2094 /* 4-(1) Write the curve order and curve length to N ,M registers */
2095 for(i = 0; i < 18; i++)
2096 {
2097 crpt->ECC_N[i] = 0UL;
2098 }
2099 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
2100
2101 /* 4-(2) Write e, w to X1, Y1 registers */
2102 for(i = 0; i < 18; i++)
2103 {
2104 crpt->ECC_X1[i] = 0UL;
2105 }
2106 Hex2Reg(message, crpt->ECC_X1);
2107
2108 for(i = 0; i < 18; i++)
2109 {
2110 crpt->ECC_Y1[i] = temp_result2[i];
2111 }
2112
2113 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_MUL);
2114
2115 /* 4-(7) Read X1 registers to get u1 */
2116 for(i = 0; i < 18; i++)
2117 {
2118 temp_result1[i] = crpt->ECC_X1[i];
2119 }
2120
2121 #if ENABLE_DEBUG
2122 Reg2Hex(pCurve->Echar, temp_result1, temp_hex_str);
2123 CRPT_DBGMSG("u1 = %s\n", temp_hex_str);
2124 #endif
2125
2126 /* 4-(8) Write the curve order and curve length to N ,M registers */
2127 for(i = 0; i < 18; i++)
2128 {
2129 crpt->ECC_N[i] = 0UL;
2130 }
2131 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
2132
2133 /* 4-(9) Write r, w to X1, Y1 registers */
2134 for(i = 0; i < 18; i++)
2135 {
2136 crpt->ECC_X1[i] = 0UL;
2137 }
2138 Hex2Reg(R, crpt->ECC_X1);
2139
2140 for(i = 0; i < 18; i++)
2141 {
2142 crpt->ECC_Y1[i] = temp_result2[i];
2143 }
2144
2145 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_MUL);
2146
2147 /* 4-(14) Read X1 registers to get u2 */
2148 for(i = 0; i < 18; i++)
2149 {
2150 temp_result2[i] = crpt->ECC_X1[i];
2151 }
2152
2153 #if ENABLE_DEBUG
2154 Reg2Hex(pCurve->Echar, temp_result2, temp_hex_str);
2155 CRPT_DBGMSG("u2 = %s\n", temp_hex_str);
2156 #endif
2157
2158 /*
2159 * 5. Compute X * (x1', y1') = u1 * G + u2 * Q
2160 * (1) Write the curve parameter A, B, N, and curve length M to corresponding registers
2161 * (2) Write the point G(x, y) to X1, Y1 registers
2162 * (3) Write u1 to K registers
2163 * (4) Set ECCOP(CRPT_ECC_CTL[10:9]) to 00
2164 * (5) Set START(CRPT_ECC_CTL[0]) to 1
2165 * (6) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
2166 * (7) Read X1, Y1 registers to get u1*G
2167 * (8) Write the curve parameter A, B, N, and curve length M to corresponding registers
2168 * (9) Write the public key Q(x,y) to X1, Y1 registers
2169 * (10) Write u2 to K registers
2170 * (11) Set ECCOP(CRPT_ECC_CTL[10:9]) to 00
2171 * (12) Set START(CRPT_ECC_CTL[0]) to 1
2172 * (13) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
2173 * (14) Write the curve parameter A, B, N, and curve length M to corresponding registers
2174 * (15) Write the result data u1*G to X2, Y2 registers
2175 * (16) Set ECCOP(CRPT_ECC_CTL[10:9]) to 10
2176 * (17) Set START(CRPT_ECC_CTL[0]) to 1
2177 * (18) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
2178 * (19) Read X1, Y1 registers to get X *(x1', y1')
2179 * (20) Write the curve order and curve length to N ,M registers
2180 * (21) Write x1 * to X1 registers
2181 * (22) Write 0x0 to Y1 registers
2182 * (23) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
2183 * (24) Set MOPOP(CRPT_ECC_CTL[12:11]) to 10
2184 * (25) Set START(CRPT_ECC_CTL[0]) to 1
2185 * (26) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
2186 * (27) Read X1 registers to get x1 * (mod n)
2187 *
2188 * 6. The signature is valid if x1 * = r, otherwise it is invalid
2189 */
2190
2191 /*
2192 * (1) Write the curve parameter A, B, N, and curve length M to corresponding registers
2193 * (2) Write the point G(x, y) to X1, Y1 registers
2194 */
2195 ecc_init_curve(crpt, ecc_curve);
2196
2197 /* (3) Write u1 to K registers */
2198 for(i = 0; i < 18; i++)
2199 {
2200 crpt->ECC_K[i] = temp_result1[i];
2201 }
2202
2203 run_ecc_codec(crpt, ECCOP_POINT_MUL);
2204
2205 /* (7) Read X1, Y1 registers to get u1*G */
2206 for(i = 0; i < 18; i++)
2207 {
2208 temp_x[i] = crpt->ECC_X1[i];
2209 temp_y[i] = crpt->ECC_Y1[i];
2210 }
2211
2212 #if ENABLE_DEBUG
2213 Reg2Hex(pCurve->Echar, temp_x, temp_hex_str);
2214 CRPT_DBGMSG("5-(7) u1*G, x = %s\n", temp_hex_str);
2215 Reg2Hex(pCurve->Echar, temp_y, temp_hex_str);
2216 CRPT_DBGMSG("5-(7) u1*G, y = %s\n", temp_hex_str);
2217 #endif
2218
2219 /* (8) Write the curve parameter A, B, N, and curve length M to corresponding registers */
2220 ecc_init_curve(crpt, ecc_curve);
2221
2222 /* (9) Write the public key Q(x,y) to X1, Y1 registers */
2223 for(i = 0; i < 18; i++)
2224 {
2225 crpt->ECC_X1[i] = 0UL;
2226 crpt->ECC_Y1[i] = 0UL;
2227 }
2228
2229 Hex2Reg(public_k1, crpt->ECC_X1);
2230 Hex2Reg(public_k2, crpt->ECC_Y1);
2231
2232 /* (10) Write u2 to K registers */
2233 for(i = 0; i < 18; i++)
2234 {
2235 crpt->ECC_K[i] = temp_result2[i];
2236 }
2237
2238 run_ecc_codec(crpt, ECCOP_POINT_MUL);
2239
2240 for(i = 0; i < 18; i++)
2241 {
2242 temp_result1[i] = crpt->ECC_X1[i];
2243 temp_result2[i] = crpt->ECC_Y1[i];
2244 }
2245
2246 #if ENABLE_DEBUG
2247 Reg2Hex(pCurve->Echar, temp_result1, temp_hex_str);
2248 CRPT_DBGMSG("5-(13) u2*Q, x = %s\n", temp_hex_str);
2249 Reg2Hex(pCurve->Echar, temp_result2, temp_hex_str);
2250 CRPT_DBGMSG("5-(13) u2*Q, y = %s\n", temp_hex_str);
2251 #endif
2252
2253 /* (14) Write the curve parameter A, B, N, and curve length M to corresponding registers */
2254 ecc_init_curve(crpt, ecc_curve);
2255
2256 /* Write the result data u2*Q to X1, Y1 registers */
2257 for(i = 0; i < 18; i++)
2258 {
2259 crpt->ECC_X1[i] = temp_result1[i];
2260 crpt->ECC_Y1[i] = temp_result2[i];
2261 }
2262
2263 /* (15) Write the result data u1*G to X2, Y2 registers */
2264 for(i = 0; i < 18; i++)
2265 {
2266 crpt->ECC_X2[i] = temp_x[i];
2267 crpt->ECC_Y2[i] = temp_y[i];
2268 }
2269
2270 run_ecc_codec(crpt, ECCOP_POINT_ADD);
2271
2272 /* (19) Read X1, Y1 registers to get X * (x1', y1') */
2273 for(i = 0; i < 18; i++)
2274 {
2275 temp_x[i] = crpt->ECC_X1[i];
2276 temp_y[i] = crpt->ECC_Y1[i];
2277 }
2278
2279 #if ENABLE_DEBUG
2280 Reg2Hex(pCurve->Echar, temp_x, temp_hex_str);
2281 CRPT_DBGMSG("5-(19) x' = %s\n", temp_hex_str);
2282 Reg2Hex(pCurve->Echar, temp_y, temp_hex_str);
2283 CRPT_DBGMSG("5-(19) y' = %s\n", temp_hex_str);
2284 #endif
2285
2286 /* (20) Write the curve order and curve length to N ,M registers */
2287 for(i = 0; i < 18; i++)
2288 {
2289 crpt->ECC_N[i] = 0UL;
2290 }
2291 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
2292
2293 /*
2294 * (21) Write x1 * to X1 registers
2295 * (22) Write 0x0 to Y1 registers
2296 */
2297 for(i = 0; i < 18; i++)
2298 {
2299 crpt->ECC_X1[i] = temp_x[i];
2300 crpt->ECC_Y1[i] = 0UL;
2301 }
2302
2303 #if ENABLE_DEBUG
2304 Reg2Hex(pCurve->Echar, crpt->ECC_X1, temp_hex_str);
2305 CRPT_DBGMSG("5-(21) x' = %s\n", temp_hex_str);
2306 Reg2Hex(pCurve->Echar, crpt->ECC_Y1, temp_hex_str);
2307 CRPT_DBGMSG("5-(22) y' = %s\n", temp_hex_str);
2308 #endif
2309
2310 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_ADD);
2311
2312 /* (27) Read X1 registers to get x1 * (mod n) */
2313 Reg2Hex(pCurve->Echar, crpt->ECC_X1, temp_hex_str);
2314 CRPT_DBGMSG("5-(27) x1' (mod n) = %s\n", temp_hex_str);
2315
2316 /* 6. The signature is valid if x1 * = r, otherwise it is invalid */
2317
2318 /* Compare with test pattern to check if r is correct or not */
2319 if(strcasecmp(temp_hex_str, R) != 0)
2320 {
2321 CRPT_DBGMSG("x1' (mod n) != R Test filed!!\n");
2322 CRPT_DBGMSG("Signature R [%s] is not matched with expected R [%s]!\n", temp_hex_str, R);
2323 ret = -2;
2324 }
2325 } /* ret == 0 */
2326
2327 return ret;
2328 }
2329
2330
2331
2332 /**
2333 * @brief ECDSA signature verification with Key Store
2334 * @param[in] crpt The pointer of CRYPTO module
2335 * @param[in] ecc_curve The pre-defined ECC curve.
2336 * @param[in] message The hash value of source context.
2337 * @param[in] public_k1 The public key 1.
2338 * @param[in] public_k2 The public key 2.
2339 * @param[in] R R of the (R,S) pair digital signature
2340 * @param[in] S S of the (R,S) pair digital signature
2341 * @return 0 Success.
2342 * @return -1 "ecc_curve" value is invalid.
2343 * @return -2 Verification failed.
2344 */
ECC_VerifySignature_KS(CRPT_T * crpt,E_ECC_CURVE ecc_curve,char * message,KS_MEM_Type mem_pk1,int32_t i32KeyIdx_pk1,KS_MEM_Type mem_pk2,int32_t i32KeyIdx_pk2,char * R,char * S)2345 int32_t ECC_VerifySignature_KS(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char *message, KS_MEM_Type mem_pk1, int32_t i32KeyIdx_pk1, KS_MEM_Type mem_pk2, int32_t i32KeyIdx_pk2, char *R, char *S)
2346 {
2347 uint32_t temp_result1[18], temp_result2[18];
2348 uint32_t temp_x[18], temp_y[18];
2349 int32_t i, ret = 0;
2350
2351 /*
2352 * 1. Verify that r and s are integers in the interval [1, n-1]. If not, the signature is invalid
2353 * 2. Compute e = HASH (m), where HASH is the hashing algorithm in signature generation
2354 * (1) Use SHA to calculate e
2355 */
2356
2357 /*
2358 * 3. Compute w = s^-1 (mod n)
2359 * (1) Write the curve order to N registers
2360 * (2) Write 0x1 to Y1 registers
2361 * (3) Write s to X1 registers
2362 * (4) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
2363 * (5) Set MOPOP(CRPT_ECC_CTL[12:11]) to 00
2364 * (6) Set FSEL(CRPT_ECC_CTL[8]) according to used curve of prime field or binary field
2365 * (7) Set START(CRPT_ECC_CTL[0]) to 1
2366 * (8) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
2367 * (9) Read X1 registers to get w
2368 */
2369
2370 if(ecc_init_curve(crpt, ecc_curve) != 0)
2371 {
2372 ret = -1;
2373 }
2374
2375 if(ret == 0)
2376 {
2377 crpt->ECC_KSCTL = 0;
2378 crpt->ECC_KSXY = 0;
2379
2380 /* 3-(1) Write the curve order to N registers */
2381 for(i = 0; i < 18; i++)
2382 {
2383 crpt->ECC_N[i] = 0UL;
2384 }
2385 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
2386
2387 /* 3-(2) Write 0x1 to Y1 registers */
2388 for(i = 0; i < 18; i++)
2389 {
2390 crpt->ECC_Y1[i] = 0UL;
2391 }
2392 crpt->ECC_Y1[0] = 0x1UL;
2393
2394 /* 3-(3) Write s to X1 registers */
2395 for(i = 0; i < 18; i++)
2396 {
2397 CRPT->ECC_X1[i] = 0UL;
2398 }
2399 Hex2Reg(S, crpt->ECC_X1);
2400
2401 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_DIV);
2402
2403 /* 3-(9) Read X1 registers to get w */
2404 for(i = 0; i < 18; i++)
2405 {
2406 temp_result2[i] = crpt->ECC_X1[i];
2407 }
2408
2409 #if ENABLE_DEBUG
2410 CRPT_DBGMSG("e = %s\n", message);
2411 Reg2Hex(pCurve->Echar, temp_result2, temp_hex_str);
2412 CRPT_DBGMSG("w = %s\n", temp_hex_str);
2413 CRPT_DBGMSG("o = %s (order)\n", pCurve->Eorder);
2414 #endif
2415
2416 /*
2417 * 4. Compute u1 = e * w (mod n) and u2 = r * w (mod n)
2418 * (1) Write the curve order and curve length to N ,M registers
2419 * (2) Write e, w to X1, Y1 registers
2420 * (3) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
2421 * (4) Set MOPOP(CRPT_ECC_CTL[12:11]) to 01
2422 * (5) Set START(CRPT_ECC_CTL[0]) to 1
2423 * (6) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
2424 * (7) Read X1 registers to get u1
2425 * (8) Write the curve order and curve length to N ,M registers
2426 * (9) Write r, w to X1, Y1 registers
2427 * (10) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
2428 * (11) Set MOPOP(CRPT_ECC_CTL[12:11]) to 01
2429 * (12) Set START(CRPT_ECC_CTL[0]) to 1
2430 * (13) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
2431 * (14) Read X1 registers to get u2
2432 */
2433
2434 /* 4-(1) Write the curve order and curve length to N ,M registers */
2435 for(i = 0; i < 18; i++)
2436 {
2437 crpt->ECC_N[i] = 0UL;
2438 }
2439 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
2440
2441 /* 4-(2) Write e, w to X1, Y1 registers */
2442 for(i = 0; i < 18; i++)
2443 {
2444 crpt->ECC_X1[i] = 0UL;
2445 }
2446 Hex2Reg(message, crpt->ECC_X1);
2447
2448 for(i = 0; i < 18; i++)
2449 {
2450 crpt->ECC_Y1[i] = temp_result2[i];
2451 }
2452
2453 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_MUL);
2454
2455 /* 4-(7) Read X1 registers to get u1 */
2456 for(i = 0; i < 18; i++)
2457 {
2458 temp_result1[i] = crpt->ECC_X1[i];
2459 }
2460
2461 #if ENABLE_DEBUG
2462 Reg2Hex(pCurve->Echar, temp_result1, temp_hex_str);
2463 CRPT_DBGMSG("u1 = %s\n", temp_hex_str);
2464 #endif
2465
2466 /* 4-(8) Write the curve order and curve length to N ,M registers */
2467 for(i = 0; i < 18; i++)
2468 {
2469 crpt->ECC_N[i] = 0UL;
2470 }
2471 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
2472
2473 /* 4-(9) Write r, w to X1, Y1 registers */
2474 for(i = 0; i < 18; i++)
2475 {
2476 crpt->ECC_X1[i] = 0UL;
2477 }
2478 Hex2Reg(R, crpt->ECC_X1);
2479
2480 for(i = 0; i < 18; i++)
2481 {
2482 crpt->ECC_Y1[i] = temp_result2[i];
2483 }
2484
2485 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_MUL);
2486
2487 /* 4-(14) Read X1 registers to get u2 */
2488 for(i = 0; i < 18; i++)
2489 {
2490 temp_result2[i] = crpt->ECC_X1[i];
2491 }
2492
2493 #if ENABLE_DEBUG
2494 Reg2Hex(pCurve->Echar, temp_result2, temp_hex_str);
2495 CRPT_DBGMSG("u2 = %s\n", temp_hex_str);
2496 #endif
2497
2498 /*
2499 * 5. Compute X * (x1', y1') = u1 * G + u2 * Q
2500 * (1) Write the curve parameter A, B, N, and curve length M to corresponding registers
2501 * (2) Write the point G(x, y) to X1, Y1 registers
2502 * (3) Write u1 to K registers
2503 * (4) Set ECCOP(CRPT_ECC_CTL[10:9]) to 00
2504 * (5) Set START(CRPT_ECC_CTL[0]) to 1
2505 * (6) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
2506 * (7) Read X1, Y1 registers to get u1*G
2507 * (8) Write the curve parameter A, B, N, and curve length M to corresponding registers
2508 * (9) Write the public key Q(x,y) to X1, Y1 registers
2509 * (10) Write u2 to K registers
2510 * (11) Set ECCOP(CRPT_ECC_CTL[10:9]) to 00
2511 * (12) Set START(CRPT_ECC_CTL[0]) to 1
2512 * (13) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
2513 * (14) Write the curve parameter A, B, N, and curve length M to corresponding registers
2514 * (15) Write the result data u1*G to X2, Y2 registers
2515 * (16) Set ECCOP(CRPT_ECC_CTL[10:9]) to 10
2516 * (17) Set START(CRPT_ECC_CTL[0]) to 1
2517 * (18) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
2518 * (19) Read X1, Y1 registers to get X * (x1', y1')
2519 * (20) Write the curve order and curve length to N ,M registers
2520 * (21) Write x1 * to X1 registers
2521 * (22) Write 0x0 to Y1 registers
2522 * (23) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
2523 * (24) Set MOPOP(CRPT_ECC_CTL[12:11]) to 10
2524 * (25) Set START(CRPT_ECC_CTL[0]) to 1
2525 * (26) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
2526 * (27) Read X1 registers to get x1 * (mod n)
2527 *
2528 * 6. The signature is valid if x1 * = r, otherwise it is invalid
2529 */
2530
2531 /*
2532 * (1) Write the curve parameter A, B, N, and curve length M to corresponding registers
2533 * (2) Write the point G(x, y) to X1, Y1 registers
2534 */
2535 ecc_init_curve(crpt, ecc_curve);
2536
2537 /* (3) Write u1 to K registers */
2538 for(i = 0; i < 18; i++)
2539 {
2540 crpt->ECC_K[i] = temp_result1[i];
2541 }
2542
2543 run_ecc_codec(crpt, ECCOP_POINT_MUL);
2544
2545 /* (7) Read X1, Y1 registers to get u1*G */
2546 for(i = 0; i < 18; i++)
2547 {
2548 temp_x[i] = crpt->ECC_X1[i];
2549 temp_y[i] = crpt->ECC_Y1[i];
2550 }
2551
2552 #if ENABLE_DEBUG
2553 Reg2Hex(pCurve->Echar, temp_x, temp_hex_str);
2554 CRPT_DBGMSG("5-(7) u1*G, x = %s\n", temp_hex_str);
2555 Reg2Hex(pCurve->Echar, temp_y, temp_hex_str);
2556 CRPT_DBGMSG("5-(7) u1*G, y = %s\n", temp_hex_str);
2557 #endif
2558
2559 /* (8) Write the curve parameter A, B, N, and curve length M to corresponding registers */
2560 ecc_init_curve(crpt, ecc_curve);
2561
2562 /* (9) Write the public key Q(x,y) to X1, Y1 registers */
2563 for(i = 0; i < 18; i++)
2564 {
2565 crpt->ECC_X1[i] = 0UL;
2566 crpt->ECC_Y1[i] = 0UL;
2567 }
2568
2569
2570 #if 0
2571 Hex2Reg(public_k1, crpt->ECC_X1);
2572 Hex2Reg(public_k2, crpt->ECC_Y1);
2573 #else
2574
2575 /* 5-(2) Get the public key from key store */
2576 crpt->ECC_KSCTL = 0ul;
2577 crpt->ECC_KSXY = CRPT_ECC_KSXY_RSRCXY_Msk |
2578 (uint32_t)(mem_pk1 << CRPT_ECC_KSXY_RSSRCX_Pos) | ((uint32_t)i32KeyIdx_pk1 << CRPT_ECC_KSXY_NUMX_Pos) | // Key Store index of pk1
2579 (uint32_t)(mem_pk2 << CRPT_ECC_KSXY_RSSRCY_Pos) | ((uint32_t)i32KeyIdx_pk2 << CRPT_ECC_KSXY_NUMY_Pos); // Key Store index of pk2
2580
2581 #endif
2582
2583 /* (10) Write u2 to K registers */
2584 for(i = 0; i < 18; i++)
2585 {
2586 crpt->ECC_K[i] = temp_result2[i];
2587 }
2588
2589 run_ecc_codec(crpt, ECCOP_POINT_MUL);
2590
2591 for(i = 0; i < 18; i++)
2592 {
2593 temp_result1[i] = crpt->ECC_X1[i];
2594 temp_result2[i] = crpt->ECC_Y1[i];
2595 }
2596
2597 #if ENABLE_DEBUG
2598 Reg2Hex(pCurve->Echar, temp_result1, temp_hex_str);
2599 CRPT_DBGMSG("5-(13) u2*Q, x = %s\n", temp_hex_str);
2600 Reg2Hex(pCurve->Echar, temp_result2, temp_hex_str);
2601 CRPT_DBGMSG("5-(13) u2*Q, y = %s\n", temp_hex_str);
2602 #endif
2603
2604 /* (14) Write the curve parameter A, B, N, and curve length M to corresponding registers */
2605 ecc_init_curve(crpt, ecc_curve);
2606
2607 /* Write the result data u2*Q to X1, Y1 registers */
2608 for(i = 0; i < 18; i++)
2609 {
2610 crpt->ECC_X1[i] = temp_result1[i];
2611 crpt->ECC_Y1[i] = temp_result2[i];
2612 }
2613
2614 /* (15) Write the result data u1*G to X2, Y2 registers */
2615 for(i = 0; i < 18; i++)
2616 {
2617 crpt->ECC_X2[i] = temp_x[i];
2618 crpt->ECC_Y2[i] = temp_y[i];
2619 }
2620
2621 run_ecc_codec(crpt, ECCOP_POINT_ADD);
2622
2623 /* (19) Read X1, Y1 registers to get X * (x1', y1') */
2624 for(i = 0; i < 18; i++)
2625 {
2626 temp_x[i] = crpt->ECC_X1[i];
2627 temp_y[i] = crpt->ECC_Y1[i];
2628 }
2629
2630 #if ENABLE_DEBUG
2631 Reg2Hex(pCurve->Echar, temp_x, temp_hex_str);
2632 CRPT_DBGMSG("5-(19) x' = %s\n", temp_hex_str);
2633 Reg2Hex(pCurve->Echar, temp_y, temp_hex_str);
2634 CRPT_DBGMSG("5-(19) y' = %s\n", temp_hex_str);
2635 #endif
2636
2637 /* (20) Write the curve order and curve length to N ,M registers */
2638 for(i = 0; i < 18; i++)
2639 {
2640 crpt->ECC_N[i] = 0UL;
2641 }
2642 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
2643
2644 /*
2645 * (21) Write x1 * to X1 registers
2646 * (22) Write 0x0 to Y1 registers
2647 */
2648 for(i = 0; i < 18; i++)
2649 {
2650 crpt->ECC_X1[i] = temp_x[i];
2651 crpt->ECC_Y1[i] = 0UL;
2652 }
2653
2654 #if ENABLE_DEBUG
2655 Reg2Hex(pCurve->Echar, crpt->ECC_X1, temp_hex_str);
2656 CRPT_DBGMSG("5-(21) x' = %s\n", temp_hex_str);
2657 Reg2Hex(pCurve->Echar, crpt->ECC_Y1, temp_hex_str);
2658 CRPT_DBGMSG("5-(22) y' = %s\n", temp_hex_str);
2659 #endif
2660
2661 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_ADD);
2662
2663 /* (27) Read X1 registers to get x1 * (mod n) */
2664 Reg2Hex(pCurve->Echar, crpt->ECC_X1, temp_hex_str);
2665 CRPT_DBGMSG("5-(27) x1' (mod n) = %s\n", temp_hex_str);
2666
2667 /* 6. The signature is valid if x1 * = r, otherwise it is invalid */
2668
2669 /* Compare with test pattern to check if r is correct or not */
2670 if(strcasecmp(temp_hex_str, R) != 0)
2671 {
2672 CRPT_DBGMSG("x1' (mod n) != R Test filed!!\n");
2673 CRPT_DBGMSG("Signature R [%s] is not matched with expected R [%s]!\n", temp_hex_str, R);
2674 ret = -2;
2675 }
2676 } /* ret == 0 */
2677
2678 return ret;
2679 }
2680
2681
get_curve(E_ECC_CURVE ecc_curve)2682 static ECC_CURVE * get_curve(E_ECC_CURVE ecc_curve)
2683 {
2684 uint32_t i;
2685 ECC_CURVE *ret = NULL;
2686
2687 for(i = 0UL; i < sizeof(_Curve) / sizeof(ECC_CURVE); i++)
2688 {
2689 if(ecc_curve == _Curve[i].curve_id)
2690 {
2691 memcpy((char *)&Curve_Copy, &_Curve[i], sizeof(ECC_CURVE));
2692 ret = &Curve_Copy; /* (ECC_CURVE *)&_Curve[i]; */
2693 }
2694 if(ret != NULL)
2695 {
2696 break;
2697 }
2698 }
2699 return ret;
2700 }
2701
2702
2703 /**
2704 * @brief ECC interrupt service routine. User application must invoke this function in
2705 * his CRYPTO_IRQHandler() to let Crypto driver know ECC processing was done.
2706 * @param[in] crpt Reference to Crypto module.
2707 * @return none
2708 */
ECC_Complete(CRPT_T * crpt)2709 void ECC_Complete(CRPT_T *crpt)
2710 {
2711 if(crpt->INTSTS & CRPT_INTSTS_ECCIF_Msk)
2712 {
2713 g_ECC_done = 1UL;
2714 crpt->INTSTS = CRPT_INTSTS_ECCIF_Msk;
2715 /* printf("ECC done IRQ.\n"); */
2716 }
2717
2718 if(crpt->INTSTS & CRPT_INTSTS_ECCEIF_Msk)
2719 {
2720 g_ECCERR_done = 1UL;
2721 crpt->INTSTS = CRPT_INTSTS_ECCEIF_Msk;
2722 printf("ECCEIF flag is set!!\n");
2723 }
2724 }
2725
2726
ECC_GetCurve(CRPT_T * crpt,E_ECC_CURVE ecc_curve,ECC_CURVE * curve)2727 int32_t ECC_GetCurve(CRPT_T *crpt, E_ECC_CURVE ecc_curve, ECC_CURVE *curve)
2728 {
2729 int32_t err;
2730
2731 /* Update pCurve pointer */
2732 err = ecc_init_curve(crpt, ecc_curve);
2733 if(err == 0)
2734 {
2735 /* get curve */
2736 memcpy(curve, pCurve, sizeof(ECC_CURVE));
2737 }
2738
2739 return err;
2740 }
2741
2742
2743 /*-----------------------------------------------------------------------------------------------*/
2744 /* */
2745 /* RSA */
2746 /* */
2747 /*-----------------------------------------------------------------------------------------------*/
2748
2749 /** @cond HIDDEN_SYMBOLS */
2750
2751 static void *s_pRSABuf;
2752 static uint32_t s_u32RsaOpMode;
2753
2754 typedef enum
2755 {
2756 BUF_NORMAL,
2757 BUF_CRT,
2758 BUF_CRTBYPASS,
2759 BUF_KS
2760 } E_RSA_BUF_SEL;
2761
2762 static int32_t CheckRsaBufferSize(uint32_t u32OpMode, uint32_t u32BufSize, uint32_t u32UseKS);
2763
2764 /** @endcond HIDDEN_SYMBOLS */
2765
2766 /* Check the allocated buffer size for RSA operation. */
CheckRsaBufferSize(uint32_t u32OpMode,uint32_t u32BufSize,uint32_t u32UseKS)2767 static int32_t CheckRsaBufferSize(uint32_t u32OpMode, uint32_t u32BufSize, uint32_t u32UseKS)
2768 {
2769 /* RSA buffer size for MODE_NORMAL, MODE_CRT, MODE_CRTBYPASS */
2770 uint32_t s_au32RsaBufSizeTbl[] = {sizeof(RSA_BUF_NORMAL_T), sizeof(RSA_BUF_CRT_T), sizeof(RSA_BUF_CRT_T), sizeof(RSA_BUF_KS_T)};
2771
2772 if(u32UseKS)
2773 {
2774 if(u32BufSize != s_au32RsaBufSizeTbl[BUF_KS])
2775 return (-1);
2776 }
2777 else
2778 {
2779 switch(u32OpMode)
2780 {
2781 case RSA_MODE_NORMAL:
2782 if(u32BufSize != s_au32RsaBufSizeTbl[BUF_NORMAL])
2783 return (-1);
2784 break;
2785 case RSA_MODE_CRT:
2786 if(u32BufSize != s_au32RsaBufSizeTbl[BUF_CRT])
2787 return (-1);
2788 break;
2789 case RSA_MODE_CRTBYPASS:
2790 if(u32BufSize != s_au32RsaBufSizeTbl[BUF_CRTBYPASS])
2791 return (-1);
2792 break;
2793 default:
2794 return (-1);
2795 }
2796 }
2797
2798 return 0;
2799 }
2800
2801 /**
2802 * @brief Open RSA encrypt/decrypt function.
2803 * @param[in] crpt The pointer of CRYPTO module
2804 * @param[in] u32OpMode RSA operation mode, including:
2805 * - \ref RSA_MODE_NORMAL
2806 * - \ref RSA_MODE_CRT
2807 * - \ref RSA_MODE_CRTBYPASS
2808 * @param[in] u32KeySize is RSA key size, including:
2809 * - \ref RSA_KEY_SIZE_1024
2810 * - \ref RSA_KEY_SIZE_2048
2811 * - \ref RSA_KEY_SIZE_3072
2812 * - \ref RSA_KEY_SIZE_4096
2813 * @param[in] psRSA_Buf The pointer of RSA buffer struct. User should declare correct RSA buffer for specific operation mode first.
2814 * - \ref RSA_BUF_NORMAL_T The struct for normal mode
2815 * - \ref RSA_BUF_CRT_T The struct for CRT ( + CRT bypass) mode
2816 * - \ref RSA_BUF_KS_T The struct for using key store
2817 * @param[in] u32BufSize is RSA buffer size.
2818 * @param[in] u32UseKS is use key store function.
2819 * - \ref 0 No use key store function
2820 * - \ref 1 Use key store function
2821 * @return 0 Success.
2822 * @return -1 The value of pointer of RSA buffer struct is null.
2823 */
RSA_Open(CRPT_T * crpt,uint32_t u32OpMode,uint32_t u32KeySize,void * psRSA_Buf,uint32_t u32BufSize,uint32_t u32UseKS)2824 int32_t RSA_Open(CRPT_T *crpt, uint32_t u32OpMode, uint32_t u32KeySize, \
2825 void *psRSA_Buf, uint32_t u32BufSize, uint32_t u32UseKS)
2826 {
2827 if(psRSA_Buf == 0)
2828 {
2829 return (-1);
2830 }
2831 if(CheckRsaBufferSize(u32OpMode, u32BufSize, u32UseKS) != 0)
2832 {
2833 return (-1);
2834 }
2835
2836 s_u32RsaOpMode = u32OpMode;
2837 s_pRSABuf = psRSA_Buf;
2838 crpt->RSA_CTL = (u32OpMode) | (u32KeySize << CRPT_RSA_CTL_KEYLENG_Pos);
2839
2840 return 0;
2841 }
2842
2843 /**
2844 * @brief Set the RSA key
2845 * @param[in] crpt The pointer of CRYPTO module
2846 * @param[in] Key The private or public key.
2847 * @return 0 Success.
2848 * @return -1 The value of pointer of RSA buffer struct is null.
2849 */
RSA_SetKey(CRPT_T * crpt,char * Key)2850 int32_t RSA_SetKey(CRPT_T *crpt, char *Key)
2851 {
2852 if(s_pRSABuf == 0)
2853 {
2854 return (-1);
2855 }
2856 Hex2Reg(Key, ((RSA_BUF_NORMAL_T *)s_pRSABuf)->au32RsaE);
2857 crpt->RSA_SADDR[2] = (uint32_t) & ((RSA_BUF_NORMAL_T *)s_pRSABuf)->au32RsaE; /* the public key or private key */
2858
2859 return 0;
2860 }
2861
2862 /**
2863 * @brief Set RSA DMA transfer configuration.
2864 * @param[in] crpt The pointer of CRYPTO module
2865 * @param[in] Src RSA DMA source data
2866 * @param[in] n The modulus for both the public and private keys
2867 * @param[in] P The factor of modulus operation(P) for CRT mode
2868 * @param[in] Q The factor of modulus operation(Q) for CRT mode
2869 * @return 0 Success.
2870 * @return -1 The value of pointer of RSA buffer struct is null.
2871 */
RSA_SetDMATransfer(CRPT_T * crpt,char * Src,char * n,char * P,char * Q)2872 int32_t RSA_SetDMATransfer(CRPT_T *crpt, char *Src, char *n, char *P, char *Q)
2873 {
2874 if(s_pRSABuf == 0)
2875 {
2876 return (-1);
2877 }
2878 Hex2Reg(Src, ((RSA_BUF_NORMAL_T *)s_pRSABuf)->au32RsaM);
2879 Hex2Reg(n, ((RSA_BUF_NORMAL_T *)s_pRSABuf)->au32RsaN);
2880
2881 /* Assign the data to DMA */
2882 crpt->RSA_SADDR[0] = (uint32_t) & ((RSA_BUF_NORMAL_T *)s_pRSABuf)->au32RsaM; /* plaintext / encrypt data */
2883 crpt->RSA_SADDR[1] = (uint32_t) & ((RSA_BUF_NORMAL_T *)s_pRSABuf)->au32RsaN; /* the base of modulus operation */
2884 crpt->RSA_DADDR = (uint32_t) & ((RSA_BUF_NORMAL_T *)s_pRSABuf)->au32RsaOutput; /* encrypt data / decrypt data */
2885
2886 if(s_u32RsaOpMode & CRPT_RSA_CTL_CRT_Msk)
2887 {
2888 /* For RSA CRT mode, two primes of private key */
2889 Hex2Reg(P, ((RSA_BUF_CRT_T *)s_pRSABuf)->au32RsaP);
2890 Hex2Reg(Q, ((RSA_BUF_CRT_T *)s_pRSABuf)->au32RsaQ);
2891
2892 crpt->RSA_SADDR[3] = (uint32_t) & ((RSA_BUF_CRT_T *)s_pRSABuf)->au32RsaP; /* prime P */
2893 crpt->RSA_SADDR[4] = (uint32_t) & ((RSA_BUF_CRT_T *)s_pRSABuf)->au32RsaQ; /* prime Q */
2894
2895 crpt->RSA_MADDR[0] = (uint32_t) & ((RSA_BUF_CRT_T *)s_pRSABuf)->au32RsaTmpCp; /* for storing the intermediate temporary value(Cp) */
2896 crpt->RSA_MADDR[1] = (uint32_t) & ((RSA_BUF_CRT_T *)s_pRSABuf)->au32RsaTmpCq; /* for storing the intermediate temporary value(Cq) */
2897 crpt->RSA_MADDR[2] = (uint32_t) & ((RSA_BUF_CRT_T *)s_pRSABuf)->au32RsaTmpDp; /* for storing the intermediate temporary value(Dp) */
2898 crpt->RSA_MADDR[3] = (uint32_t) & ((RSA_BUF_CRT_T *)s_pRSABuf)->au32RsaTmpDq; /* for storing the intermediate temporary value(Dq) */
2899 crpt->RSA_MADDR[4] = (uint32_t) & ((RSA_BUF_CRT_T *)s_pRSABuf)->au32RsaTmpRp; /* for storing the intermediate temporary value(Rp) */
2900 crpt->RSA_MADDR[5] = (uint32_t) & ((RSA_BUF_CRT_T *)s_pRSABuf)->au32RsaTmpRq; /* for storing the intermediate temporary value(Rq) */
2901 }
2902
2903 return 0;
2904 }
2905
2906 /**
2907 * @brief Start RSA encrypt/decrypt
2908 * @param[in] crpt The pointer of CRYPTO module
2909 * @return None
2910 */
RSA_Start(CRPT_T * crpt)2911 void RSA_Start(CRPT_T *crpt)
2912 {
2913 crpt->RSA_CTL |= CRPT_RSA_CTL_START_Msk;
2914 }
2915
2916 /**
2917 * @brief Read the RSA output.
2918 * @param[in] crpt The pointer of CRYPTO module
2919 * @param[out] Output The RSA operation output data.
2920 * @return 0 Success.
2921 * @return -1 The value of pointer of RSA buffer struct is null.
2922 */
RSA_Read(CRPT_T * crpt,char * Output)2923 int32_t RSA_Read(CRPT_T *crpt, char *Output)
2924 {
2925 uint32_t au32CntTbl[4] = {256, 512, 768, 1024}; /* count is key length divided by 4 */
2926 uint32_t u32CntIdx = 0;
2927
2928 if(s_pRSABuf == 0)
2929 {
2930 return (-1);
2931 }
2932
2933 u32CntIdx = (crpt->RSA_CTL & CRPT_RSA_CTL_KEYLENG_Msk) >> CRPT_RSA_CTL_KEYLENG_Pos;
2934 Reg2Hex((int32_t)au32CntTbl[u32CntIdx], ((RSA_BUF_NORMAL_T *)s_pRSABuf)->au32RsaOutput, Output);
2935
2936 return 0;
2937 }
2938
2939 /**
2940 * @brief Set the RSA key is read from key store
2941 * @param[in] crpt The pointer of CRYPTO module
2942 * @param[in] u32KeyNum The number of private or public key in key store.
2943 * @param[in] u32KSMemType The key is read from selected memory type of key store. It could be:
2944 \ref KS_SRAM
2945 \ref KS_FLASH
2946 \ref KS_OTP
2947 * @param[in] u32BlindKeyNum The number of blind key in SRAM of key store. This key is un-readable. This parameter is not used.
2948 * @return 0 Success.
2949 * @return -1 The value of pointer of RSA buffer struct is null.
2950 */
RSA_SetKey_KS(CRPT_T * crpt,uint32_t u32KeyNum,uint32_t u32KSMemType,uint32_t u32BlindKeyNum)2951 int32_t RSA_SetKey_KS(CRPT_T *crpt, uint32_t u32KeyNum, uint32_t u32KSMemType, uint32_t u32BlindKeyNum)
2952 {
2953 (void) u32BlindKeyNum;
2954
2955 crpt->RSA_KSCTL = (u32KSMemType << CRPT_RSA_KSCTL_RSSRC_Pos) | CRPT_RSA_KSCTL_RSRC_Msk | u32KeyNum;
2956
2957 return 0;
2958 }
2959
2960 /**
2961 * @brief Set RSA DMA transfer configuration while using key store.
2962 * @param[in] crpt The pointer of CRYPTO module
2963 * @param[in] u32OpMode RSA operation mode, including:
2964 * - \ref RSA_MODE_NORMAL
2965 * - \ref RSA_MODE_CRT
2966 * - \ref RSA_MODE_CRTBYPASS
2967 * @param[in] Src RSA DMA source data
2968 * @param[in] n The modulus for both the public and private keys
2969 * @param[in] u32PNum The number of the factor of modulus operation(P) in SRAM of key store for CRT mode
2970 * @param[in] u32QNum The number of the factor of modulus operation(Q) in SRAM of key store for CRT mode
2971 * @param[in] u32CpNum The number of Cp in SRAM of key store for CRT mode
2972 * @param[in] u32CqNum The number of Cq in SRAM of key store for CRT mode
2973 * @param[in] u32DpNum The number of Dp in SRAM of key store for CRT mode
2974 * @param[in] u32DqNum The number of Dq in SRAM of key store for CRT mode
2975 * @param[in] u32RpNum The number of Rp in SRAM of key store for CRT mode
2976 * @param[in] u32RqNum The number of Rq in SRAM of key store for CRT mode
2977 * @return 0 Success.
2978 * @return -1 The value of pointer of RSA buffer struct is null.
2979 * @note P, Q, Dp, Dq are equal to half key length. Cp, Cq, Rp, Rq, Blind key are equal to key length.
2980 */
RSA_SetDMATransfer_KS(CRPT_T * crpt,char * Src,char * n,uint32_t u32PNum,uint32_t u32QNum,uint32_t u32CpNum,uint32_t u32CqNum,uint32_t u32DpNum,uint32_t u32DqNum,uint32_t u32RpNum,uint32_t u32RqNum)2981 int32_t RSA_SetDMATransfer_KS(CRPT_T *crpt, char *Src, char *n, uint32_t u32PNum,
2982 uint32_t u32QNum, uint32_t u32CpNum, uint32_t u32CqNum, uint32_t u32DpNum,
2983 uint32_t u32DqNum, uint32_t u32RpNum, uint32_t u32RqNum)
2984 {
2985 if(s_pRSABuf == 0)
2986 {
2987 return (-1);
2988 }
2989 Hex2Reg(Src, ((RSA_BUF_KS_T *)s_pRSABuf)->au32RsaM);
2990 Hex2Reg(n, ((RSA_BUF_KS_T *)s_pRSABuf)->au32RsaN);
2991
2992 /* Assign the data to DMA */
2993 crpt->RSA_SADDR[0] = (uint32_t) & ((RSA_BUF_KS_T *)s_pRSABuf)->au32RsaM; /* plaintext / encrypt data */
2994 crpt->RSA_SADDR[1] = (uint32_t) & ((RSA_BUF_KS_T *)s_pRSABuf)->au32RsaN; /* the base of modulus operation */
2995 crpt->RSA_DADDR = (uint32_t) & ((RSA_BUF_KS_T *)s_pRSABuf)->au32RsaOutput; /* encrypt data / decrypt data */
2996
2997 if(s_u32RsaOpMode & CRPT_RSA_CTL_CRT_Msk)
2998 {
2999 /* For RSA CRT mode, two primes of private key */
3000 crpt->RSA_KSSTS[0] = (crpt->RSA_KSSTS[0] & (~(CRPT_RSA_KSSTS0_NUM0_Msk | CRPT_RSA_KSSTS0_NUM1_Msk))) | \
3001 (u32PNum << CRPT_RSA_KSSTS0_NUM0_Pos) | (u32QNum << CRPT_RSA_KSSTS0_NUM1_Pos);
3002
3003 /* For RSA CRT mode, Cp, Cq, Dp, Dq, Rp, Rq */
3004 crpt->RSA_KSSTS[0] = (crpt->RSA_KSSTS[0] & (~(CRPT_RSA_KSSTS0_NUM2_Msk | CRPT_RSA_KSSTS0_NUM3_Msk))) | \
3005 (u32CpNum << CRPT_RSA_KSSTS0_NUM2_Pos) | (u32CqNum << CRPT_RSA_KSSTS0_NUM3_Pos);
3006 crpt->RSA_KSSTS[1] = (u32DpNum << CRPT_RSA_KSSTS1_NUM4_Pos) | (u32DqNum << CRPT_RSA_KSSTS1_NUM5_Pos) | \
3007 (u32RpNum << CRPT_RSA_KSSTS1_NUM6_Pos) | (u32RqNum << CRPT_RSA_KSSTS1_NUM7_Pos);
3008 }
3009
3010 return 0;
3011 }
3012
3013
3014 /**@}*/ /* end of group CRYPTO_EXPORTED_FUNCTIONS */
3015
3016 /**@}*/ /* end of group CRYPTO_Driver */
3017
3018 /**@}*/ /* end of group Standard_Driver */
3019