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