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