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