1 /**************************************************************************//**
2 * @file crypto.c
3 * @version V1.10
4 * @brief Cryptographic Accelerator driver source file
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 * @copyright (C) 2016-2020 Nuvoton Technology Corp. All rights reserved.
8 *****************************************************************************/
9
10 #include <stdio.h>
11 #include <string.h>
12 #include "NuMicro.h"
13
14 /** @cond HIDDEN_SYMBOLS */
15
16 #define ENABLE_DEBUG 0
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 /** @endcond HIDDEN_SYMBOLS */
25
26 /** @addtogroup Standard_Driver Standard Driver
27 @{
28 */
29
30 /** @addtogroup CRYPTO_Driver CRYPTO Driver
31 @{
32 */
33
34
35 /** @addtogroup CRYPTO_EXPORTED_FUNCTIONS CRYPTO Exported Functions
36 @{
37 */
38
39 /** @cond HIDDEN_SYMBOLS */
40
41 static uint32_t g_AES_CTL[4];
42 static uint32_t g_TDES_CTL[4];
43
44 static char hex_char_tbl[] = "0123456789abcdef";
45
46 static void dump_ecc_reg(char *str, uint32_t volatile regs[], int32_t count);
47 static char get_Nth_nibble_char(uint32_t val32, uint32_t idx);
48 static void Hex2Reg(char input[], uint32_t volatile reg[]);
49 static void Reg2Hex(int32_t count, uint32_t volatile reg[], char output[]);
50 static void Hex2RegEx(char input[], uint32_t volatile reg[], int shift);
51 static char ch2hex(char ch);
52 static int get_nibble_value(char c);
53
54
55 /** @endcond HIDDEN_SYMBOLS */
56
57 /**
58 * @brief Open PRNG function
59 * @param[in] crpt Reference to Crypto module.
60 * @param[in] u32KeySize is PRNG key size, including:
61 * - \ref PRNG_KEY_SIZE_64
62 * - \ref PRNG_KEY_SIZE_128
63 * - \ref PRNG_KEY_SIZE_192
64 * - \ref PRNG_KEY_SIZE_256
65 * @param[in] u32SeedReload is PRNG seed reload or not, including:
66 * - \ref PRNG_SEED_CONT
67 * - \ref PRNG_SEED_RELOAD
68 * @param[in] u32Seed The new seed. Only valid when u32SeedReload is PRNG_SEED_RELOAD.
69 * @return None
70 */
PRNG_Open(CRPT_T * crpt,uint32_t u32KeySize,uint32_t u32SeedReload,uint32_t u32Seed)71 void PRNG_Open(CRPT_T *crpt, uint32_t u32KeySize, uint32_t u32SeedReload, uint32_t u32Seed)
72 {
73 if (u32SeedReload)
74 {
75 crpt->PRNG_SEED = u32Seed;
76 }
77
78 crpt->PRNG_CTL = (u32KeySize << CRPT_PRNG_CTL_KEYSZ_Pos) |
79 (u32SeedReload << CRPT_PRNG_CTL_SEEDRLD_Pos);
80 }
81
82 /**
83 * @brief Start to generate one PRNG key.
84 * @param[in] crpt Reference to Crypto module.
85 * @return None
86 */
PRNG_Start(CRPT_T * crpt)87 void PRNG_Start(CRPT_T *crpt)
88 {
89 crpt->PRNG_CTL |= CRPT_PRNG_CTL_START_Msk;
90 }
91
92 /**
93 * @brief Read the PRNG key.
94 * @param[in] crpt Reference to Crypto module.
95 * @param[out] u32RandKey The key buffer to store newly generated PRNG key.
96 * @return None
97 */
PRNG_Read(CRPT_T * crpt,uint32_t u32RandKey[])98 void PRNG_Read(CRPT_T *crpt, uint32_t u32RandKey[])
99 {
100 uint32_t i, wcnt;
101
102 wcnt = (((crpt->PRNG_CTL & CRPT_PRNG_CTL_KEYSZ_Msk) >> CRPT_PRNG_CTL_KEYSZ_Pos) + 1U) * 2U;
103
104 for (i = 0U; i < wcnt; i++)
105 {
106 u32RandKey[i] = crpt->PRNG_KEY[i];
107 }
108
109 crpt->PRNG_CTL &= ~CRPT_PRNG_CTL_SEEDRLD_Msk;
110 }
111
112
113 /**
114 * @brief Open AES encrypt/decrypt function.
115 * @param[in] crpt Reference to Crypto module.
116 * @param[in] u32Channel AES channel. Must be 0~3.
117 * @param[in] u32EncDec 1: AES encode; 0: AES decode
118 * @param[in] u32OpMode AES operation mode, including:
119 * - \ref AES_MODE_ECB
120 * - \ref AES_MODE_CBC
121 * - \ref AES_MODE_CFB
122 * - \ref AES_MODE_OFB
123 * - \ref AES_MODE_CTR
124 * - \ref AES_MODE_CBC_CS1
125 * - \ref AES_MODE_CBC_CS2
126 * - \ref AES_MODE_CBC_CS3
127 * @param[in] u32KeySize is AES key size, including:
128 * - \ref AES_KEY_SIZE_128
129 * - \ref AES_KEY_SIZE_192
130 * - \ref AES_KEY_SIZE_256
131 * @param[in] u32SwapType is AES input/output data swap control, including:
132 * - \ref AES_NO_SWAP
133 * - \ref AES_OUT_SWAP
134 * - \ref AES_IN_SWAP
135 * - \ref AES_IN_OUT_SWAP
136 * @return None
137 */
AES_Open(CRPT_T * crpt,uint32_t u32Channel,uint32_t u32EncDec,uint32_t u32OpMode,uint32_t u32KeySize,uint32_t u32SwapType)138 void AES_Open(CRPT_T *crpt, uint32_t u32Channel, uint32_t u32EncDec,
139 uint32_t u32OpMode, uint32_t u32KeySize, uint32_t u32SwapType)
140 {
141 crpt->AES_CTL = (u32Channel << CRPT_AES_CTL_CHANNEL_Pos) |
142 (u32EncDec << CRPT_AES_CTL_ENCRPT_Pos) |
143 (u32OpMode << CRPT_AES_CTL_OPMODE_Pos) |
144 (u32KeySize << CRPT_AES_CTL_KEYSZ_Pos) |
145 (u32SwapType << CRPT_AES_CTL_OUTSWAP_Pos);
146 g_AES_CTL[u32Channel] = crpt->AES_CTL;
147 }
148
149 /**
150 * @brief Start AES encrypt/decrypt
151 * @param[in] crpt Reference to Crypto module.
152 * @param[in] u32Channel AES channel. Must be 0~3.
153 * @param[in] u32DMAMode AES DMA control, including:
154 * - \ref CRYPTO_DMA_ONE_SHOT One shop AES encrypt/decrypt.
155 * - \ref CRYPTO_DMA_CONTINUE Continuous AES encrypt/decrypt.
156 * - \ref CRYPTO_DMA_LAST Last AES encrypt/decrypt of a series of AES_Start.
157 * @return None
158 */
AES_Start(CRPT_T * crpt,uint32_t u32Channel,uint32_t u32DMAMode)159 void AES_Start(CRPT_T *crpt, uint32_t u32Channel, uint32_t u32DMAMode)
160 {
161 crpt->AES_CTL = g_AES_CTL[u32Channel];
162 crpt->AES_CTL |= CRPT_AES_CTL_START_Msk | (u32DMAMode << CRPT_AES_CTL_DMALAST_Pos);
163 }
164
165 /**
166 * @brief Set AES keys
167 * @param[in] crpt Reference to Crypto module.
168 * @param[in] u32Channel AES channel. Must be 0~3.
169 * @param[in] au32Keys An word array contains AES keys.
170 * @param[in] u32KeySize is AES key size, including:
171 * - \ref AES_KEY_SIZE_128
172 * - \ref AES_KEY_SIZE_192
173 * - \ref AES_KEY_SIZE_256
174 * @return None
175 */
AES_SetKey(CRPT_T * crpt,uint32_t u32Channel,uint32_t au32Keys[],uint32_t u32KeySize)176 void AES_SetKey(CRPT_T *crpt, uint32_t u32Channel, uint32_t au32Keys[], uint32_t u32KeySize)
177 {
178 uint32_t i, wcnt, key_reg_addr;
179
180 key_reg_addr = (uint32_t)&crpt->AES0_KEY[0] + (u32Channel * 0x3CUL);
181 wcnt = 4UL + u32KeySize*2UL;
182
183 for (i = 0U; i < wcnt; i++)
184 {
185 outpw(key_reg_addr, au32Keys[i]);
186 key_reg_addr += 4UL;
187 }
188 }
189
190 /**
191 * @brief Set AES initial vectors
192 * @param[in] crpt Reference to Crypto module.
193 * @param[in] u32Channel AES channel. Must be 0~3.
194 * @param[in] au32IV A four entry word array contains AES initial vectors.
195 * @return None
196 */
AES_SetInitVect(CRPT_T * crpt,uint32_t u32Channel,uint32_t au32IV[])197 void AES_SetInitVect(CRPT_T *crpt, uint32_t u32Channel, uint32_t au32IV[])
198 {
199 uint32_t i, key_reg_addr;
200
201 key_reg_addr = (uint32_t)&crpt->AES0_IV[0] + (u32Channel * 0x3CUL);
202
203 for (i = 0U; i < 4U; i++)
204 {
205 outpw(key_reg_addr, au32IV[i]);
206 key_reg_addr += 4UL;
207 }
208 }
209
210 /**
211 * @brief Set AES DMA transfer configuration.
212 * @param[in] crpt Reference to Crypto module.
213 * @param[in] u32Channel AES channel. Must be 0~3.
214 * @param[in] u32SrcAddr AES DMA source address
215 * @param[in] u32DstAddr AES DMA destination address
216 * @param[in] u32TransCnt AES DMA transfer byte count
217 * @return None
218 */
AES_SetDMATransfer(CRPT_T * crpt,uint32_t u32Channel,uint32_t u32SrcAddr,uint32_t u32DstAddr,uint32_t u32TransCnt)219 void AES_SetDMATransfer(CRPT_T *crpt, uint32_t u32Channel, uint32_t u32SrcAddr,
220 uint32_t u32DstAddr, uint32_t u32TransCnt)
221 {
222 uint32_t reg_addr;
223
224 reg_addr = (uint32_t)&crpt->AES0_SADDR + (u32Channel * 0x3CUL);
225 outpw(reg_addr, u32SrcAddr);
226
227 reg_addr = (uint32_t)&crpt->AES0_DADDR + (u32Channel * 0x3CUL);
228 outpw(reg_addr, u32DstAddr);
229
230 reg_addr = (uint32_t)&crpt->AES0_CNT + (u32Channel * 0x3CUL);
231 outpw(reg_addr, u32TransCnt);
232 }
233
234 /**
235 * @brief Open TDES encrypt/decrypt function.
236 * @param[in] crpt Reference to Crypto module.
237 * @param[in] u32Channel TDES channel. Must be 0~3.
238 * @param[in] u32EncDec 1: TDES encode; 0: TDES decode
239 * @param[in] Is3DES 1: TDES; 0: DES
240 * @param[in] Is3Key 1: TDES 3 key mode; 0: TDES 2 key mode
241 * @param[in] u32OpMode TDES operation mode, including:
242 * - \ref TDES_MODE_ECB
243 * - \ref TDES_MODE_CBC
244 * - \ref TDES_MODE_CFB
245 * - \ref TDES_MODE_OFB
246 * - \ref TDES_MODE_CTR
247 * @param[in] u32SwapType is TDES input/output data swap control and word swap control, including:
248 * - \ref TDES_NO_SWAP
249 * - \ref TDES_WHL_SWAP
250 * - \ref TDES_OUT_SWAP
251 * - \ref TDES_OUT_WHL_SWAP
252 * - \ref TDES_IN_SWAP
253 * - \ref TDES_IN_WHL_SWAP
254 * - \ref TDES_IN_OUT_SWAP
255 * - \ref TDES_IN_OUT_WHL_SWAP
256 * @return None
257 */
TDES_Open(CRPT_T * crpt,uint32_t u32Channel,uint32_t u32EncDec,int32_t Is3DES,int32_t Is3Key,uint32_t u32OpMode,uint32_t u32SwapType)258 void TDES_Open(CRPT_T *crpt, uint32_t u32Channel, uint32_t u32EncDec, int32_t Is3DES, int32_t Is3Key,
259 uint32_t u32OpMode, uint32_t u32SwapType)
260 {
261 g_TDES_CTL[u32Channel] = (u32Channel << CRPT_TDES_CTL_CHANNEL_Pos) |
262 (u32EncDec << CRPT_TDES_CTL_ENCRPT_Pos) |
263 u32OpMode | (u32SwapType << CRPT_TDES_CTL_BLKSWAP_Pos);
264 if (Is3DES)
265 {
266 g_TDES_CTL[u32Channel] |= CRPT_TDES_CTL_TMODE_Msk;
267 }
268 if (Is3Key)
269 {
270 g_TDES_CTL[u32Channel] |= CRPT_TDES_CTL_3KEYS_Msk;
271 }
272 }
273
274 /**
275 * @brief Start TDES encrypt/decrypt
276 * @param[in] crpt Reference to Crypto module.
277 * @param[in] u32Channel TDES channel. Must be 0~3.
278 * @param[in] u32DMAMode TDES DMA control, including:
279 * - \ref CRYPTO_DMA_ONE_SHOT One shop TDES encrypt/decrypt.
280 * - \ref CRYPTO_DMA_CONTINUE Continuous TDES encrypt/decrypt.
281 * - \ref CRYPTO_DMA_LAST Last TDES encrypt/decrypt of a series of TDES_Start.
282 * @return None
283 */
TDES_Start(CRPT_T * crpt,int32_t u32Channel,uint32_t u32DMAMode)284 void TDES_Start(CRPT_T *crpt, int32_t u32Channel, uint32_t u32DMAMode)
285 {
286 g_TDES_CTL[u32Channel] |= CRPT_TDES_CTL_START_Msk | (u32DMAMode << CRPT_TDES_CTL_DMALAST_Pos);
287 crpt->TDES_CTL = g_TDES_CTL[u32Channel];
288 }
289
290 /**
291 * @brief Set TDES keys
292 * @param[in] crpt Reference to Crypto module.
293 * @param[in] u32Channel TDES channel. Must be 0~3.
294 * @param[in] au32Keys The TDES keys. au32Keys[0][0] is Key0 high word and au32Keys[0][1] is key0 low word.
295 * @return None
296 */
TDES_SetKey(CRPT_T * crpt,uint32_t u32Channel,uint32_t au32Keys[3][2])297 void TDES_SetKey(CRPT_T *crpt, uint32_t u32Channel, uint32_t au32Keys[3][2])
298 {
299 uint32_t i, reg_addr;
300
301 reg_addr = (uint32_t)&crpt->TDES0_KEY1H + (0x40UL * u32Channel);
302
303 for (i = 0U; i < 3U; i++)
304 {
305 outpw(reg_addr, au32Keys[i][0]); /* TDESn_KEYxH */
306 reg_addr += 4UL;
307 outpw(reg_addr, au32Keys[i][1]); /* TDESn_KEYxL */
308 reg_addr += 4UL;
309 }
310 }
311
312 /**
313 * @brief Set TDES initial vectors
314 * @param[in] crpt Reference to Crypto module.
315 * @param[in] u32Channel TDES channel. Must be 0~3.
316 * @param[in] u32IVH TDES initial vector high word.
317 * @param[in] u32IVL TDES initial vector low word.
318 * @return None
319 */
TDES_SetInitVect(CRPT_T * crpt,uint32_t u32Channel,uint32_t u32IVH,uint32_t u32IVL)320 void TDES_SetInitVect(CRPT_T *crpt, uint32_t u32Channel, uint32_t u32IVH, uint32_t u32IVL)
321 {
322 uint32_t reg_addr;
323
324 reg_addr = (uint32_t)&crpt->TDES0_IVH + (u32Channel * 0x40UL);
325 outpw(reg_addr, u32IVH);
326
327 reg_addr = (uint32_t)&crpt->TDES0_IVL + (u32Channel * 0x40UL);
328 outpw(reg_addr, u32IVL);
329 }
330
331 /**
332 * @brief Set TDES DMA transfer configuration.
333 * @param[in] crpt Reference to Crypto module.
334 * @param[in] u32Channel TDES channel. Must be 0~3.
335 * @param[in] u32SrcAddr TDES DMA source address
336 * @param[in] u32DstAddr TDES DMA destination address
337 * @param[in] u32TransCnt TDES DMA transfer byte count
338 * @return None
339 */
TDES_SetDMATransfer(CRPT_T * crpt,uint32_t u32Channel,uint32_t u32SrcAddr,uint32_t u32DstAddr,uint32_t u32TransCnt)340 void TDES_SetDMATransfer(CRPT_T *crpt, uint32_t u32Channel, uint32_t u32SrcAddr,
341 uint32_t u32DstAddr, uint32_t u32TransCnt)
342 {
343 uint32_t reg_addr;
344
345 reg_addr = (uint32_t)&crpt->TDES0_SA + (u32Channel * 0x40UL);
346 outpw(reg_addr, u32SrcAddr);
347
348 reg_addr = (uint32_t)&crpt->TDES0_DA + (u32Channel * 0x40UL);
349 outpw(reg_addr, u32DstAddr);
350
351 reg_addr = (uint32_t)&crpt->TDES0_CNT + (u32Channel * 0x40UL);
352 outpw(reg_addr, u32TransCnt);
353 }
354
355 /**
356 * @brief Open SHA encrypt function.
357 * @param[in] crpt Reference to Crypto module.
358 * @param[in] u32OpMode SHA operation mode, including:
359 * - \ref SHA_MODE_SHA1
360 * - \ref SHA_MODE_SHA224
361 * - \ref SHA_MODE_SHA256
362 * - \ref SHA_MODE_SHA384
363 * - \ref SHA_MODE_SHA512
364 * @param[in] u32SwapType is SHA input/output data swap control, including:
365 * - \ref SHA_NO_SWAP
366 * - \ref SHA_OUT_SWAP
367 * - \ref SHA_IN_SWAP
368 * - \ref SHA_IN_OUT_SWAP
369 * @param[in] hmac_key_len HMAC key byte count
370 * @return None
371 */
SHA_Open(CRPT_T * crpt,uint32_t u32OpMode,uint32_t u32SwapType,uint32_t hmac_key_len)372 void SHA_Open(CRPT_T *crpt, uint32_t u32OpMode, uint32_t u32SwapType, uint32_t hmac_key_len)
373 {
374 crpt->HMAC_CTL = (u32OpMode << CRPT_HMAC_CTL_OPMODE_Pos) |
375 (u32SwapType << CRPT_HMAC_CTL_OUTSWAP_Pos);
376
377 if (hmac_key_len != 0UL)
378 {
379 crpt->HMAC_KEYCNT = hmac_key_len;
380
381 if ((SYS->CSERVER & SYS_CSERVER_VERSION_Msk) == 0x0)
382 crpt->HMAC_CTL |= (1<<4); /* M480MD HMACEN is CRYPTO_HMAC_CTL[4] */
383 else
384 crpt->HMAC_CTL |= (1<<11); /* M480LD HMACEN is CRYPTO_HMAC_CTL[11] */
385 }
386 }
387
388 /**
389 * @brief Start SHA encrypt
390 * @param[in] crpt Reference to Crypto module.
391 * @param[in] u32DMAMode TDES DMA control, including:
392 * - \ref CRYPTO_DMA_ONE_SHOT One shop SHA encrypt.
393 * - \ref CRYPTO_DMA_CONTINUE Continuous SHA encrypt.
394 * - \ref CRYPTO_DMA_LAST Last SHA encrypt of a series of SHA_Start.
395 * @return None
396 */
SHA_Start(CRPT_T * crpt,uint32_t u32DMAMode)397 void SHA_Start(CRPT_T *crpt, uint32_t u32DMAMode)
398 {
399 crpt->HMAC_CTL &= ~(0x7UL << CRPT_HMAC_CTL_DMALAST_Pos);
400 crpt->HMAC_CTL |= CRPT_HMAC_CTL_START_Msk | (u32DMAMode << CRPT_HMAC_CTL_DMALAST_Pos);
401 }
402
403 /**
404 * @brief Set SHA DMA transfer
405 * @param[in] crpt Reference to Crypto module.
406 * @param[in] u32SrcAddr SHA DMA source address
407 * @param[in] u32TransCnt SHA DMA transfer byte count
408 * @return None
409 */
SHA_SetDMATransfer(CRPT_T * crpt,uint32_t u32SrcAddr,uint32_t u32TransCnt)410 void SHA_SetDMATransfer(CRPT_T *crpt, uint32_t u32SrcAddr, uint32_t u32TransCnt)
411 {
412 crpt->HMAC_SADDR = u32SrcAddr;
413 crpt->HMAC_DMACNT = u32TransCnt;
414 }
415
416 /**
417 * @brief Read the SHA digest.
418 * @param[in] crpt Reference to Crypto module.
419 * @param[out] u32Digest The SHA encrypt output digest.
420 * @return None
421 */
SHA_Read(CRPT_T * crpt,uint32_t u32Digest[])422 void SHA_Read(CRPT_T *crpt, uint32_t u32Digest[])
423 {
424 uint32_t i, wcnt, reg_addr;
425
426 i = (crpt->HMAC_CTL & CRPT_HMAC_CTL_OPMODE_Msk) >> CRPT_HMAC_CTL_OPMODE_Pos;
427
428 if (i == SHA_MODE_SHA1)
429 {
430 wcnt = 5UL;
431 }
432 else if (i == SHA_MODE_SHA224)
433 {
434 wcnt = 7UL;
435 }
436 else if (i == SHA_MODE_SHA256)
437 {
438 wcnt = 8UL;
439 }
440 else if (i == SHA_MODE_SHA384)
441 {
442 wcnt = 12UL;
443 }
444 else
445 {
446 /* SHA_MODE_SHA512 */
447 wcnt = 16UL;
448 }
449
450 reg_addr = (uint32_t)&(crpt->HMAC_DGST[0]);
451 for (i = 0UL; i < wcnt; i++)
452 {
453 u32Digest[i] = inpw(reg_addr);
454 reg_addr += 4UL;
455 }
456 }
457
458 /** @cond HIDDEN_SYMBOLS */
459
460 /*-----------------------------------------------------------------------------------------------*/
461 /* */
462 /* ECC */
463 /* */
464 /*-----------------------------------------------------------------------------------------------*/
465
466 #define ECCOP_POINT_MUL (0x0UL << CRPT_ECC_CTL_ECCOP_Pos)
467 #define ECCOP_MODULE (0x1UL << CRPT_ECC_CTL_ECCOP_Pos)
468 #define ECCOP_POINT_ADD (0x2UL << CRPT_ECC_CTL_ECCOP_Pos)
469 #define ECCOP_POINT_DOUBLE (0x0UL << CRPT_ECC_CTL_ECCOP_Pos)
470
471 #define MODOP_DIV (0x0UL << CRPT_ECC_CTL_MODOP_Pos)
472 #define MODOP_MUL (0x1UL << CRPT_ECC_CTL_MODOP_Pos)
473 #define MODOP_ADD (0x2UL << CRPT_ECC_CTL_MODOP_Pos)
474 #define MODOP_SUB (0x3UL << CRPT_ECC_CTL_MODOP_Pos)
475
476 enum
477 {
478 CURVE_GF_P,
479 CURVE_GF_2M,
480 };
481
482 /*-----------------------------------------------------*/
483 /* Define elliptic curve (EC): */
484 /*-----------------------------------------------------*/
485
486 typedef struct e_curve_t
487 {
488 E_ECC_CURVE curve_id;
489 int32_t Echar;
490 char Ea[144];
491 char Eb[144];
492 char Px[144];
493 char Py[144];
494 int32_t Epl;
495 char Pp[176];
496 int32_t Eol;
497 char Eorder[176];
498 int32_t key_len;
499 int32_t irreducible_k1;
500 int32_t irreducible_k2;
501 int32_t irreducible_k3;
502 int32_t GF;
503 } ECC_CURVE;
504
505 const ECC_CURVE _Curve[] =
506 {
507 {
508 /* NIST: Curve P-192 : y^2=x^3-ax+b (mod p) */
509 CURVE_P_192,
510 48, /* Echar */
511 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* "000000000000000000000000000000000000000000000003" */
512 "64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
513 "188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
514 "07192b95ffc8da78631011ed6b24cdd573f977a11e794811",
515 58, /* Epl */
516 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* "6277101735386680763835789423207666416083908700390324961279" */
517 58, /* Eol */
518 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* "6277101735386680763835789423176059013767194773182842284081" */
519 192, /* key_len */
520 7,
521 2,
522 1,
523 CURVE_GF_P
524 },
525 {
526 /* NIST: Curve P-224 : y^2=x^3-ax+b (mod p) */
527 CURVE_P_224,
528 56, /* Echar */
529 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* "00000000000000000000000000000000000000000000000000000003" */
530 "b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
531 "b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
532 "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
533 70, /* Epl */
534 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "0026959946667150639794667015087019630673557916260026308143510066298881" */
535 70, /* Eol */
536 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* "0026959946667150639794667015087019625940457807714424391721682722368061" */
537 224, /* key_len */
538 9,
539 8,
540 3,
541 CURVE_GF_P
542 },
543 {
544 /* NIST: Curve P-256 : y^2=x^3-ax+b (mod p) */
545 CURVE_P_256,
546 64, /* Echar */
547 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* "0000000000000000000000000000000000000000000000000000000000000003" */
548 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
549 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
550 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
551 78, /* Epl */
552 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* "115792089210356248762697446949407573530086143415290314195533631308867097853951" */
553 78, /* Eol */
554 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* "115792089210356248762697446949407573529996955224135760342422259061068512044369" */
555 256, /* key_len */
556 10,
557 5,
558 2,
559 CURVE_GF_P
560 },
561 {
562 /* NIST: Curve P-384 : y^2=x^3-ax+b (mod p) */
563 CURVE_P_384,
564 96, /* Echar */
565 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003" */
566 "b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef",
567 "aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7",
568 "3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f",
569 116, /* Epl */
570 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* "39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319" */
571 116, /* Eol */
572 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* "39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643" */
573 384, /* key_len */
574 12,
575 3,
576 2,
577 CURVE_GF_P
578 },
579 {
580 /* NIST: Curve P-521 : y^2=x^3-ax+b (mod p)*/
581 CURVE_P_521,
582 131, /* Echar */
583 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003" */
584 "051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
585 "0c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
586 "11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
587 157, /* Epl */
588 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151" */
589 157, /* Eol */
590 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* "6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449" */
591 521, /* key_len */
592 32,
593 32,
594 32,
595 CURVE_GF_P
596 },
597 {
598 /* NIST: Curve B-163 : y^2+xy=x^3+ax^2+b */
599 CURVE_B_163,
600 41, /* Echar */
601 "00000000000000000000000000000000000000001",
602 "20a601907b8c953ca1481eb10512f78744a3205fd",
603 "3f0eba16286a2d57ea0991168d4994637e8343e36",
604 "0d51fbc6c71a0094fa2cdd545b11c5c0c797324f1",
605 68, /* Epl */
606 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
607 49, /* Eol */
608 "40000000000000000000292FE77E70C12A4234C33", /* "5846006549323611672814742442876390689256843201587" */
609 163, /* key_len */
610 7,
611 6,
612 3,
613 CURVE_GF_2M
614 },
615 {
616 /* NIST: Curve B-233 : y^2+xy=x^3+ax^2+b */
617 CURVE_B_233,
618 59, /* Echar 59 */
619 "00000000000000000000000000000000000000000000000000000000001",
620 "066647ede6c332c7f8c0923bb58213b333b20e9ce4281fe115f7d8f90ad",
621 "0fac9dfcbac8313bb2139f1bb755fef65bc391f8b36f8f8eb7371fd558b",
622 "1006a08a41903350678e58528bebf8a0beff867a7ca36716f7e01f81052",
623 68, /* Epl */
624 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
625 70, /* Eol */
626 "1000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", /* "6901746346790563787434755862277025555839812737345013555379383634485463" */
627 233, /* key_len */
628 74,
629 74,
630 74,
631 CURVE_GF_2M
632 },
633 {
634 /* NIST: Curve B-283 : y^2+xy=x^3+ax^2+b */
635 CURVE_B_283,
636 71, /* Echar */
637 "00000000000000000000000000000000000000000000000000000000000000000000001",
638 "27b680ac8b8596da5a4af8a19a0303fca97fd7645309fa2a581485af6263e313b79a2f5",
639 "5f939258db7dd90e1934f8c70b0dfec2eed25b8557eac9c80e2e198f8cdbecd86b12053",
640 "3676854fe24141cb98fe6d4b20d02b4516ff702350eddb0826779c813f0df45be8112f4",
641 68, /* Epl */
642 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
643 85, /* Eol */
644 "3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", /* "7770675568902916283677847627294075626569625924376904889109196526770044277787378692871" */
645 283, /* key_len */
646 12,
647 7,
648 5,
649 CURVE_GF_2M
650 },
651 {
652 /* NIST: Curve B-409 : y^2+xy=x^3+ax^2+b */
653 CURVE_B_409,
654 103, /* Echar */
655 "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
656 "021a5c2c8ee9feb5c4b9a753b7b476b7fd6422ef1f3dd674761fa99d6ac27c8a9a197b272822f6cd57a55aa4f50ae317b13545f",
657 "15d4860d088ddb3496b0c6064756260441cde4af1771d4db01ffe5b34e59703dc255a868a1180515603aeab60794e54bb7996a7",
658 "061b1cfab6be5f32bbfa78324ed106a7636b9c5a7bd198d0158aa4f5488d08f38514f1fdf4b4f40d2181b3681c364ba0273c706",
659 68, /* Epl */
660 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
661 123, /* Eol */
662 "10000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173", /* "661055968790248598951915308032771039828404682964281219284648798304157774827374805208143723762179110965979867288366567526771" */
663 409, /* key_len */
664 87,
665 87,
666 87,
667 CURVE_GF_2M
668 },
669 {
670 /* NIST: Curve B-571 : y^2+xy=x^3+ax^2+b */
671 CURVE_B_571,
672 143, /* Echar */
673 "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
674 "2f40e7e2221f295de297117b7f3d62f5c6a97ffcb8ceff1cd6ba8ce4a9a18ad84ffabbd8efa59332be7ad6756a66e294afd185a78ff12aa520e4de739baca0c7ffeff7f2955727a",
675 "303001d34b856296c16c0d40d3cd7750a93d1d2955fa80aa5f40fc8db7b2abdbde53950f4c0d293cdd711a35b67fb1499ae60038614f1394abfa3b4c850d927e1e7769c8eec2d19",
676 "37bf27342da639b6dccfffeb73d69d78c6c27a6009cbbca1980f8533921e8a684423e43bab08a576291af8f461bb2a8b3531d2f0485c19b16e2f1516e23dd3c1a4827af1b8ac15b",
677 68, /* Epl */
678 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
679 172, /* Eol */
680 "3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47", /* "3864537523017258344695351890931987344298927329706434998657235251451519142289560424536143999389415773083133881121926944486246872462816813070234528288303332411393191105285703" */
681 571, /* key_len */
682 10,
683 5,
684 2,
685 CURVE_GF_2M
686 },
687 {
688 /* NIST: Curve K-163 : y^2+xy=x^3+ax^2+b */
689 CURVE_K_163,
690 41, /* Echar */
691 "00000000000000000000000000000000000000001",
692 "00000000000000000000000000000000000000001",
693 "2fe13c0537bbc11acaa07d793de4e6d5e5c94eee8",
694 "289070fb05d38ff58321f2e800536d538ccdaa3d9",
695 68, /* Epl */
696 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
697 49, /* Eol */
698 "4000000000000000000020108A2E0CC0D99F8A5EF", /* "5846006549323611672814741753598448348329118574063" */
699 163, /* key_len */
700 7,
701 6,
702 3,
703 CURVE_GF_2M
704 },
705 {
706 /* NIST: Curve K-233 : y^2+xy=x^3+ax^2+b */
707 CURVE_K_233,
708 59, /* Echar 59 */
709 "00000000000000000000000000000000000000000000000000000000000",
710 "00000000000000000000000000000000000000000000000000000000001",
711 "17232ba853a7e731af129f22ff4149563a419c26bf50a4c9d6eefad6126",
712 "1db537dece819b7f70f555a67c427a8cd9bf18aeb9b56e0c11056fae6a3",
713 68, /* Epl */
714 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
715 70, /* Eol */
716 "8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", /* "3450873173395281893717377931138512760570940988862252126328087024741343" */
717 233, /* key_len */
718 74,
719 74,
720 74,
721 CURVE_GF_2M
722 },
723 {
724 /* NIST: Curve K-283 : y^2+xy=x^3+ax^2+b */
725 CURVE_K_283,
726 71, /* Echar */
727 "00000000000000000000000000000000000000000000000000000000000000000000000",
728 "00000000000000000000000000000000000000000000000000000000000000000000001",
729 "503213f78ca44883f1a3b8162f188e553cd265f23c1567a16876913b0c2ac2458492836",
730 "1ccda380f1c9e318d90f95d07e5426fe87e45c0e8184698e45962364e34116177dd2259",
731 68, /* Epl */
732 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
733 85, /* Eol */
734 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61", /* "3885337784451458141838923813647037813284811733793061324295874997529815829704422603873" */
735 283, /* key_len */
736 12,
737 7,
738 5,
739 CURVE_GF_2M
740 },
741 {
742 /* NIST: Curve K-409 : y^2+xy=x^3+ax^2+b */
743 CURVE_K_409,
744 103, /* Echar */
745 "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
746 "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
747 "060f05f658f49c1ad3ab1890f7184210efd0987e307c84c27accfb8f9f67cc2c460189eb5aaaa62ee222eb1b35540cfe9023746",
748 "1e369050b7c4e42acba1dacbf04299c3460782f918ea427e6325165e9ea10e3da5f6c42e9c55215aa9ca27a5863ec48d8e0286b",
749 68, /* Epl */
750 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
751 123, /* Eol */
752 "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", /* "330527984395124299475957654016385519914202341482140609642324395022880711289249191050673258457777458014096366590617731358671" */
753 409, /* key_len */
754 87,
755 87,
756 87,
757 CURVE_GF_2M
758 },
759 {
760 /* NIST: Curve K-571 : y^2+xy=x^3+ax^2+b */
761 CURVE_K_571,
762 143, /* Echar */
763 "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
764 "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
765 "26eb7a859923fbc82189631f8103fe4ac9ca2970012d5d46024804801841ca44370958493b205e647da304db4ceb08cbbd1ba39494776fb988b47174dca88c7e2945283a01c8972",
766 "349dc807f4fbf374f4aeade3bca95314dd58cec9f307a54ffc61efc006d8a2c9d4979c0ac44aea74fbebbb9f772aedcb620b01a7ba7af1b320430c8591984f601cd4c143ef1c7a3",
767 68, /* Epl */
768 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
769 172, /* Eol */
770 "20000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001", /* "1932268761508629172347675945465993672149463664853217499328617625725759571144780212268133978522706711834706712800825351461273674974066617311929682421617092503555733685276673" */
771 571, /* key_len */
772 10,
773 5,
774 2,
775 CURVE_GF_2M
776 },
777 {
778 /* Koblitz: Curve secp192k1 : y2 = x3+ax+b over Fp */
779 CURVE_KO_192,
780 48, /* Echar */
781 "00000000000000000000000000000000000000000",
782 "00000000000000000000000000000000000000003",
783 "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D",
784 "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D",
785 58, /* Epl */
786 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* p */
787 58, /* Eol */
788 "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* n */
789 192, /* key_len */
790 7,
791 2,
792 1,
793 CURVE_GF_P
794 },
795 {
796 /* Koblitz: Curve secp224k1 : y2 = x3+ax+b over Fp */
797 CURVE_KO_224,
798 56, /* Echar */
799 "00000000000000000000000000000000000000000000000000000000",
800 "00000000000000000000000000000000000000000000000000000005",
801 "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C",
802 "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5",
803 70, /* Epl */
804 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* p */
805 70, /* Eol */
806 "0000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", /* n */
807 224, /* key_len */
808 7,
809 2,
810 1,
811 CURVE_GF_P
812 },
813 {
814 /* Koblitz: Curve secp256k1 : y2 = x3+ax+b over Fp */
815 CURVE_KO_256,
816 64, /* Echar */
817 "0000000000000000000000000000000000000000000000000000000000000000",
818 "0000000000000000000000000000000000000000000000000000000000000007",
819 "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
820 "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
821 78, /* Epl */
822 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* p */
823 78, /* Eol */
824 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* n */
825 256, /* key_len */
826 7,
827 2,
828 1,
829 CURVE_GF_P
830 },
831 {
832 /* Brainpool: Curve brainpoolP256r1 */
833 CURVE_BP_256,
834 64, /* Echar */
835 "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A */
836 "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B */
837 "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* x */
838 "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* y */
839 78, /* Epl */
840 "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* p */
841 78, /* Eol */
842 "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* q */
843 256, /* key_len */
844 7,
845 2,
846 1,
847 CURVE_GF_P
848 },
849 {
850 /* Brainpool: Curve brainpoolP384r1 */
851 CURVE_BP_384,
852 96, /* Echar */
853 "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A */
854 "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B */
855 "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* x */
856 "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* y */
857 116, /* Epl */
858 "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* p */
859 116, /* Eol */
860 "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* q */
861 384, /* key_len */
862 7,
863 2,
864 1,
865 CURVE_GF_P
866 },
867 {
868 /* Brainpool: Curve brainpoolP512r1 */
869 CURVE_BP_512,
870 128, /* Echar */
871 "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A */
872 "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B */
873 "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* x */
874 "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* y */
875 156, /* Epl */
876 "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* p */
877 156, /* Eol */
878 "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* q */
879 512, /* key_len */
880 7,
881 2,
882 1,
883 CURVE_GF_P
884 },
885 };
886
887 static ECC_CURVE *pCurve;
888 static ECC_CURVE Curve_Copy;
889
890 static ECC_CURVE * get_curve(E_ECC_CURVE ecc_curve);
891 static int32_t ecc_init_curve(CRPT_T *crpt, E_ECC_CURVE ecc_curve);
892 static void run_ecc_codec(CRPT_T *crpt, uint32_t mode);
893
894 static char temp_hex_str[160];
895
896
897 #if ENABLE_DEBUG
dump_ecc_reg(char * str,uint32_t volatile regs[],int32_t count)898 static void dump_ecc_reg(char *str, uint32_t volatile regs[], int32_t count)
899 {
900 int32_t i;
901
902 printf("%s => ", str);
903 for (i = 0; i < count; i++)
904 {
905 printf("0x%08x ", regs[i]);
906 }
907 printf("\n");
908 }
909 #else
dump_ecc_reg(char * str,uint32_t volatile regs[],int32_t count)910 static void dump_ecc_reg(char *str, uint32_t volatile regs[], int32_t count)
911 {
912 }
913 #endif
914
ch2hex(char ch)915 static char ch2hex(char ch)
916 {
917 if (ch <= '9')
918 {
919 ch = ch - '0';
920 }
921 else if ((ch <= 'z') && (ch >= 'a'))
922 {
923 ch = ch - 'a' + 10U;
924 }
925 else
926 {
927 ch = ch - 'A' + 10U;
928 }
929 return ch;
930 }
931
Hex2Reg(char input[],uint32_t volatile reg[])932 static void Hex2Reg(char input[], uint32_t volatile reg[])
933 {
934 char hex;
935 int si, ri;
936 uint32_t i, val32;
937
938 si = (int)strlen(input) - 1;
939 ri = 0;
940
941 while (si >= 0)
942 {
943 val32 = 0UL;
944 for (i = 0UL; (i < 8UL) && (si >= 0); i++)
945 {
946 hex = ch2hex(input[si]);
947 val32 |= (uint32_t)hex << (i * 4UL);
948 si--;
949 }
950 reg[ri++] = val32;
951 }
952 }
953
Hex2RegEx(char input[],uint32_t volatile reg[],int shift)954 static void Hex2RegEx(char input[], uint32_t volatile reg[], int shift)
955 {
956 uint32_t hex, carry;
957 int si, ri;
958 uint32_t i, val32;
959
960 si = (int)strlen(input) - 1;
961 ri = 0L;
962 carry = 0UL;
963 while (si >= 0)
964 {
965 val32 = 0UL;
966 for (i = 0UL; (i < 8UL) && (si >= 0L); i++)
967 {
968 hex = (uint32_t)ch2hex(input[si]);
969 hex <<= shift;
970
971 val32 |= (uint32_t)((hex & 0xFUL) | carry) << (i * 4UL);
972 carry = (hex >> 4UL) & 0xFUL;
973 si--;
974 }
975 reg[ri++] = val32;
976 }
977 if (carry != 0UL)
978 {
979 reg[ri] = carry;
980 }
981 }
982
983 /**
984 * @brief Extract specified nibble from an unsigned word in character format.
985 * For example:
986 * Suppose val32 is 0x786543210, get_Nth_nibble_char(val32, 3) will return a '3'.
987 * @param[in] val32 The input unsigned word
988 * @param[in] idx The Nth nibble to be extracted.
989 * @return The nibble in character format.
990 */
get_Nth_nibble_char(uint32_t val32,uint32_t idx)991 static char get_Nth_nibble_char(uint32_t val32, uint32_t idx)
992 {
993 return hex_char_tbl[ (val32 >> (idx * 4U)) & 0xfU ];
994 }
995
996
Reg2Hex(int32_t count,uint32_t volatile reg[],char output[])997 static void Reg2Hex(int32_t count, uint32_t volatile reg[], char output[])
998 {
999 int32_t idx, ri;
1000 uint32_t i;
1001
1002 output[count] = 0U;
1003 idx = count - 1;
1004
1005 for (ri = 0; idx >= 0; ri++)
1006 {
1007 for (i = 0UL; (i < 8UL) && (idx >= 0); i++)
1008 {
1009 output[idx] = get_Nth_nibble_char(reg[ri], i);
1010 idx--;
1011 }
1012 }
1013 }
1014
get_curve(E_ECC_CURVE ecc_curve)1015 static ECC_CURVE * get_curve(E_ECC_CURVE ecc_curve)
1016 {
1017 uint32_t i;
1018 ECC_CURVE *ret = NULL;
1019
1020 for (i = 0UL; i < sizeof(_Curve) / sizeof(ECC_CURVE); i++)
1021 {
1022 if (ecc_curve == _Curve[i].curve_id)
1023 {
1024 memcpy((char *)&Curve_Copy, &_Curve[i], sizeof(ECC_CURVE));
1025 ret = &Curve_Copy; /* (ECC_CURVE *)&_Curve[i]; */
1026 }
1027 if (ret != NULL)
1028 {
1029 break;
1030 }
1031 }
1032 return ret;
1033 }
1034
ecc_init_curve(CRPT_T * crpt,E_ECC_CURVE ecc_curve)1035 static int32_t ecc_init_curve(CRPT_T *crpt, E_ECC_CURVE ecc_curve)
1036 {
1037 int32_t i, ret = 0;
1038
1039 pCurve = get_curve(ecc_curve);
1040 if (pCurve == NULL)
1041 {
1042 CRPT_DBGMSG("Cannot find curve %d!!\n", ecc_curve);
1043 ret = -1;
1044 }
1045
1046 if (ret == 0)
1047 {
1048 for (i = 0; i < 18; i++)
1049 {
1050 crpt->ECC_A[i] = 0UL;
1051 crpt->ECC_B[i] = 0UL;
1052 crpt->ECC_X1[i] = 0UL;
1053 crpt->ECC_Y1[i] = 0UL;
1054 crpt->ECC_N[i] = 0UL;
1055 }
1056
1057 Hex2Reg(pCurve->Ea, crpt->ECC_A);
1058 Hex2Reg(pCurve->Eb, crpt->ECC_B);
1059 Hex2Reg(pCurve->Px, crpt->ECC_X1);
1060 Hex2Reg(pCurve->Py, crpt->ECC_Y1);
1061
1062 CRPT_DBGMSG("Key length = %d\n", pCurve->key_len);
1063 dump_ecc_reg("CRPT_ECC_CURVE_A", crpt->ECC_A, 10);
1064 dump_ecc_reg("CRPT_ECC_CURVE_B", crpt->ECC_B, 10);
1065 dump_ecc_reg("CRPT_ECC_POINT_X1", crpt->ECC_X1, 10);
1066 dump_ecc_reg("CRPT_ECC_POINT_Y1", crpt->ECC_Y1, 10);
1067
1068 if (pCurve->GF == (int)CURVE_GF_2M)
1069 {
1070 crpt->ECC_N[0] = 0x1UL;
1071 crpt->ECC_N[(pCurve->key_len) / 32] |= (1UL << ((pCurve->key_len) % 32));
1072 crpt->ECC_N[(pCurve->irreducible_k1) / 32] |= (1UL << ((pCurve->irreducible_k1) % 32));
1073 crpt->ECC_N[(pCurve->irreducible_k2) / 32] |= (1UL << ((pCurve->irreducible_k2) % 32));
1074 crpt->ECC_N[(pCurve->irreducible_k3) / 32] |= (1UL << ((pCurve->irreducible_k3) % 32));
1075 }
1076 else
1077 {
1078 Hex2Reg(pCurve->Pp, crpt->ECC_N);
1079 }
1080 }
1081 dump_ecc_reg("CRPT_ECC_CURVE_N", crpt->ECC_N, 10);
1082 return ret;
1083 }
1084
get_nibble_value(char c)1085 static int get_nibble_value(char c)
1086 {
1087 if ((c >= '0') && (c <= '9'))
1088 {
1089 c = c - '0';
1090 }
1091
1092 if ((c >= 'a') && (c <= 'f'))
1093 {
1094 c = c - 'a' + (char)10;
1095 }
1096
1097 if ((c >= 'A') && (c <= 'F'))
1098 {
1099 c = c - 'A' + (char)10;
1100 }
1101 return (int)c;
1102 }
1103
ecc_strcmp(char * s1,char * s2)1104 static int ecc_strcmp(char *s1, char *s2)
1105 {
1106 char c1, c2;
1107
1108 while (*s1 == '0') s1++;
1109 while (*s2 == '0') s2++;
1110
1111 for ( ; *s1 || *s2; s1++, s2++)
1112 {
1113 if ((*s1 >= 'A') && (*s1 <= 'Z'))
1114 c1 = *s1 + 32;
1115 else
1116 c1 = *s1;
1117
1118 if ((*s2 >= 'A') && (*s2 <= 'Z'))
1119 c2 = *s2 + 32;
1120 else
1121 c2 = *s2;
1122
1123 if (c1 != c2)
1124 return 1;
1125 }
1126 return 0;
1127 }
1128
1129 volatile uint32_t g_ECC_done, g_ECCERR_done;
1130
1131 /** @endcond HIDDEN_SYMBOLS */
1132
1133 /**
1134 * @brief ECC interrupt service routine. User application must invoke this function in
1135 * his CRYPTO_IRQHandler() to let Crypto driver know ECC processing was done.
1136 * @param[in] crpt Reference to Crypto module.
1137 * @return none
1138 */
ECC_Complete(CRPT_T * crpt)1139 void ECC_Complete(CRPT_T *crpt)
1140 {
1141 if (crpt->INTSTS & CRPT_INTSTS_ECCIF_Msk)
1142 {
1143 g_ECC_done = 1UL;
1144 crpt->INTSTS = CRPT_INTSTS_ECCIF_Msk;
1145 /* printf("ECC done IRQ.\n"); */
1146 }
1147
1148 if (crpt->INTSTS & CRPT_INTSTS_ECCEIF_Msk)
1149 {
1150 g_ECCERR_done = 1UL;
1151 crpt->INTSTS = CRPT_INTSTS_ECCEIF_Msk;
1152 /* printf("ECCERRIF is set!!\n"); */
1153 }
1154 }
1155
1156 /**
1157 * @brief Check if the private key is located in valid range of curve.
1158 * @param[in] crpt Reference to Crypto module.
1159 * @param[in] ecc_curve The pre-defined ECC curve.
1160 * @param[in] private_k The input private key.
1161 * @return 1 Is valid.
1162 * @return 0 Is not valid.
1163 * @return -1 Invalid curve.
1164 */
ECC_IsPrivateKeyValid(CRPT_T * crpt,E_ECC_CURVE ecc_curve,char private_k[])1165 int ECC_IsPrivateKeyValid(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char private_k[])
1166 {
1167 uint32_t i;
1168 int ret = -1;
1169
1170 pCurve = get_curve(ecc_curve);
1171 if (pCurve == NULL)
1172 {
1173 ret = -1;
1174 }
1175
1176 if (strlen(private_k) < strlen(pCurve->Eorder))
1177 {
1178 ret = 1;
1179 }
1180
1181 if (strlen(private_k) > strlen(pCurve->Eorder))
1182 {
1183 ret = 0;
1184 }
1185
1186 for (i = 0UL; i < strlen(private_k); i++)
1187 {
1188 if (get_nibble_value(private_k[i]) < get_nibble_value(pCurve->Eorder[i]))
1189 {
1190 ret = 1;
1191 break;
1192 }
1193 if (get_nibble_value(private_k[i]) > get_nibble_value(pCurve->Eorder[i]))
1194 {
1195 ret = 0;
1196 break;
1197 }
1198 }
1199 return ret;
1200 }
1201
1202 /**
1203 * @brief Given a private key and curve to generate the public key pair.
1204 * @param[in] crpt Reference to Crypto module.
1205 * @param[in] private_k The input private key.
1206 * @param[in] ecc_curve The pre-defined ECC curve.
1207 * @param[out] public_k1 The output public key 1.
1208 * @param[out] public_k2 The output public key 2.
1209 * @return 0 Success.
1210 * @return -1 "ecc_curve" value is invalid.
1211 */
ECC_GeneratePublicKey(CRPT_T * crpt,E_ECC_CURVE ecc_curve,char * private_k,char public_k1[],char public_k2[])1212 int32_t ECC_GeneratePublicKey(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char *private_k, char public_k1[], char public_k2[])
1213 {
1214 int32_t i, ret = 0;
1215
1216 if (ecc_init_curve(crpt, ecc_curve) != 0)
1217 {
1218 ret = -1;
1219 }
1220
1221 if (ret == 0)
1222 {
1223 for (i = 0; i < 18; i++)
1224 {
1225 crpt->ECC_K[i] = 0UL;
1226 }
1227 Hex2Reg(private_k, crpt->ECC_K);
1228
1229 /* set FSEL (Field selection) */
1230 if (pCurve->GF == (int)CURVE_GF_2M)
1231 {
1232 crpt->ECC_CTL = 0UL;
1233 }
1234 else
1235 {
1236 /* CURVE_GF_P */
1237 crpt->ECC_CTL = CRPT_ECC_CTL_FSEL_Msk;
1238 }
1239
1240 g_ECC_done = g_ECCERR_done = 0UL;
1241 crpt->ECC_CTL |= ((uint32_t)pCurve->key_len << CRPT_ECC_CTL_CURVEM_Pos) |
1242 ECCOP_POINT_MUL | CRPT_ECC_CTL_START_Msk;
1243
1244 while ((g_ECC_done | g_ECCERR_done) == 0UL)
1245 {
1246 }
1247
1248 Reg2Hex(pCurve->Echar, crpt->ECC_X1, public_k1);
1249 Reg2Hex(pCurve->Echar, crpt->ECC_Y1, public_k2);
1250 }
1251
1252 return ret;
1253 }
1254
1255 /**
1256 * @brief Given a private key and curve to generate the public key pair.
1257 * @param[in] crpt Reference to Crypto module.
1258 * @param[out] x1 The x-coordinate of input point.
1259 * @param[out] y1 The y-coordinate of input point.
1260 * @param[in] k The private key
1261 * @param[in] ecc_curve The pre-defined ECC curve.
1262 * @param[out] x2 The x-coordinate of output point.
1263 * @param[out] y2 The y-coordinate of output point.
1264 * @return 0 Success.
1265 * @return -1 "ecc_curve" value is invalid.
1266 */
ECC_Mutiply(CRPT_T * crpt,E_ECC_CURVE ecc_curve,char x1[],char y1[],char * k,char x2[],char y2[])1267 int32_t ECC_Mutiply(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char x1[], char y1[], char *k, char x2[], char y2[])
1268 {
1269 int32_t i, ret = 0;
1270
1271 if (ecc_init_curve(crpt, ecc_curve) != 0)
1272 {
1273 ret = -1;
1274 }
1275
1276 if (ret == 0)
1277 {
1278 for (i = 0; i < 18; i++)
1279 {
1280 crpt->ECC_X1[i] = 0UL;
1281 crpt->ECC_Y1[i] = 0UL;
1282 crpt->ECC_K[i] = 0UL;
1283 }
1284 Hex2Reg(x1, crpt->ECC_X1);
1285 Hex2Reg(y1, crpt->ECC_Y1);
1286 Hex2Reg(k, crpt->ECC_K);
1287
1288 /* set FSEL (Field selection) */
1289 if (pCurve->GF == (int)CURVE_GF_2M)
1290 {
1291 crpt->ECC_CTL = 0UL;
1292 }
1293 else
1294 {
1295 /* CURVE_GF_P */
1296 crpt->ECC_CTL = CRPT_ECC_CTL_FSEL_Msk;
1297 }
1298
1299 g_ECC_done = g_ECCERR_done = 0UL;
1300 crpt->ECC_CTL |= ((uint32_t)pCurve->key_len << CRPT_ECC_CTL_CURVEM_Pos) |
1301 ECCOP_POINT_MUL | CRPT_ECC_CTL_START_Msk;
1302
1303 while ((g_ECC_done | g_ECCERR_done) == 0UL)
1304 {
1305 }
1306
1307 Reg2Hex(pCurve->Echar, crpt->ECC_X1, x2);
1308 Reg2Hex(pCurve->Echar, crpt->ECC_Y1, y2);
1309 }
1310
1311 return ret;
1312 }
1313
1314 /**
1315 * @brief Given a curve parameter, the other party's public key, and one's own private key to generate the secret Z.
1316 * @param[in] crpt Reference to Crypto module.
1317 * @param[in] ecc_curve The pre-defined ECC curve.
1318 * @param[in] private_k One's own private key.
1319 * @param[in] public_k1 The other party's publick key 1.
1320 * @param[in] public_k2 The other party's publick key 2.
1321 * @param[out] secret_z The ECC CDH secret Z.
1322 * @return 0 Success.
1323 * @return -1 "ecc_curve" value is invalid.
1324 */
ECC_GenerateSecretZ(CRPT_T * crpt,E_ECC_CURVE ecc_curve,char * private_k,char public_k1[],char public_k2[],char secret_z[])1325 int32_t ECC_GenerateSecretZ(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char *private_k, char public_k1[], char public_k2[], char secret_z[])
1326 {
1327 int32_t i, ret = 0;
1328
1329 if (ecc_init_curve(crpt, ecc_curve) != 0)
1330 {
1331 ret = -1;
1332 }
1333
1334 if (ret == 0)
1335 {
1336 for (i = 0; i < 18; i++)
1337 {
1338 crpt->ECC_K[i] = 0UL;
1339 crpt->ECC_X1[i] = 0UL;
1340 crpt->ECC_Y1[i] = 0UL;
1341 }
1342
1343 if ((ecc_curve == CURVE_B_163) || (ecc_curve == CURVE_B_233) || (ecc_curve == CURVE_B_283) ||
1344 (ecc_curve == CURVE_B_409) || (ecc_curve == CURVE_B_571) || (ecc_curve == CURVE_K_163))
1345 {
1346 Hex2RegEx(private_k, crpt->ECC_K, 1);
1347 }
1348 else if ((ecc_curve == CURVE_K_233) || (ecc_curve == CURVE_K_283) ||
1349 (ecc_curve == CURVE_K_409) || (ecc_curve == CURVE_K_571))
1350 {
1351 Hex2RegEx(private_k, crpt->ECC_K, 2);
1352 }
1353 else
1354 {
1355 Hex2Reg(private_k, crpt->ECC_K);
1356 }
1357
1358 Hex2Reg(public_k1, crpt->ECC_X1);
1359 Hex2Reg(public_k2, crpt->ECC_Y1);
1360
1361 /* set FSEL (Field selection) */
1362 if (pCurve->GF == (int)CURVE_GF_2M)
1363 {
1364 crpt->ECC_CTL = 0UL;
1365 }
1366 else
1367 {
1368 /* CURVE_GF_P */
1369 crpt->ECC_CTL = CRPT_ECC_CTL_FSEL_Msk;
1370 }
1371 g_ECC_done = g_ECCERR_done = 0UL;
1372 crpt->ECC_CTL |= ((uint32_t)pCurve->key_len << CRPT_ECC_CTL_CURVEM_Pos) |
1373 ECCOP_POINT_MUL | CRPT_ECC_CTL_START_Msk;
1374
1375 while ((g_ECC_done | g_ECCERR_done) == 0UL)
1376 {
1377 }
1378
1379 Reg2Hex(pCurve->Echar, crpt->ECC_X1, secret_z);
1380 }
1381
1382 return ret;
1383 }
1384
1385 /** @cond HIDDEN_SYMBOLS */
1386
run_ecc_codec(CRPT_T * crpt,uint32_t mode)1387 static void run_ecc_codec(CRPT_T *crpt, uint32_t mode)
1388 {
1389 if ((mode & CRPT_ECC_CTL_ECCOP_Msk) == ECCOP_MODULE)
1390 {
1391 crpt->ECC_CTL = CRPT_ECC_CTL_FSEL_Msk;
1392 }
1393 else
1394 {
1395 if (pCurve->GF == (int)CURVE_GF_2M)
1396 {
1397 /* point */
1398 crpt->ECC_CTL = 0UL;
1399 }
1400 else
1401 {
1402 /* CURVE_GF_P */
1403 crpt->ECC_CTL = CRPT_ECC_CTL_FSEL_Msk;
1404 }
1405 }
1406
1407 g_ECC_done = g_ECCERR_done = 0UL;
1408 crpt->ECC_CTL |= ((uint32_t)pCurve->key_len << CRPT_ECC_CTL_CURVEM_Pos) | mode | CRPT_ECC_CTL_START_Msk;
1409 while ((g_ECC_done | g_ECCERR_done) == 0UL)
1410 {
1411 }
1412
1413 while (crpt->ECC_STS & CRPT_ECC_STS_BUSY_Msk)
1414 {
1415 }
1416 }
1417 /** @endcond HIDDEN_SYMBOLS */
1418
1419 /**
1420 * @brief ECDSA digital signature generation.
1421 * @param[in] crpt Reference to Crypto module.
1422 * @param[in] ecc_curve The pre-defined ECC curve.
1423 * @param[in] message The hash value of source context.
1424 * @param[in] d The private key.
1425 * @param[in] k The selected random integer.
1426 * @param[out] R R of the (R,S) pair digital signature
1427 * @param[out] S S of the (R,S) pair digital signature
1428 * @return 0 Success.
1429 * @return -1 "ecc_curve" value is invalid.
1430 */
ECC_GenerateSignature(CRPT_T * crpt,E_ECC_CURVE ecc_curve,char * message,char * d,char * k,char * R,char * S)1431 int32_t ECC_GenerateSignature(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char *message,
1432 char *d, char *k, char *R, char *S)
1433 {
1434 uint32_t volatile temp_result1[18], temp_result2[18];
1435 int32_t i, ret = 0;
1436
1437 if (ecc_init_curve(crpt, ecc_curve) != 0)
1438 {
1439 ret = -1;
1440 }
1441
1442 if (ret == 0)
1443 {
1444 /*
1445 * 1. Calculate e = HASH(m), where HASH is a cryptographic hashing algorithm, (i.e. SHA-1)
1446 * (1) Use SHA to calculate e
1447 */
1448
1449 /* 2. Select a random integer k form [1, n-1]
1450 * (1) Notice that n is order, not prime modulus or irreducible polynomial function
1451 */
1452
1453 /*
1454 * 3. Compute r = x1 (mod n), where (x1, y1) = k * G. If r = 0, go to step 2
1455 * (1) Write the curve parameter A, B, and curve length M to corresponding registers
1456 * (2) Write the prime modulus or irreducible polynomial function to N registers according
1457 * (3) Write the point G(x, y) to X1, Y1 registers
1458 * (4) Write the random integer k to K register
1459 * (5) Set ECCOP(CRPT_ECC_CTL[10:9]) to 00
1460 * (6) Set FSEL(CRPT_ECC_CTL[8]) according to used curve of prime field or binary field
1461 * (7) Set START(CRPT_ECC_CTL[0]) to 1
1462 * (8) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1463 * (9) Write the curve order and curve length to N ,M registers according
1464 * (10) Write 0x0 to Y1 registers
1465 * (11) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1466 * (12) Set MOPOP(CRPT_ECC_CTL[12:11]) to 10
1467 * (13) Set START(CRPT_ECC_CTL[0]) to 1 *
1468 * (14) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1469 * (15) Read X1 registers to get r
1470 */
1471
1472 /* 3-(4) Write the random integer k to K register */
1473 for (i = 0; i < 18; i++)
1474 {
1475 crpt->ECC_K[i] = 0UL;
1476 }
1477 Hex2Reg(k, crpt->ECC_K);
1478
1479 run_ecc_codec(crpt, ECCOP_POINT_MUL);
1480
1481 /* 3-(9) Write the curve order to N registers */
1482 for (i = 0; i < 18; i++)
1483 {
1484 crpt->ECC_N[i] = 0UL;
1485 }
1486 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
1487
1488 /* 3-(10) Write 0x0 to Y1 registers */
1489 for (i = 0; i < 18; i++)
1490 {
1491 crpt->ECC_Y1[i] = 0UL;
1492 }
1493
1494 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_ADD);
1495
1496 /* 3-(15) Read X1 registers to get r */
1497 for (i = 0; i < 18; i++)
1498 {
1499 temp_result1[i] = crpt->ECC_X1[i];
1500 }
1501
1502 Reg2Hex(pCurve->Echar, temp_result1, R);
1503
1504 /*
1505 * 4. Compute s = k ? 1 �� (e + d �� r)(mod n). If s = 0, go to step 2
1506 * (1) Write the curve order to N registers according
1507 * (2) Write 0x1 to Y1 registers
1508 * (3) Write the random integer k to X1 registers according
1509 * (4) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1510 * (5) Set MOPOP(CRPT_ECC_CTL[12:11]) to 00
1511 * (6) Set START(CRPT_ECC_CTL[0]) to 1
1512 * (7) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1513 * (8) Read X1 registers to get k^-1
1514 * (9) Write the curve order and curve length to N ,M registers
1515 * (10) Write r, d to X1, Y1 registers
1516 * (11) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1517 * (12) Set MOPOP(CRPT_ECC_CTL[12:11]) to 01
1518 * (13) Set START(CRPT_ECC_CTL[0]) to 1
1519 * (14) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1520 * (15) Write the curve order to N registers
1521 * (16) Write e to Y1 registers
1522 * (17) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1523 * (18) Set MOPOP(CRPT_ECC_CTL[12:11]) to 10
1524 * (19) Set START(CRPT_ECC_CTL[0]) to 1
1525 * (20) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1526 * (21) Write the curve order and curve length to N ,M registers
1527 * (22) Write k^-1 to Y1 registers
1528 * (23) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1529 * (24) Set MOPOP(CRPT_ECC_CTL[12:11]) to 01
1530 * (25) Set START(CRPT_ECC_CTL[0]) to 1
1531 * (26) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1532 * (27) Read X1 registers to get s
1533 */
1534
1535 /* S/W: GFp_add_mod_order(pCurve->key_len+2, 0, x1, a, R); */
1536
1537 /* 4-(1) Write the curve order to N registers */
1538 for (i = 0; i < 18; i++)
1539 {
1540 crpt->ECC_N[i] = 0UL;
1541 }
1542 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
1543
1544 /* 4-(2) Write 0x1 to Y1 registers */
1545 for (i = 0; i < 18; i++)
1546 {
1547 crpt->ECC_Y1[i] = 0UL;
1548 }
1549 crpt->ECC_Y1[0] = 0x1UL;
1550
1551 /* 4-(3) Write the random integer k to X1 registers */
1552 for (i = 0; i < 18; i++)
1553 {
1554 crpt->ECC_X1[i] = 0UL;
1555 }
1556 Hex2Reg(k, crpt->ECC_X1);
1557
1558 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_DIV);
1559
1560 #if ENABLE_DEBUG
1561 Reg2Hex(pCurve->Echar, crpt->ECC_X1, temp_hex_str);
1562 CRPT_DBGMSG("(7) output = %s\n", temp_hex_str);
1563 #endif
1564
1565 /* 4-(8) Read X1 registers to get k^-1 */
1566
1567 for (i = 0; i < 18; i++)
1568 {
1569 temp_result2[i] = crpt->ECC_X1[i];
1570 }
1571
1572 #if ENABLE_DEBUG
1573 Reg2Hex(pCurve->Echar, temp_result2, temp_hex_str);
1574 CRPT_DBGMSG("k^-1 = %s\n", temp_hex_str);
1575 #endif
1576
1577 /* 4-(9) Write the curve order and curve length to N ,M registers */
1578 for (i = 0; i < 18; i++)
1579 {
1580 crpt->ECC_N[i] = 0UL;
1581 }
1582 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
1583
1584 /* 4-(10) Write r, d to X1, Y1 registers */
1585 for (i = 0; i < 18; i++)
1586 {
1587 crpt->ECC_X1[i] = temp_result1[i];
1588 }
1589
1590 for (i = 0; i < 18; i++)
1591 {
1592 crpt->ECC_Y1[i] = 0UL;
1593 }
1594 Hex2Reg(d, crpt->ECC_Y1);
1595
1596 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_MUL);
1597
1598 #if ENABLE_DEBUG
1599 Reg2Hex(pCurve->Echar, crpt->ECC_X1, temp_hex_str);
1600 CRPT_DBGMSG("(14) output = %s\n", temp_hex_str);
1601 #endif
1602
1603 /* 4-(15) Write the curve order to N registers */
1604 for (i = 0; i < 18; i++)
1605 {
1606 crpt->ECC_N[i] = 0UL;
1607 }
1608 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
1609
1610 /* 4-(16) Write e to Y1 registers */
1611 for (i = 0; i < 18; i++)
1612 {
1613 crpt->ECC_Y1[i] = 0UL;
1614 }
1615 Hex2Reg(message, crpt->ECC_Y1);
1616
1617 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_ADD);
1618
1619 #if ENABLE_DEBUG
1620 Reg2Hex(pCurve->Echar, crpt->ECC_X1, temp_hex_str);
1621 CRPT_DBGMSG("(20) output = %s\n", temp_hex_str);
1622 #endif
1623
1624 /* 4-(21) Write the curve order and curve length to N ,M registers */
1625 for (i = 0; i < 18; i++)
1626 {
1627 crpt->ECC_N[i] = 0UL;
1628 }
1629 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
1630
1631 /* 4-(22) Write k^-1 to Y1 registers */
1632 for (i = 0; i < 18; i++)
1633 {
1634 crpt->ECC_Y1[i] = temp_result2[i];
1635 }
1636
1637 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_MUL);
1638
1639 /* 4-(27) Read X1 registers to get s */
1640 for (i = 0; i < 18; i++)
1641 {
1642 temp_result2[i] = crpt->ECC_X1[i];
1643 }
1644
1645 Reg2Hex(pCurve->Echar, temp_result2, S);
1646
1647 } /* ret == 0 */
1648
1649 return ret;
1650 }
1651
1652 /**
1653 * @brief ECDSA dogotal signature verification.
1654 * @param[in] crpt Reference to Crypto module.
1655 * @param[in] ecc_curve The pre-defined ECC curve.
1656 * @param[in] message The hash value of source context.
1657 * @param[in] public_k1 The public key 1.
1658 * @param[in] public_k2 The public key 2.
1659 * @param[in] R R of the (R,S) pair digital signature
1660 * @param[in] S S of the (R,S) pair digital signature
1661 * @return 0 Success.
1662 * @return -1 "ecc_curve" value is invalid.
1663 * @return -2 Verification failed.
1664 */
ECC_VerifySignature(CRPT_T * crpt,E_ECC_CURVE ecc_curve,char * message,char * public_k1,char * public_k2,char * R,char * S)1665 int32_t ECC_VerifySignature(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char *message,
1666 char *public_k1, char *public_k2, char *R, char *S)
1667 {
1668 uint32_t temp_result1[18], temp_result2[18];
1669 uint32_t temp_x[18], temp_y[18];
1670 int32_t i, ret = 0;
1671
1672 /*
1673 * 1. Verify that r and s are integers in the interval [1, n-1]. If not, the signature is invalid
1674 * 2. Compute e = HASH (m), where HASH is the hashing algorithm in signature generation
1675 * (1) Use SHA to calculate e
1676 */
1677
1678 /*
1679 * 3. Compute w = s^-1 (mod n)
1680 * (1) Write the curve order to N registers
1681 * (2) Write 0x1 to Y1 registers
1682 * (3) Write s to X1 registers
1683 * (4) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1684 * (5) Set MOPOP(CRPT_ECC_CTL[12:11]) to 00
1685 * (6) Set FSEL(CRPT_ECC_CTL[8]) according to used curve of prime field or binary field
1686 * (7) Set START(CRPT_ECC_CTL[0]) to 1
1687 * (8) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1688 * (9) Read X1 registers to get w
1689 */
1690
1691 if (ecc_init_curve(crpt, ecc_curve) != 0)
1692 {
1693 ret = -1;
1694 }
1695
1696 if (ret == 0)
1697 {
1698 /* 3-(1) Write the curve order to N registers */
1699 for (i = 0; i < 18; i++)
1700 {
1701 crpt->ECC_N[i] = 0UL;
1702 }
1703 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
1704
1705 /* 3-(2) Write 0x1 to Y1 registers */
1706 for (i = 0; i < 18; i++)
1707 {
1708 crpt->ECC_Y1[i] = 0UL;
1709 }
1710 crpt->ECC_Y1[0] = 0x1UL;
1711
1712 /* 3-(3) Write s to X1 registers */
1713 for (i = 0; i < 18; i++)
1714 {
1715 crpt->ECC_X1[i] = 0UL;
1716 }
1717 Hex2Reg(S, crpt->ECC_X1);
1718
1719 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_DIV);
1720
1721 /* 3-(9) Read X1 registers to get w */
1722 for (i = 0; i < 18; i++)
1723 {
1724 temp_result2[i] = crpt->ECC_X1[i];
1725 }
1726
1727 #if ENABLE_DEBUG
1728 CRPT_DBGMSG("e = %s\n", message);
1729 Reg2Hex(pCurve->Echar, temp_result2, temp_hex_str);
1730 CRPT_DBGMSG("w = %s\n", temp_hex_str);
1731 CRPT_DBGMSG("o = %s (order)\n", pCurve->Eorder);
1732 #endif
1733
1734 /*
1735 * 4. Compute u1 = e �� w (mod n) and u2 = r �� w (mod n)
1736 * (1) Write the curve order and curve length to N ,M registers
1737 * (2) Write e, w to X1, Y1 registers
1738 * (3) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1739 * (4) Set MOPOP(CRPT_ECC_CTL[12:11]) to 01
1740 * (5) Set START(CRPT_ECC_CTL[0]) to 1
1741 * (6) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1742 * (7) Read X1 registers to get u1
1743 * (8) Write the curve order and curve length to N ,M registers
1744 * (9) Write r, w to X1, Y1 registers
1745 * (10) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1746 * (11) Set MOPOP(CRPT_ECC_CTL[12:11]) to 01
1747 * (12) Set START(CRPT_ECC_CTL[0]) to 1
1748 * (13) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1749 * (14) Read X1 registers to get u2
1750 */
1751
1752 /* 4-(1) Write the curve order and curve length to N ,M registers */
1753 for (i = 0; i < 18; i++)
1754 {
1755 crpt->ECC_N[i] = 0UL;
1756 }
1757 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
1758
1759 /* 4-(2) Write e, w to X1, Y1 registers */
1760 for (i = 0; i < 18; i++)
1761 {
1762 crpt->ECC_X1[i] = 0UL;
1763 }
1764 Hex2Reg(message, crpt->ECC_X1);
1765
1766 for (i = 0; i < 18; i++)
1767 {
1768 crpt->ECC_Y1[i] = temp_result2[i];
1769 }
1770
1771 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_MUL);
1772
1773 /* 4-(7) Read X1 registers to get u1 */
1774 for (i = 0; i < 18; i++)
1775 {
1776 temp_result1[i] = crpt->ECC_X1[i];
1777 }
1778
1779 #if ENABLE_DEBUG
1780 Reg2Hex(pCurve->Echar, temp_result1, temp_hex_str);
1781 CRPT_DBGMSG("u1 = %s\n", temp_hex_str);
1782 #endif
1783
1784 /* 4-(8) Write the curve order and curve length to N ,M registers */
1785 for (i = 0; i < 18; i++)
1786 {
1787 crpt->ECC_N[i] = 0UL;
1788 }
1789 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
1790
1791 /* 4-(9) Write r, w to X1, Y1 registers */
1792 for (i = 0; i < 18; i++)
1793 {
1794 crpt->ECC_X1[i] = 0UL;
1795 }
1796 Hex2Reg(R, crpt->ECC_X1);
1797
1798 for (i = 0; i < 18; i++)
1799 {
1800 crpt->ECC_Y1[i] = temp_result2[i];
1801 }
1802
1803 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_MUL);
1804
1805 /* 4-(14) Read X1 registers to get u2 */
1806 for (i = 0; i < 18; i++)
1807 {
1808 temp_result2[i] = crpt->ECC_X1[i];
1809 }
1810
1811 #if ENABLE_DEBUG
1812 Reg2Hex(pCurve->Echar, temp_result2, temp_hex_str);
1813 CRPT_DBGMSG("u2 = %s\n", temp_hex_str);
1814 #endif
1815
1816 /*
1817 * 5. Compute X�� (x1��, y1��) = u1 * G + u2 * Q
1818 * (1) Write the curve parameter A, B, N, and curve length M to corresponding registers
1819 * (2) Write the point G(x, y) to X1, Y1 registers
1820 * (3) Write u1 to K registers
1821 * (4) Set ECCOP(CRPT_ECC_CTL[10:9]) to 00
1822 * (5) Set START(CRPT_ECC_CTL[0]) to 1
1823 * (6) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1824 * (7) Read X1, Y1 registers to get u1*G
1825 * (8) Write the curve parameter A, B, N, and curve length M to corresponding registers
1826 * (9) Write the public key Q(x,y) to X1, Y1 registers
1827 * (10) Write u2 to K registers
1828 * (11) Set ECCOP(CRPT_ECC_CTL[10:9]) to 00
1829 * (12) Set START(CRPT_ECC_CTL[0]) to 1
1830 * (13) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1831 * (14) Write the curve parameter A, B, N, and curve length M to corresponding registers
1832 * (15) Write the result data u1*G to X2, Y2 registers
1833 * (16) Set ECCOP(CRPT_ECC_CTL[10:9]) to 10
1834 * (17) Set START(CRPT_ECC_CTL[0]) to 1
1835 * (18) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1836 * (19) Read X1, Y1 registers to get X��(x1��, y1��)
1837 * (20) Write the curve order and curve length to N ,M registers
1838 * (21) Write x1�� to X1 registers
1839 * (22) Write 0x0 to Y1 registers
1840 * (23) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
1841 * (24) Set MOPOP(CRPT_ECC_CTL[12:11]) to 10
1842 * (25) Set START(CRPT_ECC_CTL[0]) to 1
1843 * (26) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
1844 * (27) Read X1 registers to get x1�� (mod n)
1845 *
1846 * 6. The signature is valid if x1�� = r, otherwise it is invalid
1847 */
1848
1849 /*
1850 * (1) Write the curve parameter A, B, N, and curve length M to corresponding registers
1851 * (2) Write the point G(x, y) to X1, Y1 registers
1852 */
1853 ecc_init_curve(crpt, ecc_curve);
1854
1855 /* (3) Write u1 to K registers */
1856 for (i = 0; i < 18; i++)
1857 {
1858 crpt->ECC_K[i] = temp_result1[i];
1859 }
1860
1861 run_ecc_codec(crpt, ECCOP_POINT_MUL);
1862
1863 /* (7) Read X1, Y1 registers to get u1*G */
1864 for (i = 0; i < 18; i++)
1865 {
1866 temp_x[i] = crpt->ECC_X1[i];
1867 temp_y[i] = crpt->ECC_Y1[i];
1868 }
1869
1870 #if ENABLE_DEBUG
1871 Reg2Hex(pCurve->Echar, temp_x, temp_hex_str);
1872 CRPT_DBGMSG("5-(7) u1*G, x = %s\n", temp_hex_str);
1873 Reg2Hex(pCurve->Echar, temp_y, temp_hex_str);
1874 CRPT_DBGMSG("5-(7) u1*G, y = %s\n", temp_hex_str);
1875 #endif
1876
1877 /* (8) Write the curve parameter A, B, N, and curve length M to corresponding registers */
1878 ecc_init_curve(crpt, ecc_curve);
1879
1880 /* (9) Write the public key Q(x,y) to X1, Y1 registers */
1881 for (i = 0; i < 18; i++)
1882 {
1883 crpt->ECC_X1[i] = 0UL;
1884 crpt->ECC_Y1[i] = 0UL;
1885 }
1886
1887 Hex2Reg(public_k1, crpt->ECC_X1);
1888 Hex2Reg(public_k2, crpt->ECC_Y1);
1889
1890 /* (10) Write u2 to K registers */
1891 for (i = 0; i < 18; i++)
1892 {
1893 crpt->ECC_K[i] = temp_result2[i];
1894 }
1895
1896 run_ecc_codec(crpt, ECCOP_POINT_MUL);
1897
1898 for (i = 0; i < 18; i++)
1899 {
1900 temp_result1[i] = crpt->ECC_X1[i];
1901 temp_result2[i] = crpt->ECC_Y1[i];
1902 }
1903
1904 #if ENABLE_DEBUG
1905 Reg2Hex(pCurve->Echar, temp_result1, temp_hex_str);
1906 CRPT_DBGMSG("5-(13) u2*Q, x = %s\n", temp_hex_str);
1907 Reg2Hex(pCurve->Echar, temp_result2, temp_hex_str);
1908 CRPT_DBGMSG("5-(13) u2*Q, y = %s\n", temp_hex_str);
1909 #endif
1910
1911 /* (14) Write the curve parameter A, B, N, and curve length M to corresponding registers */
1912 ecc_init_curve(crpt, ecc_curve);
1913
1914 /* Write the result data u2*Q to X1, Y1 registers */
1915 for (i = 0; i < 18; i++)
1916 {
1917 crpt->ECC_X1[i] = temp_result1[i];
1918 crpt->ECC_Y1[i] = temp_result2[i];
1919 }
1920
1921 /* (15) Write the result data u1*G to X2, Y2 registers */
1922 for (i = 0; i < 18; i++)
1923 {
1924 crpt->ECC_X2[i] = temp_x[i];
1925 crpt->ECC_Y2[i] = temp_y[i];
1926 }
1927
1928 run_ecc_codec(crpt, ECCOP_POINT_ADD);
1929
1930 /* (19) Read X1, Y1 registers to get X��(x1��, y1��) */
1931 for (i = 0; i < 18; i++)
1932 {
1933 temp_x[i] = crpt->ECC_X1[i];
1934 temp_y[i] = crpt->ECC_Y1[i];
1935 }
1936
1937 #if ENABLE_DEBUG
1938 Reg2Hex(pCurve->Echar, temp_x, temp_hex_str);
1939 CRPT_DBGMSG("5-(19) x' = %s\n", temp_hex_str);
1940 Reg2Hex(pCurve->Echar, temp_y, temp_hex_str);
1941 CRPT_DBGMSG("5-(19) y' = %s\n", temp_hex_str);
1942 #endif
1943
1944 /* (20) Write the curve order and curve length to N ,M registers */
1945 for (i = 0; i < 18; i++)
1946 {
1947 crpt->ECC_N[i] = 0UL;
1948 }
1949 Hex2Reg(pCurve->Eorder, crpt->ECC_N);
1950
1951 /*
1952 * (21) Write x1�� to X1 registers
1953 * (22) Write 0x0 to Y1 registers
1954 */
1955 for (i = 0; i < 18; i++)
1956 {
1957 crpt->ECC_X1[i] = temp_x[i];
1958 crpt->ECC_Y1[i] = 0UL;
1959 }
1960
1961 #if ENABLE_DEBUG
1962 Reg2Hex(pCurve->Echar, crpt->ECC_X1, temp_hex_str);
1963 CRPT_DBGMSG("5-(21) x' = %s\n", temp_hex_str);
1964 Reg2Hex(pCurve->Echar, crpt->ECC_Y1, temp_hex_str);
1965 CRPT_DBGMSG("5-(22) y' = %s\n", temp_hex_str);
1966 #endif
1967
1968 run_ecc_codec(crpt, ECCOP_MODULE | MODOP_ADD);
1969
1970 /* (27) Read X1 registers to get x1�� (mod n) */
1971 Reg2Hex(pCurve->Echar, crpt->ECC_X1, temp_hex_str);
1972 CRPT_DBGMSG("5-(27) x1' (mod n) = %s\n", temp_hex_str);
1973
1974 /* 6. The signature is valid if x1�� = r, otherwise it is invalid */
1975
1976 /* Compare with test pattern to check if r is correct or not */
1977 if (ecc_strcmp(temp_hex_str, R) != 0)
1978 {
1979 CRPT_DBGMSG("x1' (mod n) != R Test filed!!\n");
1980 CRPT_DBGMSG("Signature R [%s] is not matched with expected R [%s]!\n", temp_hex_str, R);
1981 ret = -2;
1982 }
1983 } /* ret == 0 */
1984
1985 return ret;
1986 }
1987
1988 /*@}*/ /* end of group CRYPTO_EXPORTED_FUNCTIONS */
1989
1990 /*@}*/ /* end of group CRYPTO_Driver */
1991
1992 /*@}*/ /* end of group Standard_Driver */
1993
1994 /*** (C) COPYRIGHT 2017 Nuvoton Technology Corp. ***/
1995
1996