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