pic32mz_crypto_pkc.c
Go to the documentation of this file.
1 /**
2  * @file pic32mz_crypto_pkc.c
3  * @brief PIC32MZ W1 public-key hardware accelerator (BA414E)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.5.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include <p32xxxx.h>
36 #include <sys/kmem.h>
37 #include "core/crypto.h"
40 #include "pkc/rsa.h"
41 #include "ecc/ec.h"
42 #include "ecc/ec_misc.h"
43 #include "ecc/ecdsa.h"
44 #include "ecc/x25519.h"
45 #include "ecc/ed25519.h"
46 #include "debug.h"
47 
48 //Check crypto library configuration
49 #if (PIC32MZ_CRYPTO_PKC_SUPPORT == ENABLED) && defined(_PMD1_BA414MD_MASK)
50 
51 //BA414E microcode
52 static const uint32_t ucode[] =
53 {
54  0x10032004, 0x48013E00, 0x5A800D20, 0x09A80202, 0x011A8090, 0x60287805, 0xBA022780, 0xB2E02FA8,
55  0x0CEE0070, 0x8021E00A, 0xD8039A00, 0xF5802D60, 0x13C8023A, 0x013D8050, 0x60141804, 0xF2013E80,
56  0x50201408, 0x14460540, 0x8070E01D, 0x48078205, 0x8C804FE0, 0x13F804FE, 0x013F8050, 0x2059B804,
57  0xF6035A80, 0xF3204118, 0x11B603AF, 0x8167E059, 0xF8167E05, 0x9E712014, 0x00144011, 0x10854441,
58  0x80001702, 0x41C51100, 0x10000017, 0x0A490012, 0x4024A005, 0x17200000, 0x010000A0, 0x03678918,
59  0x40007893, 0x44001730, 0x01F30209, 0xB1800015, 0x00040002, 0x800D9E24, 0x610001E2, 0x4D10005C,
60  0xC007CE08, 0x26C60000, 0x54001000, 0x0A003640, 0xE45C580A, 0x80E9C29A, 0x7AB18C38, 0x07AD1CC3,
61  0x8173001C, 0x8007AB2C, 0x23C67AD3, 0x023C67EA, 0x080D4B7A, 0xC6C0D4B0, 0x00054001, 0x0000A003,
62  0x640E45C5, 0x80A80E9E, 0x11330E01, 0xE11430E0, 0x5E115026, 0x51C2927C, 0x4080A920, 0x00054001,
63  0x00009C29, 0xA4086A00, 0x3640E460, 0x05D50004, 0x000270A4, 0x90212800, 0xD9039180, 0x1CD40010,
64  0x000A0036, 0x40001E24, 0x610005E2, 0x4D10001C, 0xC007D808, 0x26C60000, 0x54001000, 0x09C58078,
65  0x93440057, 0x89184004, 0x73001F40, 0x609B1800, 0x01802994, 0x0014044A, 0x003E4401, 0x90092444,
66  0x1A004600, 0x00400027, 0x0A490212, 0x8026DCC0, 0x0A02D140, 0x015057C0, 0x00270A49, 0x02123401,
67  0x5C580789, 0x34000078, 0x91840047, 0x3001F406, 0x09B19CC0, 0x0A02D100, 0x158040CD, 0x00044015,
68  0x00804045, 0xA0046730, 0x0240B430, 0x05910054, 0x42191106, 0x80145000, 0x04421911, 0x0640E469,
69  0x073E4175, 0x10044421, 0x91106801, 0x19120680, 0x26DC8003, 0x000200A6, 0x7300250E, 0x40000540,
70  0x0174A180, 0x00100009, 0x00158040, 0xCC01570A, 0x49C80030, 0x249FA863, 0x0A11EB1B, 0x30A11C80,
71  0x030000C0, 0x90500040, 0x00240056, 0x01033005, 0x5C292720, 0x00C0927C, 0x418C2847, 0x2000C000,
72  0x30240000, 0x150005D2, 0x8072001E, 0x24610001, 0xE24D1000, 0x1CC0078E, 0x4C26C672, 0x000C0137,
73  0x89180013, 0x73001F38, 0x009B19C8, 0x0000004C, 0x00030241, 0x01005025, 0xD4001000, 0x09C580A8,
74  0x0E903917, 0x0A490016, 0x7C400839, 0x244021F1, 0x0030E111, 0x08020439, 0xF1093000, 0x51089284,
75  0x01E88020, 0xE4AB59C7, 0x46148001, 0x20441C90, 0x072401C9, 0x0072401C, 0x98028400, 0xA0007E81,
76  0x80900000, 0x05400150, 0x00540015, 0x00054001, 0x50005400, 0x17EA0048, 0x8172001F, 0xB0812224,
77  0x00018050, 0x9EDC6022, 0x69FB1002, 0x269C8000, 0x0005C580, 0xA80E9C29, 0xA4021221, 0x5B442263,
78  0x15B00041, 0x00844004, 0xA0142000, 0x05EAC612, 0x205EB470, 0x2201C800, 0x78F2C234, 0x77AB180D,
79  0x4B7EC040, 0xD4B00004, 0x00027300, 0x1C800D45, 0xB4000150, 0x00540430, 0x000A014F, 0xAD675108,
80  0x44010E01, 0x48442110, 0x01480509, 0x00434030, 0xF624798B, 0x450096D8, 0x85262BF4, 0x005A0142,
81  0x4010D00C, 0x34045362, 0x9298C150, 0x098D8852, 0x62BF4006, 0x20142004, 0x02B59D74, 0x615C8002,
82  0x00048120, 0x8467711A, 0xD72E01C8, 0x0028400A, 0x0004010D, 0x1086D885, 0x262BF000, 0x0601BD50,
83  0x00500434, 0x030F6247, 0x98B47624, 0x798B4771, 0xA99C6AD0, 0x900D8A4A, 0x63050000, 0x50043000,
84  0x05004C00, 0x00771AF0, 0x00050043, 0x42201F20, 0x010005F2, 0x0810025E, 0xDC602269, 0xFB100226,
85  0xAC59D000, 0x80000150, 0x11DC8000, 0x002200A6, 0x44C3A00A, 0x60000400, 0x02020011, 0x00440201,
86  0x011B8014, 0x5CC00720, 0x0341D344, 0x02200517, 0x3001C800, 0xD074C000, 0x15000540, 0x0B000080,
87  0x80040005, 0x00804046, 0xE0051730, 0x01C80094, 0x77C00015, 0x0005400F, 0x00008080, 0x04001100,
88  0x804046E0, 0x05173001, 0xC800D084, 0x91008801, 0x45CC0072, 0x00342129, 0x883E014F, 0x40449E24,
89  0x610009E2, 0x4710029E, 0x34B08D19, 0xE34C08F1, 0xDEDCD097, 0x2DEB4B09, 0x72DE34C0, 0x8F31EACB,
90  0x08D2DEB4, 0xC09931C3, 0x4E78D342, 0x64C78D2C, 0x264B70D3, 0x9E34C09B, 0x2DCC0072, 0x00252128,
91  0x083C0002, 0x00005400, 0x14001140, 0x1B7B72CC, 0x8107AD18, 0xC8107300, 0x1C800946, 0xF1EDCB32,
92  0x041EB472, 0x2119CC00, 0x7200251B, 0xC7D00463, 0x007D0246, 0x38800004, 0x00028053, 0xD1084401,
93  0x0E014240, 0x44900437, 0x8930400A, 0x7AB2CC00, 0x07AD18C1, 0x007AB2C8, 0x04B7AD1C, 0xC40878D2,
94  0xC234B70D, 0x35E34B09, 0x731C34D7, 0x8F1825C7, 0x8059C000, 0x28053D10, 0x844010E0, 0x1484030D,
95  0xC80078D3, 0x4C48978D, 0x18C0817A, 0xB3484CD7, 0xAD38C891, 0x7AB1826C, 0x67AD1C26, 0xCD7AB2CC,
96  0x0817AD34, 0x274E78D1, 0xC23C778D, 0x3025CB7B, 0x738094D7, 0xAD34094D, 0x78D30264, 0xB78D3823,
97  0x4678D2C2, 0x6CC78D34, 0xC489A49F, 0x392827CE, 0x00274C72, 0x001E3CE2, 0x0119C800, 0x7EA4088C,
98  0xD7AD3027, 0x4B72001F, 0x38808F30, 0x00014421, 0xA0214806, 0xF540017F, 0x62025CB7, 0xAD3025CB,
99  0x72000000, 0x17AB3025, 0xCB7EC202, 0x5CB00004, 0x00028053, 0xD1084401, 0x0E014844, 0x21500148,
100  0x05090043, 0x4030D011, 0x47AB34C8, 0x917AD1CC, 0x88A7AB18, 0x814D7AD1, 0xC26C778F, 0x2C80C678,
101  0xF3084C77, 0xAB1825CB, 0x7AD38264, 0xC7AB1C25, 0xC67AD348, 0x0C67CE00, 0x23CE78D3, 0x826CD7F6,
102  0x2084C77A, 0xD1884C77, 0xCE006700, 0x72001E3C, 0x720135FA, 0x902232DE, 0xB4D0991D, 0xC8007CE2,
103  0x0234D000, 0x05108680, 0x85201BD5, 0x0005EDCC, 0x32041EB4, 0x632041CC, 0x00720025, 0x1BC7D004,
104  0xC8007D02, 0x46308000, 0x04000280, 0x53D10844, 0x010E0148, 0x4030DC80, 0x07AB18C8, 0x917AD1CC,
105  0x0817AB2C, 0x23467EC4, 0x023C6730, 0x01C80094, 0x6F1EAC60, 0x272DEB47, 0x08F1DEAC, 0xB31225EB,
106  0x4C12441F, 0x30008F19, 0xE34B08D2, 0xDEDCD221, 0x19EB4622, 0x119E3470, 0x9731C800, 0x7B72C804,
107  0x77AD2C80, 0x477CC202, 0x5C600005, 0x108680AF, 0xD4001000, 0x0A014F44, 0x21100438, 0x05211085,
108  0x40052014, 0x24010D00, 0xC340451E, 0xAC632245, 0xEB473220, 0x9EACB215, 0x19EB4602, 0x519E3472,
109  0x031DE34B, 0x2132DEAC, 0xC2231DEB, 0x4708F1DE, 0x34609919, 0xC8007AB1, 0x823477EC, 0x40264C73,
110  0x001C8009, 0x46F1EACC, 0x0992DEB4, 0xB0972DE3, 0x4609919E, 0xAC730441, 0xEB4D3144, 0x1F30008D,
111  0x2DC80078, 0xD1C80477, 0x8D2C804D, 0x7AB1823C, 0xC7AD1C88, 0x4B72001F, 0x30808F18, 0x00014421,
112  0xA02BF500, 0x04000280, 0x53D10844, 0x010E0142, 0x40449004, 0x37893040, 0x0A7AB2CC, 0x0007AD18,
113  0xC1007AB2, 0xC804B7AD, 0x1880467A, 0xB1CC4087, 0xAD34C400, 0x78D2C234, 0xB78D1C26, 0xC778D2C2,
114  0x5CC70D39, 0xE3C60971, 0xE0167716, 0x02A03A70, 0xA69E24A0, 0x0069CC00, 0x78F2C254, 0xA4005110,
115  0x847EA004, 0x8817EC20, 0x48894010, 0xD01457EA, 0x0048817E, 0xC20089A7, 0xEA08089A, 0x7EC2808C,
116  0xB4005001, 0x0074615C, 0x80020004, 0x8120DCEA, 0x673AC80E, 0x11CB8072, 0x000A1002, 0x80010145,
117  0x44219F40, 0x13140940, 0x0178D28C, 0x48178F2C, 0xC4817AB3, 0x0254A7AD, 0x3425CB78, 0xD38C5027,
118  0x8F1CC502, 0x7AB3825C, 0xE7AD1C23, 0xCA78F282, 0x6CC7EA04, 0x26CC7AD2, 0xC650878D, 0x3423CE78,
119  0xF3823CE7, 0xEA0826CD, 0x7AD1C274, 0xE78D3025, 0xCC7EA288, 0x0477EC24, 0x264A0000, 0x500C3405,
120  0x14000140, 0x31501430, 0x00040002, 0x71602A03, 0xA70A4DEA, 0x9412211E, 0xB1512231, 0xEAC70285,
121  0x1EB4802A, 0x55EACC02, 0x229EB4D0, 0x911DEACE, 0x0224DEB4, 0xC09B31E3, 0xC708F21E, 0x34809939,
122  0xCC0078F1, 0xC2447442, 0x12016700, 0x009C580A, 0x80E9C293, 0x7AA50088, 0x87AC4808, 0x8A7AB300,
123  0xA147AD2C, 0x08937AB3, 0x4261278F, 0x3025CC78, 0xD3425CD7, 0xAB3826CD, 0x73001EAC, 0xE09B39CC,
124  0x007AA542, 0x74E7AA50, 0x26957AA5, 0x026147AC, 0x54274C78, 0x93800137, 0x3001EA94, 0x09C51CC0,
125  0x00002102, 0x1440A110, 0x31440E46, 0x011E7200, 0x000087AA, 0x5008947A, 0xA540A157, 0xAB380A95,
126  0x73001EAC, 0xE09B39CC, 0x0078D382, 0x64E73001, 0xC800D503, 0x5EA86016, 0x55CC0050, 0x005EA860,
127  0x2655CC00, 0x50004000, 0x271602A0, 0x3A70A4DE, 0xAA20224D, 0x10044030, 0xE04DD401, 0x0D109040,
128  0x52D11928, 0x12F90043, 0x44241011, 0x64464A04, 0xF94012D1, 0x09040469, 0x1192813E, 0x51004403,
129  0x0E04DD40, 0x10D10904, 0x052D1192, 0x812F9004, 0x34424101, 0x1644649F, 0x20010009, 0xF2081002,
130  0x9F201100, 0x0DF20910, 0x02D004B4, 0x42410143, 0x4464A04A, 0x04012D10, 0x90404791, 0x192813E5,
131  0x004B4424, 0x1F380044, 0x89F20800, 0x089F2010, 0x0089F389, 0x04489004, 0xB4424101, 0x124464A0,
132  0x4F94012D, 0x10900040, 0x1D185720, 0x00800120, 0x481014B4, 0x464A04BE, 0x812F9090, 0x04464A04,
133  0xA072E01C, 0x80028400, 0xA0004012, 0xD1086814, 0x18000150, 0x00400027, 0x1602A03A, 0x70A4DEAA,
134  0x20224D02, 0x0240A110, 0x30A8105D, 0x020640A1, 0x5030C810, 0x5D020840, 0xA31030E8, 0x1239000A,
135  0x40239011, 0x480145CC, 0x00720035, 0x11544021, 0x10894045, 0x20051730, 0x01C800D4, 0x45540014,
136  0x401500CB, 0x81375004, 0xB4032E04, 0xE8440110, 0x0C381375, 0x00434424, 0x1014B446, 0x4A04A040,
137  0x10D10868, 0x14180001, 0x78D1CC00, 0x878F20C0, 0x087AB1C8, 0x1477AD20, 0x85487AB2, 0x4C5897AD,
138  0x28C1817C, 0xC2424477, 0x8F1C2447, 0x78F2024C, 0xA78D2424, 0xCA7EA002, 0x4477EC20, 0x64897EA0,
139  0x424C87EC, 0x24638973, 0x00000017, 0x8D1CC008, 0x78F20C00, 0x87AB2823, 0xC77AD242, 0x4477AB1C,
140  0xC4817AD2, 0x0C08178D, 0x1C23C778, 0xD2024487, 0x3001E3C8, 0x09321E3C, 0xA08F29FA, 0x820911DF,
141  0xB0309321, 0xFA8A0952, 0x5FB0B095, 0x1DCC0000, 0x005FA811, 0x2201FB09, 0x12221111, 0x17C80800,
142  0x227EA28C, 0x48173000, 0x000178D1, 0xCC0087CE, 0x24C00878, 0xF2023C77, 0xCC042447, 0x44041109,
143  0x17CC04C0, 0x0073001F, 0xA8910221, 0xCC000000, 0x5FA8B102, 0x25CC0000, 0x021F3023, 0x0021F38A,
144  0x30021F30, 0x330205CC, 0x00000200, 0x00144441, 0xF20A0008, 0x9E414304, 0x29FA8112, 0x801FB091,
145  0x2821CC00, 0x00004000, 0x28053D02, 0x0240A1D0, 0x30E805C5, 0xC8000200, 0x0C001716, 0x01C09271,
146  0x44CC0924, 0x0039009A, 0x40429039, 0x38017DCC, 0x00944550, 0x21A40A1D, 0x030D8026, 0xDCC00400,
147  0x19008A40, 0x42D03938, 0x017DCC00, 0x00021000, 0xC4022D01, 0x0B80119C, 0xC0000021, 0x000D4022,
148  0xD010B801, 0x7DCC0094, 0x454C0003, 0x02414001, 0x00008080, 0x070A68C0, 0x0171601C, 0x0927144C,
149  0xC0924086, 0x9028B40C, 0x36009B73, 0x001000C4, 0x0235011C, 0x40E4E005, 0xF7300100, 0x0A402350,
150  0x11B8017D, 0xCC000300, 0x0C000302, 0x42014F40, 0x821029B4, 0x0C7A0171, 0x72001020, 0x240A7103,
151  0x1C805C5C, 0x80040271, 0x00438052, 0x1009E400, 0x52014240, 0x10D00C34, 0x04536292, 0x98C15008,
152  0xED885262, 0xBF720000, 0x80030005, 0xC5807024, 0x9C513302, 0x49000E40, 0x269011C4, 0x0E4E005F,
153  0x73000000, 0x84007100, 0x8A4046E0, 0x05173001, 0xC800D445, 0x4C000302, 0x41400100, 0x00808008,
154  0x078A01D6, 0x40009008, 0x04046E01, 0xC8030010, 0x0824010E, 0x0142D88B, 0x26340500, 0x05400100,
155  0x00400015, 0x00054001
156 };
157 
158 
159 /**
160  * @brief Initialize BA414E public key accelerator
161  * @return Error code
162  **/
163 
164 error_t ba414eInit(void)
165 {
166  uint_t i;
167  uint_t j;
168  const uint32_t *src;
169  volatile uint32_t *dest;
170 
171  //Point to the microcode to be loaded
172  src = ucode;
173  //Point to the microcode SRAM
174  dest = KVA0_TO_KVA1(__CRYPTO1UCM_BASE);
175 
176  //Initialize the microcode RAM with the microcode
177  for(i = 0; i < arraysize(ucode) / 9; i++)
178  {
179  //Load the current block
180  dest[0] = src[0] >> 14;
181  dest[1] = src[0] << 4;
182  dest[1] |= src[1] >> 28;
183  dest[2] = src[1] >> 10;
184  dest[3] = src[1] << 8;
185  dest[3] |= src[2] >> 24;
186  dest[4] = src[2] >> 6;
187  dest[5] = src[2] << 12;
188  dest[5] |= src[3] >> 20;
189  dest[6] = src[3] >> 2;
190  dest[7] = src[3] << 16;
191  dest[7] |= src[4] >> 16;
192  dest[8] = src[4] << 2;
193  dest[8] |= src[5] >> 30;
194  dest[9] = src[5] >> 12;
195  dest[10] = src[5] << 6;
196  dest[10] |= src[6] >> 26;
197  dest[11] = src[6] >> 8;
198  dest[12] = src[6] << 10;
199  dest[12] |= src[7] >> 22;
200  dest[13] = src[7] >> 4;
201  dest[14] = src[7] << 14;
202  dest[14] |= src[8] >> 18;
203  dest[15] = src[8];
204 
205  //Each block contains 16 words of 18 bits
206  for(j = 0; j < 16; j++)
207  {
208  dest[j] &= 0x3FFFF;
209  }
210 
211  //Point to the next block
212  src += 9;
213  dest += 16;
214  }
215 
216  //Clear the SCM memory
217  ba414eClearScm();
218 
219  //Successful initialization
220  return NO_ERROR;
221 }
222 
223 
224 /**
225  * @brief Clear SCM memory
226  **/
227 
228 void ba414eClearScm(void)
229 {
230  uint_t i;
231  volatile uint32_t *p;
232 
233  //Point to the SCM memory
234  p = (uint32_t *) __CRYPTO1SCM_BASE;
235 
236  //The SCM memory contains 304 words of 64 bits
237  for(i = 0; i < 608; i++)
238  {
239  p[i] = 0;
240  }
241 }
242 
243 
244 /**
245  * @brief Import byte array
246  * @param[in] src Pointer to the byte array
247  * @param[in] length Length of the array to be copied, in bytes
248  * @param[in] slot SCM memory location
249  **/
250 
251 void ba414eImportArray(const uint8_t *src, size_t length, uint_t slot)
252 {
253  uint_t i;
254  uint_t j;
255  uint32_t temp;
256  volatile uint32_t *p;
257 
258  //Point to the specified SCM memory location
259  p = BA414E_GET_SCM_SLOT(slot);
260 
261  //Copy the array to the SCM memory
262  for(i = 0, j = 0; i < length; i++)
263  {
264  switch(i % 4)
265  {
266  case 0:
267  temp = src[length - i - 1];
268  break;
269  case 1:
270  temp |= src[length - i - 1] << 8;
271  break;
272  case 2:
273  temp |= src[length - i - 1] << 16;
274  break;
275  default:
276  temp |= src[length - i - 1] << 24;
277  p[j++] = temp;
278  break;
279  }
280  }
281 
282  //Pad the operand with zeroes
283  for(; i < 64; i++)
284  {
285  switch(i % 4)
286  {
287  case 0:
288  temp = 0;
289  break;
290  case 3:
291  p[j++] = temp;
292  break;
293  default:
294  break;
295  }
296  }
297 }
298 
299 
300 /**
301  * @brief Import scalar
302  * @param[in] src Pointer to the scalar
303  * @param[in] length Length of the scalar, in words
304  * @param[in] slot SCM memory location
305  **/
306 
307 void ba414eImportScalar(const uint32_t *src, uint_t length, uint_t slot)
308 {
309  uint_t i;
310  volatile uint32_t *p;
311 
312  //Point to the specified SCM memory location
313  p = BA414E_GET_SCM_SLOT(slot);
314 
315  //Copy the scalar to the SCM memory
316  for(i = 0; i < length; i++)
317  {
318  p[i] = src[i];
319  }
320 
321  //Pad the operand with zeroes
322  for(; i < 16; i++)
323  {
324  p[i] = 0;
325  }
326 }
327 
328 
329 /**
330  * @brief Import multiple-precision integer
331  * @param[in] src Pointer to the multiple-precision integer
332  * @param[in] size Size of the operand, in words
333  * @param[in] slot SCM memory location
334  **/
335 
336 void ba414eImportMpi(const Mpi *src, uint_t slot)
337 {
338  uint_t i;
339  uint_t length;
340  volatile uint32_t *p;
341 
342  //Get the actual length of the multiple-precision integer, in words
343  length = mpiGetLength(src);
344 
345  //Point to the specified SCM memory location
346  p = BA414E_GET_SCM_SLOT(slot);
347 
348  //Copy the multiple-precision integer to the SCM memory
349  for(i = 0; i < length && i < 16; i++)
350  {
351  p[i] = src->data[i];
352  }
353 
354  //Pad the operand with zeroes
355  for(; i < 16; i++)
356  {
357  p[i] = 0;
358  }
359 }
360 
361 
362 /**
363  * @brief Export scalar
364  * @param[out] dest Pointer to the scalar
365  * @param[in] length Length of the scalar, in words
366  * @param[in] slot SCM memory location
367  * @return Error code
368  **/
369 
370 void ba414eExportScalar(uint32_t *dest, uint_t length, uint_t slot)
371 {
372  uint_t i;
373  volatile uint32_t *p;
374 
375  //Point to the specified SCM memory location
376  p = BA414E_GET_SCM_SLOT(slot);
377 
378  //Copy the scalar from the SCM memory
379  for(i = 0; i < length; i++)
380  {
381  dest[i] = p[i];
382  }
383 }
384 
385 
386 /**
387  * @brief Export multiple-precision integer
388  * @param[out] dest Pointer to the multiple-precision integer
389  * @param[in] slot SCM memory location
390  * @return Error code
391  **/
392 
393 error_t ba414eExportMpi(Mpi *dest, uint_t slot)
394 {
395  error_t error;
396  uint_t i;
397  uint_t length;
398  volatile uint32_t *p;
399 
400  //Point to the specified SCM memory location
401  p = BA414E_GET_SCM_SLOT(slot);
402 
403  //Skip trailing zeroes
404  for(length = 16; length > 0 && p[length - 1] == 0; length--)
405  {
406  }
407 
408  //Ajust the size of the multiple precision integer
409  error = mpiGrow(dest, length);
410 
411  //Check status code
412  if(!error)
413  {
414  //Copy the multiple-precision integer from the SCM memory
415  for(i = 0; i < length; i++)
416  {
417  dest->data[i] = p[i];
418  }
419 
420  //Pad the resulting value with zeroes
421  for(; i < dest->size; i++)
422  {
423  dest->data[i] = 0;
424  }
425 
426  //Set the sign
427  dest->sign = 1;
428  }
429 
430  //Return status code
431  return error;
432 }
433 
434 
435 #if (MPI_SUPPORT == ENABLED)
436 
437 /**
438  * @brief Modular exponentiation (regular calculation)
439  * @param[out] r Resulting integer R = A ^ E mod P
440  * @param[in] a Pointer to a multiple precision integer
441  * @param[in] e Exponent
442  * @param[in] p Modulus
443  * @return Error code
444  **/
445 
446 error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
447 {
448  error_t error;
449  uint_t aLen;
450  uint_t eLen;
451  uint_t pLen;
452  uint_t opSize;
453 
454  //Get the length of the integer, in words
455  aLen = mpiGetLength(a);
456  //Get the length of the exponent, in words
457  eLen = mpiGetLength(e);
458  //Get the length of the modulus, in words
459  pLen = mpiGetLength(p);
460 
461  //The accelerator supports operand lengths up to 512 bits
462  if(mpiIsOdd(p) && pLen <= 16 && aLen <= pLen && eLen <= pLen)
463  {
464  //Acquire exclusive access to the BA414E module
466 
467  //Determine the size of the operands
468  if(pLen <= 4)
469  {
470  opSize = PKCOMMAND_OPSIZE_128B;
471  }
472  else if(pLen <= 8)
473  {
474  opSize = PKCOMMAND_OPSIZE_256B;
475  }
476  else
477  {
478  opSize = PKCOMMAND_OPSIZE_512B;
479  }
480 
481  //Clear the SCM memory
482  ba414eClearScm();
483 
484  //Write all required parameters, operands and data into the SCM memory
485  ba414eImportMpi(p, BA414E_RSA_MOD_EXP_SLOT_P);
486  ba414eImportMpi(a, BA414E_RSA_MOD_EXP_SLOT_A);
487  ba414eImportMpi(e, BA414E_RSA_MOD_EXP_SLOT_E);
488 
489  //Specify locations where operands are stored in the SCM memory
490  PKCONFIG = (BA414E_RSA_MOD_EXP_SLOT_A << _PKCONFIG_OPPTRA_POSITION) |
491  (BA414E_RSA_MOD_EXP_SLOT_E << _PKCONFIG_OPPTRB_POSITION) |
492  (BA414E_RSA_MOD_EXP_SLOT_C << _PKCONFIG_OPPTRC_POSITION);
493 
494  //Specify the operation to be performed
495  PKCOMMAND = _PKCOMMAND_CALCR2_MASK | PKCOMMAND_OP_RSA_MOD_EXP | opSize;
496 
497  //Set the START signal in the control register
498  PKCONTROL = _PKCONTROL_START_MASK;
499 
500  //The START signal is automatically cleared when the operation is finished
501  while((PKSTATUS & _PKSTATUS_BUSY_MASK) != 0)
502  {
503  }
504 
505  //Read the result from the SCM memory
506  error = ba414eExportMpi(r, BA414E_RSA_MOD_EXP_SLOT_C);
507 
508  //Release exclusive access to the BA414E module
510  }
511  else
512  {
513  //Perform modular exponentiation
514  error = mpiExpMod(r, a, e, p);
515  }
516 
517  //Return status code
518  return error;
519 }
520 
521 #endif
522 #if (EC_SUPPORT == ENABLED)
523 
524 /**
525  * @brief Scalar multiplication (fast calculation)
526  * @param[in] curve Elliptic curve parameters
527  * @param[out] r Resulting point R = d.S
528  * @param[in] d An integer d such as 0 <= d < p
529  * @param[in] s EC point
530  * @return Error code
531  **/
532 
533 error_t ecMulFast(const EcCurve *curve, EcPoint3 *r, const uint32_t *d,
534  const EcPoint3 *s)
535 {
536  //Compute R = d.S
537  return ecMulRegular(curve, r, d, s);
538 }
539 
540 
541 /**
542  * @brief Scalar multiplication (regular calculation)
543  * @param[in] curve Elliptic curve parameters
544  * @param[out] r Resulting point R = d.S
545  * @param[in] d An integer d such as 0 <= d < q
546  * @param[in] s EC point
547  * @return Error code
548  **/
549 
550 error_t ecMulRegular(const EcCurve *curve, EcPoint3 *r, const uint32_t *d,
551  const EcPoint3 *s)
552 {
553  error_t error;
554  uint_t modLen;
555  uint_t orderLen;
556  uint_t opSize;
557 
558  //Get the length of the modulus, in words
559  modLen = (curve->fieldSize + 31) / 32;
560  //Get the length of the order, in words
561  orderLen = (curve->orderSize + 31) / 32;
562 
563  //The accelerator supports operand lengths up to 512 bits
564  if(modLen <= 4 && orderLen <= 4)
565  {
566  opSize = PKCOMMAND_OPSIZE_128B;
567  }
568  else if(modLen <= 8 && orderLen <= 8)
569  {
570  opSize = PKCOMMAND_OPSIZE_256B;
571  }
572  else if(modLen <= 16 && orderLen <= 16)
573  {
574  opSize = PKCOMMAND_OPSIZE_512B;
575  }
576  else
577  {
578  return ERROR_FAILURE;
579  }
580 
581  //Acquire exclusive access to the BA414E module
583 
584  //Clear the SCM memory
585  ba414eClearScm();
586 
587  //Write all required parameters, operands and data into the SCM memory
588  ba414eImportScalar(curve->p, modLen, BA414E_ECC_SLOT_P);
589  ba414eImportScalar(curve->q, orderLen, BA414E_ECC_SLOT_N);
590  ba414eImportScalar(curve->g.x, modLen, BA414E_ECC_SLOT_GX);
591  ba414eImportScalar(curve->g.y, modLen, BA414E_ECC_SLOT_GY);
592  ba414eImportScalar(curve->a, modLen, BA414E_ECC_SLOT_A);
593  ba414eImportScalar(curve->b, modLen, BA414E_ECC_SLOT_B);
594  ba414eImportScalar(s->x, modLen, BA414E_ECC_SLOT_P1X);
595  ba414eImportScalar(s->y, modLen, BA414E_ECC_SLOT_P1Y);
596  ba414eImportScalar(d, orderLen, BA414E_ECC_SLOT_K);
597 
598  //Specify locations where operands are stored in the SCM memory
599  PKCONFIG = (BA414E_ECC_SLOT_P1X << _PKCONFIG_OPPTRA_POSITION) |
600  (BA414E_ECC_SLOT_K << _PKCONFIG_OPPTRB_POSITION) |
601  (BA414E_ECC_SLOT_P3X << _PKCONFIG_OPPTRC_POSITION);
602 
603  //Specify the operation to be performed
604  PKCOMMAND = _PKCOMMAND_CALCR2_MASK | PKCOMMAND_OP_ECC_POINT_MUL | opSize;
605 
606  //Set the START signal in the control register
607  PKCONTROL = _PKCONTROL_START_MASK;
608 
609  //The START signal is automatically cleared when the operation is finished
610  while((PKSTATUS & _PKSTATUS_BUSY_MASK) != 0)
611  {
612  }
613 
614  //Point at the infinity?
615  if((PKSTATUS & _PKSTATUS_PXINF_MASK) != 0)
616  {
617  //Set R = (1, 1, 0)
621  }
622  else
623  {
624  //Copy the x-coordinate of the result
626  ba414eExportScalar(r->x, modLen, BA414E_ECC_SLOT_P3X);
627 
628  //Copy the y-coordinate of the result
630  ba414eExportScalar(r->y, modLen, BA414E_ECC_SLOT_P3Y);
631 
632  //Set the z-coordinate of the result
634  }
635 
636  //Release exclusive access to the BA414E module
638 
639  //Successful processing
640  return NO_ERROR;
641 }
642 
643 #endif
644 #if (ECDSA_SUPPORT == ENABLED)
645 
646 /**
647  * @brief ECDSA signature generation
648  * @param[in] prngAlgo PRNG algorithm
649  * @param[in] prngContext Pointer to the PRNG context
650  * @param[in] privateKey Signer's EC private key
651  * @param[in] digest Digest of the message to be signed
652  * @param[in] digestLen Length in octets of the digest
653  * @param[out] signature (R, S) integer pair
654  * @return Error code
655  **/
656 
657 error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext,
658  const EcPrivateKey *privateKey, const uint8_t *digest, size_t digestLen,
659  EcdsaSignature *signature)
660 {
661  error_t error;
662  uint_t modLen;
663  uint_t orderLen;
664  uint_t opSize;
665  uint32_t k[EC_MAX_ORDER_SIZE];
666  const EcCurve *curve;
667 
668  //Check parameters
669  if(privateKey == NULL || digest == NULL || signature == NULL)
671 
672  //Invalid elliptic curve?
673  if(privateKey->curve == NULL)
675 
676  //Get elliptic curve parameters
677  curve = privateKey->curve;
678 
679  //Get the length of the modulus, in words
680  modLen = (curve->fieldSize + 31) / 32;
681  //Get the length of the order, in words
682  orderLen = (curve->orderSize + 31) / 32;
683 
684  //The accelerator supports operand lengths up to 512 bits
685  if(modLen <= 4 && orderLen <= 4)
686  {
687  opSize = PKCOMMAND_OPSIZE_128B;
688  }
689  else if(modLen <= 8 && orderLen <= 8)
690  {
691  opSize = PKCOMMAND_OPSIZE_256B;
692  }
693  else if(modLen <= 16 && orderLen <= 16)
694  {
695  opSize = PKCOMMAND_OPSIZE_512B;
696  }
697  else
698  {
699  return ERROR_FAILURE;
700  }
701 
702  //Generate a random number k such as 0 < k < q - 1
703  error = ecScalarRand(curve, k, prngAlgo, prngContext);
704 
705  //Check status code
706  if(!error)
707  {
708  //Acquire exclusive access to the BA414E module
710 
711  //Clear the SCM memory
712  ba414eClearScm();
713 
714  //Write all required parameters, operands and data into the SCM memory
715  ba414eImportScalar(curve->p, modLen, BA414E_ECDSA_SLOT_P);
716  ba414eImportScalar(curve->q, orderLen, BA414E_ECDSA_SLOT_N);
717  ba414eImportScalar(curve->g.x, modLen, BA414E_ECDSA_SLOT_GX);
718  ba414eImportScalar(curve->g.y, modLen, BA414E_ECDSA_SLOT_GY);
719  ba414eImportScalar(curve->a, modLen, BA414E_ECDSA_SLOT_A);
720  ba414eImportScalar(curve->b, modLen, BA414E_ECDSA_SLOT_B);
721  ba414eImportScalar(privateKey->d, orderLen, BA414E_ECDSA_SLOT_D);
722  ba414eImportScalar(k, orderLen, BA414E_ECDSA_SLOT_K);
723 
724  //Keep the leftmost bits of the hash value
725  digestLen = MIN(digestLen, (curve->orderSize + 7) / 8);
726  //Load the hash value into the SCM memory
727  ba414eImportArray(digest, digestLen, BA414E_ECDSA_SLOT_H);
728 
729  //Clear PKCONFIG register
730  PKCONFIG = 0;
731  //Specify the operation to be performed
732  PKCOMMAND = _PKCOMMAND_CALCR2_MASK | PKCOMMAND_OP_ECDSA_SIGN_GEN | opSize;
733  //Set the START signal in the control register
734  PKCONTROL = _PKCONTROL_START_MASK;
735 
736  //The START signal is automatically cleared when the operation is finished
737  while((PKSTATUS & _PKSTATUS_BUSY_MASK) != 0)
738  {
739  }
740 
741  //Check status register
742  if((PKSTATUS & (_PKSTATUS_SIGINVAL_MASK | _PKSTATUS_CPLINVAL_MASK |
743  _PKSTATUS_PXINF_MASK | _PKSTATUS_PXNOC_MASK)) == 0)
744  {
745  //Save elliptic curve parameters
746  signature->curve = curve;
747 
748  //Copy integer R
749  ecScalarSetInt(signature->r, 0, EC_MAX_ORDER_SIZE);
750  ba414eExportScalar(signature->r, orderLen, BA414E_ECDSA_SLOT_R);
751 
752  //Copy integer S
753  ecScalarSetInt(signature->s, 0, EC_MAX_ORDER_SIZE);
754  ba414eExportScalar(signature->s, orderLen, BA414E_ECDSA_SLOT_S);
755  }
756  else
757  {
758  //Report an error
759  error = ERROR_FAILURE;
760  }
761 
762  //Release exclusive access to the BA414E module
764  }
765 
766  //Return status code
767  return error;
768 }
769 
770 
771 /**
772  * @brief ECDSA signature verification
773  * @param[in] publicKey Signer's EC public key
774  * @param[in] digest Digest of the message whose signature is to be verified
775  * @param[in] digestLen Length in octets of the digest
776  * @param[in] signature (R, S) integer pair
777  * @return Error code
778  **/
779 
780 error_t ecdsaVerifySignature(const EcPublicKey *publicKey,
781  const uint8_t *digest, size_t digestLen, const EcdsaSignature *signature)
782 {
783  error_t error;
784  uint_t modLen;
785  uint_t orderLen;
786  uint_t opSize;
787  const EcCurve *curve;
788 
789  //Check parameters
790  if(publicKey == NULL || digest == NULL || signature == NULL)
792 
793  //Invalid elliptic curve?
794  if(publicKey->curve == NULL)
796 
797  //Verify that the public key is on the curve
798  if(!ecIsPointAffine(publicKey->curve, &publicKey->q))
799  {
801  }
802 
803  //The verifier shall check that 0 < r < q
804  if(ecScalarCompInt(signature->r, 0, EC_MAX_ORDER_SIZE) <= 0 ||
805  ecScalarComp(signature->r, publicKey->curve->q, EC_MAX_ORDER_SIZE) >= 0)
806  {
807  //If the condition is violated, the signature shall be rejected as invalid
809  }
810 
811  //The verifier shall check that 0 < s < q
812  if(ecScalarCompInt(signature->s, 0, EC_MAX_ORDER_SIZE) <= 0 ||
813  ecScalarComp(signature->s, publicKey->curve->q, EC_MAX_ORDER_SIZE) >= 0)
814  {
815  //If the condition is violated, the signature shall be rejected as invalid
817  }
818 
819  //Get elliptic curve parameters
820  curve = publicKey->curve;
821 
822  //Get the length of the modulus, in words
823  modLen = (curve->fieldSize + 31) / 32;
824  //Get the length of the order, in words
825  orderLen = (curve->orderSize + 31) / 32;
826 
827  //The accelerator supports operand lengths up to 512 bits
828  if(modLen <= 4 && orderLen <= 4)
829  {
830  opSize = PKCOMMAND_OPSIZE_128B;
831  }
832  else if(modLen <= 8 && orderLen <= 8)
833  {
834  opSize = PKCOMMAND_OPSIZE_256B;
835  }
836  else if(modLen <= 16 && orderLen <= 16)
837  {
838  opSize = PKCOMMAND_OPSIZE_512B;
839  }
840  else
841  {
842  return ERROR_FAILURE;
843  }
844 
845  //Acquire exclusive access to the BA414E module
847 
848  //Clear the SCM memory
849  ba414eClearScm();
850 
851  //Write all required parameters, operands and data into the SCM memory
852  ba414eImportScalar(curve->p, modLen, BA414E_ECDSA_SLOT_P);
853  ba414eImportScalar(curve->q, orderLen, BA414E_ECDSA_SLOT_N);
854  ba414eImportScalar(curve->g.x, modLen, BA414E_ECDSA_SLOT_GX);
855  ba414eImportScalar(curve->g.y, modLen, BA414E_ECDSA_SLOT_GY);
856  ba414eImportScalar(curve->a, modLen, BA414E_ECDSA_SLOT_A);
857  ba414eImportScalar(curve->b, modLen, BA414E_ECDSA_SLOT_B);
858  ba414eImportScalar(publicKey->q.x, modLen, BA414E_ECDSA_SLOT_QX);
859  ba414eImportScalar(publicKey->q.y, modLen, BA414E_ECDSA_SLOT_QY);
860  ba414eImportScalar(signature->r, orderLen, BA414E_ECDSA_SLOT_R);
861  ba414eImportScalar(signature->s, orderLen, BA414E_ECDSA_SLOT_S);
862 
863  //Keep the leftmost bits of the hash value
864  digestLen = MIN(digestLen, (curve->orderSize + 7) / 8);
865  //Load the hash value into the SCM memory
866  ba414eImportArray(digest, digestLen, BA414E_ECDSA_SLOT_H);
867 
868  //Clear PKCONFIG register
869  PKCONFIG = 0;
870  //Specify the operation to be performed
871  PKCOMMAND = _PKCOMMAND_CALCR2_MASK | PKCOMMAND_OP_ECDSA_SIGN_VERIFY | opSize;
872  //Set the START signal in the control register
873  PKCONTROL = _PKCONTROL_START_MASK;
874 
875  //The START signal is automatically cleared when the operation is finished
876  while((PKSTATUS & _PKSTATUS_BUSY_MASK) != 0)
877  {
878  }
879 
880  //Check status register
881  if((PKSTATUS & (_PKSTATUS_SIGINVAL_MASK | _PKSTATUS_CPLINVAL_MASK |
882  _PKSTATUS_PXINF_MASK | _PKSTATUS_PXNOC_MASK)) == 0)
883  {
884  error = NO_ERROR;
885  }
886  else
887  {
888  error = ERROR_INVALID_SIGNATURE;
889  }
890 
891  //Release exclusive access to the BA414E module
893 
894  //Return status code
895  return error;
896 }
897 
898 #endif
899 #if (X25519_SUPPORT == ENABLED)
900 
901 /**
902  * @brief X25519 function (scalar multiplication on Curve25519)
903  * @param[out] r Output u-coordinate
904  * @param[in] k Input scalar
905  * @param[in] u Input u-coordinate
906  * @return Error code
907  **/
908 
909 error_t x25519(uint8_t *r, const uint8_t *k, const uint8_t *u)
910 {
911  volatile uint32_t *arg;
912 
913  //Acquire exclusive access to the BA414E module
915 
916  //Clear the SCM memory
917  ba414eClearScm();
918 
919  //Write the modulus into the SCM memory
921  arg[0] = 0xFFFFFFED;
922  arg[1] = 0xFFFFFFFF;
923  arg[2] = 0xFFFFFFFF;
924  arg[3] = 0xFFFFFFFF;
925  arg[4] = 0xFFFFFFFF;
926  arg[5] = 0xFFFFFFFF;
927  arg[6] = 0xFFFFFFFF;
928  arg[7] = 0x7FFFFFFF;
929 
930  //Write the input u-coordinate into the SCM memory
932  arg[0] = LOAD32LE(u);
933  arg[1] = LOAD32LE(u + 4);
934  arg[2] = LOAD32LE(u + 8);
935  arg[3] = LOAD32LE(u + 12);
936  arg[4] = LOAD32LE(u + 16);
937  arg[5] = LOAD32LE(u + 20);
938  arg[6] = LOAD32LE(u + 24);
939  arg[7] = LOAD32LE(u + 28);
940 
941  //Implementations must mask the most significant bit in the final byte
942  arg[7] &= 0x7FFFFFFF;
943 
944  //Write the pre-calculated value of (a - 2) / 4) into the SCM memory
946  arg[0] = 121665;
947  arg[1] = 0;
948  arg[2] = 0;
949  arg[3] = 0;
950  arg[4] = 0;
951  arg[5] = 0;
952  arg[6] = 0;
953  arg[7] = 0;
954 
955  //Write the scalar into the SCM memory
957  arg[0] = LOAD32LE(k);
958  arg[1] = LOAD32LE(k + 4);
959  arg[2] = LOAD32LE(k + 8);
960  arg[3] = LOAD32LE(k + 12);
961  arg[4] = LOAD32LE(k + 16);
962  arg[5] = LOAD32LE(k + 20);
963  arg[6] = LOAD32LE(k + 24);
964  arg[7] = LOAD32LE(k + 28);
965 
966  //Set the three least significant bits of the first byte and the most
967  //significant bit of the last to zero, set the second most significant
968  //bit of the last byte to 1
969  arg[0] &= 0xFFFFFFF8;
970  arg[7] &= 0x7FFFFFFF;
971  arg[7] |= 0x40000000;
972 
973  //Specify locations where operands are stored in the SCM memory
974  PKCONFIG = (BA414E_CURVE25519_SLOT_X1 << _PKCONFIG_OPPTRA_POSITION) |
975  (BA414E_CURVE25519_SLOT_K << _PKCONFIG_OPPTRB_POSITION) |
976  (BA414E_CURVE25519_SLOT_X3 << _PKCONFIG_OPPTRC_POSITION);
977 
978  //Specify the operation to be performed
979  PKCOMMAND = _PKCOMMAND_CALCR2_MASK | PKCOMMAND_OPSIZE_256B |
981 
982  //Set the START signal in the control register
983  PKCONTROL = _PKCONTROL_START_MASK;
984 
985  //The START signal is automatically cleared when the operation is finished
986  while((PKSTATUS & _PKSTATUS_BUSY_MASK) != 0)
987  {
988  }
989 
990  //Read the result from the SCM memory
992  STORE32LE(arg[0], r);
993  STORE32LE(arg[1], r + 4);
994  STORE32LE(arg[2], r + 8);
995  STORE32LE(arg[3], r + 12);
996  STORE32LE(arg[4], r + 16);
997  STORE32LE(arg[5], r + 20);
998  STORE32LE(arg[6], r + 24);
999  STORE32LE(arg[7], r + 28);
1000 
1001  //Release exclusive access to the BA414E module
1003 
1004  //Successful processing
1005  return NO_ERROR;
1006 }
1007 
1008 #endif
1009 #if (ED25519_SUPPORT == ENABLED)
1010 
1011 /**
1012  * @brief Scalar multiplication (regular calculation)
1013  * @param[in] state Pointer to the working state
1014  * @param[out] r Resulting point R = k * P
1015  * @param[in] k Input scalar
1016  * @param[in] p Input point
1017  **/
1018 
1020  const uint8_t *k, const Ed25519Point *p)
1021 {
1022  volatile uint32_t *arg;
1023 
1024  //Acquire exclusive access to the BA414E module
1026 
1027  //Clear the SCM memory
1028  ba414eClearScm();
1029 
1030  //Write the modulus into the SCM memory
1032  arg[0] = 0xFFFFFFED;
1033  arg[1] = 0xFFFFFFFF;
1034  arg[2] = 0xFFFFFFFF;
1035  arg[3] = 0xFFFFFFFF;
1036  arg[4] = 0xFFFFFFFF;
1037  arg[5] = 0xFFFFFFFF;
1038  arg[6] = 0xFFFFFFFF;
1039  arg[7] = 0x7FFFFFFF;
1040 
1041  //Write the pre-calculated value of D2 into the SCM memory
1043  arg[0] = 0xBE8FD3F4;
1044  arg[1] = 0x01DB17FD;
1045  arg[2] = 0x5F8C52E7;
1046  arg[3] = 0x21430EEF;
1047  arg[4] = 0x78310D20;
1048  arg[5] = 0xCB27240F;
1049  arg[6] = 0xE53F8A4D;
1050  arg[7] = 0x590456B4;
1051 
1052  //Write the x-coordinate of the input point into the SCM memory
1054  arg[0] = (p->x[1] << 29) | p->x[0];
1055  arg[1] = (p->x[2] << 26) | (p->x[1] >> 3);
1056  arg[2] = (p->x[3] << 23) | (p->x[2] >> 6);
1057  arg[3] = (p->x[4] << 20) | (p->x[3] >> 9);
1058  arg[4] = (p->x[5] << 17) | (p->x[4] >> 12);
1059  arg[5] = (p->x[6] << 14) | (p->x[5] >> 15);
1060  arg[6] = (p->x[7] << 11) | (p->x[6] >> 18);
1061  arg[7] = (p->x[8] << 8) | (p->x[7] >> 21);
1062 
1063  //Write the y-coordinate of the input point into the SCM memory
1065  arg[0] = (p->y[1] << 29) | p->y[0];
1066  arg[1] = (p->y[2] << 26) | (p->y[1] >> 3);
1067  arg[2] = (p->y[3] << 23) | (p->y[2] >> 6);
1068  arg[3] = (p->y[4] << 20) | (p->y[3] >> 9);
1069  arg[4] = (p->y[5] << 17) | (p->y[4] >> 12);
1070  arg[5] = (p->y[6] << 14) | (p->y[5] >> 15);
1071  arg[6] = (p->y[7] << 11) | (p->y[6] >> 18);
1072  arg[7] = (p->y[8] << 8) | (p->y[7] >> 21);
1073 
1074  //Write the scalar into the SCM memory
1076  arg[0] = LOAD32LE(k);
1077  arg[1] = LOAD32LE(k + 4);
1078  arg[2] = LOAD32LE(k + 8);
1079  arg[3] = LOAD32LE(k + 12);
1080  arg[4] = LOAD32LE(k + 16);
1081  arg[5] = LOAD32LE(k + 20);
1082  arg[6] = LOAD32LE(k + 24);
1083  arg[7] = LOAD32LE(k + 28);
1084 
1085  //Specify locations where operands are stored in the SCM memory
1086  PKCONFIG = (BA414E_ED25519_SLOT_PX << _PKCONFIG_OPPTRA_POSITION) |
1087  (BA414E_ED25519_SLOT_E << _PKCONFIG_OPPTRB_POSITION) |
1088  (BA414E_ED25519_SLOT_CX << _PKCONFIG_OPPTRC_POSITION);
1089 
1090  //Specify the operation to be performed
1091  PKCOMMAND = _PKCOMMAND_CALCR2_MASK | PKCOMMAND_OPSIZE_256B |
1093 
1094  //Set the START signal in the control register
1095  PKCONTROL = _PKCONTROL_START_MASK;
1096 
1097  //The START signal is automatically cleared when the operation is finished
1098  while((PKSTATUS & _PKSTATUS_BUSY_MASK) != 0)
1099  {
1100  }
1101 
1102  //Read the x-coordinate of the resulting point from the SCM memory
1104  r->x[0] = arg[0] & 0x1FFFFFFF;
1105  r->x[1] = (arg[0] >> 29) | ((arg[1] << 3) & 0x1FFFFFFF);
1106  r->x[2] = (arg[1] >> 26) | ((arg[2] << 6) & 0x1FFFFFFF);
1107  r->x[3] = (arg[2] >> 23) | ((arg[3] << 9) & 0x1FFFFFFF);
1108  r->x[4] = (arg[3] >> 20) | ((arg[4] << 12) & 0x1FFFFFFF);
1109  r->x[5] = (arg[4] >> 17) | ((arg[5] << 15) & 0x1FFFFFFF);
1110  r->x[6] = (arg[5] >> 14) | ((arg[6] << 18) & 0x1FFFFFFF);
1111  r->x[7] = (arg[6] >> 11) | ((arg[7] << 21) & 0x1FFFFFFF);
1112  r->x[8] = arg[7] >> 8;
1113 
1114  //Read the y-coordinate of the resulting point from the SCM memory
1116  r->y[0] = arg[0] & 0x1FFFFFFF;
1117  r->y[1] = (arg[0] >> 29) | ((arg[1] << 3) & 0x1FFFFFFF);
1118  r->y[2] = (arg[1] >> 26) | ((arg[2] << 6) & 0x1FFFFFFF);
1119  r->y[3] = (arg[2] >> 23) | ((arg[3] << 9) & 0x1FFFFFFF);
1120  r->y[4] = (arg[3] >> 20) | ((arg[4] << 12) & 0x1FFFFFFF);
1121  r->y[5] = (arg[4] >> 17) | ((arg[5] << 15) & 0x1FFFFFFF);
1122  r->y[6] = (arg[5] >> 14) | ((arg[6] << 18) & 0x1FFFFFFF);
1123  r->y[7] = (arg[6] >> 11) | ((arg[7] << 21) & 0x1FFFFFFF);
1124  r->y[8] = arg[7] >> 8;
1125 
1126  //Release exclusive access to the BA414E module
1128 
1129  //Calculate extended point representation
1130  curve25519SetInt(r->z, 1);
1131  curve25519Mul(r->t, r->x, r->y);
1132 }
1133 
1134 
1135 /**
1136  * @brief Twin multiplication
1137  * @param[in] state Pointer to the working state
1138  * @param[out] r Resulting point R = k1 * P + k2 * Q
1139  * @param[in] k1 First input scalar
1140  * @param[in] p First input point
1141  * @param[in] k2 Second input scalar
1142  * @param[in] q Second input point
1143  **/
1144 
1146  const uint8_t *k1, const Ed25519Point *p, const uint8_t *k2,
1147  const Ed25519Point *q)
1148 {
1149  Ed25519Point p1;
1150  Ed25519Point p2;
1151 
1152  //Reduce non-canonical values
1153  curve25519Canonicalize(p1.x, p->x);
1154  curve25519Canonicalize(p1.y, p->y);
1155  curve25519Canonicalize(p2.x, q->x);
1156  curve25519Canonicalize(p2.y, q->y);
1157 
1158  //Compute R = k1 * P + k2 * Q
1159  ed25519Mul(state, &p1, k1, &p1);
1160  ed25519Mul(state, &p2, k2, &p2);
1161  ed25519Add(state, r, &p1, &p2);
1162 }
1163 
1164 #endif
1165 #endif
__weak_func error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const EcPrivateKey *privateKey, const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
ECDSA signature generation.
Definition: ecdsa.c:509
#define BA414E_ECC_SLOT_GY
ECDSA signature.
Definition: ecdsa.h:63
#define mpiIsOdd(a)
Definition: mpi.h:78
Ed25519 elliptic curve (constant-time implementation)
#define BA414E_ECDSA_SLOT_H
void curve25519Canonicalize(int32_t *r, const int32_t *a)
Reduce non-canonical value.
Definition: curve25519.c:749
#define BA414E_RSA_MOD_EXP_SLOT_E
__weak_func error_t ecMulFast(const EcCurve *curve, EcPoint3 *r, const uint32_t *d, const EcPoint3 *s)
Scalar multiplication (fast calculation)
Definition: ec.c:1181
#define BA414E_ECDSA_SLOT_A
__weak_func void ed25519Mul(Ed25519SubState *state, Ed25519Point *r, const uint8_t *k, const Ed25519Point *p)
Scalar multiplication (regular calculation)
Definition: ed25519.c:573
Extended point representation.
Definition: ed25519.h:62
uint8_t a
Definition: ndp.h:411
Arbitrary precision integer.
Definition: mpi.h:102
#define BA414E_CURVE25519_SLOT_K
#define PrngAlgo
Definition: crypto.h:973
#define PKCOMMAND_OPSIZE_256B
#define BA414E_ECDSA_SLOT_B
ECDSA (Elliptic Curve Digital Signature Algorithm)
uint8_t p
Definition: ndp.h:300
#define BA414E_GET_SCM_SLOT(n)
const EcCurve * curve
Elliptic curve parameters.
Definition: ecdsa.h:64
const EcCurve * curve
Elliptic curve parameters.
Definition: ec.h:433
#define STORE32LE(a, p)
Definition: cpu_endian.h:279
#define EC_MAX_ORDER_SIZE
Definition: ec.h:315
#define BA414E_RSA_MOD_EXP_SLOT_A
int32_t y[9]
Definition: ed25519.h:64
OsMutex pic32mzCryptoMutex
#define PKCOMMAND_OP_RSA_MOD_EXP
#define PKCOMMAND_OP_ECC_POINT_MUL
#define BA414E_ECC_SLOT_P
uint32_t y[EC_MAX_MODULUS_SIZE]
y-coordinate
Definition: ec.h:400
PIC32MZ hardware cryptographic accelerator.
#define BA414E_ECDSA_SLOT_R
#define BA414E_ECC_SLOT_P3X
__weak_func error_t x25519(uint8_t *r, const uint8_t *k, const uint8_t *u)
X25519 function (scalar multiplication on Curve25519)
Definition: x25519.c:53
error_t ba414eInit(void)
uint8_t r
Definition: ndp.h:346
__weak_func void ed25519TwinMul(Ed25519SubState *state, Ed25519Point *r, const uint8_t *k1, const Ed25519Point *p, const uint8_t *k2, const Ed25519Point *q)
Twin multiplication.
Definition: ed25519.c:621
#define BA414E_ECDSA_SLOT_QY
#define BA414E_ECC_SLOT_P3Y
@ ERROR_INVALID_ELLIPTIC_CURVE
Definition: error.h:134
#define BA414E_ECDSA_SLOT_N
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define BA414E_ECDSA_SLOT_GX
error_t
Error codes.
Definition: error.h:43
#define BA414E_RSA_MOD_EXP_SLOT_C
#define BA414E_ED25519_SLOT_PX
Working state (scalar multiplication)
Definition: ed25519.h:75
#define BA414E_ECC_SLOT_B
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
#define BA414E_ECC_SLOT_GX
void ecScalarSetInt(uint32_t *a, uint32_t b, uint_t n)
Set integer value.
Definition: ec_misc.c:505
#define PKCOMMAND_OPSIZE_512B
#define PKCOMMAND_OP_ED25519_SCALAR_MUL
Helper routines for ECC.
#define PKCOMMAND_OP_ECDSA_SIGN_VERIFY
uint32_t r[EC_MAX_ORDER_SIZE]
Integer R.
Definition: ecdsa.h:65
General definitions for cryptographic algorithms.
#define BA414E_CURVE25519_SLOT_X3
RSA public-key cryptography standard.
#define PKCOMMAND_OPSIZE_128B
EC private key.
Definition: ec.h:432
uint8_t u
Definition: lldp_ext_med.h:213
uint8_t length
Definition: tcp.h:375
#define MIN(a, b)
Definition: os_port.h:63
#define BA414E_ECC_SLOT_P1Y
X25519 function implementation.
#define BA414E_ECDSA_SLOT_K
#define BA414E_ED25519_SLOT_CY
void curve25519SetInt(int32_t *a, int32_t b)
Set integer value.
Definition: curve25519.c:57
#define BA414E_ECDSA_SLOT_D
EC public key.
Definition: ec.h:421
__weak_func bool_t ecIsPointAffine(const EcCurve *curve, const EcPoint *s)
Check whether the affine point S is on the curve.
Definition: ec.c:798
uint_t mpiGetLength(const Mpi *a)
Get the actual length in words.
Definition: mpi.c:188
int32_t x[9]
Definition: ed25519.h:63
#define PKCOMMAND_OP_CURVE25519_POINT_MUL
uint32_t d[EC_MAX_ORDER_SIZE]
Private key.
Definition: ec.h:434
int_t ecScalarCompInt(const uint32_t *a, uint32_t b, uint_t n)
Compare integers.
Definition: ec_misc.c:374
#define BA414E_CURVE25519_SLOT_A24
#define BA414E_ED25519_SLOT_CX
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
uint_t size
Definition: mpi.h:104
EC point (projective coordinates)
Definition: ec.h:409
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
__weak_func error_t ecdsaVerifySignature(const EcPublicKey *publicKey, const uint8_t *digest, size_t digestLen, const EcdsaSignature *signature)
ECDSA signature verification.
Definition: ecdsa.c:655
void ba414eClearScm(void)
#define BA414E_ECDSA_SLOT_S
__weak_func error_t ecMulRegular(const EcCurve *curve, EcPoint3 *r, const uint32_t *d, const EcPoint3 *s)
Scalar multiplication (regular calculation)
Definition: ec.c:1312
EcPoint q
Public key.
Definition: ec.h:423
uint32_t s[EC_MAX_ORDER_SIZE]
Integer S.
Definition: ecdsa.h:66
#define BA414E_ECDSA_SLOT_P
#define BA414E_ECC_SLOT_N
error_t ecScalarRand(const EcCurve *curve, uint32_t *r, const PrngAlgo *prngAlgo, void *prngContext)
Generate a random value.
Definition: ec_misc.c:603
#define BA414E_ECDSA_SLOT_QX
uint8_t s
Definition: igmp_common.h:234
#define BA414E_ECDSA_SLOT_GY
PIC32MZ W1 public-key hardware accelerator (BA414E)
#define BA414E_ED25519_SLOT_D2
#define EcCurve
Definition: ec.h:346
#define BA414E_CURVE25519_SLOT_P
#define LOAD32LE(p)
Definition: cpu_endian.h:203
int_t ecScalarComp(const uint32_t *a, const uint32_t *b, uint_t n)
Compare integers.
Definition: ec_misc.c:337
#define BA414E_ED25519_SLOT_P
__weak_func void curve25519Mul(int32_t *r, const int32_t *a, const int32_t *b)
Modular multiplication.
Definition: curve25519.c:267
unsigned int uint_t
Definition: compiler_port.h:57
uint32_t x[EC_MAX_MODULUS_SIZE]
x-coordinate
Definition: ec.h:399
#define BA414E_RSA_MOD_EXP_SLOT_P
#define BA414E_CURVE25519_SLOT_X1
#define BA414E_ECC_SLOT_A
ECC (Elliptic Curve Cryptography)
#define BA414E_ECC_SLOT_P1X
@ ERROR_INVALID_SIGNATURE
Definition: error.h:228
mpi_word_t * data
Definition: mpi.h:106
error_t mpiGrow(Mpi *r, uint_t size)
Adjust the size of multiple precision integer.
Definition: mpi.c:102
const EcCurve * curve
Elliptic curve parameters.
Definition: ec.h:422
#define BA414E_ED25519_SLOT_PY
#define PKCOMMAND_OP_ECDSA_SIGN_GEN
error_t mpiExpMod(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation.
#define EC_MAX_MODULUS_SIZE
Definition: ec.h:284
@ NO_ERROR
Success.
Definition: error.h:44
error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation (regular calculation)
#define BA414E_ED25519_SLOT_E
Debugging facilities.
int_t sign
Definition: mpi.h:103
#define arraysize(a)
Definition: os_port.h:71
void ed25519Add(Ed25519SubState *state, Ed25519Point *r, const Ed25519Point *p, const Ed25519Point *q)
Point addition.
Definition: ed25519.c:685
#define BA414E_ECC_SLOT_K