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