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