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-2026 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.6.4
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 
644 /**
645  * @brief Twin multiplication
646  * @param[in] curve Elliptic curve parameters
647  * @param[out] r Resulting point R = d0.S + d1.T
648  * @param[in] d0 An integer d such as 0 <= d0 < p
649  * @param[in] s EC point
650  * @param[in] d1 An integer d such as 0 <= d1 < p
651  * @param[in] t EC point
652  * @return Error code
653  **/
654 
655 error_t ecTwinMul(const EcCurve *curve, EcPoint3 *r, const uint32_t *d0,
656  const EcPoint3 *s, const uint32_t *d1, const EcPoint3 *t)
657 {
658  error_t error;
659  EcPoint3 u;
660 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
661  EcState *state;
662 #else
663  EcState state[1];
664 #endif
665 
666 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
667  //Allocate working state
668  state = cryptoAllocMem(sizeof(EcState));
669  //Failed to allocate memory?
670  if(state == NULL)
671  return ERROR_OUT_OF_MEMORY;
672 #endif
673 
674  //Initialize working state
675  osMemset(state, 0, sizeof(EcState));
676  //Save elliptic curve parameters
677  state->curve = curve;
678 
679  //Compute d0.S
680  error = ecMulFast(curve, r, d0, s);
681 
682  //Check status code
683  if(!error)
684  {
685  //Compute d1.T
686  error = ecMulFast(curve, &u, d1, t);
687  }
688 
689  //Check status code
690  if(!error)
691  {
692  //Compute d0.S + d1.T
693  ecFullAdd(state, r, r, &u);
694  }
695 
696  //Return status code
697  return error;
698 }
699 
700 #endif
701 #if (ECDSA_SUPPORT == ENABLED)
702 
703 /**
704  * @brief ECDSA signature generation
705  * @param[in] prngAlgo PRNG algorithm
706  * @param[in] prngContext Pointer to the PRNG context
707  * @param[in] privateKey Signer's EC private key
708  * @param[in] digest Digest of the message to be signed
709  * @param[in] digestLen Length in octets of the digest
710  * @param[out] signature (R, S) integer pair
711  * @return Error code
712  **/
713 
714 error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext,
715  const EcPrivateKey *privateKey, const uint8_t *digest, size_t digestLen,
716  EcdsaSignature *signature)
717 {
718  error_t error;
719  uint_t modLen;
720  uint_t orderLen;
721  uint_t opSize;
722  uint32_t k[EC_MAX_ORDER_SIZE];
723  const EcCurve *curve;
724 
725  //Check parameters
726  if(privateKey == NULL || digest == NULL || signature == NULL)
728 
729  //Invalid elliptic curve?
730  if(privateKey->curve == NULL)
732 
733  //Get elliptic curve parameters
734  curve = privateKey->curve;
735 
736  //Get the length of the modulus, in words
737  modLen = (curve->fieldSize + 31) / 32;
738  //Get the length of the order, in words
739  orderLen = (curve->orderSize + 31) / 32;
740 
741  //The accelerator supports operand lengths up to 512 bits
742  if(modLen <= 4 && orderLen <= 4)
743  {
744  opSize = PKCOMMAND_OPSIZE_128B;
745  }
746  else if(modLen <= 8 && orderLen <= 8)
747  {
748  opSize = PKCOMMAND_OPSIZE_256B;
749  }
750  else if(modLen <= 16 && orderLen <= 16)
751  {
752  opSize = PKCOMMAND_OPSIZE_512B;
753  }
754  else
755  {
756  return ERROR_FAILURE;
757  }
758 
759  //Generate a random number k such as 0 < k < q - 1
760  error = ecScalarRand(curve, k, prngAlgo, prngContext);
761 
762  //Check status code
763  if(!error)
764  {
765  //Acquire exclusive access to the BA414E module
767 
768  //Clear the SCM memory
769  ba414eClearScm();
770 
771  //Write all required parameters, operands and data into the SCM memory
772  ba414eImportScalar(curve->p, modLen, BA414E_ECDSA_SLOT_P);
773  ba414eImportScalar(curve->q, orderLen, BA414E_ECDSA_SLOT_N);
774  ba414eImportScalar(curve->g.x, modLen, BA414E_ECDSA_SLOT_GX);
775  ba414eImportScalar(curve->g.y, modLen, BA414E_ECDSA_SLOT_GY);
776  ba414eImportScalar(curve->a, modLen, BA414E_ECDSA_SLOT_A);
777  ba414eImportScalar(curve->b, modLen, BA414E_ECDSA_SLOT_B);
778  ba414eImportScalar(privateKey->d, orderLen, BA414E_ECDSA_SLOT_D);
779  ba414eImportScalar(k, orderLen, BA414E_ECDSA_SLOT_K);
780 
781  //Keep the leftmost bits of the hash value
782  digestLen = MIN(digestLen, (curve->orderSize + 7) / 8);
783  //Load the hash value into the SCM memory
784  ba414eImportArray(digest, digestLen, BA414E_ECDSA_SLOT_H);
785 
786  //Clear PKCONFIG register
787  PKCONFIG = 0;
788  //Specify the operation to be performed
789  PKCOMMAND = _PKCOMMAND_CALCR2_MASK | PKCOMMAND_OP_ECDSA_SIGN_GEN | opSize;
790  //Set the START signal in the control register
791  PKCONTROL = _PKCONTROL_START_MASK;
792 
793  //The START signal is automatically cleared when the operation is finished
794  while((PKSTATUS & _PKSTATUS_BUSY_MASK) != 0)
795  {
796  }
797 
798  //Check status register
799  if((PKSTATUS & (_PKSTATUS_SIGINVAL_MASK | _PKSTATUS_CPLINVAL_MASK |
800  _PKSTATUS_PXINF_MASK | _PKSTATUS_PXNOC_MASK)) == 0)
801  {
802  //Save elliptic curve parameters
803  signature->curve = curve;
804 
805  //Copy integer R
806  ecScalarSetInt(signature->r, 0, EC_MAX_ORDER_SIZE);
807  ba414eExportScalar(signature->r, orderLen, BA414E_ECDSA_SLOT_R);
808 
809  //Copy integer S
810  ecScalarSetInt(signature->s, 0, EC_MAX_ORDER_SIZE);
811  ba414eExportScalar(signature->s, orderLen, BA414E_ECDSA_SLOT_S);
812  }
813  else
814  {
815  //Report an error
816  error = ERROR_FAILURE;
817  }
818 
819  //Release exclusive access to the BA414E module
821  }
822 
823  //Return status code
824  return error;
825 }
826 
827 
828 /**
829  * @brief ECDSA signature verification
830  * @param[in] publicKey Signer's EC public key
831  * @param[in] digest Digest of the message whose signature is to be verified
832  * @param[in] digestLen Length in octets of the digest
833  * @param[in] signature (R, S) integer pair
834  * @return Error code
835  **/
836 
837 error_t ecdsaVerifySignature(const EcPublicKey *publicKey,
838  const uint8_t *digest, size_t digestLen, const EcdsaSignature *signature)
839 {
840  error_t error;
841  uint_t modLen;
842  uint_t orderLen;
843  uint_t opSize;
844  const EcCurve *curve;
845 
846  //Check parameters
847  if(publicKey == NULL || digest == NULL || signature == NULL)
849 
850  //Invalid elliptic curve?
851  if(publicKey->curve == NULL)
853 
854  //Verify that the public key is on the curve
855  if(!ecIsPointAffine(publicKey->curve, &publicKey->q))
856  {
858  }
859 
860  //The verifier shall check that 0 < r < q
861  if(ecScalarCompInt(signature->r, 0, EC_MAX_ORDER_SIZE) <= 0 ||
862  ecScalarComp(signature->r, publicKey->curve->q, EC_MAX_ORDER_SIZE) >= 0)
863  {
864  //If the condition is violated, the signature shall be rejected as invalid
866  }
867 
868  //The verifier shall check that 0 < s < q
869  if(ecScalarCompInt(signature->s, 0, EC_MAX_ORDER_SIZE) <= 0 ||
870  ecScalarComp(signature->s, publicKey->curve->q, EC_MAX_ORDER_SIZE) >= 0)
871  {
872  //If the condition is violated, the signature shall be rejected as invalid
874  }
875 
876  //Get elliptic curve parameters
877  curve = publicKey->curve;
878 
879  //Get the length of the modulus, in words
880  modLen = (curve->fieldSize + 31) / 32;
881  //Get the length of the order, in words
882  orderLen = (curve->orderSize + 31) / 32;
883 
884  //The accelerator supports operand lengths up to 512 bits
885  if(modLen <= 4 && orderLen <= 4)
886  {
887  opSize = PKCOMMAND_OPSIZE_128B;
888  }
889  else if(modLen <= 8 && orderLen <= 8)
890  {
891  opSize = PKCOMMAND_OPSIZE_256B;
892  }
893  else if(modLen <= 16 && orderLen <= 16)
894  {
895  opSize = PKCOMMAND_OPSIZE_512B;
896  }
897  else
898  {
899  return ERROR_FAILURE;
900  }
901 
902  //Acquire exclusive access to the BA414E module
904 
905  //Clear the SCM memory
906  ba414eClearScm();
907 
908  //Write all required parameters, operands and data into the SCM memory
909  ba414eImportScalar(curve->p, modLen, BA414E_ECDSA_SLOT_P);
910  ba414eImportScalar(curve->q, orderLen, BA414E_ECDSA_SLOT_N);
911  ba414eImportScalar(curve->g.x, modLen, BA414E_ECDSA_SLOT_GX);
912  ba414eImportScalar(curve->g.y, modLen, BA414E_ECDSA_SLOT_GY);
913  ba414eImportScalar(curve->a, modLen, BA414E_ECDSA_SLOT_A);
914  ba414eImportScalar(curve->b, modLen, BA414E_ECDSA_SLOT_B);
915  ba414eImportScalar(publicKey->q.x, modLen, BA414E_ECDSA_SLOT_QX);
916  ba414eImportScalar(publicKey->q.y, modLen, BA414E_ECDSA_SLOT_QY);
917  ba414eImportScalar(signature->r, orderLen, BA414E_ECDSA_SLOT_R);
918  ba414eImportScalar(signature->s, orderLen, BA414E_ECDSA_SLOT_S);
919 
920  //Keep the leftmost bits of the hash value
921  digestLen = MIN(digestLen, (curve->orderSize + 7) / 8);
922  //Load the hash value into the SCM memory
923  ba414eImportArray(digest, digestLen, BA414E_ECDSA_SLOT_H);
924 
925  //Clear PKCONFIG register
926  PKCONFIG = 0;
927  //Specify the operation to be performed
928  PKCOMMAND = _PKCOMMAND_CALCR2_MASK | PKCOMMAND_OP_ECDSA_SIGN_VERIFY | opSize;
929  //Set the START signal in the control register
930  PKCONTROL = _PKCONTROL_START_MASK;
931 
932  //The START signal is automatically cleared when the operation is finished
933  while((PKSTATUS & _PKSTATUS_BUSY_MASK) != 0)
934  {
935  }
936 
937  //Check status register
938  if((PKSTATUS & (_PKSTATUS_SIGINVAL_MASK | _PKSTATUS_CPLINVAL_MASK |
939  _PKSTATUS_PXINF_MASK | _PKSTATUS_PXNOC_MASK)) == 0)
940  {
941  error = NO_ERROR;
942  }
943  else
944  {
945  error = ERROR_INVALID_SIGNATURE;
946  }
947 
948  //Release exclusive access to the BA414E module
950 
951  //Return status code
952  return error;
953 }
954 
955 #endif
956 #if (X25519_SUPPORT == ENABLED)
957 
958 /**
959  * @brief X25519 function (scalar multiplication on Curve25519)
960  * @param[out] r Output u-coordinate
961  * @param[in] k Input scalar
962  * @param[in] u Input u-coordinate
963  * @return Error code
964  **/
965 
966 error_t x25519(uint8_t *r, const uint8_t *k, const uint8_t *u)
967 {
968  volatile uint32_t *arg;
969 
970  //Acquire exclusive access to the BA414E module
972 
973  //Clear the SCM memory
974  ba414eClearScm();
975 
976  //Write the modulus into the SCM memory
978  arg[0] = 0xFFFFFFED;
979  arg[1] = 0xFFFFFFFF;
980  arg[2] = 0xFFFFFFFF;
981  arg[3] = 0xFFFFFFFF;
982  arg[4] = 0xFFFFFFFF;
983  arg[5] = 0xFFFFFFFF;
984  arg[6] = 0xFFFFFFFF;
985  arg[7] = 0x7FFFFFFF;
986 
987  //Write the input u-coordinate into the SCM memory
989  arg[0] = LOAD32LE(u);
990  arg[1] = LOAD32LE(u + 4);
991  arg[2] = LOAD32LE(u + 8);
992  arg[3] = LOAD32LE(u + 12);
993  arg[4] = LOAD32LE(u + 16);
994  arg[5] = LOAD32LE(u + 20);
995  arg[6] = LOAD32LE(u + 24);
996  arg[7] = LOAD32LE(u + 28);
997 
998  //Implementations must mask the most significant bit in the final byte
999  arg[7] &= 0x7FFFFFFF;
1000 
1001  //Write the pre-calculated value of (a - 2) / 4) into the SCM memory
1003  arg[0] = 121665;
1004  arg[1] = 0;
1005  arg[2] = 0;
1006  arg[3] = 0;
1007  arg[4] = 0;
1008  arg[5] = 0;
1009  arg[6] = 0;
1010  arg[7] = 0;
1011 
1012  //Write the scalar into the SCM memory
1014  arg[0] = LOAD32LE(k);
1015  arg[1] = LOAD32LE(k + 4);
1016  arg[2] = LOAD32LE(k + 8);
1017  arg[3] = LOAD32LE(k + 12);
1018  arg[4] = LOAD32LE(k + 16);
1019  arg[5] = LOAD32LE(k + 20);
1020  arg[6] = LOAD32LE(k + 24);
1021  arg[7] = LOAD32LE(k + 28);
1022 
1023  //Set the three least significant bits of the first byte and the most
1024  //significant bit of the last to zero, set the second most significant
1025  //bit of the last byte to 1
1026  arg[0] &= 0xFFFFFFF8;
1027  arg[7] &= 0x7FFFFFFF;
1028  arg[7] |= 0x40000000;
1029 
1030  //Specify locations where operands are stored in the SCM memory
1031  PKCONFIG = (BA414E_CURVE25519_SLOT_X1 << _PKCONFIG_OPPTRA_POSITION) |
1032  (BA414E_CURVE25519_SLOT_K << _PKCONFIG_OPPTRB_POSITION) |
1033  (BA414E_CURVE25519_SLOT_X3 << _PKCONFIG_OPPTRC_POSITION);
1034 
1035  //Specify the operation to be performed
1036  PKCOMMAND = _PKCOMMAND_CALCR2_MASK | PKCOMMAND_OPSIZE_256B |
1038 
1039  //Set the START signal in the control register
1040  PKCONTROL = _PKCONTROL_START_MASK;
1041 
1042  //The START signal is automatically cleared when the operation is finished
1043  while((PKSTATUS & _PKSTATUS_BUSY_MASK) != 0)
1044  {
1045  }
1046 
1047  //Read the result from the SCM memory
1049  STORE32LE(arg[0], r);
1050  STORE32LE(arg[1], r + 4);
1051  STORE32LE(arg[2], r + 8);
1052  STORE32LE(arg[3], r + 12);
1053  STORE32LE(arg[4], r + 16);
1054  STORE32LE(arg[5], r + 20);
1055  STORE32LE(arg[6], r + 24);
1056  STORE32LE(arg[7], r + 28);
1057 
1058  //Release exclusive access to the BA414E module
1060 
1061  //Successful processing
1062  return NO_ERROR;
1063 }
1064 
1065 #endif
1066 #if (ED25519_SUPPORT == ENABLED)
1067 
1068 /**
1069  * @brief Scalar multiplication (regular calculation)
1070  * @param[in] state Pointer to the working state
1071  * @param[out] r Resulting point R = k * P
1072  * @param[in] k Input scalar
1073  * @param[in] p Input point
1074  **/
1075 
1077  const uint8_t *k, const Ed25519Point *p)
1078 {
1079  volatile uint32_t *arg;
1080 
1081  //Acquire exclusive access to the BA414E module
1083 
1084  //Clear the SCM memory
1085  ba414eClearScm();
1086 
1087  //Write the modulus into the SCM memory
1089  arg[0] = 0xFFFFFFED;
1090  arg[1] = 0xFFFFFFFF;
1091  arg[2] = 0xFFFFFFFF;
1092  arg[3] = 0xFFFFFFFF;
1093  arg[4] = 0xFFFFFFFF;
1094  arg[5] = 0xFFFFFFFF;
1095  arg[6] = 0xFFFFFFFF;
1096  arg[7] = 0x7FFFFFFF;
1097 
1098  //Write the pre-calculated value of D2 into the SCM memory
1100  arg[0] = 0xBE8FD3F4;
1101  arg[1] = 0x01DB17FD;
1102  arg[2] = 0x5F8C52E7;
1103  arg[3] = 0x21430EEF;
1104  arg[4] = 0x78310D20;
1105  arg[5] = 0xCB27240F;
1106  arg[6] = 0xE53F8A4D;
1107  arg[7] = 0x590456B4;
1108 
1109  //Write the x-coordinate of the input point into the SCM memory
1111  arg[0] = (p->x[1] << 29) | p->x[0];
1112  arg[1] = (p->x[2] << 26) | (p->x[1] >> 3);
1113  arg[2] = (p->x[3] << 23) | (p->x[2] >> 6);
1114  arg[3] = (p->x[4] << 20) | (p->x[3] >> 9);
1115  arg[4] = (p->x[5] << 17) | (p->x[4] >> 12);
1116  arg[5] = (p->x[6] << 14) | (p->x[5] >> 15);
1117  arg[6] = (p->x[7] << 11) | (p->x[6] >> 18);
1118  arg[7] = (p->x[8] << 8) | (p->x[7] >> 21);
1119 
1120  //Write the y-coordinate of the input point into the SCM memory
1122  arg[0] = (p->y[1] << 29) | p->y[0];
1123  arg[1] = (p->y[2] << 26) | (p->y[1] >> 3);
1124  arg[2] = (p->y[3] << 23) | (p->y[2] >> 6);
1125  arg[3] = (p->y[4] << 20) | (p->y[3] >> 9);
1126  arg[4] = (p->y[5] << 17) | (p->y[4] >> 12);
1127  arg[5] = (p->y[6] << 14) | (p->y[5] >> 15);
1128  arg[6] = (p->y[7] << 11) | (p->y[6] >> 18);
1129  arg[7] = (p->y[8] << 8) | (p->y[7] >> 21);
1130 
1131  //Write the scalar into the SCM memory
1133  arg[0] = LOAD32LE(k);
1134  arg[1] = LOAD32LE(k + 4);
1135  arg[2] = LOAD32LE(k + 8);
1136  arg[3] = LOAD32LE(k + 12);
1137  arg[4] = LOAD32LE(k + 16);
1138  arg[5] = LOAD32LE(k + 20);
1139  arg[6] = LOAD32LE(k + 24);
1140  arg[7] = LOAD32LE(k + 28);
1141 
1142  //Specify locations where operands are stored in the SCM memory
1143  PKCONFIG = (BA414E_ED25519_SLOT_PX << _PKCONFIG_OPPTRA_POSITION) |
1144  (BA414E_ED25519_SLOT_E << _PKCONFIG_OPPTRB_POSITION) |
1145  (BA414E_ED25519_SLOT_CX << _PKCONFIG_OPPTRC_POSITION);
1146 
1147  //Specify the operation to be performed
1148  PKCOMMAND = _PKCOMMAND_CALCR2_MASK | PKCOMMAND_OPSIZE_256B |
1150 
1151  //Set the START signal in the control register
1152  PKCONTROL = _PKCONTROL_START_MASK;
1153 
1154  //The START signal is automatically cleared when the operation is finished
1155  while((PKSTATUS & _PKSTATUS_BUSY_MASK) != 0)
1156  {
1157  }
1158 
1159  //Read the x-coordinate of the resulting point from the SCM memory
1161  r->x[0] = arg[0] & 0x1FFFFFFF;
1162  r->x[1] = (arg[0] >> 29) | ((arg[1] << 3) & 0x1FFFFFFF);
1163  r->x[2] = (arg[1] >> 26) | ((arg[2] << 6) & 0x1FFFFFFF);
1164  r->x[3] = (arg[2] >> 23) | ((arg[3] << 9) & 0x1FFFFFFF);
1165  r->x[4] = (arg[3] >> 20) | ((arg[4] << 12) & 0x1FFFFFFF);
1166  r->x[5] = (arg[4] >> 17) | ((arg[5] << 15) & 0x1FFFFFFF);
1167  r->x[6] = (arg[5] >> 14) | ((arg[6] << 18) & 0x1FFFFFFF);
1168  r->x[7] = (arg[6] >> 11) | ((arg[7] << 21) & 0x1FFFFFFF);
1169  r->x[8] = arg[7] >> 8;
1170 
1171  //Read the y-coordinate of the resulting point from the SCM memory
1173  r->y[0] = arg[0] & 0x1FFFFFFF;
1174  r->y[1] = (arg[0] >> 29) | ((arg[1] << 3) & 0x1FFFFFFF);
1175  r->y[2] = (arg[1] >> 26) | ((arg[2] << 6) & 0x1FFFFFFF);
1176  r->y[3] = (arg[2] >> 23) | ((arg[3] << 9) & 0x1FFFFFFF);
1177  r->y[4] = (arg[3] >> 20) | ((arg[4] << 12) & 0x1FFFFFFF);
1178  r->y[5] = (arg[4] >> 17) | ((arg[5] << 15) & 0x1FFFFFFF);
1179  r->y[6] = (arg[5] >> 14) | ((arg[6] << 18) & 0x1FFFFFFF);
1180  r->y[7] = (arg[6] >> 11) | ((arg[7] << 21) & 0x1FFFFFFF);
1181  r->y[8] = arg[7] >> 8;
1182 
1183  //Release exclusive access to the BA414E module
1185 
1186  //Calculate extended point representation
1187  curve25519SetInt(r->z, 1);
1188  curve25519Mul(r->t, r->x, r->y);
1189 }
1190 
1191 
1192 /**
1193  * @brief Twin multiplication
1194  * @param[in] state Pointer to the working state
1195  * @param[out] r Resulting point R = k1 * P + k2 * Q
1196  * @param[in] k1 First input scalar
1197  * @param[in] p First input point
1198  * @param[in] k2 Second input scalar
1199  * @param[in] q Second input point
1200  **/
1201 
1203  const uint8_t *k1, const Ed25519Point *p, const uint8_t *k2,
1204  const Ed25519Point *q)
1205 {
1206  Ed25519Point p1;
1207  Ed25519Point p2;
1208 
1209  //Reduce non-canonical values
1210  curve25519Canonicalize(p1.x, p->x);
1211  curve25519Canonicalize(p1.y, p->y);
1212  curve25519Canonicalize(p2.x, q->x);
1213  curve25519Canonicalize(p2.y, q->y);
1214 
1215  //Compute R = k1 * P + k2 * Q
1216  ed25519Mul(state, &p1, k1, &p1);
1217  ed25519Mul(state, &p2, k2, &p2);
1218  ed25519Add(state, r, &p1, &p2);
1219 }
1220 
1221 #endif
1222 #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:495
#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:1223
#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:574
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:1049
#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
uint8_t t
Definition: lldp_ext_med.h:212
void ecFullAdd(EcState *state, EcPoint3 *r, const EcPoint3 *s, const EcPoint3 *t)
Point addition.
Definition: ec.c:1136
#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
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
#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)
__weak_func error_t ecTwinMul(const EcCurve *curve, EcPoint3 *r, const uint32_t *d0, const EcPoint3 *s, const uint32_t *d1, const EcPoint3 *t)
Twin multiplication.
Definition: ec.c:1460
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:622
#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:840
uint_t mpiGetLength(const Mpi *a)
Get the actual length in words.
Definition: mpi.c:189
const EcCurve * curve
Definition: ec.h:446
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
Working state (point addition/subtraction/doubling)
Definition: ec.h:445
#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:951
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:1354
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 cryptoAllocMem(size)
Definition: crypto.h:870
#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 osMemset(p, value, length)
Definition: os_port.h:141
#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:103
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:686
#define BA414E_ECC_SLOT_K