1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** NetX Crypto Component */
17 /** */
18 /** Elliptic Curve */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #include "nx_crypto_ec.h"
24
25 /* secp192r1 */
26 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp192r1_p[] =
27 {
28
29 /* p = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF FFFFFFFF */
30 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
31 HN_ULONG_TO_UBASE(0xFFFFFFFE), HN_ULONG_TO_UBASE(0xFFFFFFFF),
32 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF)
33 };
34 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp192r1_a[] =
35 {
36
37 /* a = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF FFFFFFFC */
38 HN_ULONG_TO_UBASE(0xFFFFFFFC), HN_ULONG_TO_UBASE(0xFFFFFFFF),
39 HN_ULONG_TO_UBASE(0xFFFFFFFE), HN_ULONG_TO_UBASE(0xFFFFFFFF),
40 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF)
41 };
42 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp192r1_b[] =
43 {
44
45 /* b = 64210519 E59C80E7 0FA7E9AB 72243049 FEB8DEEC C146B9B1 */
46 HN_ULONG_TO_UBASE(0xC146B9B1), HN_ULONG_TO_UBASE(0xFEB8DEEC),
47 HN_ULONG_TO_UBASE(0x72243049), HN_ULONG_TO_UBASE(0x0FA7E9AB),
48 HN_ULONG_TO_UBASE(0xE59C80E7), HN_ULONG_TO_UBASE(0x64210519)
49 };
50 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp192r1_gx[] =
51 {
52
53 /* G.x = 188DA80E B03090F6 7CBF20EB 43A18800 F4FF0AFD 82FF1012 */
54 HN_ULONG_TO_UBASE(0x82FF1012), HN_ULONG_TO_UBASE(0xF4FF0AFD),
55 HN_ULONG_TO_UBASE(0x43A18800), HN_ULONG_TO_UBASE(0x7CBF20EB),
56 HN_ULONG_TO_UBASE(0xB03090F6), HN_ULONG_TO_UBASE(0x188DA80E)
57 };
58 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp192r1_gy[] =
59 {
60
61 /* G.y = 07192B95 FFC8DA78 631011ED 6B24CDD5 73F977A1 1E794811*/
62 HN_ULONG_TO_UBASE(0x1E794811), HN_ULONG_TO_UBASE(0x73F977A1),
63 HN_ULONG_TO_UBASE(0x6B24CDD5), HN_ULONG_TO_UBASE(0x631011ED),
64 HN_ULONG_TO_UBASE(0xFFC8DA78), HN_ULONG_TO_UBASE(0x07192B95)
65 };
66 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp192r1_n[] =
67 {
68
69 /* n = FFFFFFFF FFFFFFFF FFFFFFFF 99DEF836 146BC9B1 B4D22831 */
70 HN_ULONG_TO_UBASE(0xB4D22831), HN_ULONG_TO_UBASE(0x146BC9B1),
71 HN_ULONG_TO_UBASE(0x99DEF836), HN_ULONG_TO_UBASE(0xFFFFFFFF),
72 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF)
73 };
74 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp192r1_h[] =
75 {
76
77 /* h = 01 */
78 HN_ULONG_TO_UBASE(0x00000001)
79 };
80
81 /* secp224r1 */
82 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp224r1_p[] =
83 {
84
85 /* p = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 00000000 00000001 */
86 HN_ULONG_TO_UBASE(0x00000001), HN_ULONG_TO_UBASE(0x00000000),
87 HN_ULONG_TO_UBASE(0x00000000), HN_ULONG_TO_UBASE(0xFFFFFFFF),
88 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
89 HN_ULONG_TO_UBASE(0xFFFFFFFF)
90 };
91 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp224r1_a[] =
92 {
93
94 /* a = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFE */
95 HN_ULONG_TO_UBASE(0xFFFFFFFE), HN_ULONG_TO_UBASE(0xFFFFFFFF),
96 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFE),
97 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
98 HN_ULONG_TO_UBASE(0xFFFFFFFF)
99 };
100 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp224r1_b[] =
101 {
102
103 /* b = B4050A85 0C04B3AB F5413256 5044B0B7 D7BFD8BA 270B3943 2355FFB4 */
104 HN_ULONG_TO_UBASE(0x2355FFB4), HN_ULONG_TO_UBASE(0x270B3943),
105 HN_ULONG_TO_UBASE(0xD7BFD8BA), HN_ULONG_TO_UBASE(0x5044B0B7),
106 HN_ULONG_TO_UBASE(0xF5413256), HN_ULONG_TO_UBASE(0x0C04B3AB),
107 HN_ULONG_TO_UBASE(0xB4050A85)
108 };
109 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp224r1_gx[] =
110 {
111
112 /* G.x = B70E0CBD 6BB4BF7F 321390B9 4A03C1D3 56C21122 343280D6 115C1D21 */
113 HN_ULONG_TO_UBASE(0x115C1D21), HN_ULONG_TO_UBASE(0x343280D6),
114 HN_ULONG_TO_UBASE(0x56C21122), HN_ULONG_TO_UBASE(0x4A03C1D3),
115 HN_ULONG_TO_UBASE(0x321390B9), HN_ULONG_TO_UBASE(0x6BB4BF7F),
116 HN_ULONG_TO_UBASE(0xB70E0CBD)
117 };
118 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp224r1_gy[] =
119 {
120
121 /* G.y = BD376388 B5F723FB 4C22DFE6 CD4375A0 5A074764 44D58199 85007E34 */
122 HN_ULONG_TO_UBASE(0x85007E34), HN_ULONG_TO_UBASE(0x44D58199),
123 HN_ULONG_TO_UBASE(0x5A074764), HN_ULONG_TO_UBASE(0xCD4375A0),
124 HN_ULONG_TO_UBASE(0x4C22DFE6), HN_ULONG_TO_UBASE(0xB5F723FB),
125 HN_ULONG_TO_UBASE(0xBD376388)
126 };
127 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp224r1_n[] =
128 {
129
130 /* n = FFFFFFFF FFFFFFFF FFFFFFFF FFFF16A2 E0B8F03E 13DD2945 5C5C2A3D */
131 HN_ULONG_TO_UBASE(0x5C5C2A3D), HN_ULONG_TO_UBASE(0x13DD2945),
132 HN_ULONG_TO_UBASE(0xE0B8F03E), HN_ULONG_TO_UBASE(0xFFFF16A2),
133 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
134 HN_ULONG_TO_UBASE(0xFFFFFFFF)
135 };
136 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp224r1_h[] =
137 {
138
139 /* h = 01 */
140 HN_ULONG_TO_UBASE(0x00000001)
141 };
142
143 /* secp256r1 */
144 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp256r1_p[] =
145 {
146
147 /* p = FFFFFFFF 00000001 00000000 00000000 00000000 FFFFFFFF FFFFFFFF FFFFFFFF */
148 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
149 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0x00000000),
150 HN_ULONG_TO_UBASE(0x00000000), HN_ULONG_TO_UBASE(0x00000000),
151 HN_ULONG_TO_UBASE(0x00000001), HN_ULONG_TO_UBASE(0xFFFFFFFF)
152 };
153 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp256r1_a[] =
154 {
155
156 /* a = FFFFFFFF 00000001 00000000 00000000 00000000 FFFFFFFF FFFFFFFF FFFFFFFC */
157 HN_ULONG_TO_UBASE(0xFFFFFFFC), HN_ULONG_TO_UBASE(0xFFFFFFFF),
158 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0x00000000),
159 HN_ULONG_TO_UBASE(0x00000000), HN_ULONG_TO_UBASE(0x00000000),
160 HN_ULONG_TO_UBASE(0x00000001), HN_ULONG_TO_UBASE(0xFFFFFFFF)
161 };
162 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp256r1_b[] =
163 {
164
165 /* b = 5AC635D8 AA3A93E7 B3EBBD55 769886BC 651D06B0 CC53B0F6 3BCE3C3E 27D2604B */
166 HN_ULONG_TO_UBASE(0x27D2604B), HN_ULONG_TO_UBASE(0x3BCE3C3E),
167 HN_ULONG_TO_UBASE(0xCC53B0F6), HN_ULONG_TO_UBASE(0x651D06B0),
168 HN_ULONG_TO_UBASE(0x769886BC), HN_ULONG_TO_UBASE(0xB3EBBD55),
169 HN_ULONG_TO_UBASE(0xAA3A93E7), HN_ULONG_TO_UBASE(0x5AC635D8)
170 };
171 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp256r1_gx[] =
172 {
173
174 /* G.x = 6B17D1F2 E12C4247 F8BCE6E5 63A440F2 77037D81 2DEB33A0 F4A13945 D898C296 */
175 HN_ULONG_TO_UBASE(0xD898C296), HN_ULONG_TO_UBASE(0xF4A13945),
176 HN_ULONG_TO_UBASE(0x2DEB33A0), HN_ULONG_TO_UBASE(0x77037D81),
177 HN_ULONG_TO_UBASE(0x63A440F2), HN_ULONG_TO_UBASE(0xF8BCE6E5),
178 HN_ULONG_TO_UBASE(0xE12C4247), HN_ULONG_TO_UBASE(0x6B17D1F2)
179 };
180 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp256r1_gy[] =
181 {
182
183 /* G.y = 4FE342E2 FE1A7F9B 8EE7EB4A 7C0F9E16 2BCE3357 6B315ECE CBB64068 37BF51F5 */
184 HN_ULONG_TO_UBASE(0x37BF51F5), HN_ULONG_TO_UBASE(0xCBB64068),
185 HN_ULONG_TO_UBASE(0x6B315ECE), HN_ULONG_TO_UBASE(0x2BCE3357),
186 HN_ULONG_TO_UBASE(0x7C0F9E16), HN_ULONG_TO_UBASE(0x8EE7EB4A),
187 HN_ULONG_TO_UBASE(0xFE1A7F9B), HN_ULONG_TO_UBASE(0x4FE342E2)
188 };
189 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp256r1_n[] =
190 {
191
192 /* n = FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632551 */
193 HN_ULONG_TO_UBASE(0xFC632551), HN_ULONG_TO_UBASE(0xF3B9CAC2),
194 HN_ULONG_TO_UBASE(0xA7179E84), HN_ULONG_TO_UBASE(0xBCE6FAAD),
195 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
196 HN_ULONG_TO_UBASE(0x00000000), HN_ULONG_TO_UBASE(0xFFFFFFFF)
197 };
198 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp256r1_h[] =
199 {
200
201 /* h = 01 */
202 HN_ULONG_TO_UBASE(0x00000001)
203 };
204
205 /* secp384r1 */
206 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp384r1_p[] =
207 {
208
209 /* p = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF 00000000 00000000 FFFFFFFF */
210 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0x00000000),
211 HN_ULONG_TO_UBASE(0x00000000), HN_ULONG_TO_UBASE(0xFFFFFFFF),
212 HN_ULONG_TO_UBASE(0xFFFFFFFE), HN_ULONG_TO_UBASE(0xFFFFFFFF),
213 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
214 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
215 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF)
216 };
217 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp384r1_a[] =
218 {
219
220 /* a = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF 00000000 00000000 FFFFFFFC */
221 HN_ULONG_TO_UBASE(0xFFFFFFFC), HN_ULONG_TO_UBASE(0x00000000),
222 HN_ULONG_TO_UBASE(0x00000000), HN_ULONG_TO_UBASE(0xFFFFFFFF),
223 HN_ULONG_TO_UBASE(0xFFFFFFFE), HN_ULONG_TO_UBASE(0xFFFFFFFF),
224 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
225 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
226 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF)
227 };
228 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp384r1_b[] =
229 {
230
231 /* b = B3312FA7 E23EE7E4 988E056B E3F82D19 181D9C6E FE814112 0314088F 5013875A C656398D 8A2ED19D 2A85C8ED D3EC2AEF */
232 HN_ULONG_TO_UBASE(0xD3EC2AEF), HN_ULONG_TO_UBASE(0x2A85C8ED),
233 HN_ULONG_TO_UBASE(0x8A2ED19D), HN_ULONG_TO_UBASE(0xC656398D),
234 HN_ULONG_TO_UBASE(0x5013875A), HN_ULONG_TO_UBASE(0x0314088F),
235 HN_ULONG_TO_UBASE(0xFE814112), HN_ULONG_TO_UBASE(0x181D9C6E),
236 HN_ULONG_TO_UBASE(0xE3F82D19), HN_ULONG_TO_UBASE(0x988E056B),
237 HN_ULONG_TO_UBASE(0xE23EE7E4), HN_ULONG_TO_UBASE(0xB3312FA7)
238 };
239 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp384r1_gx[] =
240 {
241
242 /* G.x = AA87CA22 BE8B0537 8EB1C71E F320AD74 6E1D3B62 8BA79B98
243 59F741E0 82542A38 5502F25D BF55296C 3A545E38 72760AB7 */
244 HN_ULONG_TO_UBASE(0x72760AB7), HN_ULONG_TO_UBASE(0x3A545E38),
245 HN_ULONG_TO_UBASE(0xBF55296C), HN_ULONG_TO_UBASE(0x5502F25D),
246 HN_ULONG_TO_UBASE(0x82542A38), HN_ULONG_TO_UBASE(0x59F741E0),
247 HN_ULONG_TO_UBASE(0x8BA79B98), HN_ULONG_TO_UBASE(0x6E1D3B62),
248 HN_ULONG_TO_UBASE(0xF320AD74), HN_ULONG_TO_UBASE(0x8EB1C71E),
249 HN_ULONG_TO_UBASE(0xBE8B0537), HN_ULONG_TO_UBASE(0xAA87CA22)
250 };
251 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp384r1_gy[] =
252 {
253
254 /* G.y = 3617DE4A 96262C6F 5D9E98BF 9292DC29 F8F41DBD 289A147C
255 E9DA3113 B5F0B8C0 0A60B1CE 1D7E819D 7A431D7C 90EA0E5F */
256 HN_ULONG_TO_UBASE(0x90EA0E5F), HN_ULONG_TO_UBASE(0x7A431D7C),
257 HN_ULONG_TO_UBASE(0x1D7E819D), HN_ULONG_TO_UBASE(0x0A60B1CE),
258 HN_ULONG_TO_UBASE(0xB5F0B8C0), HN_ULONG_TO_UBASE(0xE9DA3113),
259 HN_ULONG_TO_UBASE(0x289A147C), HN_ULONG_TO_UBASE(0xF8F41DBD),
260 HN_ULONG_TO_UBASE(0x9292DC29), HN_ULONG_TO_UBASE(0x5D9E98BF),
261 HN_ULONG_TO_UBASE(0x96262C6F), HN_ULONG_TO_UBASE(0x3617DE4A)
262 };
263 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp384r1_n[] =
264 {
265
266 /* n = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF C7634D81 F4372DDF 581A0DB2 48B0A77A ECEC196A CCC52973 */
267 HN_ULONG_TO_UBASE(0xCCC52973), HN_ULONG_TO_UBASE(0xECEC196A),
268 HN_ULONG_TO_UBASE(0x48B0A77A), HN_ULONG_TO_UBASE(0x581A0DB2),
269 HN_ULONG_TO_UBASE(0xF4372DDF), HN_ULONG_TO_UBASE(0xC7634D81),
270 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
271 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
272 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF)
273 };
274 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp384r1_h[] =
275 {
276
277 /* h = 01 */
278 HN_ULONG_TO_UBASE(0x00000001)
279 };
280
281 /* secp521r1 */
282 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp521r1_p[] =
283 {
284
285 /* p = 01FF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF */
286 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
287 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
288 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
289 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
290 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
291 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
292 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
293 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
294 HN_ULONG_TO_UBASE(0x000001FF)
295 };
296 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp521r1_a[] =
297 {
298
299 /* a = 01FF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFC */
300 HN_ULONG_TO_UBASE(0xFFFFFFFC), HN_ULONG_TO_UBASE(0xFFFFFFFF),
301 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
302 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
303 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
304 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
305 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
306 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
307 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
308 HN_ULONG_TO_UBASE(0x000001FF)
309 };
310 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp521r1_b[] =
311 {
312
313 /* b = 0051 953EB961 8E1C9A1F 929A21A0 B68540EE A2DA725B 99B315F3 B8B48991 8EF109E1 56193951 EC7E937B 1652C0BD 3BB1BF07 3573DF88 3D2C34F1 EF451FD4 6B503F00 */
314 HN_ULONG_TO_UBASE(0x6B503F00), HN_ULONG_TO_UBASE(0xEF451FD4),
315 HN_ULONG_TO_UBASE(0x3D2C34F1), HN_ULONG_TO_UBASE(0x3573DF88),
316 HN_ULONG_TO_UBASE(0x3BB1BF07), HN_ULONG_TO_UBASE(0x1652C0BD),
317 HN_ULONG_TO_UBASE(0xEC7E937B), HN_ULONG_TO_UBASE(0x56193951),
318 HN_ULONG_TO_UBASE(0x8EF109E1), HN_ULONG_TO_UBASE(0xB8B48991),
319 HN_ULONG_TO_UBASE(0x99B315F3), HN_ULONG_TO_UBASE(0xA2DA725B),
320 HN_ULONG_TO_UBASE(0xB68540EE), HN_ULONG_TO_UBASE(0x929A21A0),
321 HN_ULONG_TO_UBASE(0x8E1C9A1F), HN_ULONG_TO_UBASE(0x953EB961),
322 HN_ULONG_TO_UBASE(0x00000051)
323 };
324 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp521r1_gx[] =
325 {
326
327 /* G.x = 00C6858E 06B70404 E9CD9E3E CB662395 B4429C64 8139053F B521F828 AF606B4D 3DBAA14B 5E77EFE7 5928FE1D C127A2FF A8DE3348 B3C1856A 429BF97E 7E31C2E5 BD66 */
328 HN_ULONG_TO_UBASE(0xC2E5BD66), HN_ULONG_TO_UBASE(0xF97E7E31),
329 HN_ULONG_TO_UBASE(0x856A429B), HN_ULONG_TO_UBASE(0x3348B3C1),
330 HN_ULONG_TO_UBASE(0xA2FFA8DE), HN_ULONG_TO_UBASE(0xFE1DC127),
331 HN_ULONG_TO_UBASE(0xEFE75928), HN_ULONG_TO_UBASE(0xA14B5E77),
332 HN_ULONG_TO_UBASE(0x6B4D3DBA), HN_ULONG_TO_UBASE(0xF828AF60),
333 HN_ULONG_TO_UBASE(0x053FB521), HN_ULONG_TO_UBASE(0x9C648139),
334 HN_ULONG_TO_UBASE(0x2395B442), HN_ULONG_TO_UBASE(0x9E3ECB66),
335 HN_ULONG_TO_UBASE(0x0404E9CD), HN_ULONG_TO_UBASE(0x858E06B7),
336 HN_ULONG_TO_UBASE(0x000000C6)
337 };
338 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp521r1_gy[] =
339 {
340
341 /* G.y = 0118 39296A78 9A3BC004 5C8A5FB4 2C7D1BD9 98F54449 579B4468 17AFBD17 273E662C 97EE7299 5EF42640 C550B901 3FAD0761 353C7086 A272C240 88BE9476 9FD16650*/
342 HN_ULONG_TO_UBASE(0x9FD16650), HN_ULONG_TO_UBASE(0x88BE9476),
343 HN_ULONG_TO_UBASE(0xA272C240), HN_ULONG_TO_UBASE(0x353C7086),
344 HN_ULONG_TO_UBASE(0x3FAD0761), HN_ULONG_TO_UBASE(0xC550B901),
345 HN_ULONG_TO_UBASE(0x5EF42640), HN_ULONG_TO_UBASE(0x97EE7299),
346 HN_ULONG_TO_UBASE(0x273E662C), HN_ULONG_TO_UBASE(0x17AFBD17),
347 HN_ULONG_TO_UBASE(0x579B4468), HN_ULONG_TO_UBASE(0x98F54449),
348 HN_ULONG_TO_UBASE(0x2C7D1BD9), HN_ULONG_TO_UBASE(0x5C8A5FB4),
349 HN_ULONG_TO_UBASE(0x9A3BC004), HN_ULONG_TO_UBASE(0x39296A78),
350 HN_ULONG_TO_UBASE(0x00000118)
351 };
352 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp521r1_n[] =
353 {
354
355 /* n = 01FF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFA 51868783 BF2F966B 7FCC0148 F709A5D0 3BB5C9B8 899C47AE BB6FB71E 91386409 */
356 HN_ULONG_TO_UBASE(0x91386409), HN_ULONG_TO_UBASE(0xBB6FB71E),
357 HN_ULONG_TO_UBASE(0x899C47AE), HN_ULONG_TO_UBASE(0x3BB5C9B8),
358 HN_ULONG_TO_UBASE(0xF709A5D0), HN_ULONG_TO_UBASE(0x7FCC0148),
359 HN_ULONG_TO_UBASE(0xBF2F966B), HN_ULONG_TO_UBASE(0x51868783),
360 HN_ULONG_TO_UBASE(0xFFFFFFFA), HN_ULONG_TO_UBASE(0xFFFFFFFF),
361 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
362 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
363 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
364 HN_ULONG_TO_UBASE(0x000001FF)
365 };
366 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp521r1_h[] =
367 {
368
369 /* h = 01 */
370 HN_ULONG_TO_UBASE(0x00000001)
371 };
372
373 extern NX_CRYPTO_CONST NX_CRYPTO_EC_FIXED_POINTS _nx_crypto_ec_secp192r1_fixed_points;
374 extern NX_CRYPTO_CONST NX_CRYPTO_EC_FIXED_POINTS _nx_crypto_ec_secp224r1_fixed_points;
375 extern NX_CRYPTO_CONST NX_CRYPTO_EC_FIXED_POINTS _nx_crypto_ec_secp256r1_fixed_points;
376 extern NX_CRYPTO_CONST NX_CRYPTO_EC_FIXED_POINTS _nx_crypto_ec_secp384r1_fixed_points;
377 extern NX_CRYPTO_CONST NX_CRYPTO_EC_FIXED_POINTS _nx_crypto_ec_secp521r1_fixed_points;
378
379 NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_secp192r1 =
380 {
381 "secp192r1",
382 NX_CRYPTO_EC_SECP192R1,
383 4,
384 192,
385 {
386 .fp =
387 {
388 (HN_UBASE *)_nx_crypto_ec_secp192r1_p,
389 sizeof(_nx_crypto_ec_secp192r1_p) >> HN_SIZE_SHIFT,
390 sizeof(_nx_crypto_ec_secp192r1_p),
391 (UINT)NX_CRYPTO_FALSE
392 }
393 },
394 {
395 (HN_UBASE *)_nx_crypto_ec_secp192r1_a,
396 sizeof(_nx_crypto_ec_secp192r1_a) >> HN_SIZE_SHIFT,
397 sizeof(_nx_crypto_ec_secp192r1_a),
398 (UINT)NX_CRYPTO_FALSE
399 },
400 {
401 (HN_UBASE *)_nx_crypto_ec_secp192r1_b,
402 sizeof(_nx_crypto_ec_secp192r1_b) >> HN_SIZE_SHIFT,
403 sizeof(_nx_crypto_ec_secp192r1_b),
404 (UINT)NX_CRYPTO_FALSE
405 },
406 {
407 NX_CRYPTO_EC_POINT_AFFINE,
408 {
409 (HN_UBASE *)_nx_crypto_ec_secp192r1_gx,
410 sizeof(_nx_crypto_ec_secp192r1_gx) >> HN_SIZE_SHIFT,
411 sizeof(_nx_crypto_ec_secp192r1_gx),
412 (UINT)NX_CRYPTO_FALSE
413 },
414 {
415 (HN_UBASE *)_nx_crypto_ec_secp192r1_gy,
416 sizeof(_nx_crypto_ec_secp192r1_gy) >> HN_SIZE_SHIFT,
417 sizeof(_nx_crypto_ec_secp192r1_gy),
418 (UINT)NX_CRYPTO_FALSE
419 },
420 {(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u}
421 },
422 {
423 (HN_UBASE *)_nx_crypto_ec_secp192r1_n,
424 sizeof(_nx_crypto_ec_secp192r1_n) >> HN_SIZE_SHIFT,
425 sizeof(_nx_crypto_ec_secp192r1_n),
426 (UINT)NX_CRYPTO_FALSE
427 },
428 {
429 (HN_UBASE *)_nx_crypto_ec_secp192r1_h,
430 sizeof(_nx_crypto_ec_secp192r1_h) >> HN_SIZE_SHIFT,
431 sizeof(_nx_crypto_ec_secp192r1_h),
432 (UINT)NX_CRYPTO_FALSE
433 },
434 (NX_CRYPTO_EC_FIXED_POINTS *)&_nx_crypto_ec_secp192r1_fixed_points,
435 _nx_crypto_ec_fp_affine_add,
436 _nx_crypto_ec_fp_affine_subtract,
437 _nx_crypto_ec_fp_projective_multiple,
438 _nx_crypto_ec_secp192r1_reduce
439 };
440
441 NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_secp224r1 =
442 {
443 "secp224r1",
444 NX_CRYPTO_EC_SECP224R1,
445 4,
446 224,
447 {
448 .fp =
449 {
450 (HN_UBASE *)_nx_crypto_ec_secp224r1_p,
451 sizeof(_nx_crypto_ec_secp224r1_p) >> HN_SIZE_SHIFT,
452 sizeof(_nx_crypto_ec_secp224r1_p),
453 (UINT)NX_CRYPTO_FALSE
454 }
455 },
456 {
457 (HN_UBASE *)_nx_crypto_ec_secp224r1_a,
458 sizeof(_nx_crypto_ec_secp224r1_a) >> HN_SIZE_SHIFT,
459 sizeof(_nx_crypto_ec_secp224r1_a),
460 (UINT)NX_CRYPTO_FALSE
461 },
462 {
463 (HN_UBASE *)_nx_crypto_ec_secp224r1_b,
464 sizeof(_nx_crypto_ec_secp224r1_b) >> HN_SIZE_SHIFT,
465 sizeof(_nx_crypto_ec_secp224r1_b),
466 (UINT)NX_CRYPTO_FALSE
467 },
468 {
469 NX_CRYPTO_EC_POINT_AFFINE,
470 {
471 (HN_UBASE *)_nx_crypto_ec_secp224r1_gx,
472 sizeof(_nx_crypto_ec_secp224r1_gx) >> HN_SIZE_SHIFT,
473 sizeof(_nx_crypto_ec_secp224r1_gx),
474 (UINT)NX_CRYPTO_FALSE
475 },
476 {
477 (HN_UBASE *)_nx_crypto_ec_secp224r1_gy,
478 sizeof(_nx_crypto_ec_secp224r1_gy) >> HN_SIZE_SHIFT,
479 sizeof(_nx_crypto_ec_secp224r1_gy),
480 (UINT)NX_CRYPTO_FALSE
481 },
482 {(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u}
483 },
484 {
485 (HN_UBASE *)_nx_crypto_ec_secp224r1_n,
486 sizeof(_nx_crypto_ec_secp224r1_n) >> HN_SIZE_SHIFT,
487 sizeof(_nx_crypto_ec_secp224r1_n),
488 (UINT)NX_CRYPTO_FALSE
489 },
490 {
491 (HN_UBASE *)_nx_crypto_ec_secp224r1_h,
492 sizeof(_nx_crypto_ec_secp224r1_h) >> HN_SIZE_SHIFT,
493 sizeof(_nx_crypto_ec_secp224r1_h),
494 (UINT)NX_CRYPTO_FALSE
495 },
496 (NX_CRYPTO_EC_FIXED_POINTS *)&_nx_crypto_ec_secp224r1_fixed_points,
497 _nx_crypto_ec_fp_affine_add,
498 _nx_crypto_ec_fp_affine_subtract,
499 _nx_crypto_ec_fp_projective_multiple,
500 _nx_crypto_ec_secp224r1_reduce
501 };
502
503 NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_secp256r1 =
504 {
505 "secp256r1",
506 NX_CRYPTO_EC_SECP256R1,
507 4,
508 256,
509 {
510 .fp =
511 {
512 (HN_UBASE *)_nx_crypto_ec_secp256r1_p,
513 sizeof(_nx_crypto_ec_secp256r1_p) >> HN_SIZE_SHIFT,
514 sizeof(_nx_crypto_ec_secp256r1_p),
515 (UINT)NX_CRYPTO_FALSE
516 }
517 },
518 {
519 (HN_UBASE *)_nx_crypto_ec_secp256r1_a,
520 sizeof(_nx_crypto_ec_secp256r1_a) >> HN_SIZE_SHIFT,
521 sizeof(_nx_crypto_ec_secp256r1_a),
522 (UINT)NX_CRYPTO_FALSE
523 },
524 {
525 (HN_UBASE *)_nx_crypto_ec_secp256r1_b,
526 sizeof(_nx_crypto_ec_secp256r1_b) >> HN_SIZE_SHIFT,
527 sizeof(_nx_crypto_ec_secp256r1_b),
528 (UINT)NX_CRYPTO_FALSE
529 },
530 {
531 NX_CRYPTO_EC_POINT_AFFINE,
532 {
533 (HN_UBASE *)_nx_crypto_ec_secp256r1_gx,
534 sizeof(_nx_crypto_ec_secp256r1_gx) >> HN_SIZE_SHIFT,
535 sizeof(_nx_crypto_ec_secp256r1_gx),
536 (UINT)NX_CRYPTO_FALSE
537 },
538 {
539 (HN_UBASE *)_nx_crypto_ec_secp256r1_gy,
540 sizeof(_nx_crypto_ec_secp256r1_gy) >> HN_SIZE_SHIFT,
541 sizeof(_nx_crypto_ec_secp256r1_gy),
542 (UINT)NX_CRYPTO_FALSE
543 },
544 {(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u}
545 },
546 {
547 (HN_UBASE *)_nx_crypto_ec_secp256r1_n,
548 sizeof(_nx_crypto_ec_secp256r1_n) >> HN_SIZE_SHIFT,
549 sizeof(_nx_crypto_ec_secp256r1_n),
550 (UINT)NX_CRYPTO_FALSE
551 },
552 {
553 (HN_UBASE *)_nx_crypto_ec_secp256r1_h,
554 sizeof(_nx_crypto_ec_secp256r1_h) >> HN_SIZE_SHIFT,
555 sizeof(_nx_crypto_ec_secp256r1_h),
556 (UINT)NX_CRYPTO_FALSE
557 },
558 (NX_CRYPTO_EC_FIXED_POINTS *)&_nx_crypto_ec_secp256r1_fixed_points,
559 _nx_crypto_ec_fp_affine_add,
560 _nx_crypto_ec_fp_affine_subtract,
561 _nx_crypto_ec_fp_projective_multiple,
562 _nx_crypto_ec_secp256r1_reduce
563 };
564
565 NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_secp384r1 =
566 {
567 "secp384r1",
568 NX_CRYPTO_EC_SECP384R1,
569 5,
570 384,
571 {
572 .fp =
573 {
574 (HN_UBASE *)_nx_crypto_ec_secp384r1_p,
575 sizeof(_nx_crypto_ec_secp384r1_p) >> HN_SIZE_SHIFT,
576 sizeof(_nx_crypto_ec_secp384r1_p),
577 (UINT)NX_CRYPTO_FALSE
578 }
579 },
580 {
581 (HN_UBASE *)_nx_crypto_ec_secp384r1_a,
582 sizeof(_nx_crypto_ec_secp384r1_a) >> HN_SIZE_SHIFT,
583 sizeof(_nx_crypto_ec_secp384r1_a),
584 (UINT)NX_CRYPTO_FALSE
585 },
586 {
587 (HN_UBASE *)_nx_crypto_ec_secp384r1_b,
588 sizeof(_nx_crypto_ec_secp384r1_b) >> HN_SIZE_SHIFT,
589 sizeof(_nx_crypto_ec_secp384r1_b),
590 (UINT)NX_CRYPTO_FALSE
591 },
592 {
593 NX_CRYPTO_EC_POINT_AFFINE,
594 {
595 (HN_UBASE *)_nx_crypto_ec_secp384r1_gx,
596 sizeof(_nx_crypto_ec_secp384r1_gx) >> HN_SIZE_SHIFT,
597 sizeof(_nx_crypto_ec_secp384r1_gx),
598 (UINT)NX_CRYPTO_FALSE
599 },
600 {
601 (HN_UBASE *)_nx_crypto_ec_secp384r1_gy,
602 sizeof(_nx_crypto_ec_secp384r1_gy) >> HN_SIZE_SHIFT,
603 sizeof(_nx_crypto_ec_secp384r1_gy),
604 (UINT)NX_CRYPTO_FALSE
605 },
606 {(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u}
607 },
608 {
609 (HN_UBASE *)_nx_crypto_ec_secp384r1_n,
610 sizeof(_nx_crypto_ec_secp384r1_n) >> HN_SIZE_SHIFT,
611 sizeof(_nx_crypto_ec_secp384r1_n),
612 (UINT)NX_CRYPTO_FALSE
613 },
614 {
615 (HN_UBASE *)_nx_crypto_ec_secp384r1_h,
616 sizeof(_nx_crypto_ec_secp384r1_h) >> HN_SIZE_SHIFT,
617 sizeof(_nx_crypto_ec_secp384r1_h),
618 (UINT)NX_CRYPTO_FALSE
619 },
620 (NX_CRYPTO_EC_FIXED_POINTS *)&_nx_crypto_ec_secp384r1_fixed_points,
621 _nx_crypto_ec_fp_affine_add,
622 _nx_crypto_ec_fp_affine_subtract,
623 _nx_crypto_ec_fp_projective_multiple,
624 _nx_crypto_ec_secp384r1_reduce
625 };
626
627 NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_secp521r1 =
628 {
629 "secp521r1",
630 NX_CRYPTO_EC_SECP521R1,
631 5,
632 521,
633 {
634 .fp =
635 {
636 (HN_UBASE *)_nx_crypto_ec_secp521r1_p,
637 sizeof(_nx_crypto_ec_secp521r1_p) >> HN_SIZE_SHIFT,
638 sizeof(_nx_crypto_ec_secp521r1_p),
639 (UINT)NX_CRYPTO_FALSE
640 }
641 },
642 {
643 (HN_UBASE *)_nx_crypto_ec_secp521r1_a,
644 sizeof(_nx_crypto_ec_secp521r1_a) >> HN_SIZE_SHIFT,
645 sizeof(_nx_crypto_ec_secp521r1_a),
646 (UINT)NX_CRYPTO_FALSE
647 },
648 {
649 (HN_UBASE *)_nx_crypto_ec_secp521r1_b,
650 sizeof(_nx_crypto_ec_secp521r1_b) >> HN_SIZE_SHIFT,
651 sizeof(_nx_crypto_ec_secp521r1_b),
652 (UINT)NX_CRYPTO_FALSE
653 },
654 {
655 NX_CRYPTO_EC_POINT_AFFINE,
656 {
657 (HN_UBASE *)_nx_crypto_ec_secp521r1_gx,
658 sizeof(_nx_crypto_ec_secp521r1_gx) >> HN_SIZE_SHIFT,
659 sizeof(_nx_crypto_ec_secp521r1_gx),
660 (UINT)NX_CRYPTO_FALSE
661 },
662 {
663 (HN_UBASE *)_nx_crypto_ec_secp521r1_gy,
664 sizeof(_nx_crypto_ec_secp521r1_gy) >> HN_SIZE_SHIFT,
665 sizeof(_nx_crypto_ec_secp521r1_gy),
666 (UINT)NX_CRYPTO_FALSE
667 },
668 {(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u}
669 },
670 {
671 (HN_UBASE *)_nx_crypto_ec_secp521r1_n,
672 sizeof(_nx_crypto_ec_secp521r1_n) >> HN_SIZE_SHIFT,
673 sizeof(_nx_crypto_ec_secp521r1_n),
674 (UINT)NX_CRYPTO_FALSE
675 },
676 {
677 (HN_UBASE *)_nx_crypto_ec_secp521r1_h,
678 sizeof(_nx_crypto_ec_secp521r1_h) >> HN_SIZE_SHIFT,
679 sizeof(_nx_crypto_ec_secp521r1_h),
680 (UINT)NX_CRYPTO_FALSE
681 },
682 (NX_CRYPTO_EC_FIXED_POINTS *)&_nx_crypto_ec_secp521r1_fixed_points,
683 _nx_crypto_ec_fp_affine_add,
684 _nx_crypto_ec_fp_affine_subtract,
685 _nx_crypto_ec_fp_projective_multiple,
686 _nx_crypto_ec_secp521r1_reduce
687 };
688 #ifndef NX_CRYPTO_SELF_TEST
689 static NX_CRYPTO_CONST NX_CRYPTO_EC *_nx_crypto_ec_named_curves[] =
690 {
691 &_nx_crypto_ec_secp192r1,
692 &_nx_crypto_ec_secp224r1,
693 &_nx_crypto_ec_secp256r1,
694 &_nx_crypto_ec_secp384r1,
695 &_nx_crypto_ec_secp521r1
696 };
697 #endif
698 /**************************************************************************/
699 /* */
700 /* FUNCTION RELEASE */
701 /* */
702 /* _nx_crypto_ec_point_is_infinite PORTABLE C */
703 /* 6.1 */
704 /* AUTHOR */
705 /* */
706 /* Timothy Stapko, Microsoft Corporation */
707 /* */
708 /* DESCRIPTION */
709 /* */
710 /* This function checks whether the point is infinite. */
711 /* */
712 /* INPUT */
713 /* */
714 /* point Pointer to point */
715 /* */
716 /* OUTPUT */
717 /* */
718 /* NX_CRYPTO_TRUE Point is infinite */
719 /* NX_CRYPTO_FALSE Point is not infinite */
720 /* */
721 /* CALLS */
722 /* */
723 /* _nx_crypto_huge_number_is_zero Check if number is zero or not*/
724 /* */
725 /* CALLED BY */
726 /* */
727 /* _nx_crypto_ec_point_fp_projective_to_affine */
728 /* Convert point from projective */
729 /* to affine */
730 /* _nx_crypto_ec_fp_projective_add Perform addition for points of*/
731 /* projective and affine */
732 /* _nx_crypto_ec_fp_projective_double Perform doubling for points of*/
733 /* projective */
734 /* */
735 /* RELEASE HISTORY */
736 /* */
737 /* DATE NAME DESCRIPTION */
738 /* */
739 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
740 /* 09-30-2020 Timothy Stapko Modified comment(s), */
741 /* resulting in version 6.1 */
742 /* */
743 /**************************************************************************/
_nx_crypto_ec_point_is_infinite(NX_CRYPTO_EC_POINT * point)744 NX_CRYPTO_KEEP UINT _nx_crypto_ec_point_is_infinite(NX_CRYPTO_EC_POINT *point)
745 {
746 if (point -> nx_crypto_ec_point_type == NX_CRYPTO_EC_POINT_AFFINE)
747 {
748 if (_nx_crypto_huge_number_is_zero(&point -> nx_crypto_ec_point_x) &&
749 _nx_crypto_huge_number_is_zero(&point -> nx_crypto_ec_point_y))
750 {
751 return(NX_CRYPTO_TRUE);
752 }
753 else
754 {
755 return(NX_CRYPTO_FALSE);
756 }
757 }
758
759 return(_nx_crypto_huge_number_is_zero(&point -> nx_crypto_ec_point_z));
760 }
761
762 /**************************************************************************/
763 /* */
764 /* FUNCTION RELEASE */
765 /* */
766 /* _nx_crypto_ec_point_set_infinite PORTABLE C */
767 /* 6.1 */
768 /* AUTHOR */
769 /* */
770 /* Timothy Stapko, Microsoft Corporation */
771 /* */
772 /* DESCRIPTION */
773 /* */
774 /* This function sets the point to infinite. */
775 /* */
776 /* INPUT */
777 /* */
778 /* point Pointer to point */
779 /* */
780 /* OUTPUT */
781 /* */
782 /* None */
783 /* */
784 /* CALLS */
785 /* */
786 /* NX_CRYPTO_HUGE_NUMBER_SET_DIGIT Set value of huge number */
787 /* between 0 and (HN_RADIX - 1)*/
788 /* */
789 /* CALLED BY */
790 /* */
791 /* _nx_crypto_ec_fp_fixed_multiple Calculate the fixed */
792 /* multiplication */
793 /* _nx_crypto_ec_fp_projective_multiple Calculate the projective */
794 /* multiplication */
795 /* _nx_crypto_ec_point_fp_projective_to_affine */
796 /* Convert point from projective */
797 /* to affine */
798 /* */
799 /* RELEASE HISTORY */
800 /* */
801 /* DATE NAME DESCRIPTION */
802 /* */
803 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
804 /* 09-30-2020 Timothy Stapko Modified comment(s), */
805 /* resulting in version 6.1 */
806 /* */
807 /**************************************************************************/
_nx_crypto_ec_point_set_infinite(NX_CRYPTO_EC_POINT * point)808 NX_CRYPTO_KEEP VOID _nx_crypto_ec_point_set_infinite(NX_CRYPTO_EC_POINT *point)
809 {
810 if (point -> nx_crypto_ec_point_type == NX_CRYPTO_EC_POINT_AFFINE)
811 {
812 NX_CRYPTO_HUGE_NUMBER_SET_DIGIT(&point -> nx_crypto_ec_point_x, 0);
813 NX_CRYPTO_HUGE_NUMBER_SET_DIGIT(&point -> nx_crypto_ec_point_y, 0);
814 }
815 else
816 {
817 NX_CRYPTO_HUGE_NUMBER_SET_DIGIT(&point -> nx_crypto_ec_point_z, 0);
818 }
819 }
820
821 /**************************************************************************/
822 /* */
823 /* FUNCTION RELEASE */
824 /* */
825 /* _nx_crypto_ec_point_setup PORTABLE C */
826 /* 6.1 */
827 /* AUTHOR */
828 /* */
829 /* Timothy Stapko, Microsoft Corporation */
830 /* */
831 /* DESCRIPTION */
832 /* */
833 /* This function sets up point from byte steam. */
834 /* */
835 /* Note: only uncompressed format is supported now. */
836 /* */
837 /* INPUT */
838 /* */
839 /* point Pointer to point */
840 /* byte_stream Byte stream */
841 /* byte_stream_size Size of byte stream */
842 /* */
843 /* OUTPUT */
844 /* */
845 /* None */
846 /* */
847 /* CALLS */
848 /* */
849 /* _nx_crypto_huge_number_setup Setup huge number */
850 /* */
851 /* CALLED BY */
852 /* */
853 /* _nx_crypto_ecjpake_hello_process Process hello message */
854 /* _nx_crypto_ecjpake_key_exchange_process */
855 /* Process key exchange message */
856 /* */
857 /* RELEASE HISTORY */
858 /* */
859 /* DATE NAME DESCRIPTION */
860 /* */
861 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
862 /* 09-30-2020 Timothy Stapko Modified comment(s), updated */
863 /* constants, resulting */
864 /* in version 6.1 */
865 /* */
866 /**************************************************************************/
_nx_crypto_ec_point_setup(NX_CRYPTO_EC_POINT * point,UCHAR * byte_stream,UINT byte_stream_size)867 NX_CRYPTO_KEEP UINT _nx_crypto_ec_point_setup(NX_CRYPTO_EC_POINT *point, UCHAR *byte_stream, UINT byte_stream_size)
868 {
869 UINT len;
870 UINT status;
871
872 if (*byte_stream != 0x04)
873 {
874
875 /* Only uncompressed format is supported. */
876 return(NX_CRYPTO_FORMAT_NOT_SUPPORTED);
877 }
878
879 byte_stream++;
880 byte_stream_size--;
881 len = (byte_stream_size >> 1);
882 status = _nx_crypto_huge_number_setup(&point -> nx_crypto_ec_point_x, byte_stream, len);
883 if (status != NX_CRYPTO_SUCCESS)
884 {
885 return(status);
886 }
887
888 byte_stream += len;
889 status = _nx_crypto_huge_number_setup(&point -> nx_crypto_ec_point_y, byte_stream, len);
890
891 return(status);
892 }
893
894 /**************************************************************************/
895 /* */
896 /* FUNCTION RELEASE */
897 /* */
898 /* _nx_crypto_ec_point_extract_uncompressed PORTABLE C */
899 /* 6.1 */
900 /* AUTHOR */
901 /* */
902 /* Timothy Stapko, Microsoft Corporation */
903 /* */
904 /* DESCRIPTION */
905 /* */
906 /* This function extracts point to byte stream in uncompressed format. */
907 /* */
908 /* INPUT */
909 /* */
910 /* curve Pointer to curve */
911 /* point Pointer to point */
912 /* byte_stream Byte stream for output */
913 /* byte_stream_size Size of byte stream buffer */
914 /* huge_number_size Actual size of byte stream */
915 /* */
916 /* OUTPUT */
917 /* */
918 /* None */
919 /* */
920 /* CALLS */
921 /* */
922 /* _nx_crypto_huge_number_extract Extract huge number */
923 /* */
924 /* CALLED BY */
925 /* */
926 /* _nx_crypto_ecjpake_hello_generate Generate hello message */
927 /* _nx_crypto_ecjpake_key_exchange_generate */
928 /* Generate key exchange message */
929 /* _nx_crypto_ecjpake_schnorr_zkp_hash Perform Schnorr ZKP hash */
930 /* calculation */
931 /* */
932 /* RELEASE HISTORY */
933 /* */
934 /* DATE NAME DESCRIPTION */
935 /* */
936 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
937 /* 09-30-2020 Timothy Stapko Modified comment(s), */
938 /* resulting in version 6.1 */
939 /* */
940 /**************************************************************************/
_nx_crypto_ec_point_extract_uncompressed(NX_CRYPTO_EC * curve,NX_CRYPTO_EC_POINT * point,UCHAR * byte_stream,UINT byte_stream_size,UINT * huge_number_size)941 NX_CRYPTO_KEEP VOID _nx_crypto_ec_point_extract_uncompressed(NX_CRYPTO_EC *curve, NX_CRYPTO_EC_POINT *point,
942 UCHAR *byte_stream, UINT byte_stream_size,
943 UINT *huge_number_size)
944 {
945 UINT status;
946 UINT clen;
947
948 clen = (curve -> nx_crypto_ec_bits + 7) >> 3;
949
950 if (byte_stream_size < 1 + (clen << 1))
951 {
952 *huge_number_size = 0;
953 return;
954 }
955
956 *byte_stream++ = 0x04;
957 *huge_number_size = 1;
958 byte_stream_size--;
959
960 status = _nx_crypto_huge_number_extract_fixed_size(&point -> nx_crypto_ec_point_x,
961 byte_stream, clen);
962 if (status)
963 {
964 *huge_number_size = 0;
965 return;
966 }
967
968 byte_stream += clen;
969 *huge_number_size = *huge_number_size + clen;
970 byte_stream_size -= clen;
971
972 status = _nx_crypto_huge_number_extract_fixed_size(&point -> nx_crypto_ec_point_y,
973 byte_stream, clen);
974 if (status)
975 {
976 *huge_number_size = 0;
977 return;
978 }
979
980 *huge_number_size = *huge_number_size + clen;
981 }
982
983 /**************************************************************************/
984 /* */
985 /* FUNCTION RELEASE */
986 /* */
987 /* _nx_crypto_ec_point_fp_affine_to_projective PORTABLE C */
988 /* 6.1 */
989 /* AUTHOR */
990 /* */
991 /* Timothy Stapko, Microsoft Corporation */
992 /* */
993 /* DESCRIPTION */
994 /* */
995 /* This function converts point from affine coordinate to projective */
996 /* coordinate in prime field. */
997 /* */
998 /* INPUT */
999 /* */
1000 /* point Pointer to point */
1001 /* */
1002 /* OUTPUT */
1003 /* */
1004 /* None */
1005 /* */
1006 /* CALLS */
1007 /* */
1008 /* NX_CRYPTO_HUGE_NUMBER_SET_DIGIT Set value of huge number */
1009 /* between 0 and (HN_RADIX - 1)*/
1010 /* */
1011 /* CALLED BY */
1012 /* */
1013 /* _nx_crypto_ec_fp_projective_add Perform addition for points of*/
1014 /* projective and affine */
1015 /* */
1016 /* RELEASE HISTORY */
1017 /* */
1018 /* DATE NAME DESCRIPTION */
1019 /* */
1020 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1021 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1022 /* resulting in version 6.1 */
1023 /* */
1024 /**************************************************************************/
_nx_crypto_ec_point_fp_affine_to_projective(NX_CRYPTO_EC_POINT * point)1025 NX_CRYPTO_KEEP VOID _nx_crypto_ec_point_fp_affine_to_projective(NX_CRYPTO_EC_POINT *point)
1026 {
1027 point -> nx_crypto_ec_point_type = NX_CRYPTO_EC_POINT_PROJECTIVE;
1028 NX_CRYPTO_HUGE_NUMBER_SET_DIGIT(&point -> nx_crypto_ec_point_z, 1);
1029 }
1030
1031 /* FP: (X, Y, Z) -> (X/Z^2, Y/Z^3) */
1032 /**************************************************************************/
1033 /* */
1034 /* FUNCTION RELEASE */
1035 /* */
1036 /* _nx_crypto_ec_point_fp_projective_to_affine PORTABLE C */
1037 /* 6.1 */
1038 /* AUTHOR */
1039 /* */
1040 /* Timothy Stapko, Microsoft Corporation */
1041 /* */
1042 /* DESCRIPTION */
1043 /* */
1044 /* This function converts point from projective coordinate to affine */
1045 /* coordinate in prime field. */
1046 /* */
1047 /* INPUT */
1048 /* */
1049 /* curve Pointer to curve */
1050 /* point Pointer to point */
1051 /* scratch Pointer to scratch buffer */
1052 /* */
1053 /* OUTPUT */
1054 /* */
1055 /* None */
1056 /* */
1057 /* CALLS */
1058 /* */
1059 /* _nx_crypto_ec_point_is_infinite Check if the point is infinite*/
1060 /* _nx_crypto_huge_number_inverse_modulus_prime */
1061 /* Perform an inverse modulus */
1062 /* operation for prime number */
1063 /* NX_CRYPTO_EC_MULTIPLE_REDUCE Multiply two huge numbers */
1064 /* NX_CRYPTO_EC_SQUARE_REDUCE Computes the square of a value*/
1065 /* NX_CRYPTO_HUGE_NUMBER_COPY Copy huge number */
1066 /* NX_CRYPTO_HUGE_NUMBER_INITIALIZE Initialize the buffer of */
1067 /* huge number */
1068 /* */
1069 /* CALLED BY */
1070 /* */
1071 /* _nx_crypto_ec_fp_fixed_multiple Calculate the fixed */
1072 /* multiplication */
1073 /* _nx_crypto_ec_fp_projective_multiple Calculate the projective */
1074 /* multiplication */
1075 /* */
1076 /* RELEASE HISTORY */
1077 /* */
1078 /* DATE NAME DESCRIPTION */
1079 /* */
1080 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1081 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1082 /* resulting in version 6.1 */
1083 /* */
1084 /**************************************************************************/
_nx_crypto_ec_point_fp_projective_to_affine(NX_CRYPTO_EC * curve,NX_CRYPTO_EC_POINT * point,HN_UBASE * scratch)1085 NX_CRYPTO_KEEP VOID _nx_crypto_ec_point_fp_projective_to_affine(NX_CRYPTO_EC *curve,
1086 NX_CRYPTO_EC_POINT *point,
1087 HN_UBASE *scratch)
1088 {
1089 NX_CRYPTO_HUGE_NUMBER temp1, temp2, zi;
1090 NX_CRYPTO_HUGE_NUMBER *p;
1091 UINT buffer_size;
1092
1093 p = &curve -> nx_crypto_ec_field.fp;
1094
1095 if (_nx_crypto_ec_point_is_infinite(point))
1096 {
1097 point -> nx_crypto_ec_point_type = NX_CRYPTO_EC_POINT_AFFINE;
1098 _nx_crypto_ec_point_set_infinite(point);
1099 return;
1100 }
1101
1102 buffer_size = point -> nx_crypto_ec_point_x.nx_crypto_huge_buffer_size;
1103 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp1, scratch, buffer_size << 1);
1104 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp2, scratch, buffer_size << 1);
1105 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&zi, scratch, buffer_size);
1106
1107 /* zi = Z ^ -1 mod p */
1108 _nx_crypto_huge_number_inverse_modulus_prime(&point -> nx_crypto_ec_point_z,
1109 p, &zi, scratch);
1110
1111 /* X = X * Z ^ -2 mod p */
1112 NX_CRYPTO_EC_SQUARE_REDUCE(curve, &zi, &temp1, scratch);
1113 NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &point -> nx_crypto_ec_point_x,
1114 &temp1, &temp2, scratch);
1115 NX_CRYPTO_HUGE_NUMBER_COPY(&point -> nx_crypto_ec_point_x, &temp2);
1116
1117 /* Y = Y * Z ^ -3 mod p */
1118 NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &zi, &temp1, &temp2, scratch);
1119 NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &point -> nx_crypto_ec_point_y,
1120 &temp2, &temp1, scratch);
1121 NX_CRYPTO_HUGE_NUMBER_COPY(&point -> nx_crypto_ec_point_y, &temp1);
1122 }
1123
1124 /**************************************************************************/
1125 /* */
1126 /* FUNCTION RELEASE */
1127 /* */
1128 /* _nx_crypto_ec_secp192r1_reduce PORTABLE C */
1129 /* 6.1.10 */
1130 /* AUTHOR */
1131 /* */
1132 /* Timothy Stapko, Microsoft Corporation */
1133 /* */
1134 /* DESCRIPTION */
1135 /* */
1136 /* This function reduces the value of curve secp192r1. */
1137 /* */
1138 /* INPUT */
1139 /* */
1140 /* curve Pointer to curve */
1141 /* point Pointer to point */
1142 /* scratch Pointer to scratch buffer */
1143 /* */
1144 /* OUTPUT */
1145 /* */
1146 /* None */
1147 /* */
1148 /* CALLS */
1149 /* */
1150 /* NX_CRYPTO_EC_SECP192R1_DATA_SETUP Setup EC SECP192R1 data */
1151 /* NX_CRYPTO_HUGE_NUMBER_INITIALIZE Initialize the buffer of */
1152 /* huge number */
1153 /* NX_CRYPTO_HUGE_NUMBER_SET_DIGIT Set value of huge number */
1154 /* between 0 and (HN_RADIX - 1)*/
1155 /* _nx_crypto_huge_number_add Calculate addition for */
1156 /* huge numbers */
1157 /* _nx_crypto_huge_number_compare Compare two huge numbers */
1158 /* _nx_crypto_huge_number_compare_unsigned */
1159 /* Compare two unsigned */
1160 /* huge numbers */
1161 /* _nx_crypto_huge_number_extract Extract huge number */
1162 /* _nx_crypto_huge_number_setup Setup huge number */
1163 /* _nx_crypto_huge_number_subtract_unsigned */
1164 /* Calculate subtraction for */
1165 /* unsigned huge numbers */
1166 /* */
1167 /* CALLED BY */
1168 /* */
1169 /* Application Code */
1170 /* */
1171 /* RELEASE HISTORY */
1172 /* */
1173 /* DATE NAME DESCRIPTION */
1174 /* */
1175 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1176 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1177 /* verified memmove use cases, */
1178 /* resulting in version 6.1 */
1179 /* 01-31-2022 Timothy Stapko Modified comment(s), and */
1180 /* improved performance, */
1181 /* resulting in version 6.1.10 */
1182 /* */
1183 /**************************************************************************/
_nx_crypto_ec_secp192r1_reduce(NX_CRYPTO_EC * curve,NX_CRYPTO_HUGE_NUMBER * value,HN_UBASE * scratch)1184 NX_CRYPTO_KEEP VOID _nx_crypto_ec_secp192r1_reduce(NX_CRYPTO_EC *curve,
1185 NX_CRYPTO_HUGE_NUMBER *value,
1186 HN_UBASE *scratch)
1187 {
1188 NX_CRYPTO_HUGE_NUMBER temp;
1189 UINT *data;
1190 HN_UBASE rev1;
1191 UINT size = 0;
1192 UINT compare_value;
1193
1194 compare_value = _nx_crypto_huge_number_compare(value, &curve -> nx_crypto_ec_field.fp);
1195 if (compare_value == NX_CRYPTO_HUGE_NUMBER_LESS)
1196 {
1197 return;
1198 }
1199 else if (compare_value == NX_CRYPTO_HUGE_NUMBER_EQUAL)
1200 {
1201 NX_CRYPTO_HUGE_NUMBER_SET_DIGIT(value, 0);
1202 return;
1203 }
1204
1205 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp, scratch, 36);
1206
1207 data = (UINT *)(((ULONG)scratch + 3) & (ULONG) ~3);
1208
1209 /* c= (c5,...,c2,c1,c0), ci is a 64-bit word */
1210 _nx_crypto_huge_number_extract(value, (UCHAR *)data, 48, &size);
1211 if (size < 48)
1212 {
1213 NX_CRYPTO_MEMMOVE((UCHAR *)data + (48 - size), data, size); /* Use case of memmove is verified. */
1214 NX_CRYPTO_MEMSET(data, 0, (48 - size));
1215 }
1216
1217 /* r = s1 + s2 + s3 + s4 mod p */
1218
1219 /* s1 = (c2,c1,c0) */
1220 _nx_crypto_huge_number_setup(value, (UCHAR *)data + 24, 24);
1221
1222 /* s2 = (0,c3,c3) */
1223 NX_CRYPTO_EC_SECP192R1_DATA_SETUP(&temp, rev1,
1224 0, 0, data[4], data[5],
1225 data[4], data[5]);
1226 _nx_crypto_huge_number_add(value, &temp);
1227
1228 /* s3 = (c4,c4,0) */
1229 NX_CRYPTO_EC_SECP192R1_DATA_SETUP(&temp, rev1,
1230 data[2], data[3], data[2],
1231 data[3], 0, 0);
1232 _nx_crypto_huge_number_add(value, &temp);
1233
1234 /* s4 = (c5,c5,c5) */
1235 NX_CRYPTO_EC_SECP192R1_DATA_SETUP(&temp, rev1,
1236 data[0], data[1], data[0], data[1],
1237 data[0], data[1]);
1238 _nx_crypto_huge_number_add(value, &temp);
1239
1240 compare_value = _nx_crypto_huge_number_compare_unsigned(value, &curve -> nx_crypto_ec_field.fp);
1241 while (compare_value != NX_CRYPTO_HUGE_NUMBER_LESS)
1242 {
1243 _nx_crypto_huge_number_subtract_unsigned(value, &curve -> nx_crypto_ec_field.fp, value);
1244 compare_value = _nx_crypto_huge_number_compare_unsigned(value,
1245 &curve -> nx_crypto_ec_field.fp);
1246 }
1247 if (_nx_crypto_huge_number_is_zero(value))
1248 {
1249 value -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
1250 }
1251 else if (value -> nx_crypto_huge_number_is_negative)
1252 {
1253 _nx_crypto_huge_number_subtract_unsigned(&curve -> nx_crypto_ec_field.fp, value, value);
1254 value -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
1255 }
1256 }
1257
1258 /**************************************************************************/
1259 /* */
1260 /* FUNCTION RELEASE */
1261 /* */
1262 /* _nx_crypto_ec_secp224r1_reduce PORTABLE C */
1263 /* 6.1.10 */
1264 /* AUTHOR */
1265 /* */
1266 /* Timothy Stapko, Microsoft Corporation */
1267 /* */
1268 /* DESCRIPTION */
1269 /* */
1270 /* This function reduces the value of curve secp224r1. */
1271 /* */
1272 /* INPUT */
1273 /* */
1274 /* curve Pointer to curve */
1275 /* point Pointer to point */
1276 /* scratch Pointer to scratch buffer */
1277 /* */
1278 /* OUTPUT */
1279 /* */
1280 /* None */
1281 /* */
1282 /* CALLS */
1283 /* */
1284 /* NX_CRYPTO_EC_SECP224R1_DATA_SETUP Setup EC SECP224R1 data */
1285 /* NX_CRYPTO_HUGE_NUMBER_INITIALIZE Initialize the buffer of */
1286 /* huge number */
1287 /* NX_CRYPTO_HUGE_NUMBER_SET_DIGIT Set value of huge number */
1288 /* between 0 and (HN_RADIX - 1)*/
1289 /* _nx_crypto_huge_number_is_zero Check if number is zero or not*/
1290 /* _nx_crypto_huge_number_add Calculate addition for */
1291 /* huge numbers */
1292 /* _nx_crypto_huge_number_compare Compare two huge numbers */
1293 /* _nx_crypto_huge_number_compare_unsigned */
1294 /* Compare two unsigned */
1295 /* huge numbers */
1296 /* _nx_crypto_huge_number_extract Extract huge number */
1297 /* _nx_crypto_huge_number_setup Setup huge number */
1298 /* _nx_crypto_huge_number_subtract Calculate subtraction for */
1299 /* huge numbers */
1300 /* _nx_crypto_huge_number_subtract_unsigned */
1301 /* Calculate subtraction for */
1302 /* unsigned huge numbers */
1303 /* */
1304 /* CALLED BY */
1305 /* */
1306 /* Application Code */
1307 /* */
1308 /* RELEASE HISTORY */
1309 /* */
1310 /* DATE NAME DESCRIPTION */
1311 /* */
1312 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1313 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1314 /* verified memmove use cases, */
1315 /* resulting in version 6.1 */
1316 /* 01-31-2022 Timothy Stapko Modified comment(s), and */
1317 /* improved performance, */
1318 /* resulting in version 6.1.10 */
1319 /* */
1320 /**************************************************************************/
_nx_crypto_ec_secp224r1_reduce(NX_CRYPTO_EC * curve,NX_CRYPTO_HUGE_NUMBER * value,HN_UBASE * scratch)1321 NX_CRYPTO_KEEP VOID _nx_crypto_ec_secp224r1_reduce(NX_CRYPTO_EC *curve,
1322 NX_CRYPTO_HUGE_NUMBER *value,
1323 HN_UBASE *scratch)
1324 {
1325 NX_CRYPTO_HUGE_NUMBER temp;
1326 UINT *data;
1327 HN_UBASE rev1;
1328 UINT size = 0;
1329 UINT compare_value;
1330
1331 compare_value = _nx_crypto_huge_number_compare(value, &curve -> nx_crypto_ec_field.fp);
1332 if (compare_value == NX_CRYPTO_HUGE_NUMBER_LESS)
1333 {
1334 return;
1335 }
1336 else if (compare_value == NX_CRYPTO_HUGE_NUMBER_EQUAL)
1337 {
1338 NX_CRYPTO_HUGE_NUMBER_SET_DIGIT(value, 0);
1339 return;
1340 }
1341
1342 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp, scratch, 36);
1343
1344 data = (UINT *)(((ULONG)scratch + 3) & (ULONG) ~3);
1345
1346 /* c= (c13,...,c2,c1,c0), ci is a 32-bit word */
1347 _nx_crypto_huge_number_extract(value, (UCHAR *)data, 56, &size);
1348 if (size < 56)
1349 {
1350 NX_CRYPTO_MEMMOVE((UCHAR *)data + (56 - size), data, size); /* Use case of memmove is verified. */
1351 NX_CRYPTO_MEMSET(data, 0, (56 - size));
1352 }
1353
1354 /* r = s1 + s2 + s3 - s4 - s5 mod p */
1355
1356 /* s1 = (c6,c5,c4,c3,c2,c1,c0) */
1357 _nx_crypto_huge_number_setup(value, (UCHAR *)data + 28, 28);
1358
1359 /* s2 = (c10,c9,c8,c7,0,0,0) */
1360 NX_CRYPTO_EC_SECP224R1_DATA_SETUP(&temp, rev1,
1361 data[3], data[4], data[5],
1362 data[6], 0, 0, 0);
1363 _nx_crypto_huge_number_add(value, &temp);
1364
1365 /* s3 = (0,c13,c12,c11,0,0,0) */
1366 NX_CRYPTO_EC_SECP224R1_DATA_SETUP(&temp, rev1,
1367 0, data[0], data[1],
1368 data[2], 0, 0, 0);
1369 _nx_crypto_huge_number_add(value, &temp);
1370
1371 /* s4 = (c13,c12,c11,c10,c9,c8,c7) */
1372 NX_CRYPTO_EC_SECP224R1_DATA_SETUP(&temp, rev1,
1373 data[0], data[1], data[2], data[3],
1374 data[4], data[5], data[6]);
1375 _nx_crypto_huge_number_subtract(value, &temp);
1376
1377 /* s5 = (0,0,0,0,c13,c12,c11) */
1378 NX_CRYPTO_EC_SECP224R1_DATA_SETUP(&temp, rev1,
1379 0, 0, 0, 0, data[0],
1380 data[1], data[2]);
1381 _nx_crypto_huge_number_subtract(value, &temp);
1382
1383 compare_value = _nx_crypto_huge_number_compare_unsigned(value, &curve -> nx_crypto_ec_field.fp);
1384 while (compare_value != NX_CRYPTO_HUGE_NUMBER_LESS)
1385 {
1386 _nx_crypto_huge_number_subtract_unsigned(value, &curve -> nx_crypto_ec_field.fp, value);
1387 compare_value = _nx_crypto_huge_number_compare_unsigned(value,
1388 &curve -> nx_crypto_ec_field.fp);
1389 }
1390 if (_nx_crypto_huge_number_is_zero(value))
1391 {
1392 value -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
1393 }
1394 else if (value -> nx_crypto_huge_number_is_negative)
1395 {
1396 _nx_crypto_huge_number_subtract_unsigned(&curve -> nx_crypto_ec_field.fp, value, value);
1397 value -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
1398 }
1399 }
1400
1401 /**************************************************************************/
1402 /* */
1403 /* FUNCTION RELEASE */
1404 /* */
1405 /* _nx_crypto_ec_secp256r1_reduce PORTABLE C */
1406 /* 6.1.10 */
1407 /* AUTHOR */
1408 /* */
1409 /* Timothy Stapko, Microsoft Corporation */
1410 /* */
1411 /* DESCRIPTION */
1412 /* */
1413 /* This function reduces the value of curve secp256r1. */
1414 /* */
1415 /* INPUT */
1416 /* */
1417 /* curve Pointer to curve */
1418 /* point Pointer to point */
1419 /* scratch Pointer to scratch buffer */
1420 /* */
1421 /* OUTPUT */
1422 /* */
1423 /* None */
1424 /* */
1425 /* CALLS */
1426 /* */
1427 /* NX_CRYPTO_EC_SECP256R1_DATA_SETUP Setup EC SECP256R1 data */
1428 /* NX_CRYPTO_HUGE_NUMBER_INITIALIZE Initialize the buffer of */
1429 /* huge number */
1430 /* NX_CRYPTO_HUGE_NUMBER_SET_DIGIT Set value of huge number */
1431 /* between 0 and (HN_RADIX - 1)*/
1432 /* _nx_crypto_huge_number_add Calculate addition for */
1433 /* huge numbers */
1434 /* _nx_crypto_huge_number_compare Compare two huge numbers */
1435 /* _nx_crypto_huge_number_compare_unsigned */
1436 /* Compare two unsigned */
1437 /* huge numbers */
1438 /* _nx_crypto_huge_number_extract Extract huge number */
1439 /* _nx_crypto_huge_number_shift_left Shift left for huge number */
1440 /* _nx_crypto_huge_number_setup Setup huge number */
1441 /* _nx_crypto_huge_number_subtract Calculate subtraction for */
1442 /* huge numbers */
1443 /* _nx_crypto_huge_number_subtract_unsigned */
1444 /* Calculate subtraction for */
1445 /* unsigned huge numbers */
1446 /* */
1447 /* CALLED BY */
1448 /* */
1449 /* Application Code */
1450 /* */
1451 /* RELEASE HISTORY */
1452 /* */
1453 /* DATE NAME DESCRIPTION */
1454 /* */
1455 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1456 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1457 /* verified memmove use cases, */
1458 /* resulting in version 6.1 */
1459 /* 01-31-2022 Timothy Stapko Modified comment(s), and */
1460 /* improved performance, */
1461 /* resulting in version 6.1.10 */
1462 /* */
1463 /**************************************************************************/
_nx_crypto_ec_secp256r1_reduce(NX_CRYPTO_EC * curve,NX_CRYPTO_HUGE_NUMBER * value,HN_UBASE * scratch)1464 NX_CRYPTO_KEEP VOID _nx_crypto_ec_secp256r1_reduce(NX_CRYPTO_EC *curve,
1465 NX_CRYPTO_HUGE_NUMBER *value,
1466 HN_UBASE *scratch)
1467 {
1468 NX_CRYPTO_HUGE_NUMBER temp;
1469 UINT *data;
1470 HN_UBASE rev1;
1471 HN_UBASE rev2;
1472 UINT size = 0;
1473 UINT compare_value;
1474
1475 compare_value = _nx_crypto_huge_number_compare(value, &curve -> nx_crypto_ec_field.fp);
1476 if (compare_value == NX_CRYPTO_HUGE_NUMBER_LESS)
1477 {
1478 return;
1479 }
1480 else if (compare_value == NX_CRYPTO_HUGE_NUMBER_EQUAL)
1481 {
1482 NX_CRYPTO_HUGE_NUMBER_SET_DIGIT(value, 0);
1483 return;
1484 }
1485
1486 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp, scratch, 36);
1487
1488 data = (UINT *)(((ULONG)scratch + 3) & (ULONG) ~3);
1489
1490 /* c= (c15,...,c2,c1,c0), ci is a 32-bit word */
1491 _nx_crypto_huge_number_extract(value, (UCHAR *)data, 64, &size);
1492 if (size < 64)
1493 {
1494 NX_CRYPTO_MEMMOVE((UCHAR *)data + (64 - size), data, size); /* Use case of memmove is verified. */
1495 NX_CRYPTO_MEMSET(data, 0, (64 - size));
1496 }
1497
1498 /* r = s1 + 2 * s2 + 2 * s3 + s4 + s5 - s6 - s7 - s8 - s9 mod p */
1499
1500 /* s1 = (c7,c6,c5,c4,c3,c2,c1,c0) */
1501 _nx_crypto_huge_number_setup(value, (UCHAR *)data + 32, 32);
1502
1503 /* s2 = (c15,c14,c13,c12,c11,0,0,0) */
1504 NX_CRYPTO_EC_SECP256R1_DATA_SETUP_LS1(&temp, rev1, rev2,
1505 data[0], data[1], data[2], data[3],
1506 data[4], 0, 0, 0);
1507 _nx_crypto_huge_number_add(value, &temp);
1508
1509 /* s3 = (0,c15,c14,c13,c12,0,0,0) */
1510 NX_CRYPTO_EC_SECP256R1_DATA_SETUP_LS1(&temp, rev1, rev2,
1511 0, data[0], data[1], data[2],
1512 data[3], 0, 0, 0);
1513 _nx_crypto_huge_number_add(value, &temp);
1514
1515 /* s4 = (c15,c14,0,0,0,c10,c9,c8) */
1516 NX_CRYPTO_EC_SECP256R1_DATA_SETUP(&temp, rev1,
1517 data[0], data[1], 0, 0,
1518 0, data[5], data[6], data[7]);
1519 _nx_crypto_huge_number_add(value, &temp);
1520
1521 /* s5 = (c8,c13,c15,c14,c13,c11,c10,c9) */
1522 NX_CRYPTO_EC_SECP256R1_DATA_SETUP(&temp, rev1,
1523 data[7], data[2], data[0], data[1],
1524 data[2], data[4], data[5], data[6]);
1525 _nx_crypto_huge_number_add(value, &temp);
1526
1527 /* s6 = (c10,c8,0,0,0,c13,c12,c11) */
1528 NX_CRYPTO_EC_SECP256R1_DATA_SETUP(&temp, rev1,
1529 data[5], data[7], 0, 0,
1530 0, data[2], data[3], data[4]);
1531 _nx_crypto_huge_number_subtract(value, &temp);
1532
1533 /* s7 = (c11,c9,0,0,c15,c14,c13,c12) */
1534 NX_CRYPTO_EC_SECP256R1_DATA_SETUP(&temp, rev1,
1535 data[4], data[6], 0, 0,
1536 data[0], data[1], data[2], data[3]);
1537 _nx_crypto_huge_number_subtract(value, &temp);
1538
1539 /* s8 = (c12,0,c10,c9,c8,c15,c14,c13) */
1540 NX_CRYPTO_EC_SECP256R1_DATA_SETUP(&temp, rev1,
1541 data[3], 0, data[5], data[6],
1542 data[7], data[0], data[1], data[2]);
1543 _nx_crypto_huge_number_subtract(value, &temp);
1544
1545 /* s9 = (c13,0,c11,c10,c9,0,c15,c14) */
1546 NX_CRYPTO_EC_SECP256R1_DATA_SETUP(&temp, rev1,
1547 data[2], 0, data[4], data[5],
1548 data[6], 0, data[0], data[1]);
1549 _nx_crypto_huge_number_subtract(value, &temp);
1550
1551 compare_value = _nx_crypto_huge_number_compare_unsigned(value, &curve -> nx_crypto_ec_field.fp);
1552 while (compare_value != NX_CRYPTO_HUGE_NUMBER_LESS)
1553 {
1554 _nx_crypto_huge_number_subtract_unsigned(value, &curve -> nx_crypto_ec_field.fp, value);
1555 compare_value = _nx_crypto_huge_number_compare_unsigned(value,
1556 &curve -> nx_crypto_ec_field.fp);
1557 }
1558 if (_nx_crypto_huge_number_is_zero(value))
1559 {
1560 value -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
1561 }
1562 else if (value -> nx_crypto_huge_number_is_negative)
1563 {
1564 _nx_crypto_huge_number_subtract_unsigned(&curve -> nx_crypto_ec_field.fp, value, value);
1565 value -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
1566 }
1567 }
1568
1569 /**************************************************************************/
1570 /* */
1571 /* FUNCTION RELEASE */
1572 /* */
1573 /* _nx_crypto_ec_secp384r1_reduce PORTABLE C */
1574 /* 6.1.10 */
1575 /* AUTHOR */
1576 /* */
1577 /* Timothy Stapko, Microsoft Corporation */
1578 /* */
1579 /* DESCRIPTION */
1580 /* */
1581 /* This function reduces the value of curve secp384r1. */
1582 /* */
1583 /* INPUT */
1584 /* */
1585 /* curve Pointer to curve */
1586 /* point Pointer to point */
1587 /* scratch Pointer to scratch buffer */
1588 /* */
1589 /* OUTPUT */
1590 /* */
1591 /* None */
1592 /* */
1593 /* CALLS */
1594 /* */
1595 /* NX_CRYPTO_EC_SECP384R1_DATA_SETUP Setup EC SECP384R1 data */
1596 /* NX_CRYPTO_HUGE_NUMBER_INITIALIZE Initialize the buffer of */
1597 /* huge number */
1598 /* NX_CRYPTO_HUGE_NUMBER_SET_DIGIT Set value of huge number */
1599 /* between 0 and (HN_RADIX - 1)*/
1600 /* _nx_crypto_huge_number_add Calculate addition for */
1601 /* huge numbers */
1602 /* _nx_crypto_huge_number_compare Compare two huge numbers */
1603 /* _nx_crypto_huge_number_compare_unsigned */
1604 /* Compare two unsigned */
1605 /* huge numbers */
1606 /* _nx_crypto_huge_number_extract Extract huge number */
1607 /* _nx_crypto_huge_number_setup Setup huge number */
1608 /* _nx_crypto_huge_number_subtract_unsigned */
1609 /* Calculate subtraction for */
1610 /* unsigned huge numbers */
1611 /* */
1612 /* CALLED BY */
1613 /* */
1614 /* Application Code */
1615 /* */
1616 /* RELEASE HISTORY */
1617 /* */
1618 /* DATE NAME DESCRIPTION */
1619 /* */
1620 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1621 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1622 /* verified memmove use cases, */
1623 /* resulting in version 6.1 */
1624 /* 01-31-2022 Timothy Stapko Modified comment(s), and */
1625 /* improved performance, */
1626 /* resulting in version 6.1.10 */
1627 /* */
1628 /**************************************************************************/
_nx_crypto_ec_secp384r1_reduce(NX_CRYPTO_EC * curve,NX_CRYPTO_HUGE_NUMBER * value,HN_UBASE * scratch)1629 NX_CRYPTO_KEEP VOID _nx_crypto_ec_secp384r1_reduce(NX_CRYPTO_EC *curve,
1630 NX_CRYPTO_HUGE_NUMBER *value,
1631 HN_UBASE *scratch)
1632 {
1633 NX_CRYPTO_HUGE_NUMBER temp;
1634 UINT *data;
1635 HN_UBASE rev1;
1636 HN_UBASE rev2;
1637 UINT size = 0;
1638 UINT compare_value;
1639
1640 compare_value = _nx_crypto_huge_number_compare(value, &curve -> nx_crypto_ec_field.fp);
1641 if (compare_value == NX_CRYPTO_HUGE_NUMBER_LESS)
1642 {
1643 return;
1644 }
1645 else if (compare_value == NX_CRYPTO_HUGE_NUMBER_EQUAL)
1646 {
1647 NX_CRYPTO_HUGE_NUMBER_SET_DIGIT(value, 0);
1648 return;
1649 }
1650
1651 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp, scratch, 52);
1652
1653 data = (UINT *)(((ULONG)scratch + 3) & (ULONG) ~3);
1654
1655 /* c= (c23,...,c2,c1,c0), ci is a 32-bit word */
1656 _nx_crypto_huge_number_extract(value, (UCHAR *)data, 96, &size);
1657 if (size < 96)
1658 {
1659 NX_CRYPTO_MEMMOVE((UCHAR *)data + (96 - size), data, size); /* Use case of memmove is verified. */
1660 NX_CRYPTO_MEMSET(data, 0, (96 - size));
1661 }
1662
1663 /* r = s1 + 2 * s2 + s3 + s4 + s5 + s6 + s7 - s8 - s9 -s10 mod p */
1664
1665 /* s1 = (c11,c10,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0) */
1666 _nx_crypto_huge_number_setup(value, (UCHAR *)data + 48, 48);
1667
1668 /* s2 = (0,0,0,0,0,c23,c22,c21,0,0,0,0) */
1669 NX_CRYPTO_EC_SECP384R1_DATA_SETUP_LS1(&temp, rev1, rev2,
1670 0, 0, 0, 0, 0, data[0],
1671 data[1], data[2], 0, 0, 0, 0);
1672 _nx_crypto_huge_number_add(value, &temp);
1673
1674 /* s3 = (c23,c22,c21,c20,c19,c18,c17,c16,c15,c14,c13,c12) */
1675 _nx_crypto_huge_number_setup(&temp, (UCHAR *)data, 48);
1676 _nx_crypto_huge_number_add(value, &temp);
1677
1678 /* s4 = (c20,c19,c18,c17,c16,c15,c14,c13,c12,c23,c22,c21) */
1679 NX_CRYPTO_EC_SECP384R1_DATA_SETUP(&temp, rev1,
1680 data[3], data[4], data[5], data[6],
1681 data[7], data[8], data[9], data[10],
1682 data[11], data[0], data[1], data[2]);
1683 _nx_crypto_huge_number_add(value, &temp);
1684
1685 /* s5 = (c19,c18,c17,c16,c15,c14,c13,c12,c20,0,c23,0) */
1686 NX_CRYPTO_EC_SECP384R1_DATA_SETUP(&temp, rev1,
1687 data[4], data[5], data[6],
1688 data[7], data[8], data[9], data[10],
1689 data[11], data[3], 0, data[0], 0);
1690 _nx_crypto_huge_number_add(value, &temp);
1691
1692 /* s6 = (0,0,0,0,c23,c22,c21,c20,0,0,0,0) */
1693 NX_CRYPTO_EC_SECP384R1_DATA_SETUP(&temp, rev1,
1694 0, 0, 0, 0,
1695 data[0], data[1], data[2], data[3],
1696 0, 0, 0, 0);
1697 _nx_crypto_huge_number_add(value, &temp);
1698
1699 /* s7 = (0,0,0,0,0,0,c23,c22,c21,0,0,c20) */
1700 NX_CRYPTO_EC_SECP384R1_DATA_SETUP(&temp, rev1,
1701 0, 0, 0, 0, 0, 0,
1702 data[0], data[1], data[2],
1703 0, 0, data[3]);
1704 _nx_crypto_huge_number_add(value, &temp);
1705
1706 /* s8 = (c22,c21,c20,c19,c18,c17,c16,c15,c14,c13,c12,c23) */
1707 NX_CRYPTO_EC_SECP384R1_DATA_SETUP(&temp, rev1,
1708 data[1], data[2], data[3], data[4],
1709 data[5], data[6], data[7], data[8],
1710 data[9], data[10], data[11], data[0]);
1711 _nx_crypto_huge_number_subtract(value, &temp);
1712
1713 /* s9 = (0,0,0,0,0,0,0,c23,c22,c21,c20,0) */
1714 NX_CRYPTO_EC_SECP384R1_DATA_SETUP(&temp, rev1,
1715 0, 0, 0, 0, 0, 0, 0, data[0],
1716 data[1], data[2], data[3], 0);
1717 _nx_crypto_huge_number_subtract(value, &temp);
1718
1719 /* s10 = (0,0,0,0,0,0,0,c23,c23,0,0,0) */
1720 NX_CRYPTO_EC_SECP384R1_DATA_SETUP(&temp, rev1,
1721 0, 0, 0, 0, 0, 0, 0, data[0],
1722 data[0], 0, 0, 0);
1723 _nx_crypto_huge_number_subtract(value, &temp);
1724
1725 compare_value = _nx_crypto_huge_number_compare_unsigned(value, &curve -> nx_crypto_ec_field.fp);
1726 while (compare_value != NX_CRYPTO_HUGE_NUMBER_LESS)
1727 {
1728 _nx_crypto_huge_number_subtract_unsigned(value, &curve -> nx_crypto_ec_field.fp, value);
1729 compare_value = _nx_crypto_huge_number_compare_unsigned(value,
1730 &curve -> nx_crypto_ec_field.fp);
1731 }
1732 if (_nx_crypto_huge_number_is_zero(value))
1733 {
1734 value -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
1735 }
1736 else if (value -> nx_crypto_huge_number_is_negative)
1737 {
1738 _nx_crypto_huge_number_subtract_unsigned(&curve -> nx_crypto_ec_field.fp, value, value);
1739 value -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
1740 }
1741 }
1742
1743 /**************************************************************************/
1744 /* */
1745 /* FUNCTION RELEASE */
1746 /* */
1747 /* _nx_crypto_ec_secp521r1_reduce PORTABLE C */
1748 /* 6.1 */
1749 /* AUTHOR */
1750 /* */
1751 /* Timothy Stapko, Microsoft Corporation */
1752 /* */
1753 /* DESCRIPTION */
1754 /* */
1755 /* This function reduces the value of curve secp521r1. */
1756 /* */
1757 /* INPUT */
1758 /* */
1759 /* curve Pointer to curve */
1760 /* point Pointer to point */
1761 /* scratch Pointer to scratch buffer */
1762 /* */
1763 /* OUTPUT */
1764 /* */
1765 /* None */
1766 /* */
1767 /* CALLS */
1768 /* */
1769 /* NX_CRYPTO_EC_SECP521R1_DATA_SETUP Setup EC SECP521R1 data */
1770 /* NX_CRYPTO_HUGE_NUMBER_INITIALIZE Initialize the buffer of */
1771 /* huge number */
1772 /* NX_CRYPTO_HUGE_NUMBER_SET_DIGIT Set value of huge number */
1773 /* between 0 and (HN_RADIX - 1)*/
1774 /* _nx_crypto_huge_number_is_zero Check if number is zero or not*/
1775 /* _nx_crypto_huge_number_add Calculate addition for */
1776 /* huge numbers */
1777 /* _nx_crypto_huge_number_compare Compare two huge numbers */
1778 /* _nx_crypto_huge_number_compare_unsigned */
1779 /* Compare two unsigned */
1780 /* huge numbers */
1781 /* _nx_crypto_huge_number_extract Extract huge number */
1782 /* _nx_crypto_huge_number_shift_right Shift right for huge number */
1783 /* _nx_crypto_huge_number_setup Setup huge number */
1784 /* _nx_crypto_huge_number_subtract_unsigned */
1785 /* Calculate subtraction for */
1786 /* unsigned huge numbers */
1787 /* */
1788 /* CALLED BY */
1789 /* */
1790 /* Application Code */
1791 /* */
1792 /* RELEASE HISTORY */
1793 /* */
1794 /* DATE NAME DESCRIPTION */
1795 /* */
1796 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1797 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1798 /* verified memmove use cases, */
1799 /* resulting in version 6.1 */
1800 /* */
1801 /**************************************************************************/
_nx_crypto_ec_secp521r1_reduce(NX_CRYPTO_EC * curve,NX_CRYPTO_HUGE_NUMBER * value,HN_UBASE * scratch)1802 NX_CRYPTO_KEEP VOID _nx_crypto_ec_secp521r1_reduce(NX_CRYPTO_EC *curve,
1803 NX_CRYPTO_HUGE_NUMBER *value,
1804 HN_UBASE *scratch)
1805 {
1806 NX_CRYPTO_HUGE_NUMBER temp;
1807 UCHAR *data;
1808 UINT size = 0;
1809 UINT compare_value;
1810
1811 compare_value = _nx_crypto_huge_number_compare(value, &curve -> nx_crypto_ec_field.fp);
1812 if (compare_value == NX_CRYPTO_HUGE_NUMBER_LESS)
1813 {
1814 return;
1815 }
1816 else if (compare_value == NX_CRYPTO_HUGE_NUMBER_EQUAL)
1817 {
1818 NX_CRYPTO_HUGE_NUMBER_SET_DIGIT(value, 0);
1819 return;
1820 }
1821
1822 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp, scratch, 66);
1823
1824 data = (UCHAR *)(((ULONG)scratch + 3) & (ULONG) ~3);
1825
1826
1827 /* c= (c1041,...,c2,c1,c0) */
1828 _nx_crypto_huge_number_extract(value, (UCHAR *)data, 132, &size);
1829 if (size < 132)
1830 {
1831 NX_CRYPTO_MEMMOVE(data + (132 - size), data, size); /* Use case of memmove is verified. */
1832 NX_CRYPTO_MEMSET(data, 0, (132 - size));
1833 }
1834
1835 /* r = s1 + s2 mod p */
1836
1837 /* s1 = (c1041,...,c523,c522,c521) */
1838 _nx_crypto_huge_number_setup(value, data, 67);
1839 _nx_crypto_huge_number_shift_right(value, 1);
1840
1841 /* s2 = (c520,...,c2,c1,c0) */
1842 data[66] &= 1;
1843 _nx_crypto_huge_number_setup(&temp, data + 66, 66);
1844 _nx_crypto_huge_number_add(value, &temp);
1845
1846 compare_value = _nx_crypto_huge_number_compare_unsigned(value, &curve -> nx_crypto_ec_field.fp);
1847 while (compare_value != NX_CRYPTO_HUGE_NUMBER_LESS)
1848 {
1849 _nx_crypto_huge_number_subtract_unsigned(value, &curve -> nx_crypto_ec_field.fp, value);
1850 compare_value = _nx_crypto_huge_number_compare_unsigned(value,
1851 &curve -> nx_crypto_ec_field.fp);
1852 }
1853 if (_nx_crypto_huge_number_is_zero(value))
1854 {
1855 value -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
1856 }
1857 else if (value -> nx_crypto_huge_number_is_negative)
1858 {
1859 _nx_crypto_huge_number_subtract_unsigned(&curve -> nx_crypto_ec_field.fp, value, value);
1860 value -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
1861 }
1862 }
1863
1864 /**************************************************************************/
1865 /* */
1866 /* FUNCTION RELEASE */
1867 /* */
1868 /* _nx_crypto_ec_add_digit_reduce PORTABLE C */
1869 /* 6.1.7 */
1870 /* AUTHOR */
1871 /* */
1872 /* Timothy Stapko, Microsoft Corporation */
1873 /* */
1874 /* DESCRIPTION */
1875 /* */
1876 /* This function performs addition between huge number and digit */
1877 /* number. The result is reduced after addition. */
1878 /* */
1879 /* INPUT */
1880 /* */
1881 /* curve Pointer to curve */
1882 /* value Huge number */
1883 /* digit Digit value */
1884 /* scratch Pointer to scratch buffer */
1885 /* */
1886 /* OUTPUT */
1887 /* */
1888 /* None */
1889 /* */
1890 /* CALLS */
1891 /* */
1892 /* _nx_crypto_huge_number_add_digit_unsigned */
1893 /* Calculate addition for */
1894 /* unsigned huge numbers */
1895 /* _nx_crypto_huge_number_compare_unsigned */
1896 /* Compare two unsigned */
1897 /* huge numbers */
1898 /* _nx_crypto_huge_number_subtract_unsigned */
1899 /* Calculate subtraction for */
1900 /* unsigned huge numbers */
1901 /* */
1902 /* CALLED BY */
1903 /* */
1904 /* Application */
1905 /* */
1906 /* RELEASE HISTORY */
1907 /* */
1908 /* DATE NAME DESCRIPTION */
1909 /* */
1910 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1911 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1912 /* resulting in version 6.1 */
1913 /* 06-02-2021 Bhupendra Naphade Modified comment(s), */
1914 /* renamed FIPS symbol to */
1915 /* self-test, */
1916 /* resulting in version 6.1.7 */
1917 /* */
1918 /**************************************************************************/
1919 #ifndef NX_CRYPTO_SELF_TEST
_nx_crypto_ec_add_digit_reduce(NX_CRYPTO_EC * curve,NX_CRYPTO_HUGE_NUMBER * value,HN_UBASE digit,HN_UBASE * scratch)1920 NX_CRYPTO_KEEP VOID _nx_crypto_ec_add_digit_reduce(NX_CRYPTO_EC *curve,
1921 NX_CRYPTO_HUGE_NUMBER *value,
1922 HN_UBASE digit,
1923 HN_UBASE *scratch)
1924 {
1925 NX_CRYPTO_PARAMETER_NOT_USED(scratch);
1926
1927 _nx_crypto_huge_number_add_digit_unsigned(value, digit);
1928 if (_nx_crypto_huge_number_compare_unsigned(value,
1929 &curve -> nx_crypto_ec_field.fp) != NX_CRYPTO_HUGE_NUMBER_LESS)
1930 {
1931 _nx_crypto_huge_number_subtract_unsigned(value, &curve -> nx_crypto_ec_field.fp, value);
1932 }
1933 }
1934 #endif
1935
1936 /**************************************************************************/
1937 /* */
1938 /* FUNCTION RELEASE */
1939 /* */
1940 /* _nx_crypto_ec_subtract_digit_reduce PORTABLE C */
1941 /* 6.1 */
1942 /* AUTHOR */
1943 /* */
1944 /* Timothy Stapko, Microsoft Corporation */
1945 /* */
1946 /* DESCRIPTION */
1947 /* */
1948 /* This function performs subtraction between huge number and digit */
1949 /* number. The result is reduced after subtraction. */
1950 /* */
1951 /* INPUT */
1952 /* */
1953 /* curve Pointer to curve */
1954 /* value Huge number */
1955 /* digit Digit value */
1956 /* scratch Pointer to scratch buffer */
1957 /* */
1958 /* OUTPUT */
1959 /* */
1960 /* None */
1961 /* */
1962 /* CALLS */
1963 /* */
1964 /* _nx_crypto_huge_number_add_unsigned Calculate addition for */
1965 /* unsigned huge numbers */
1966 /* _nx_crypto_huge_number_subtract_digit_unsigned */
1967 /* Calculate subtraction for */
1968 /* unsigned huge numbers */
1969 /* */
1970 /* CALLED BY */
1971 /* */
1972 /* _nx_crypto_ec_fp_affine_add Perform addition for points of*/
1973 /* affine */
1974 /* */
1975 /* RELEASE HISTORY */
1976 /* */
1977 /* DATE NAME DESCRIPTION */
1978 /* */
1979 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1980 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1981 /* resulting in version 6.1 */
1982 /* */
1983 /**************************************************************************/
_nx_crypto_ec_subtract_digit_reduce(NX_CRYPTO_EC * curve,NX_CRYPTO_HUGE_NUMBER * value,HN_UBASE digit,HN_UBASE * scratch)1984 NX_CRYPTO_KEEP VOID _nx_crypto_ec_subtract_digit_reduce(NX_CRYPTO_EC *curve,
1985 NX_CRYPTO_HUGE_NUMBER *value,
1986 HN_UBASE digit,
1987 HN_UBASE *scratch)
1988 {
1989 NX_CRYPTO_PARAMETER_NOT_USED(scratch);
1990
1991 if (((value -> nx_crypto_huge_number_size == 1) ||
1992 (value -> nx_crypto_huge_number_data[0] < digit)))
1993 {
1994 _nx_crypto_huge_number_add_unsigned(value, &curve -> nx_crypto_ec_field.fp);
1995 }
1996 _nx_crypto_huge_number_subtract_digit_unsigned(value, digit);
1997 }
1998
1999 /**************************************************************************/
2000 /* */
2001 /* FUNCTION RELEASE */
2002 /* */
2003 /* _nx_crypto_ec_fp_reduce PORTABLE C */
2004 /* 6.1.7 */
2005 /* AUTHOR */
2006 /* */
2007 /* Timothy Stapko, Microsoft Corporation */
2008 /* */
2009 /* DESCRIPTION */
2010 /* */
2011 /* This function reduces huge number for common prime field. */
2012 /* */
2013 /* INPUT */
2014 /* */
2015 /* curve Pointer to curve */
2016 /* value Huge number */
2017 /* scratch Pointer to scratch buffer */
2018 /* */
2019 /* OUTPUT */
2020 /* */
2021 /* None */
2022 /* */
2023 /* CALLS */
2024 /* */
2025 /* _nx_crypto_huge_number_modulus Perform a modulus operation */
2026 /* */
2027 /* CALLED BY */
2028 /* */
2029 /* Application Code */
2030 /* */
2031 /* RELEASE HISTORY */
2032 /* */
2033 /* DATE NAME DESCRIPTION */
2034 /* */
2035 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
2036 /* 09-30-2020 Timothy Stapko Modified comment(s), */
2037 /* resulting in version 6.1 */
2038 /* 06-02-2021 Bhupendra Naphade Modified comment(s), */
2039 /* renamed FIPS symbol to */
2040 /* self-test, */
2041 /* resulting in version 6.1.7 */
2042 /* */
2043 /**************************************************************************/
2044 #ifndef NX_CRYPTO_SELF_TEST
_nx_crypto_ec_fp_reduce(NX_CRYPTO_EC * curve,NX_CRYPTO_HUGE_NUMBER * value,HN_UBASE * scratch)2045 NX_CRYPTO_KEEP VOID _nx_crypto_ec_fp_reduce(NX_CRYPTO_EC *curve,
2046 NX_CRYPTO_HUGE_NUMBER *value,
2047 HN_UBASE *scratch)
2048 {
2049 NX_CRYPTO_PARAMETER_NOT_USED(scratch);
2050
2051 _nx_crypto_huge_number_modulus(value, &curve -> nx_crypto_ec_field.fp);
2052 }
2053 #endif
2054 /**************************************************************************/
2055 /* */
2056 /* FUNCTION RELEASE */
2057 /* */
2058 /* _nx_crypto_ec_add_reduce PORTABLE C */
2059 /* 6.1 */
2060 /* AUTHOR */
2061 /* */
2062 /* Timothy Stapko, Microsoft Corporation */
2063 /* */
2064 /* DESCRIPTION */
2065 /* */
2066 /* This function performs addition between two huge numbers. The result*/
2067 /* is reduced after addition. */
2068 /* */
2069 /* INPUT */
2070 /* */
2071 /* curve Pointer to curve */
2072 /* left Left huge number */
2073 /* right Right huge number */
2074 /* scratch Pointer to scratch buffer */
2075 /* */
2076 /* OUTPUT */
2077 /* */
2078 /* None */
2079 /* */
2080 /* CALLS */
2081 /* */
2082 /* _nx_crypto_huge_number_add_unsigned Calculate addition for */
2083 /* unsigned huge numbers */
2084 /* _nx_crypto_huge_number_compare_unsigned */
2085 /* Compare two unsigned */
2086 /* huge numbers */
2087 /* _nx_crypto_huge_number_subtract_unsigned */
2088 /* Calculate subtraction for */
2089 /* unsigned huge numbers */
2090 /* */
2091 /* CALLED BY */
2092 /* */
2093 /* _nx_crypto_ec_fp_projective_add Perform addition for points of*/
2094 /* projective and affine */
2095 /* _nx_crypto_ec_fp_projective_double Perform doubling for points of*/
2096 /* projective */
2097 /* */
2098 /* RELEASE HISTORY */
2099 /* */
2100 /* DATE NAME DESCRIPTION */
2101 /* */
2102 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
2103 /* 09-30-2020 Timothy Stapko Modified comment(s), */
2104 /* resulting in version 6.1 */
2105 /* */
2106 /**************************************************************************/
_nx_crypto_ec_add_reduce(NX_CRYPTO_EC * curve,NX_CRYPTO_HUGE_NUMBER * left,NX_CRYPTO_HUGE_NUMBER * right,HN_UBASE * scratch)2107 NX_CRYPTO_KEEP VOID _nx_crypto_ec_add_reduce(NX_CRYPTO_EC *curve,
2108 NX_CRYPTO_HUGE_NUMBER *left,
2109 NX_CRYPTO_HUGE_NUMBER *right,
2110 HN_UBASE *scratch)
2111 {
2112 NX_CRYPTO_PARAMETER_NOT_USED(scratch);
2113
2114 _nx_crypto_huge_number_add_unsigned(left, right);
2115 if (_nx_crypto_huge_number_compare_unsigned(left,
2116 &curve -> nx_crypto_ec_field.fp) != NX_CRYPTO_HUGE_NUMBER_LESS)
2117 {
2118 _nx_crypto_huge_number_subtract_unsigned(left, &curve -> nx_crypto_ec_field.fp, left);
2119 }
2120 }
2121
2122 /**************************************************************************/
2123 /* */
2124 /* FUNCTION RELEASE */
2125 /* */
2126 /* _nx_crypto_ec_subtract_reduce PORTABLE C */
2127 /* 6.1 */
2128 /* AUTHOR */
2129 /* */
2130 /* Timothy Stapko, Microsoft Corporation */
2131 /* */
2132 /* DESCRIPTION */
2133 /* */
2134 /* This function performs subtraction between two huge numbers. The */
2135 /* result is reduced after subtraction. */
2136 /* */
2137 /* INPUT */
2138 /* */
2139 /* curve Pointer to curve */
2140 /* left Left huge number */
2141 /* right Right huge number */
2142 /* scratch Pointer to scratch buffer */
2143 /* */
2144 /* OUTPUT */
2145 /* */
2146 /* None */
2147 /* */
2148 /* CALLS */
2149 /* */
2150 /* _nx_crypto_huge_number_compare_unsigned */
2151 /* Compare two unsigned */
2152 /* huge numbers */
2153 /* _nx_crypto_huge_number_add_unsigned Calculate addition for */
2154 /* unsigned huge numbers */
2155 /* _nx_crypto_huge_number_subtract_unsigned */
2156 /* Calculate subtraction for */
2157 /* unsigned huge numbers */
2158 /* */
2159 /* CALLED BY */
2160 /* */
2161 /* _nx_crypto_ec_fp_affine_add Perform addition for points of*/
2162 /* affine */
2163 /* _nx_crypto_ec_fp_affine_subtract Perform subtraction for points*/
2164 /* of affine */
2165 /* _nx_crypto_ec_fp_projective_add Perform addition for points of*/
2166 /* projective and affine */
2167 /* _nx_crypto_ec_fp_projective_double Perform doubling for points of*/
2168 /* projective */
2169 /* _nx_crypto_ec_fp_projective_multiple Calculate the projective */
2170 /* multiplication */
2171 /* */
2172 /* RELEASE HISTORY */
2173 /* */
2174 /* DATE NAME DESCRIPTION */
2175 /* */
2176 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
2177 /* 09-30-2020 Timothy Stapko Modified comment(s), */
2178 /* resulting in version 6.1 */
2179 /* */
2180 /**************************************************************************/
_nx_crypto_ec_subtract_reduce(NX_CRYPTO_EC * curve,NX_CRYPTO_HUGE_NUMBER * left,NX_CRYPTO_HUGE_NUMBER * right,HN_UBASE * scratch)2181 NX_CRYPTO_KEEP VOID _nx_crypto_ec_subtract_reduce(NX_CRYPTO_EC *curve,
2182 NX_CRYPTO_HUGE_NUMBER *left,
2183 NX_CRYPTO_HUGE_NUMBER *right,
2184 HN_UBASE *scratch)
2185 {
2186 NX_CRYPTO_PARAMETER_NOT_USED(scratch);
2187
2188 if (_nx_crypto_huge_number_compare_unsigned(left, right) == NX_CRYPTO_HUGE_NUMBER_LESS)
2189 {
2190 _nx_crypto_huge_number_add_unsigned(left, &curve -> nx_crypto_ec_field.fp);
2191 }
2192 _nx_crypto_huge_number_subtract_unsigned(left, right, left);
2193 }
2194
2195 /**************************************************************************/
2196 /* */
2197 /* FUNCTION RELEASE */
2198 /* */
2199 /* _nx_crypto_ec_fp_projective_add PORTABLE C */
2200 /* 6.1 */
2201 /* AUTHOR */
2202 /* */
2203 /* Timothy Stapko, Microsoft Corporation */
2204 /* */
2205 /* DESCRIPTION */
2206 /* */
2207 /* This function performs addition for points of projective and affine */
2208 /* coordinates in prime filed. */
2209 /* */
2210 /* INPUT */
2211 /* */
2212 /* curve Pointer to curve */
2213 /* projective_point Projective point */
2214 /* affine_point Affine point */
2215 /* scratch Pointer to scratch buffer */
2216 /* */
2217 /* OUTPUT */
2218 /* */
2219 /* status Completion status */
2220 /* */
2221 /* CALLS */
2222 /* */
2223 /* NX_CRYPTO_EC_MULTIPLE_REDUCE Multiply two huge numbers */
2224 /* NX_CRYPTO_EC_SHIFT_LEFT_REDUCE Shift left N bits */
2225 /* NX_CRYPTO_EC_SQUARE_REDUCE Computes the square of a value*/
2226 /* NX_CRYPTO_HUGE_NUMBER_COPY Copy huge number */
2227 /* NX_CRYPTO_HUGE_NUMBER_INITIALIZE Initialize the buffer of */
2228 /* huge number */
2229 /* _nx_crypto_ec_add_reduce Perform addition between */
2230 /* two huge numbers */
2231 /* _nx_crypto_ec_point_is_infinite Check if the point is infinite*/
2232 /* _nx_crypto_ec_point_fp_affine_to_projective */
2233 /* Convert point from affine to */
2234 /* projective */
2235 /* _nx_crypto_ec_subtract_reduce Perform subtraction between */
2236 /* two huge numbers */
2237 /* */
2238 /* CALLED BY */
2239 /* */
2240 /* _nx_crypto_ec_fp_fixed_multiple Calculate the fixed */
2241 /* multiplication */
2242 /* _nx_crypto_ec_fp_projective_multiple Calculate the projective */
2243 /* multiplication */
2244 /* */
2245 /* RELEASE HISTORY */
2246 /* */
2247 /* DATE NAME DESCRIPTION */
2248 /* */
2249 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
2250 /* 09-30-2020 Timothy Stapko Modified comment(s), */
2251 /* resulting in version 6.1 */
2252 /* */
2253 /**************************************************************************/
_nx_crypto_ec_fp_projective_add(NX_CRYPTO_EC * curve,NX_CRYPTO_EC_POINT * projective_point,NX_CRYPTO_EC_POINT * affine_point,HN_UBASE * scratch)2254 NX_CRYPTO_KEEP VOID _nx_crypto_ec_fp_projective_add(NX_CRYPTO_EC *curve,
2255 NX_CRYPTO_EC_POINT *projective_point,
2256 NX_CRYPTO_EC_POINT *affine_point,
2257 HN_UBASE *scratch)
2258 {
2259 NX_CRYPTO_HUGE_NUMBER temp1, temp2, temp3, temp4, temp5;
2260 UINT buffer_size;
2261
2262 /* Page 12, Software Implementation of the NIST Elliptic Curves Over Prime Fields. */
2263 /*
2264 A = X2 * Z1 ^ 2
2265 B = Y2 * Z1 ^ 3
2266 C = A - X1
2267 D = B - Y1
2268 X3 = D ^ 2 - (C ^ 3 + 2 * X1 * C ^ 2)
2269 Y3 = D * (X1 * C ^ 2 - X3) - Y1 * C ^ 3
2270 Z3 = Z1 * C
2271 */
2272
2273 if (_nx_crypto_ec_point_is_infinite(projective_point))
2274 {
2275 NX_CRYPTO_HUGE_NUMBER_COPY(&projective_point -> nx_crypto_ec_point_x,
2276 &affine_point -> nx_crypto_ec_point_x);
2277 NX_CRYPTO_HUGE_NUMBER_COPY(&projective_point -> nx_crypto_ec_point_y,
2278 &affine_point -> nx_crypto_ec_point_y);
2279 _nx_crypto_ec_point_fp_affine_to_projective(projective_point);
2280 return;
2281 }
2282
2283 if (_nx_crypto_ec_point_is_infinite(affine_point))
2284 {
2285 return;
2286 }
2287
2288 buffer_size = projective_point -> nx_crypto_ec_point_x.nx_crypto_huge_buffer_size;
2289 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp1, scratch, buffer_size << 1);
2290 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp2, scratch, buffer_size << 1);
2291 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp3, scratch, buffer_size << 1);
2292 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp4, scratch, buffer_size << 1);
2293 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp5, scratch, buffer_size << 1);
2294
2295 /* A = X2 * Z1 ^ 2 */
2296 /* C = A - X1 */
2297 NX_CRYPTO_EC_SQUARE_REDUCE(curve, &projective_point -> nx_crypto_ec_point_z,
2298 &temp1, scratch);
2299 NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &affine_point -> nx_crypto_ec_point_x,
2300 &temp1, &temp2, scratch);
2301 _nx_crypto_ec_subtract_reduce(curve, &temp2, &projective_point -> nx_crypto_ec_point_x,
2302 scratch);
2303
2304 /* temp1 = Z1 ^ 2 */
2305 /* B = Y2 * Z1 ^ 3 */
2306 /* D = B - Y1 */
2307 NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &projective_point -> nx_crypto_ec_point_z,
2308 &temp1, &temp3, scratch);
2309 NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &affine_point -> nx_crypto_ec_point_y,
2310 &temp3, &temp1, scratch);
2311 _nx_crypto_ec_subtract_reduce(curve, &temp1, &projective_point -> nx_crypto_ec_point_y,
2312 scratch);
2313
2314 /* temp2 = C */
2315 /* Z3 = Z1 * C */
2316 NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &projective_point -> nx_crypto_ec_point_z,
2317 &temp2, &temp3, scratch);
2318 NX_CRYPTO_HUGE_NUMBER_COPY(&projective_point -> nx_crypto_ec_point_z, &temp3);
2319
2320 /* temp1 = D
2321 * temp2 = C */
2322 /* X3 = D ^ 2 - (C ^ 3 + 2 * X1 * C ^ 2) */
2323 NX_CRYPTO_EC_SQUARE_REDUCE(curve, &temp2, &temp3, scratch);
2324 NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &temp2, &temp3, &temp4, scratch);
2325 NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &projective_point -> nx_crypto_ec_point_x,
2326 &temp3, &temp2, scratch);
2327 NX_CRYPTO_HUGE_NUMBER_COPY(&temp3, &temp2);
2328 NX_CRYPTO_EC_SHIFT_LEFT_REDUCE(curve, &temp3, 1, scratch);
2329 _nx_crypto_ec_add_reduce(curve, &temp3, &temp4, scratch);
2330 NX_CRYPTO_EC_SQUARE_REDUCE(curve, &temp1, &temp5, scratch);
2331 _nx_crypto_ec_subtract_reduce(curve, &temp5, &temp3, scratch);
2332 NX_CRYPTO_HUGE_NUMBER_COPY(&projective_point -> nx_crypto_ec_point_x, &temp5);
2333
2334 /* temp1 = D
2335 * temp2 = X1 * C ^ 2
2336 * temp4 = C ^ 3
2337 * temp5 = X3 */
2338 /* Y3 = D * (X1 * C ^ 2 - X3) - Y1 * C ^ 3 */
2339 _nx_crypto_ec_subtract_reduce(curve, &temp2, &temp5, scratch);
2340 NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &temp1, &temp2, &temp3, scratch);
2341 NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &projective_point -> nx_crypto_ec_point_y,
2342 &temp4, &temp1, scratch);
2343 _nx_crypto_ec_subtract_reduce(curve, &temp3, &temp1, scratch);
2344 NX_CRYPTO_HUGE_NUMBER_COPY(&projective_point -> nx_crypto_ec_point_y, &temp3);
2345 }
2346
2347 /**************************************************************************/
2348 /* */
2349 /* FUNCTION RELEASE */
2350 /* */
2351 /* _nx_crypto_ec_fp_projective_double PORTABLE C */
2352 /* 6.1 */
2353 /* AUTHOR */
2354 /* */
2355 /* Timothy Stapko, Microsoft Corporation */
2356 /* */
2357 /* DESCRIPTION */
2358 /* */
2359 /* This function performs doubling for point of projective coordinate */
2360 /* in prime filed. */
2361 /* */
2362 /* INPUT */
2363 /* */
2364 /* curve Pointer to curve */
2365 /* projective_point Point in projective coordinate*/
2366 /* scratch Pointer to scratch buffer */
2367 /* */
2368 /* OUTPUT */
2369 /* */
2370 /* status Completion status */
2371 /* */
2372 /* CALLS */
2373 /* */
2374 /* NX_CRYPTO_EC_MULTIPLE_DIGIT_REDUCE Multiply two huge numbers */
2375 /* with digit */
2376 /* NX_CRYPTO_EC_MULTIPLE_REDUCE Multiply two huge numbers */
2377 /* NX_CRYPTO_EC_SHIFT_LEFT_REDUCE Shift left N bits */
2378 /* NX_CRYPTO_EC_SQUARE_REDUCE Computes the square of a value*/
2379 /* NX_CRYPTO_HUGE_NUMBER_COPY Copy huge number */
2380 /* NX_CRYPTO_HUGE_NUMBER_INITIALIZE Initialize the buffer of */
2381 /* huge number */
2382 /* _nx_crypto_ec_add_reduce Perform addition between */
2383 /* two huge numbers */
2384 /* _nx_crypto_ec_subtract_reduce Perform subtraction between */
2385 /* two huge numbers */
2386 /* _nx_crypto_ec_point_is_infinite Check if the point is infinite*/
2387 /* */
2388 /* CALLED BY */
2389 /* */
2390 /* _nx_crypto_ec_fp_fixed_multiple Calculate the fixed */
2391 /* multiplication */
2392 /* _nx_crypto_ec_fp_projective_multiple Calculate the projective */
2393 /* multiplication */
2394 /* */
2395 /* RELEASE HISTORY */
2396 /* */
2397 /* DATE NAME DESCRIPTION */
2398 /* */
2399 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
2400 /* 09-30-2020 Timothy Stapko Modified comment(s), */
2401 /* resulting in version 6.1 */
2402 /* */
2403 /**************************************************************************/
_nx_crypto_ec_fp_projective_double(NX_CRYPTO_EC * curve,NX_CRYPTO_EC_POINT * projective_point,HN_UBASE * scratch)2404 NX_CRYPTO_KEEP VOID _nx_crypto_ec_fp_projective_double(NX_CRYPTO_EC *curve,
2405 NX_CRYPTO_EC_POINT *projective_point,
2406 HN_UBASE *scratch)
2407 {
2408 NX_CRYPTO_HUGE_NUMBER temp1, temp2, temp3, temp4, temp5;
2409 UINT buffer_size;
2410
2411 /* Page 12, Software Implementation of the NIST Elliptic Curves Over Prime Fields. */
2412 /*
2413 A = 4 * X1 * Y1 ^ 2
2414 B = 8 * Y1 ^ 4
2415 C = 3 * (X1 - Z1 ^ 2) * (X1 + Z1 ^ 2)
2416 D = C ^ 2 - 2 * A
2417 X3 = D
2418 Y3 = C * (A - D) - B
2419 Z3 = 2 * Y1 * Z1
2420 */
2421
2422 if (_nx_crypto_ec_point_is_infinite(projective_point))
2423 {
2424 return;
2425 }
2426
2427 buffer_size = projective_point -> nx_crypto_ec_point_x.nx_crypto_huge_buffer_size;
2428 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp1, scratch, buffer_size << 1);
2429 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp2, scratch, buffer_size << 1);
2430 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp3, scratch, buffer_size << 1);
2431 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp4, scratch, buffer_size << 1);
2432 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp5, scratch, buffer_size << 1);
2433
2434 /* A = 4 * X1 * Y1 ^ 2 */
2435 NX_CRYPTO_EC_SQUARE_REDUCE(curve, &projective_point -> nx_crypto_ec_point_y,
2436 &temp3, scratch);
2437 NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &projective_point -> nx_crypto_ec_point_x,
2438 &temp3, &temp1, scratch);
2439 NX_CRYPTO_EC_SHIFT_LEFT_REDUCE(curve, &temp1, 2, scratch);
2440
2441 /* temp3 = Y1 ^ 2 */
2442 /* B = 8 * Y1 ^ 4 */
2443 NX_CRYPTO_EC_SQUARE_REDUCE(curve, &temp3, &temp2, scratch);
2444 NX_CRYPTO_EC_SHIFT_LEFT_REDUCE(curve, &temp2, 3, scratch);
2445
2446 /* C = 3 * (X1 - Z1 ^ 2) * (X1 + Z1 ^ 2) */
2447 NX_CRYPTO_EC_SQUARE_REDUCE(curve, &projective_point -> nx_crypto_ec_point_z,
2448 &temp3, scratch);
2449 NX_CRYPTO_HUGE_NUMBER_COPY(&temp4, &projective_point -> nx_crypto_ec_point_x);
2450 NX_CRYPTO_HUGE_NUMBER_COPY(&temp5, &projective_point -> nx_crypto_ec_point_x);
2451 _nx_crypto_ec_subtract_reduce(curve, &temp4, &temp3, scratch);
2452 _nx_crypto_ec_add_reduce(curve, &temp5, &temp3, scratch);
2453 NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &temp4, &temp5, &temp3, scratch);
2454 NX_CRYPTO_EC_MULTIPLE_DIGIT_REDUCE(curve, &temp3, 3, &temp4, scratch);
2455
2456 /* Z3 = 2 * Y1 * Z1 */
2457 NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &projective_point -> nx_crypto_ec_point_y,
2458 &projective_point -> nx_crypto_ec_point_z, &temp5, scratch);
2459 NX_CRYPTO_EC_SHIFT_LEFT_REDUCE(curve, &temp5, 1, scratch);
2460 NX_CRYPTO_HUGE_NUMBER_COPY(&projective_point -> nx_crypto_ec_point_z, &temp5);
2461
2462 /* temp1 = A
2463 * temp4 = C */
2464 /* D = C ^ 2 - 2 * A */
2465 NX_CRYPTO_EC_SQUARE_REDUCE(curve, &temp4, &temp3, scratch);
2466 NX_CRYPTO_HUGE_NUMBER_COPY(&temp5, &temp1);
2467 NX_CRYPTO_EC_SHIFT_LEFT_REDUCE(curve, &temp5, 1, scratch);
2468 _nx_crypto_ec_subtract_reduce(curve, &temp3, &temp5, scratch);
2469 NX_CRYPTO_HUGE_NUMBER_COPY(&projective_point -> nx_crypto_ec_point_x, &temp3);
2470
2471 /* temp1 = A
2472 * temp2 = B
2473 * temp3 = D
2474 * temp4 = C */
2475 /* Y3 = C * (A - D) - B */
2476 _nx_crypto_ec_subtract_reduce(curve, &temp1, &temp3, scratch);
2477 NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &temp1, &temp4, &temp3, scratch);
2478 _nx_crypto_ec_subtract_reduce(curve, &temp3, &temp2, scratch);
2479 NX_CRYPTO_HUGE_NUMBER_COPY(&projective_point -> nx_crypto_ec_point_y, &temp3);
2480 }
2481
2482 /**************************************************************************/
2483 /* */
2484 /* FUNCTION RELEASE */
2485 /* */
2486 /* _nx_crypto_ec_fp_affine_add PORTABLE C */
2487 /* 6.1 */
2488 /* AUTHOR */
2489 /* */
2490 /* Timothy Stapko, Microsoft Corporation */
2491 /* */
2492 /* DESCRIPTION */
2493 /* */
2494 /* This function performs addition for two points of affine coordinate */
2495 /* in prime field. */
2496 /* */
2497 /* INPUT */
2498 /* */
2499 /* curve Pointer to curve */
2500 /* left Left huge number */
2501 /* right Right huge number */
2502 /* scratch Pointer to scratch buffer */
2503 /* */
2504 /* OUTPUT */
2505 /* */
2506 /* status Completion status */
2507 /* */
2508 /* CALLS */
2509 /* */
2510 /* NX_CRYPTO_EC_MULTIPLE_DIGIT_REDUCE Multiply two huge numbers */
2511 /* with digit */
2512 /* NX_CRYPTO_EC_MULTIPLE_REDUCE Multiply two huge numbers */
2513 /* NX_CRYPTO_EC_SHIFT_LEFT_REDUCE Shift left N bits */
2514 /* NX_CRYPTO_EC_SQUARE_REDUCE Computes the square of a value*/
2515 /* NX_CRYPTO_HUGE_NUMBER_COPY Copy huge number */
2516 /* NX_CRYPTO_HUGE_NUMBER_INITIALIZE Initialize the buffer of */
2517 /* huge number */
2518 /* _nx_crypto_ec_subtract_digit_reduce Perform subtraction between */
2519 /* huge number and digit number*/
2520 /* _nx_crypto_ec_subtract_reduce Perform subtraction between */
2521 /* two huge numbers */
2522 /* _nx_crypto_huge_number_compare Compare two huge numbers */
2523 /* _nx_crypto_huge_number_inverse_modulus_prime */
2524 /* Perform an inverse modulus */
2525 /* operation for prime number */
2526 /* */
2527 /* CALLED BY */
2528 /* */
2529 /* _nx_crypto_ec_fp_affine_subtract Perform subtraction for points*/
2530 /* of affine */
2531 /* */
2532 /* RELEASE HISTORY */
2533 /* */
2534 /* DATE NAME DESCRIPTION */
2535 /* */
2536 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
2537 /* 09-30-2020 Timothy Stapko Modified comment(s), */
2538 /* resulting in version 6.1 */
2539 /* */
2540 /**************************************************************************/
_nx_crypto_ec_fp_affine_add(NX_CRYPTO_EC * curve,NX_CRYPTO_EC_POINT * left,NX_CRYPTO_EC_POINT * right,HN_UBASE * scratch)2541 NX_CRYPTO_KEEP VOID _nx_crypto_ec_fp_affine_add(NX_CRYPTO_EC *curve,
2542 NX_CRYPTO_EC_POINT *left,
2543 NX_CRYPTO_EC_POINT *right,
2544 HN_UBASE *scratch)
2545 {
2546 NX_CRYPTO_HUGE_NUMBER temp1, temp2, temp3;
2547 NX_CRYPTO_HUGE_NUMBER *p;
2548 UINT buffer_size;
2549
2550 if (_nx_crypto_ec_point_is_infinite(left))
2551 {
2552 NX_CRYPTO_HUGE_NUMBER_COPY(&left -> nx_crypto_ec_point_x,
2553 &right -> nx_crypto_ec_point_x);
2554 NX_CRYPTO_HUGE_NUMBER_COPY(&left -> nx_crypto_ec_point_y,
2555 &right -> nx_crypto_ec_point_y);
2556 return;
2557 }
2558
2559 if (_nx_crypto_ec_point_is_infinite(right))
2560 {
2561 return;
2562 }
2563
2564 p = &curve -> nx_crypto_ec_field.fp;
2565
2566 buffer_size = left -> nx_crypto_ec_point_x.nx_crypto_huge_buffer_size;
2567 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp1, scratch, buffer_size << 1);
2568 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp2, scratch, buffer_size << 1);
2569 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp3, scratch, buffer_size << 1);
2570
2571 if ((_nx_crypto_huge_number_compare(&left -> nx_crypto_ec_point_x,
2572 &right -> nx_crypto_ec_point_x) == NX_CRYPTO_HUGE_NUMBER_EQUAL) &&
2573 (_nx_crypto_huge_number_compare(&left -> nx_crypto_ec_point_y,
2574 &right -> nx_crypto_ec_point_y) == NX_CRYPTO_HUGE_NUMBER_EQUAL))
2575 {
2576
2577 /* Double */
2578 /* r = (3 * x1 ^ 2 - 3) * (2 * y1) ^ -1 mod p */
2579 NX_CRYPTO_HUGE_NUMBER_COPY(&temp3, &left -> nx_crypto_ec_point_y);
2580 NX_CRYPTO_EC_SHIFT_LEFT_REDUCE(curve, &temp3, 1, scratch);
2581 _nx_crypto_huge_number_inverse_modulus_prime(&temp3, p, &temp1, scratch);
2582 NX_CRYPTO_EC_SQUARE_REDUCE(curve, &left -> nx_crypto_ec_point_x,
2583 &temp3, scratch);
2584 NX_CRYPTO_EC_MULTIPLE_DIGIT_REDUCE(curve, &temp3, 3, &temp2, scratch);
2585 _nx_crypto_ec_subtract_digit_reduce(curve, &temp2, 3, scratch);
2586 NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &temp2, &temp1, &temp3, scratch);
2587 }
2588 else
2589 {
2590
2591 /* Add */
2592 /* r = (y2 - y1) * (x2 - x1) ^ -1 mod p */
2593 NX_CRYPTO_HUGE_NUMBER_COPY(&temp1, &right -> nx_crypto_ec_point_x);
2594 _nx_crypto_ec_subtract_reduce(curve, &temp1, &left -> nx_crypto_ec_point_x, scratch);
2595 _nx_crypto_huge_number_inverse_modulus_prime(&temp1, p, &temp2, scratch);
2596 NX_CRYPTO_HUGE_NUMBER_COPY(&temp1, &right -> nx_crypto_ec_point_y);
2597 _nx_crypto_ec_subtract_reduce(curve, &temp1, &left -> nx_crypto_ec_point_y, scratch);
2598 NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &temp1, &temp2, &temp3, scratch);
2599 }
2600
2601 /* x3 = r ^ 2 - x1 - x2 */
2602 NX_CRYPTO_EC_SQUARE_REDUCE(curve, &temp3, &temp1, scratch);
2603 _nx_crypto_ec_subtract_reduce(curve, &temp1, &left -> nx_crypto_ec_point_x, scratch);
2604 _nx_crypto_ec_subtract_reduce(curve, &temp1, &right -> nx_crypto_ec_point_x, scratch);
2605 NX_CRYPTO_HUGE_NUMBER_COPY(&temp2, &left -> nx_crypto_ec_point_x);
2606 NX_CRYPTO_HUGE_NUMBER_COPY(&left -> nx_crypto_ec_point_x, &temp1);
2607
2608 /* y3 = r * (x1 - x3) - y1 */
2609 _nx_crypto_ec_subtract_reduce(curve, &temp2, &temp1, scratch);
2610 NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &temp2, &temp3, &temp1, scratch);
2611 _nx_crypto_ec_subtract_reduce(curve, &temp1, &left -> nx_crypto_ec_point_y, scratch);
2612 NX_CRYPTO_HUGE_NUMBER_COPY(&left -> nx_crypto_ec_point_y, &temp1);
2613 }
2614
2615 /**************************************************************************/
2616 /* */
2617 /* FUNCTION RELEASE */
2618 /* */
2619 /* _nx_crypto_ec_fp_affine_subtract PORTABLE C */
2620 /* 6.1 */
2621 /* AUTHOR */
2622 /* */
2623 /* Timothy Stapko, Microsoft Corporation */
2624 /* */
2625 /* DESCRIPTION */
2626 /* */
2627 /* This function performs subtraction for two points of affine */
2628 /* coordinate in prime field. */
2629 /* */
2630 /* INPUT */
2631 /* */
2632 /* curve Pointer to curve */
2633 /* left Left huge number */
2634 /* right Right huge number */
2635 /* scratch Pointer to scratch buffer */
2636 /* */
2637 /* OUTPUT */
2638 /* */
2639 /* status Completion status */
2640 /* */
2641 /* CALLS */
2642 /* */
2643 /* NX_CRYPTO_EC_POINT_INITIALIZE Initialize EC point */
2644 /* NX_CRYPTO_HUGE_NUMBER_COPY Copy huge number */
2645 /* _nx_crypto_ec_fp_affine_add Perform addition for points of*/
2646 /* affine */
2647 /* _nx_crypto_ec_subtract_reduce Perform subtraction between */
2648 /* two huge numbers */
2649 /* */
2650 /* CALLED BY */
2651 /* */
2652 /* Application Code */
2653 /* */
2654 /* RELEASE HISTORY */
2655 /* */
2656 /* DATE NAME DESCRIPTION */
2657 /* */
2658 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
2659 /* 09-30-2020 Timothy Stapko Modified comment(s), */
2660 /* resulting in version 6.1 */
2661 /* */
2662 /**************************************************************************/
_nx_crypto_ec_fp_affine_subtract(NX_CRYPTO_EC * curve,NX_CRYPTO_EC_POINT * left,NX_CRYPTO_EC_POINT * right,HN_UBASE * scratch)2663 NX_CRYPTO_KEEP VOID _nx_crypto_ec_fp_affine_subtract(NX_CRYPTO_EC *curve,
2664 NX_CRYPTO_EC_POINT *left,
2665 NX_CRYPTO_EC_POINT *right,
2666 HN_UBASE *scratch)
2667 {
2668 NX_CRYPTO_EC_POINT point;
2669
2670 NX_CRYPTO_EC_POINT_INITIALIZE(&point, NX_CRYPTO_EC_POINT_AFFINE, scratch,
2671 right -> nx_crypto_ec_point_y.nx_crypto_huge_buffer_size);
2672 NX_CRYPTO_HUGE_NUMBER_COPY(&point.nx_crypto_ec_point_x, &right -> nx_crypto_ec_point_x);
2673 NX_CRYPTO_HUGE_NUMBER_COPY(&point.nx_crypto_ec_point_y, &curve -> nx_crypto_ec_field.fp);
2674
2675 _nx_crypto_ec_subtract_reduce(curve, &point.nx_crypto_ec_point_y,
2676 &right -> nx_crypto_ec_point_y, scratch);
2677 _nx_crypto_ec_fp_affine_add(curve, left, &point, scratch);
2678 }
2679
2680 /**************************************************************************/
2681 /* */
2682 /* FUNCTION RELEASE */
2683 /* */
2684 /* _nx_crypto_ec_naf_compute PORTABLE C */
2685 /* 6.1 */
2686 /* AUTHOR */
2687 /* */
2688 /* Timothy Stapko, Microsoft Corporation */
2689 /* */
2690 /* DESCRIPTION */
2691 /* */
2692 /* This function computes the non-adjacent form(NAF) of huge number. */
2693 /* It has the property that no two consecutive coeffcients are nonzero.*/
2694 /* */
2695 /* INPUT */
2696 /* */
2697 /* d Pointer to huge number */
2698 /* naf_data Buffer of NAF for output */
2699 /* naf_size Size of NAF */
2700 /* */
2701 /* OUTPUT */
2702 /* */
2703 /* status Completion status */
2704 /* */
2705 /* CALLS */
2706 /* */
2707 /* None */
2708 /* */
2709 /* CALLED BY */
2710 /* */
2711 /* _nx_crypto_ec_fp_projective_multiple Calculate the projective */
2712 /* multiplication */
2713 /* */
2714 /* RELEASE HISTORY */
2715 /* */
2716 /* DATE NAME DESCRIPTION */
2717 /* */
2718 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
2719 /* 09-30-2020 Timothy Stapko Modified comment(s), */
2720 /* resulting in version 6.1 */
2721 /* */
2722 /**************************************************************************/
_nx_crypto_ec_naf_compute(NX_CRYPTO_HUGE_NUMBER * d,HN_UBASE * naf_data,UINT * naf_size)2723 NX_CRYPTO_KEEP VOID _nx_crypto_ec_naf_compute(NX_CRYPTO_HUGE_NUMBER *d, HN_UBASE *naf_data, UINT *naf_size)
2724 {
2725 HN_UBASE2 digit;
2726 HN_UBASE value;
2727 HN_UBASE *ptr;
2728 UINT shift;
2729 UINT i, j;
2730
2731 shift = 0;
2732 ptr = naf_data;
2733 *ptr = 0;
2734 digit = 0;
2735 for (i = 0; i < d -> nx_crypto_huge_number_size - 1; i++)
2736 {
2737 digit = digit + d -> nx_crypto_huge_number_data[i];
2738 for (j = 0; j < (HN_SHIFT - 1); j++)
2739 {
2740 value = digit & 3;
2741
2742 *ptr = *ptr | (value << shift);
2743 shift += 2;
2744 if (shift == HN_SHIFT)
2745 {
2746 shift = 0;
2747 ptr++;
2748 *ptr = 0;
2749 }
2750
2751 digit >>= 1;
2752
2753 if (value == 3)
2754 {
2755 digit++;
2756 }
2757 }
2758
2759 value = (((d -> nx_crypto_huge_number_data[i + 1] & 1) << 1) + digit) & 3;
2760
2761 *ptr = *ptr | (value << shift);
2762 shift += 2;
2763 if (shift == HN_SHIFT)
2764 {
2765 shift = 0;
2766 ptr++;
2767 *ptr = 0;
2768 }
2769
2770 digit >>= 1;
2771
2772 if (value == 3)
2773 {
2774 digit++;
2775 }
2776 }
2777
2778 digit = digit + d -> nx_crypto_huge_number_data[i];
2779 while (digit >= 1)
2780 {
2781 value = digit & 3;
2782
2783 *ptr = *ptr | (value << shift);
2784 shift += 2;
2785 if (shift == HN_SHIFT)
2786 {
2787 shift = 0;
2788 ptr++;
2789 *ptr = 0;
2790 }
2791
2792 digit >>= 1;
2793
2794 if (value == 3)
2795 {
2796 digit++;
2797 }
2798 }
2799
2800 *naf_size = ((ULONG)ptr - (ULONG)naf_data) >> HN_SIZE_SHIFT;
2801 if (shift != 0)
2802 {
2803 *naf_size = *naf_size + 1;
2804 }
2805 }
2806
2807 /* r and g are allowed to be the same pointer. */
2808 /**************************************************************************/
2809 /* */
2810 /* FUNCTION RELEASE */
2811 /* */
2812 /* _nx_crypto_ec_fp_projective_multiple PORTABLE C */
2813 /* 6.1 */
2814 /* AUTHOR */
2815 /* */
2816 /* Timothy Stapko, Microsoft Corporation */
2817 /* */
2818 /* DESCRIPTION */
2819 /* */
2820 /* This function calculates the multiplication in prime field. The */
2821 /* point g is unknown. r = g * d. */
2822 /* */
2823 /* INPUT */
2824 /* */
2825 /* curve Pointer to curve */
2826 /* g Base point g */
2827 /* d Factor d */
2828 /* r Result r */
2829 /* scratch Pointer to scratch buffer */
2830 /* */
2831 /* OUTPUT */
2832 /* */
2833 /* status Completion status */
2834 /* */
2835 /* CALLS */
2836 /* */
2837 /* NX_CRYPTO_EC_POINT_INITIALIZE Initialize EC point */
2838 /* NX_CRYPTO_HUGE_NUMBER_COPY Copy huge number */
2839 /* _nx_crypto_ec_fp_fixed_multiple Calculate the fixed */
2840 /* multiplication */
2841 /* _nx_crypto_ec_fp_projective_add Perform addition for points of*/
2842 /* projective and affine */
2843 /* _nx_crypto_ec_fp_projective_double Perform doubling for points of*/
2844 /* projective */
2845 /* _nx_crypto_ec_naf_compute Compute the non-adjacent form */
2846 /* of huge number */
2847 /* _nx_crypto_ec_point_fp_projective_to_affine */
2848 /* Convert point from projective */
2849 /* to affine */
2850 /* _nx_crypto_ec_point_set_infinite Set the point to infinite */
2851 /* _nx_crypto_ec_subtract_reduce Perform subtraction between */
2852 /* two huge numbers */
2853 /* */
2854 /* CALLED BY */
2855 /* */
2856 /* Application Code */
2857 /* */
2858 /* RELEASE HISTORY */
2859 /* */
2860 /* DATE NAME DESCRIPTION */
2861 /* */
2862 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
2863 /* 09-30-2020 Timothy Stapko Modified comment(s), */
2864 /* resulting in version 6.1 */
2865 /* */
2866 /**************************************************************************/
_nx_crypto_ec_fp_projective_multiple(NX_CRYPTO_EC * curve,NX_CRYPTO_EC_POINT * g,NX_CRYPTO_HUGE_NUMBER * d,NX_CRYPTO_EC_POINT * r,HN_UBASE * scratch)2867 NX_CRYPTO_KEEP VOID _nx_crypto_ec_fp_projective_multiple(NX_CRYPTO_EC *curve,
2868 NX_CRYPTO_EC_POINT *g,
2869 NX_CRYPTO_HUGE_NUMBER *d,
2870 NX_CRYPTO_EC_POINT *r,
2871 HN_UBASE *scratch)
2872 {
2873 NX_CRYPTO_EC_POINT projective_point;
2874 NX_CRYPTO_EC_POINT negative_g;
2875 HN_UBASE *naf_data;
2876 UINT naf_size;
2877 HN_UBASE digit;
2878 HN_UBASE value;
2879 HN_UBASE *ptr;
2880 UINT bit;
2881
2882 if ((curve -> nx_crypto_ec_fixed_points) && (&curve -> nx_crypto_ec_g == g))
2883 {
2884 _nx_crypto_ec_fp_fixed_multiple(curve, d, r, scratch);
2885 return;
2886 }
2887
2888 NX_CRYPTO_EC_POINT_INITIALIZE(&projective_point, NX_CRYPTO_EC_POINT_PROJECTIVE, scratch,
2889 g -> nx_crypto_ec_point_x.nx_crypto_huge_buffer_size);
2890 NX_CRYPTO_EC_POINT_INITIALIZE(&negative_g, NX_CRYPTO_EC_POINT_AFFINE, scratch,
2891 g -> nx_crypto_ec_point_x.nx_crypto_huge_buffer_size);
2892
2893 _nx_crypto_ec_point_set_infinite(&projective_point);
2894 NX_CRYPTO_HUGE_NUMBER_COPY(&negative_g.nx_crypto_ec_point_x, &g -> nx_crypto_ec_point_x);
2895 NX_CRYPTO_HUGE_NUMBER_COPY(&negative_g.nx_crypto_ec_point_y, &curve -> nx_crypto_ec_field.fp);
2896 _nx_crypto_ec_subtract_reduce(curve, &negative_g.nx_crypto_ec_point_y,
2897 &g -> nx_crypto_ec_point_y, scratch);
2898
2899 naf_data = scratch;
2900 _nx_crypto_ec_naf_compute(d, naf_data, &naf_size);
2901 scratch += naf_size;
2902
2903 /* Trim zero bit from the highest significant bit. */
2904 ptr = naf_data + naf_size - 1;
2905 digit = *ptr;
2906 for (bit = 0; bit < HN_SHIFT - 1; bit += 2)
2907 {
2908 value = (digit >> (HN_SHIFT - bit - 2)) & 3;
2909 if (value != 0)
2910 {
2911 break;
2912 }
2913 }
2914
2915 for (; (ULONG)ptr >= (ULONG)naf_data; ptr--)
2916 {
2917 digit = *ptr;
2918
2919 for (; bit < HN_SHIFT - 1; bit += 2)
2920 {
2921 _nx_crypto_ec_fp_projective_double(curve, &projective_point, scratch);
2922
2923 value = (digit >> (HN_SHIFT - bit - 2)) & 3;
2924
2925 if (value == 1)
2926 {
2927 _nx_crypto_ec_fp_projective_add(curve, &projective_point, g, scratch);
2928 }
2929 else if (value == 3)
2930 {
2931 _nx_crypto_ec_fp_projective_add(curve, &projective_point, &negative_g, scratch);
2932 }
2933 }
2934 bit = 0;
2935 }
2936
2937 _nx_crypto_ec_point_fp_projective_to_affine(curve, &projective_point, scratch);
2938 NX_CRYPTO_HUGE_NUMBER_COPY(&r -> nx_crypto_ec_point_x,
2939 &projective_point.nx_crypto_ec_point_x);
2940 NX_CRYPTO_HUGE_NUMBER_COPY(&r -> nx_crypto_ec_point_y,
2941 &projective_point.nx_crypto_ec_point_y);
2942 }
2943
2944 /**************************************************************************/
2945 /* */
2946 /* FUNCTION RELEASE */
2947 /* */
2948 /* _nx_crypto_ec_fp_fixed_multiple PORTABLE C */
2949 /* 6.1 */
2950 /* AUTHOR */
2951 /* */
2952 /* Timothy Stapko, Microsoft Corporation */
2953 /* */
2954 /* DESCRIPTION */
2955 /* */
2956 /* This function calculates the multiplication in prime field. The */
2957 /* point g is selected from the curve. And the value of 2 ^ N * g */
2958 /* has been precomputed. r = g * d. */
2959 /* */
2960 /* INPUT */
2961 /* */
2962 /* curve Pointer to curve */
2963 /* d Factor d */
2964 /* r Result r */
2965 /* scratch Pointer to scratch buffer */
2966 /* */
2967 /* OUTPUT */
2968 /* */
2969 /* status Completion status */
2970 /* */
2971 /* CALLS */
2972 /* */
2973 /* NX_CRYPTO_EC_POINT_INITIALIZE Initialize EC point */
2974 /* NX_CRYPTO_HUGE_NUMBER_COPY Copy huge number */
2975 /* NX_CRYPTO_HUGE_NUMBER_INITIALIZE Initialize the buffer of */
2976 /* huge number */
2977 /* _nx_crypto_ec_fp_projective_add Perform addition for points of*/
2978 /* projective and affine */
2979 /* _nx_crypto_ec_fp_projective_double Perform doubling for points of*/
2980 /* projective */
2981 /* _nx_crypto_ec_point_fp_projective_to_affine */
2982 /* Convert point from projective */
2983 /* to affine */
2984 /* _nx_crypto_ec_point_set_infinite Set the point to infinite */
2985 /* */
2986 /* CALLED BY */
2987 /* */
2988 /* _nx_crypto_ec_fp_projective_multiple Calculate the projective */
2989 /* multiplication */
2990 /* */
2991 /* RELEASE HISTORY */
2992 /* */
2993 /* DATE NAME DESCRIPTION */
2994 /* */
2995 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
2996 /* 09-30-2020 Timothy Stapko Modified comment(s), */
2997 /* resulting in version 6.1 */
2998 /* */
2999 /**************************************************************************/
_nx_crypto_ec_fp_fixed_multiple(NX_CRYPTO_EC * curve,NX_CRYPTO_HUGE_NUMBER * d,NX_CRYPTO_EC_POINT * r,HN_UBASE * scratch)3000 NX_CRYPTO_KEEP VOID _nx_crypto_ec_fp_fixed_multiple(NX_CRYPTO_EC *curve,
3001 NX_CRYPTO_HUGE_NUMBER *d,
3002 NX_CRYPTO_EC_POINT *r,
3003 HN_UBASE *scratch)
3004 {
3005 NX_CRYPTO_EC_POINT projective_point;
3006 NX_CRYPTO_EC_POINT *g;
3007 NX_CRYPTO_EC_FIXED_POINTS *fixed_points;
3008 NX_CRYPTO_HUGE_NUMBER expanded_d;
3009 UINT expanded_size;
3010 ULONG transpose_d;
3011 HN_UBASE value;
3012 UINT bit_index;
3013 INT i;
3014 UINT j;
3015
3016 fixed_points = curve -> nx_crypto_ec_fixed_points;
3017 expanded_size = fixed_points -> nx_crypto_ec_fixed_points_window_width *
3018 (fixed_points -> nx_crypto_ec_fixed_points_e << 1);
3019 expanded_size = (expanded_size + 7) >> 3;
3020 expanded_size = (expanded_size + 3) & (ULONG) ~3;
3021
3022 g = &curve -> nx_crypto_ec_g;
3023
3024 NX_CRYPTO_EC_POINT_INITIALIZE(&projective_point, NX_CRYPTO_EC_POINT_PROJECTIVE, scratch,
3025 g -> nx_crypto_ec_point_x.nx_crypto_huge_buffer_size << 1);
3026 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&expanded_d, scratch, expanded_size);
3027 _nx_crypto_ec_point_set_infinite(&projective_point);
3028
3029 NX_CRYPTO_HUGE_NUMBER_COPY(&expanded_d, d);
3030 NX_CRYPTO_MEMSET(&expanded_d.nx_crypto_huge_number_data[expanded_d.nx_crypto_huge_number_size], 0,
3031 expanded_size - (d -> nx_crypto_huge_number_size << HN_SIZE_SHIFT));
3032 expanded_d.nx_crypto_huge_number_size = expanded_size >> HN_SIZE_SHIFT;
3033
3034 for (i = (INT)(fixed_points -> nx_crypto_ec_fixed_points_e - 1); i >= 0; i--)
3035 {
3036 _nx_crypto_ec_fp_projective_double(curve, &projective_point, scratch);
3037
3038 transpose_d = 0;
3039 bit_index = (UINT)i;
3040
3041 for (j = 0; j < fixed_points -> nx_crypto_ec_fixed_points_window_width; j++)
3042 {
3043 value = expanded_d.nx_crypto_huge_number_data[bit_index >> (HN_SIZE_SHIFT + 3)];
3044 transpose_d |= (((value >> (bit_index & (NX_CRYPTO_HUGE_NUMBER_BITS - 1))) & 1) << j);
3045 bit_index += fixed_points -> nx_crypto_ec_fixed_points_d;
3046 }
3047
3048 if (transpose_d == 1)
3049 {
3050 _nx_crypto_ec_fp_projective_add(curve, &projective_point, g, scratch);
3051 }
3052 else if (transpose_d > 0)
3053 {
3054 _nx_crypto_ec_fp_projective_add(curve, &projective_point,
3055 &fixed_points -> nx_crypto_ec_fixed_points_array[transpose_d - 2],
3056 scratch);
3057 }
3058 if ((fixed_points -> nx_crypto_ec_fixed_points_d & 1) &&
3059 (i == (INT)(fixed_points -> nx_crypto_ec_fixed_points_e - 1)))
3060 {
3061 continue;
3062 }
3063
3064 transpose_d = 0;
3065 bit_index = (UINT)(i + (INT)fixed_points -> nx_crypto_ec_fixed_points_e);
3066 for (j = 0; j < fixed_points -> nx_crypto_ec_fixed_points_window_width; j++)
3067 {
3068 value = expanded_d.nx_crypto_huge_number_data[bit_index >> (HN_SIZE_SHIFT + 3)];
3069 transpose_d |= (((value >> (bit_index & (NX_CRYPTO_HUGE_NUMBER_BITS - 1))) & 1) << j);
3070 bit_index += fixed_points -> nx_crypto_ec_fixed_points_d;
3071 }
3072
3073 if (transpose_d > 0)
3074 {
3075 _nx_crypto_ec_fp_projective_add(curve, &projective_point,
3076 &fixed_points -> nx_crypto_ec_fixed_points_array_2e[transpose_d - 1],
3077 scratch);
3078 }
3079 }
3080
3081 _nx_crypto_ec_point_fp_projective_to_affine(curve, &projective_point, scratch);
3082 NX_CRYPTO_HUGE_NUMBER_COPY(&r -> nx_crypto_ec_point_x,
3083 &projective_point.nx_crypto_ec_point_x);
3084 NX_CRYPTO_HUGE_NUMBER_COPY(&r -> nx_crypto_ec_point_y,
3085 &projective_point.nx_crypto_ec_point_y);
3086 }
3087
3088 /* nist.fips.186-4 APPENDIX B.4.1 */
3089 /**************************************************************************/
3090 /* */
3091 /* FUNCTION RELEASE */
3092 /* */
3093 /* _nx_crypto_ec_key_pair_generation_extra PORTABLE C */
3094 /* 6.1 */
3095 /* AUTHOR */
3096 /* */
3097 /* Timothy Stapko, Microsoft Corporation */
3098 /* */
3099 /* DESCRIPTION */
3100 /* */
3101 /* This function generates Elliptic Curve Key Pair using extra random */
3102 /* bits per nist.fips.186-4 APPENDIX B.4.1. */
3103 /* */
3104 /* INPUT */
3105 /* */
3106 /* curve Pointer to curve */
3107 /* g Base point g */
3108 /* private_key Private key generated */
3109 /* public_key Public key generated */
3110 /* scratch Pointer to scratch buffer */
3111 /* */
3112 /* OUTPUT */
3113 /* */
3114 /* status Completion status */
3115 /* */
3116 /* CALLS */
3117 /* */
3118 /* NX_CRYPTO_HUGE_NUMBER_COPY Copy huge number */
3119 /* NX_CRYPTO_HUGE_NUMBER_INITIALIZE Initialize the buffer of */
3120 /* huge number */
3121 /* [nx_crypto_ec_multiple] Perform multiplication for EC */
3122 /* _nx_crypto_huge_number_subtract_digit_unsigned */
3123 /* Calculate subtraction for */
3124 /* unsigned huge numbers */
3125 /* _nx_crypto_huge_number_modulus Perform a modulus operation */
3126 /* _nx_crypto_huge_number_add_digit_unsigned */
3127 /* Calculate addition for */
3128 /* unsigned huge numbers */
3129 /* _nx_crypto_huge_number_adjust_size Adjust the size of a huge */
3130 /* number to remove leading */
3131 /* zeroes */
3132 /* */
3133 /* CALLED BY */
3134 /* */
3135 /* Application Code */
3136 /* _nx_crypto_ec_key_pair_stream_generate */
3137 /* */
3138 /* RELEASE HISTORY */
3139 /* */
3140 /* DATE NAME DESCRIPTION */
3141 /* */
3142 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
3143 /* 09-30-2020 Timothy Stapko Modified comment(s), */
3144 /* resulting in version 6.1 */
3145 /* */
3146 /**************************************************************************/
_nx_crypto_ec_key_pair_generation_extra(NX_CRYPTO_EC * curve,NX_CRYPTO_EC_POINT * g,NX_CRYPTO_HUGE_NUMBER * private_key,NX_CRYPTO_EC_POINT * public_key,HN_UBASE * scratch)3147 NX_CRYPTO_KEEP UINT _nx_crypto_ec_key_pair_generation_extra(NX_CRYPTO_EC *curve,
3148 NX_CRYPTO_EC_POINT *g,
3149 NX_CRYPTO_HUGE_NUMBER *private_key,
3150 NX_CRYPTO_EC_POINT *public_key,
3151 HN_UBASE *scratch)
3152 {
3153 UINT status;
3154 UINT bits = curve -> nx_crypto_ec_bits + 64;
3155 UINT buffer_size = (bits + 7) >> 3;
3156 NX_CRYPTO_HUGE_NUMBER random_number;
3157 NX_CRYPTO_HUGE_NUMBER modulus;
3158
3159 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&random_number, scratch, buffer_size);
3160 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&modulus, scratch, buffer_size);
3161
3162 /* Get random number with specified length. */
3163 status = NX_CRYPTO_RBG(bits, (UCHAR *)scratch);
3164
3165 if (status)
3166 {
3167 return(status);
3168 }
3169
3170 status = _nx_crypto_huge_number_setup(&random_number, (const UCHAR *)scratch, buffer_size);
3171
3172 if (status)
3173 {
3174 return(status);
3175 }
3176
3177 /* d = (c mod (n-1))+1 */
3178 NX_CRYPTO_HUGE_NUMBER_COPY(&modulus, &curve -> nx_crypto_ec_n);
3179 _nx_crypto_huge_number_subtract_digit_unsigned(&modulus, 1u);
3180
3181 _nx_crypto_huge_number_modulus(&random_number, &modulus);
3182 _nx_crypto_huge_number_add_digit_unsigned(&random_number, 1u);
3183 _nx_crypto_huge_number_adjust_size(&random_number);
3184 NX_CRYPTO_HUGE_NUMBER_COPY(private_key, &random_number);
3185
3186 /* Q = dG */
3187 curve -> nx_crypto_ec_multiple(curve, g, private_key, public_key, scratch);
3188
3189 return(NX_CRYPTO_SUCCESS);
3190 }
3191
3192 /**************************************************************************/
3193 /* */
3194 /* FUNCTION RELEASE */
3195 /* */
3196 /* _nx_crypto_ec_key_pair_stream_generate PORTABLE C */
3197 /* 6.1 */
3198 /* AUTHOR */
3199 /* */
3200 /* Timothy Stapko, Microsoft Corporation */
3201 /* */
3202 /* DESCRIPTION */
3203 /* */
3204 /* This function generates Elliptic Curve Key Pair using extra random */
3205 /* bits per nist.fips.186-4 APPENDIX B.4.1. */
3206 /* */
3207 /* The output is: private_key || public_key. The public_key is in */
3208 /* uncompressed format. The output length is (3 * key_size + 1). */
3209 /* */
3210 /* INPUT */
3211 /* */
3212 /* curve Pointer to curve */
3213 /* output Pointer to output buffer */
3214 /* output_length_in_byte Length of output in byte */
3215 /* actual_output_length Actual length of output buffer*/
3216 /* scratch Pointer to scratch buffer */
3217 /* */
3218 /* OUTPUT */
3219 /* */
3220 /* status Completion status */
3221 /* */
3222 /* CALLS */
3223 /* */
3224 /* _nx_crypto_ec_key_pair_generation_extra */
3225 /* Generate key pair */
3226 /* */
3227 /* CALLED BY */
3228 /* */
3229 /* Application */
3230 /* */
3231 /* RELEASE HISTORY */
3232 /* */
3233 /* DATE NAME DESCRIPTION */
3234 /* */
3235 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
3236 /* 09-30-2020 Timothy Stapko Modified comment(s), */
3237 /* resulting in version 6.1 */
3238 /* */
3239 /**************************************************************************/
_nx_crypto_ec_key_pair_stream_generate(NX_CRYPTO_EC * curve,UCHAR * output,ULONG output_length_in_byte,ULONG * actual_output_length,HN_UBASE * scratch)3240 NX_CRYPTO_KEEP UINT _nx_crypto_ec_key_pair_stream_generate(NX_CRYPTO_EC *curve,
3241 UCHAR *output,
3242 ULONG output_length_in_byte,
3243 ULONG *actual_output_length,
3244 HN_UBASE *scratch)
3245 {
3246 UINT status;
3247 UINT private_key_len;
3248 UINT public_key_len;
3249 /* Actual huge numbers used in calculations */
3250 NX_CRYPTO_HUGE_NUMBER private_key;
3251 NX_CRYPTO_EC_POINT public_key;
3252
3253 /* Get key length. */
3254 private_key_len = (curve -> nx_crypto_ec_bits + 7) >> 3;
3255 public_key_len = 1 + (private_key_len << 1);
3256
3257 /* Check output buffer size. */
3258 if ((private_key_len + public_key_len) > output_length_in_byte)
3259 {
3260 return(NX_CRYPTO_SIZE_ERROR);
3261 }
3262
3263 /* Public key buffer (and scratch). */
3264 NX_CRYPTO_EC_POINT_INITIALIZE(&public_key, NX_CRYPTO_EC_POINT_AFFINE, scratch,
3265 private_key_len);
3266
3267 /* Private key buffer - note that no scratch is required for the private key. */
3268 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&private_key, scratch, private_key_len);
3269
3270 /* Generate Key Pair. */
3271 status = _nx_crypto_ec_key_pair_generation_extra(curve, &curve -> nx_crypto_ec_g, &private_key,
3272 &public_key, scratch);
3273 if (status)
3274 {
3275 return(status);
3276 }
3277
3278 /* Copy the private key and public key into the return buffer. */
3279 status = _nx_crypto_huge_number_extract_fixed_size(&private_key, output, private_key_len);
3280 if (status)
3281 {
3282 return(status);
3283 }
3284
3285 _nx_crypto_ec_point_extract_uncompressed(curve, &public_key, &output[private_key_len],
3286 public_key_len, &public_key_len);
3287
3288 if (public_key_len == 0)
3289 {
3290 return(NX_CRYPTO_SIZE_ERROR);
3291 }
3292 *actual_output_length = (private_key_len + public_key_len);
3293
3294 return(NX_CRYPTO_SUCCESS);
3295 }
3296
3297 /**************************************************************************/
3298 /* */
3299 /* FUNCTION RELEASE */
3300 /* */
3301 /* _nx_crypto_ec_precomputation PORTABLE C */
3302 /* 6.1.7 */
3303 /* AUTHOR */
3304 /* */
3305 /* Timothy Stapko, Microsoft Corporation */
3306 /* */
3307 /* DESCRIPTION */
3308 /* */
3309 /* This function precomputes the fixed points of the curve. With fixed */
3310 /* points, the multiplication of the curve is faster than the one */
3311 /* without fixed points. */
3312 /* */
3313 /* INPUT */
3314 /* */
3315 /* curve Pointer to curve */
3316 /* window_width Width of window */
3317 /* bits Bits of fixed points */
3318 /* scratch Pointer to scratch buffer */
3319 /* */
3320 /* OUTPUT */
3321 /* */
3322 /* status Completion status */
3323 /* */
3324 /* CALLS */
3325 /* */
3326 /* NX_CRYPTO_EC_POINT_INITIALIZE Initialize EC point */
3327 /* NX_CRYPTO_HUGE_NUMBER_COPY Copy huge number */
3328 /* NX_CRYPTO_HUGE_NUMBER_INITIALIZE Initialize the buffer of */
3329 /* huge number */
3330 /* [nx_crypto_ec_add] Perform addtion for EC */
3331 /* [nx_crypto_ec_multiple] Perform multiplication for EC */
3332 /* */
3333 /* CALLED BY */
3334 /* */
3335 /* Application Code */
3336 /* */
3337 /* RELEASE HISTORY */
3338 /* */
3339 /* DATE NAME DESCRIPTION */
3340 /* */
3341 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
3342 /* 09-30-2020 Timothy Stapko Modified comment(s), */
3343 /* resulting in version 6.1 */
3344 /* 06-02-2021 Bhupendra Naphade Modified comment(s), */
3345 /* renamed FIPS symbol to */
3346 /* self-test, */
3347 /* resulting in version 6.1.7 */
3348 /* */
3349 /**************************************************************************/
3350 #ifndef NX_CRYPTO_SELF_TEST
_nx_crypto_ec_precomputation(NX_CRYPTO_EC * curve,UINT window_width,UINT bits,HN_UBASE ** scratch_pptr)3351 NX_CRYPTO_KEEP VOID _nx_crypto_ec_precomputation(NX_CRYPTO_EC *curve,
3352 UINT window_width,
3353 UINT bits,
3354 HN_UBASE **scratch_pptr)
3355 {
3356 NX_CRYPTO_EC_FIXED_POINTS *fixed_points;
3357 NX_CRYPTO_EC_POINT *g;
3358 NX_CRYPTO_EC_POINT *array;
3359 NX_CRYPTO_HUGE_NUMBER d;
3360 HN_UBASE *scratch_ptr;
3361 UINT offset;
3362 UINT i, j;
3363
3364 if (curve -> nx_crypto_ec_fixed_points)
3365 {
3366
3367 /* Fixed points are already computed. */
3368 return;
3369 }
3370
3371 if (window_width == 0)
3372 {
3373 return;
3374 }
3375
3376 g = &curve -> nx_crypto_ec_g;
3377
3378 scratch_ptr = *scratch_pptr;
3379 fixed_points = (NX_CRYPTO_EC_FIXED_POINTS *)scratch_ptr;
3380 scratch_ptr += sizeof(NX_CRYPTO_EC_FIXED_POINTS) >> HN_SIZE_SHIFT;
3381
3382 fixed_points -> nx_crypto_ec_fixed_points_window_width = window_width;
3383 fixed_points -> nx_crypto_ec_fixed_points_bits = bits;
3384 fixed_points -> nx_crypto_ec_fixed_points_d = (bits + window_width - 1) / window_width;
3385 fixed_points -> nx_crypto_ec_fixed_points_e = (fixed_points -> nx_crypto_ec_fixed_points_d +
3386 1) >> 1;
3387
3388 fixed_points -> nx_crypto_ec_fixed_points_array = (NX_CRYPTO_EC_POINT *)scratch_ptr;
3389 scratch_ptr += (sizeof(NX_CRYPTO_EC_POINT) * (UINT)((1 << window_width) - 2)) >> HN_SIZE_SHIFT;
3390 fixed_points -> nx_crypto_ec_fixed_points_array_2e = (NX_CRYPTO_EC_POINT *)scratch_ptr;
3391 scratch_ptr += (sizeof(NX_CRYPTO_EC_POINT) * (UINT)((1 << window_width) - 1)) >> HN_SIZE_SHIFT;
3392
3393 /* Allocate buffers for fixed points. */
3394 for (i = 0; i < (1u << window_width) - 2; i++)
3395 {
3396 NX_CRYPTO_EC_POINT_INITIALIZE(&fixed_points -> nx_crypto_ec_fixed_points_array[i],
3397 NX_CRYPTO_EC_POINT_AFFINE, scratch_ptr,
3398 g -> nx_crypto_ec_point_x.nx_crypto_huge_buffer_size);
3399 }
3400 for (i = 0; i < (1u << window_width) - 1; i++)
3401 {
3402 NX_CRYPTO_EC_POINT_INITIALIZE(&fixed_points -> nx_crypto_ec_fixed_points_array_2e[i],
3403 NX_CRYPTO_EC_POINT_AFFINE, scratch_ptr,
3404 g -> nx_crypto_ec_point_x.nx_crypto_huge_buffer_size);
3405 }
3406
3407 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&d, scratch_ptr,
3408 (((fixed_points -> nx_crypto_ec_fixed_points_d >> 3) + 4) & (ULONG) ~3));
3409
3410 /* Calculate [a(w-1),...a(0)]G */
3411 /* First calculate 2 ^ d * G */
3412 array = fixed_points -> nx_crypto_ec_fixed_points_array;
3413 d.nx_crypto_huge_number_size = (fixed_points -> nx_crypto_ec_fixed_points_d >>
3414 (HN_SIZE_SHIFT + 3)) + 1;
3415 NX_CRYPTO_MEMSET(d.nx_crypto_huge_number_data, 0, d.nx_crypto_huge_number_size << HN_SIZE_SHIFT);
3416 d.nx_crypto_huge_number_data[d.nx_crypto_huge_number_size - 1] =
3417 (HN_UBASE)(1 << (fixed_points -> nx_crypto_ec_fixed_points_d & (NX_CRYPTO_HUGE_NUMBER_BITS - 1)));
3418 curve -> nx_crypto_ec_multiple(curve, g, &d, &array[0], scratch_ptr);
3419
3420 /* Calculate rest of [a(w-1),...a(0)]G */
3421 for (i = 1; i < window_width; i++)
3422 {
3423 offset = (UINT)(1 << i);
3424 if (i > 1)
3425 {
3426 curve -> nx_crypto_ec_multiple(curve, &array[(1 << (i - 1)) - 2], &d,
3427 &array[offset - 2], scratch_ptr);
3428 }
3429 NX_CRYPTO_HUGE_NUMBER_COPY(&array[offset - 1].nx_crypto_ec_point_x,
3430 &array[offset - 2].nx_crypto_ec_point_x);
3431 NX_CRYPTO_HUGE_NUMBER_COPY(&array[offset - 1].nx_crypto_ec_point_y,
3432 &array[offset - 2].nx_crypto_ec_point_y);
3433 curve -> nx_crypto_ec_add(curve, &array[offset - 1], g, scratch_ptr);
3434
3435 for (j = 1; j < offset - 1; j++)
3436 {
3437 NX_CRYPTO_HUGE_NUMBER_COPY(&array[offset + j - 1].nx_crypto_ec_point_x,
3438 &array[offset - 2].nx_crypto_ec_point_x);
3439 NX_CRYPTO_HUGE_NUMBER_COPY(&array[offset + j - 1].nx_crypto_ec_point_y,
3440 &array[offset - 2].nx_crypto_ec_point_y);
3441 curve -> nx_crypto_ec_add(curve, &array[offset + j - 1], &array[j - 1], scratch_ptr);
3442 }
3443 }
3444
3445 /* 2^e[a(w-1),...a(0)]G */
3446 /* First calculate 2 ^ e * G and 2 ^ e * 2 ^ d * G */
3447 array = fixed_points -> nx_crypto_ec_fixed_points_array_2e;
3448 d.nx_crypto_huge_number_size = (fixed_points -> nx_crypto_ec_fixed_points_e >>
3449 (HN_SIZE_SHIFT + 3)) + 1;
3450 NX_CRYPTO_MEMSET(d.nx_crypto_huge_number_data, 0, d.nx_crypto_huge_number_size << HN_SIZE_SHIFT);
3451 d.nx_crypto_huge_number_data[d.nx_crypto_huge_number_size - 1] =
3452 (HN_UBASE)(1 << (fixed_points -> nx_crypto_ec_fixed_points_e & (NX_CRYPTO_HUGE_NUMBER_BITS - 1)));
3453 curve -> nx_crypto_ec_multiple(curve, g, &d, &array[0], scratch_ptr);
3454 d.nx_crypto_huge_number_size = (fixed_points -> nx_crypto_ec_fixed_points_d >>
3455 (HN_SIZE_SHIFT + 3)) + 1;
3456 NX_CRYPTO_MEMSET(d.nx_crypto_huge_number_data, 0, d.nx_crypto_huge_number_size << HN_SIZE_SHIFT);
3457 d.nx_crypto_huge_number_data[d.nx_crypto_huge_number_size - 1] =
3458 (HN_UBASE)(1 << (fixed_points -> nx_crypto_ec_fixed_points_d & (NX_CRYPTO_HUGE_NUMBER_BITS - 1)));
3459 curve -> nx_crypto_ec_multiple(curve, &array[0], &d, &array[1], scratch_ptr);
3460
3461 /* Calculate rest of 2^e[a(w-1),...a(0)]G */
3462 for (i = 1; i < window_width; i++)
3463 {
3464 offset = (UINT)(1 << i);
3465 if (i > 1)
3466 {
3467 curve -> nx_crypto_ec_multiple(curve, &array[(1 << (i - 1)) - 1], &d,
3468 &array[offset - 1], scratch_ptr);
3469 }
3470
3471 for (j = 0; j < offset - 1; j++)
3472 {
3473 NX_CRYPTO_HUGE_NUMBER_COPY(&array[offset + j].nx_crypto_ec_point_x,
3474 &array[offset - 1].nx_crypto_ec_point_x);
3475 NX_CRYPTO_HUGE_NUMBER_COPY(&array[offset + j].nx_crypto_ec_point_y,
3476 &array[offset - 1].nx_crypto_ec_point_y);
3477 curve -> nx_crypto_ec_add(curve, &array[offset + j], &array[j], scratch_ptr);
3478 }
3479 }
3480
3481 curve -> nx_crypto_ec_fixed_points = fixed_points;
3482
3483 *scratch_pptr = scratch_ptr;
3484 }
3485 #endif
3486 /* NOTE: This function should be run when NX_CRYPTO_HUGE_NUMBER_BITS is 32. */
3487 /**************************************************************************/
3488 /* */
3489 /* FUNCTION RELEASE */
3490 /* */
3491 /* _nx_crypto_ec_fixed_output PORTABLE C */
3492 /* 6.1.7 */
3493 /* AUTHOR */
3494 /* */
3495 /* Timothy Stapko, Microsoft Corporation */
3496 /* */
3497 /* DESCRIPTION */
3498 /* */
3499 /* This function outputs the fixed points. So the fixed points can be */
3500 /* stored outside the RAM or avoid computation every time. */
3501 /* */
3502 /* INPUT */
3503 /* */
3504 /* curve Pointer to curve */
3505 /* output Callback function for output */
3506 /* tab String of TAB */
3507 /* line_ending String of line ending */
3508 /* */
3509 /* OUTPUT */
3510 /* */
3511 /* None */
3512 /* */
3513 /* CALLS */
3514 /* */
3515 /* None */
3516 /* */
3517 /* CALLED BY */
3518 /* */
3519 /* Application Code */
3520 /* */
3521 /* RELEASE HISTORY */
3522 /* */
3523 /* DATE NAME DESCRIPTION */
3524 /* */
3525 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
3526 /* 09-30-2020 Timothy Stapko Modified comment(s), */
3527 /* resulting in version 6.1 */
3528 /* 06-02-2021 Bhupendra Naphade Modified comment(s), */
3529 /* renamed FIPS symbol to */
3530 /* self-test, */
3531 /* resulting in version 6.1.7 */
3532 /* */
3533 /**************************************************************************/
3534 #ifndef NX_CRYPTO_SELF_TEST
_nx_crypto_ec_fixed_output(NX_CRYPTO_EC * curve,INT (* output)(const CHAR * format,...),const CHAR * tab,const CHAR * line_ending)3535 NX_CRYPTO_KEEP VOID _nx_crypto_ec_fixed_output(NX_CRYPTO_EC *curve,
3536 INT (*output)(const CHAR *format, ...),
3537 const CHAR *tab,
3538 const CHAR *line_ending)
3539 {
3540 UINT i, j, k;
3541 UINT array_index;
3542 UINT array_size;
3543 NX_CRYPTO_EC_FIXED_POINTS *fixed_points;
3544 NX_CRYPTO_EC_POINT *points;
3545 NX_CRYPTO_HUGE_NUMBER *value;
3546 HN_UBASE *buffer;
3547 UINT window_width;
3548 const CHAR *coordinate_name[] = {"x", "y"};
3549 const CHAR *array_name[] = {"", "_2e"};
3550
3551 #if (NX_CRYPTO_HUGE_NUMBER_BITS != 32)
3552 return;
3553 #endif /* (NX_CRYPTO_HUGE_NUMBER_BITS != 32) */
3554
3555 fixed_points = curve -> nx_crypto_ec_fixed_points;
3556 if (fixed_points == NX_CRYPTO_NULL)
3557 {
3558
3559 /* Fixed points are not pre-computed. */
3560 return;
3561 }
3562
3563 window_width = fixed_points -> nx_crypto_ec_fixed_points_window_width;
3564
3565 /* Output data in buffer of each point. */
3566
3567 for (array_index = 0; array_index < 2; array_index++)
3568 {
3569 if (array_index == 0)
3570 {
3571 array_size = (1u << window_width) - 2;
3572 points = fixed_points -> nx_crypto_ec_fixed_points_array;
3573 }
3574 else
3575 {
3576 array_size = (1u << window_width) - 1;
3577 points = fixed_points -> nx_crypto_ec_fixed_points_array_2e;
3578 }
3579 output("static NX_CRYPTO_CONST HN_UBASE %s_fixed_points%s_data[][%u >> HN_SIZE_SHIFT] =%s",
3580 curve -> nx_crypto_ec_name,
3581 array_name[array_index],
3582 curve -> nx_crypto_ec_g.nx_crypto_ec_point_x.nx_crypto_huge_buffer_size,
3583 line_ending);
3584 output("{%s", line_ending);
3585 for (i = 0; i < array_size; i++)
3586 {
3587 for (j = 0; j < 2; j++)
3588 {
3589 if (array_index == 0)
3590 {
3591 output("%s%s/* %uG.%s */%s", line_ending, tab, i + 2, coordinate_name[j], line_ending);
3592 }
3593 else
3594 {
3595 output("%s%s/* 2^e * %uG.%s */%s", line_ending, tab, i + 1, coordinate_name[j], line_ending);
3596 }
3597 output("%s{%s", tab, line_ending);
3598
3599 if (j == 0)
3600 {
3601 value = &points[i].nx_crypto_ec_point_x;
3602 }
3603 else
3604 {
3605 value = &points[i].nx_crypto_ec_point_y;
3606 }
3607 buffer = (HN_UBASE *)value -> nx_crypto_huge_number_data;
3608 for (k = 0; k < ((value -> nx_crypto_huge_buffer_size) >> HN_SIZE_SHIFT); k++)
3609 {
3610 if (((k + 1) & 0x1) == 1)
3611 {
3612 output("%s%s", tab, tab);
3613 }
3614
3615 if (k < value -> nx_crypto_huge_number_size)
3616 {
3617 output("HN_ULONG_TO_UBASE(0x%08X)", buffer[k]);
3618 }
3619 else
3620 {
3621 output("HN_ULONG_TO_UBASE(0x00000000)");
3622 }
3623
3624 if (k != ((value -> nx_crypto_huge_buffer_size) >> HN_SIZE_SHIFT) - 1)
3625 {
3626 output(", ");
3627 }
3628 if (((k + 1) & 0x1) == 0)
3629 {
3630 output("%s", line_ending);
3631 }
3632 }
3633
3634 if ((j == 1) && (i == (array_size - 1)))
3635 {
3636 output("%s%s}%s", line_ending, tab, line_ending);
3637 }
3638 else
3639 {
3640 output("%s%s},%s", line_ending, tab, line_ending);
3641 }
3642 }
3643 }
3644 output("};%s", line_ending);
3645 }
3646
3647 /* Output each point structure. */
3648 for (array_index = 0; array_index < 2; array_index++)
3649 {
3650 if (array_index == 0)
3651 {
3652 array_size = (1u << window_width) - 2;
3653 points = fixed_points -> nx_crypto_ec_fixed_points_array;
3654 }
3655 else
3656 {
3657 array_size = (1u << window_width) - 1;
3658 points = fixed_points -> nx_crypto_ec_fixed_points_array_2e;
3659 }
3660 output("static NX_CRYPTO_CONST NX_CRYPTO_EC_POINT %s_fixed_points%s_array[] =%s",
3661 curve -> nx_crypto_ec_name,
3662 array_name[array_index],
3663 line_ending);
3664 output("{%s", line_ending);
3665 for (i = 0; i < array_size; i++)
3666 {
3667 if (array_index == 0)
3668 {
3669 output("%s%s/* %uG */%s", line_ending, tab, i + 2, line_ending);
3670 }
3671 else
3672 {
3673 output("%s%s/* 2^e * %uG */%s", line_ending, tab, i + 1, line_ending);
3674 }
3675
3676 output("%s{%s", tab, line_ending);
3677 output("%s%sNX_CRYPTO_EC_POINT_AFFINE,%s", tab, tab, line_ending);
3678
3679 /* Output X and Y */
3680 for (j = 0; j < 2; j++)
3681 {
3682 if (j == 0)
3683 {
3684 value = &points[i].nx_crypto_ec_point_x;
3685 }
3686 else
3687 {
3688 value = &points[i].nx_crypto_ec_point_y;
3689 }
3690 output("%s%s{%s", tab, tab, line_ending);
3691 output("%s%s%s(HN_UBASE *)&%s_fixed_points%s_data[%u],%s",
3692 tab, tab, tab,
3693 curve -> nx_crypto_ec_name, array_name[array_index], (i << 1) + j,
3694 line_ending);
3695 output("%s%s%s%u >> HN_SIZE_SHIFT, ",
3696 tab, tab, tab,
3697 value -> nx_crypto_huge_number_size << HN_SIZE_SHIFT);
3698 output("%u, (UINT)NX_CRYPTO_FALSE%s",
3699 value -> nx_crypto_huge_buffer_size,
3700 line_ending);
3701 output("%s%s},%s", tab, tab, line_ending);
3702 }
3703
3704 /* Output Z which is not used. */
3705 output("%s%s{(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u}%s", tab, tab, line_ending);
3706
3707 output("%s}", tab);
3708 if (i != (array_size - 1))
3709 {
3710 output(",%s", line_ending);
3711 }
3712 else
3713 {
3714 output("%s", line_ending);
3715 }
3716 }
3717 output("};%s", line_ending);
3718 }
3719
3720 /* Output structure for fixed points. */
3721 output("%s%sNX_CRYPTO_CONST NX_CRYPTO_EC_FIXED_POINTS _nx_crypto_ec_%s_fixed_points =%s",
3722 line_ending, line_ending, curve -> nx_crypto_ec_name, line_ending);
3723 output("{%s", line_ending);
3724 output("%s%uu, %uu, %uu, %uu,%s", tab,
3725 fixed_points -> nx_crypto_ec_fixed_points_window_width,
3726 fixed_points -> nx_crypto_ec_fixed_points_bits,
3727 fixed_points -> nx_crypto_ec_fixed_points_d,
3728 fixed_points -> nx_crypto_ec_fixed_points_e,
3729 line_ending);
3730 output("%s(NX_CRYPTO_EC_POINT *)%s_fixed_points_array,%s",
3731 tab, curve -> nx_crypto_ec_name, line_ending);
3732 output("%s(NX_CRYPTO_EC_POINT *)%s_fixed_points_2e_array%s",
3733 tab, curve -> nx_crypto_ec_name, line_ending);
3734 output("};%s", line_ending);
3735 }
3736 #endif
3737
3738 /**************************************************************************/
3739 /* */
3740 /* FUNCTION RELEASE */
3741 /* */
3742 /* _nx_crypto_ec_get_named_curve PORTABLE C */
3743 /* 6.1.7 */
3744 /* AUTHOR */
3745 /* */
3746 /* Timothy Stapko, Microsoft Corporation */
3747 /* */
3748 /* DESCRIPTION */
3749 /* */
3750 /* This function gets the named curve by ID. */
3751 /* */
3752 /* INPUT */
3753 /* */
3754 /* curve Pointer to curve */
3755 /* curve_id Curve ID */
3756 /* */
3757 /* OUTPUT */
3758 /* */
3759 /* status Completion status */
3760 /* */
3761 /* CALLS */
3762 /* */
3763 /* None */
3764 /* */
3765 /* CALLED BY */
3766 /* */
3767 /* Application Code */
3768 /* */
3769 /* RELEASE HISTORY */
3770 /* */
3771 /* DATE NAME DESCRIPTION */
3772 /* */
3773 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
3774 /* 09-30-2020 Timothy Stapko Modified comment(s), updated */
3775 /* constants, resulting */
3776 /* in version 6.1 */
3777 /* 06-02-2021 Bhupendra Naphade Modified comment(s), */
3778 /* renamed FIPS symbol to */
3779 /* self-test, */
3780 /* resulting in version 6.1.7 */
3781 /* */
3782 /**************************************************************************/
3783 #ifndef NX_CRYPTO_SELF_TEST
_nx_crypto_ec_get_named_curve(NX_CRYPTO_EC ** curve,UINT curve_id)3784 NX_CRYPTO_KEEP UINT _nx_crypto_ec_get_named_curve(NX_CRYPTO_EC **curve, UINT curve_id)
3785 {
3786 UINT i;
3787
3788 for (i = 0; i < sizeof(_nx_crypto_ec_named_curves) / sizeof(NX_CRYPTO_EC *); i++)
3789 {
3790 if (curve_id == _nx_crypto_ec_named_curves[i] -> nx_crypto_ec_id)
3791 {
3792 *curve = (NX_CRYPTO_EC *)_nx_crypto_ec_named_curves[i];
3793 return(NX_CRYPTO_SUCCESS);
3794 }
3795 }
3796
3797 *curve = NX_CRYPTO_NULL;
3798 return(NX_CRYTPO_MISSING_ECC_CURVE);
3799 }
3800 #endif
3801 /**************************************************************************/
3802 /* */
3803 /* FUNCTION RELEASE */
3804 /* */
3805 /* _nx_crypto_method_ec_secp192r1_operation PORTABLE C */
3806 /* 6.1 */
3807 /* AUTHOR */
3808 /* */
3809 /* Timothy Stapko, Microsoft Corporation */
3810 /* */
3811 /* DESCRIPTION */
3812 /* */
3813 /* This function returns the secp192r1 curve. */
3814 /* */
3815 /* INPUT */
3816 /* */
3817 /* op Operation */
3818 /* handle Crypto handle */
3819 /* method Cryption Method Object */
3820 /* key Encryption Key */
3821 /* key_size_in_bits Key size in bits */
3822 /* input Input data */
3823 /* input_length_in_byte Input data size */
3824 /* iv_ptr Initial vector */
3825 /* output Output buffer */
3826 /* output_length_in_byte Output buffer size */
3827 /* crypto_metadata Metadata area */
3828 /* crypto_metadata_size Metadata area size */
3829 /* packet_ptr Pointer to packet */
3830 /* nx_crypto_hw_process_callback Callback function pointer */
3831 /* */
3832 /* OUTPUT */
3833 /* */
3834 /* status Completion status */
3835 /* */
3836 /* CALLS */
3837 /* */
3838 /* None */
3839 /* */
3840 /* CALLED BY */
3841 /* */
3842 /* Application Code */
3843 /* */
3844 /* RELEASE HISTORY */
3845 /* */
3846 /* DATE NAME DESCRIPTION */
3847 /* */
3848 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
3849 /* 09-30-2020 Timothy Stapko Modified comment(s), */
3850 /* resulting in version 6.1 */
3851 /* */
3852 /**************************************************************************/
_nx_crypto_method_ec_secp192r1_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID *,UINT))3853 NX_CRYPTO_KEEP UINT _nx_crypto_method_ec_secp192r1_operation(UINT op,
3854 VOID *handle,
3855 struct NX_CRYPTO_METHOD_STRUCT *method,
3856 UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
3857 UCHAR *input, ULONG input_length_in_byte,
3858 UCHAR *iv_ptr,
3859 UCHAR *output, ULONG output_length_in_byte,
3860 VOID *crypto_metadata, ULONG crypto_metadata_size,
3861 VOID *packet_ptr,
3862 VOID (*nx_crypto_hw_process_callback)(VOID *, UINT))
3863 {
3864 NX_CRYPTO_PARAMETER_NOT_USED(handle);
3865 NX_CRYPTO_PARAMETER_NOT_USED(method);
3866 NX_CRYPTO_PARAMETER_NOT_USED(key);
3867 NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
3868 NX_CRYPTO_PARAMETER_NOT_USED(input);
3869 NX_CRYPTO_PARAMETER_NOT_USED(input_length_in_byte);
3870 NX_CRYPTO_PARAMETER_NOT_USED(iv_ptr);
3871 NX_CRYPTO_PARAMETER_NOT_USED(output);
3872 NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
3873 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata);
3874 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata_size);
3875 NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
3876 NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
3877
3878 if (op != NX_CRYPTO_EC_CURVE_GET)
3879 {
3880 return(NX_CRYPTO_NOT_SUCCESSFUL);
3881 }
3882
3883 *((NX_CRYPTO_EC **)output) = (NX_CRYPTO_EC *)&_nx_crypto_ec_secp192r1;
3884
3885 return(NX_CRYPTO_SUCCESS);
3886 }
3887
3888
3889 /**************************************************************************/
3890 /* */
3891 /* FUNCTION RELEASE */
3892 /* */
3893 /* _nx_crypto_method_ec_secp224r1_operation PORTABLE C */
3894 /* 6.1 */
3895 /* AUTHOR */
3896 /* */
3897 /* Timothy Stapko, Microsoft Corporation */
3898 /* */
3899 /* DESCRIPTION */
3900 /* */
3901 /* This function returns the secp224r1 curve. */
3902 /* */
3903 /* INPUT */
3904 /* */
3905 /* op Operation */
3906 /* handle Crypto handle */
3907 /* method Cryption Method Object */
3908 /* key Encryption Key */
3909 /* key_size_in_bits Key size in bits */
3910 /* input Input data */
3911 /* input_length_in_byte Input data size */
3912 /* iv_ptr Initial vector */
3913 /* output Output buffer */
3914 /* output_length_in_byte Output buffer size */
3915 /* crypto_metadata Metadata area */
3916 /* crypto_metadata_size Metadata area size */
3917 /* packet_ptr Pointer to packet */
3918 /* nx_crypto_hw_process_callback Callback function pointer */
3919 /* */
3920 /* OUTPUT */
3921 /* */
3922 /* status Completion status */
3923 /* */
3924 /* CALLS */
3925 /* */
3926 /* None */
3927 /* */
3928 /* CALLED BY */
3929 /* */
3930 /* Application Code */
3931 /* */
3932 /* RELEASE HISTORY */
3933 /* */
3934 /* DATE NAME DESCRIPTION */
3935 /* */
3936 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
3937 /* 09-30-2020 Timothy Stapko Modified comment(s), */
3938 /* resulting in version 6.1 */
3939 /* */
3940 /**************************************************************************/
_nx_crypto_method_ec_secp224r1_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID *,UINT))3941 NX_CRYPTO_KEEP UINT _nx_crypto_method_ec_secp224r1_operation(UINT op,
3942 VOID *handle,
3943 struct NX_CRYPTO_METHOD_STRUCT *method,
3944 UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
3945 UCHAR *input, ULONG input_length_in_byte,
3946 UCHAR *iv_ptr,
3947 UCHAR *output, ULONG output_length_in_byte,
3948 VOID *crypto_metadata, ULONG crypto_metadata_size,
3949 VOID *packet_ptr,
3950 VOID (*nx_crypto_hw_process_callback)(VOID *, UINT))
3951 {
3952 NX_CRYPTO_PARAMETER_NOT_USED(handle);
3953 NX_CRYPTO_PARAMETER_NOT_USED(method);
3954 NX_CRYPTO_PARAMETER_NOT_USED(key);
3955 NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
3956 NX_CRYPTO_PARAMETER_NOT_USED(input);
3957 NX_CRYPTO_PARAMETER_NOT_USED(input_length_in_byte);
3958 NX_CRYPTO_PARAMETER_NOT_USED(iv_ptr);
3959 NX_CRYPTO_PARAMETER_NOT_USED(output);
3960 NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
3961 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata);
3962 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata_size);
3963 NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
3964 NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
3965
3966 if (op != NX_CRYPTO_EC_CURVE_GET)
3967 {
3968 return(NX_CRYPTO_NOT_SUCCESSFUL);
3969 }
3970
3971 *((NX_CRYPTO_EC **)output) = (NX_CRYPTO_EC *)&_nx_crypto_ec_secp224r1;
3972
3973 return(NX_CRYPTO_SUCCESS);
3974 }
3975
3976 /**************************************************************************/
3977 /* */
3978 /* FUNCTION RELEASE */
3979 /* */
3980 /* _nx_crypto_method_ec_secp256r1_operation PORTABLE C */
3981 /* 6.1 */
3982 /* AUTHOR */
3983 /* */
3984 /* Timothy Stapko, Microsoft Corporation */
3985 /* */
3986 /* DESCRIPTION */
3987 /* */
3988 /* This function returns the secp256r1 curve. */
3989 /* */
3990 /* INPUT */
3991 /* */
3992 /* op Operation */
3993 /* handle Crypto handle */
3994 /* method Cryption Method Object */
3995 /* key Encryption Key */
3996 /* key_size_in_bits Key size in bits */
3997 /* input Input data */
3998 /* input_length_in_byte Input data size */
3999 /* iv_ptr Initial vector */
4000 /* output Output buffer */
4001 /* output_length_in_byte Output buffer size */
4002 /* crypto_metadata Metadata area */
4003 /* crypto_metadata_size Metadata area size */
4004 /* packet_ptr Pointer to packet */
4005 /* nx_crypto_hw_process_callback Callback function pointer */
4006 /* */
4007 /* OUTPUT */
4008 /* */
4009 /* status Completion status */
4010 /* */
4011 /* CALLS */
4012 /* */
4013 /* None */
4014 /* */
4015 /* CALLED BY */
4016 /* */
4017 /* Application Code */
4018 /* */
4019 /* RELEASE HISTORY */
4020 /* */
4021 /* DATE NAME DESCRIPTION */
4022 /* */
4023 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
4024 /* 09-30-2020 Timothy Stapko Modified comment(s), */
4025 /* resulting in version 6.1 */
4026 /* */
4027 /**************************************************************************/
_nx_crypto_method_ec_secp256r1_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID *,UINT))4028 NX_CRYPTO_KEEP UINT _nx_crypto_method_ec_secp256r1_operation(UINT op,
4029 VOID *handle,
4030 struct NX_CRYPTO_METHOD_STRUCT *method,
4031 UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
4032 UCHAR *input, ULONG input_length_in_byte,
4033 UCHAR *iv_ptr,
4034 UCHAR *output, ULONG output_length_in_byte,
4035 VOID *crypto_metadata, ULONG crypto_metadata_size,
4036 VOID *packet_ptr,
4037 VOID (*nx_crypto_hw_process_callback)(VOID *, UINT))
4038 {
4039 NX_CRYPTO_PARAMETER_NOT_USED(handle);
4040 NX_CRYPTO_PARAMETER_NOT_USED(method);
4041 NX_CRYPTO_PARAMETER_NOT_USED(key);
4042 NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
4043 NX_CRYPTO_PARAMETER_NOT_USED(input);
4044 NX_CRYPTO_PARAMETER_NOT_USED(input_length_in_byte);
4045 NX_CRYPTO_PARAMETER_NOT_USED(iv_ptr);
4046 NX_CRYPTO_PARAMETER_NOT_USED(output);
4047 NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
4048 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata);
4049 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata_size);
4050 NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
4051 NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
4052
4053 if (op != NX_CRYPTO_EC_CURVE_GET)
4054 {
4055 return(NX_CRYPTO_NOT_SUCCESSFUL);
4056 }
4057
4058 *((NX_CRYPTO_EC **)output) = (NX_CRYPTO_EC *)&_nx_crypto_ec_secp256r1;
4059
4060 return(NX_CRYPTO_SUCCESS);
4061 }
4062
4063 /**************************************************************************/
4064 /* */
4065 /* FUNCTION RELEASE */
4066 /* */
4067 /* _nx_crypto_method_ec_secp384r1_operation PORTABLE C */
4068 /* 6.1 */
4069 /* AUTHOR */
4070 /* */
4071 /* Timothy Stapko, Microsoft Corporation */
4072 /* */
4073 /* DESCRIPTION */
4074 /* */
4075 /* This function returns the secp384r1 curve. */
4076 /* */
4077 /* INPUT */
4078 /* */
4079 /* op Operation */
4080 /* handle Crypto handle */
4081 /* method Cryption Method Object */
4082 /* key Encryption Key */
4083 /* key_size_in_bits Key size in bits */
4084 /* input Input data */
4085 /* input_length_in_byte Input data size */
4086 /* iv_ptr Initial vector */
4087 /* output Output buffer */
4088 /* output_length_in_byte Output buffer size */
4089 /* crypto_metadata Metadata area */
4090 /* crypto_metadata_size Metadata area size */
4091 /* packet_ptr Pointer to packet */
4092 /* nx_crypto_hw_process_callback Callback function pointer */
4093 /* */
4094 /* OUTPUT */
4095 /* */
4096 /* status Completion status */
4097 /* */
4098 /* CALLS */
4099 /* */
4100 /* None */
4101 /* */
4102 /* CALLED BY */
4103 /* */
4104 /* Application Code */
4105 /* */
4106 /* RELEASE HISTORY */
4107 /* */
4108 /* DATE NAME DESCRIPTION */
4109 /* */
4110 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
4111 /* 09-30-2020 Timothy Stapko Modified comment(s), */
4112 /* resulting in version 6.1 */
4113 /* */
4114 /**************************************************************************/
_nx_crypto_method_ec_secp384r1_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID *,UINT))4115 NX_CRYPTO_KEEP UINT _nx_crypto_method_ec_secp384r1_operation(UINT op,
4116 VOID *handle,
4117 struct NX_CRYPTO_METHOD_STRUCT *method,
4118 UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
4119 UCHAR *input, ULONG input_length_in_byte,
4120 UCHAR *iv_ptr,
4121 UCHAR *output, ULONG output_length_in_byte,
4122 VOID *crypto_metadata, ULONG crypto_metadata_size,
4123 VOID *packet_ptr,
4124 VOID (*nx_crypto_hw_process_callback)(VOID *, UINT))
4125 {
4126 NX_CRYPTO_PARAMETER_NOT_USED(handle);
4127 NX_CRYPTO_PARAMETER_NOT_USED(method);
4128 NX_CRYPTO_PARAMETER_NOT_USED(key);
4129 NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
4130 NX_CRYPTO_PARAMETER_NOT_USED(input);
4131 NX_CRYPTO_PARAMETER_NOT_USED(input_length_in_byte);
4132 NX_CRYPTO_PARAMETER_NOT_USED(iv_ptr);
4133 NX_CRYPTO_PARAMETER_NOT_USED(output);
4134 NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
4135 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata);
4136 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata_size);
4137 NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
4138 NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
4139
4140 if (op != NX_CRYPTO_EC_CURVE_GET)
4141 {
4142 return(NX_CRYPTO_NOT_SUCCESSFUL);
4143 }
4144
4145 *((NX_CRYPTO_EC **)output) = (NX_CRYPTO_EC *)&_nx_crypto_ec_secp384r1;
4146
4147 return(NX_CRYPTO_SUCCESS);
4148 }
4149
4150 /**************************************************************************/
4151 /* */
4152 /* FUNCTION RELEASE */
4153 /* */
4154 /* _nx_crypto_method_ec_secp521r1_operation PORTABLE C */
4155 /* 6.1 */
4156 /* AUTHOR */
4157 /* */
4158 /* Timothy Stapko, Microsoft Corporation */
4159 /* */
4160 /* DESCRIPTION */
4161 /* */
4162 /* This function returns the secp521r1 curve. */
4163 /* */
4164 /* INPUT */
4165 /* */
4166 /* op Operation */
4167 /* handle Crypto handle */
4168 /* method Cryption Method Object */
4169 /* key Encryption Key */
4170 /* key_size_in_bits Key size in bits */
4171 /* input Input data */
4172 /* input_length_in_byte Input data size */
4173 /* iv_ptr Initial vector */
4174 /* output Output buffer */
4175 /* output_length_in_byte Output buffer size */
4176 /* crypto_metadata Metadata area */
4177 /* crypto_metadata_size Metadata area size */
4178 /* packet_ptr Pointer to packet */
4179 /* nx_crypto_hw_process_callback Callback function pointer */
4180 /* */
4181 /* OUTPUT */
4182 /* */
4183 /* status Completion status */
4184 /* */
4185 /* CALLS */
4186 /* */
4187 /* None */
4188 /* */
4189 /* CALLED BY */
4190 /* */
4191 /* Application Code */
4192 /* */
4193 /* RELEASE HISTORY */
4194 /* */
4195 /* DATE NAME DESCRIPTION */
4196 /* */
4197 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
4198 /* 09-30-2020 Timothy Stapko Modified comment(s), */
4199 /* resulting in version 6.1 */
4200 /* */
4201 /**************************************************************************/
_nx_crypto_method_ec_secp521r1_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID *,UINT))4202 NX_CRYPTO_KEEP UINT _nx_crypto_method_ec_secp521r1_operation(UINT op,
4203 VOID *handle,
4204 struct NX_CRYPTO_METHOD_STRUCT *method,
4205 UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
4206 UCHAR *input, ULONG input_length_in_byte,
4207 UCHAR *iv_ptr,
4208 UCHAR *output, ULONG output_length_in_byte,
4209 VOID *crypto_metadata, ULONG crypto_metadata_size,
4210 VOID *packet_ptr,
4211 VOID (*nx_crypto_hw_process_callback)(VOID *, UINT))
4212 {
4213 NX_CRYPTO_PARAMETER_NOT_USED(handle);
4214 NX_CRYPTO_PARAMETER_NOT_USED(method);
4215 NX_CRYPTO_PARAMETER_NOT_USED(key);
4216 NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
4217 NX_CRYPTO_PARAMETER_NOT_USED(input);
4218 NX_CRYPTO_PARAMETER_NOT_USED(input_length_in_byte);
4219 NX_CRYPTO_PARAMETER_NOT_USED(iv_ptr);
4220 NX_CRYPTO_PARAMETER_NOT_USED(output);
4221 NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
4222 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata);
4223 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata_size);
4224 NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
4225 NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
4226
4227 if (op != NX_CRYPTO_EC_CURVE_GET)
4228 {
4229 return(NX_CRYPTO_NOT_SUCCESSFUL);
4230 }
4231
4232 *((NX_CRYPTO_EC **)output) = (NX_CRYPTO_EC *)&_nx_crypto_ec_secp521r1;
4233
4234 return(NX_CRYPTO_SUCCESS);
4235 }
4236
4237
4238 /**************************************************************************/
4239 /* */
4240 /* FUNCTION RELEASE */
4241 /* */
4242 /* _nx_crypto_ec_validate_public_key PORTABLE C */
4243 /* 6.1.10 */
4244 /* AUTHOR */
4245 /* */
4246 /* Timothy Stapko, Microsoft Corporation */
4247 /* */
4248 /* DESCRIPTION */
4249 /* */
4250 /* This function validates the public key by ensuring that the point */
4251 /* is a valid point on the elliptic curve. This function supports prime*/
4252 /* field curves only. */
4253 /* */
4254 /* INPUT */
4255 /* */
4256 /* public_key Public key to be verified */
4257 /* chosen_curve Curve used by the key */
4258 /* partial Perform partial validation */
4259 /* scratch Pointer to scratch buffer. */
4260 /* This scratch buffer can be */
4261 /* reused after this function */
4262 /* returns. */
4263 /* */
4264 /* OUTPUT */
4265 /* */
4266 /* status Completion status */
4267 /* */
4268 /* CALLS */
4269 /* */
4270 /* _nx_crypto_huge_number_compare Compare huge number */
4271 /* */
4272 /* CALLED BY */
4273 /* */
4274 /* Application Code */
4275 /* */
4276 /* RELEASE HISTORY */
4277 /* */
4278 /* DATE NAME DESCRIPTION */
4279 /* */
4280 /* 09-30-2020 Timothy Stapko Initial Version 6.1 */
4281 /* 01-31-2022 Timothy Stapko Modified comment(s), and */
4282 /* improved performance, */
4283 /* resulting in version 6.1.10 */
4284 /* */
4285 /**************************************************************************/
4286 #ifndef NX_CRYPTO_ECC_DISABLE_KEY_VALIDATION
_nx_crypto_ec_validate_public_key(NX_CRYPTO_EC_POINT * public_key,NX_CRYPTO_EC * chosen_curve,UINT partial,HN_UBASE * scratch)4287 UINT _nx_crypto_ec_validate_public_key(NX_CRYPTO_EC_POINT *public_key,
4288 NX_CRYPTO_EC *chosen_curve,
4289 UINT partial,
4290 HN_UBASE *scratch)
4291 {
4292 NX_CRYPTO_HUGE_NUMBER temp;
4293 NX_CRYPTO_HUGE_NUMBER right;
4294 UINT compare_value;
4295 UINT buffer_size = chosen_curve -> nx_crypto_ec_n.nx_crypto_huge_buffer_size;
4296 HN_UBASE *scratch2 = scratch;
4297
4298 NX_CRYPTO_PARAMETER_NOT_USED(partial);
4299
4300 /* 1. Verify Q is not the point at infinity. */
4301 if(_nx_crypto_ec_point_is_infinite(public_key))
4302 {
4303 return(NX_CRYPTO_INVALID_KEY);
4304 }
4305
4306 /* 2. Verify that xQ and yQ are integers in the interval [0, p-1].
4307 (Ensures that each coordinate of the public key has the unique correct representation of
4308 an element in the underlying field.) */
4309 compare_value = _nx_crypto_huge_number_compare(&public_key -> nx_crypto_ec_point_x, &chosen_curve -> nx_crypto_ec_field.fp);
4310 if (compare_value != NX_CRYPTO_HUGE_NUMBER_LESS)
4311 {
4312 return(NX_CRYPTO_INVALID_KEY);
4313 }
4314
4315 compare_value = _nx_crypto_huge_number_compare(&public_key -> nx_crypto_ec_point_y, &chosen_curve -> nx_crypto_ec_field.fp);
4316 if (compare_value != NX_CRYPTO_HUGE_NUMBER_LESS)
4317 {
4318 return(NX_CRYPTO_INVALID_KEY);
4319 }
4320
4321 if (public_key -> nx_crypto_ec_point_x.nx_crypto_huge_number_is_negative ||
4322 public_key -> nx_crypto_ec_point_y.nx_crypto_huge_number_is_negative)
4323 {
4324 return(NX_CRYPTO_INVALID_KEY);
4325 }
4326
4327 /* 3. Verify that (yQ)^2 = (xQ)^3 + axQ + b in GF(p) , where the arithmetic is
4328 performed modulo p.
4329 (xQ)^3 + axQ + b = ((xQ)^2 + a)xQ + b
4330 (This step is to ensure that the public key is on the correct elliptic curve.)
4331 */
4332 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp, scratch2, buffer_size * 2);
4333 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&right, scratch2, buffer_size * 2);
4334
4335 _nx_crypto_huge_number_multiply(&public_key -> nx_crypto_ec_point_x, &public_key -> nx_crypto_ec_point_x, &temp);
4336 _nx_crypto_huge_number_modulus(&temp, &chosen_curve -> nx_crypto_ec_field.fp);
4337 _nx_crypto_huge_number_add_unsigned(&temp, &chosen_curve -> nx_crypto_ec_a);
4338 _nx_crypto_huge_number_modulus(&temp, &chosen_curve -> nx_crypto_ec_field.fp);
4339
4340 _nx_crypto_huge_number_multiply(&temp, &public_key -> nx_crypto_ec_point_x, &right);
4341 _nx_crypto_huge_number_modulus(&right, &chosen_curve -> nx_crypto_ec_field.fp);
4342
4343 _nx_crypto_huge_number_add_unsigned(&right, &chosen_curve -> nx_crypto_ec_b);
4344 _nx_crypto_huge_number_modulus(&right, &chosen_curve -> nx_crypto_ec_field.fp);
4345
4346 _nx_crypto_huge_number_multiply(&public_key -> nx_crypto_ec_point_y, &public_key -> nx_crypto_ec_point_y, &temp);
4347 _nx_crypto_huge_number_modulus(&temp, &chosen_curve -> nx_crypto_ec_field.fp);
4348
4349 compare_value = _nx_crypto_huge_number_compare(&temp, &right);
4350 if (compare_value != NX_CRYPTO_HUGE_NUMBER_EQUAL)
4351 {
4352 return(NX_CRYPTO_INVALID_KEY);
4353 }
4354
4355 /* 4. Verify that nQ = O.
4356 (This step is to ensure that the public key has the correct order. Along with the
4357 verification in step 1, ensures that the public key is in the correct range in the correct EC
4358 subgroup; that is, it is in the correct EC subgroup and is not the identity element O.)
4359 */
4360 /* Removed this validation as h is 1 for all the software supported curves and nQ = O
4361 is implied by the checks in step 2 and 3.
4362 if (!partial)
4363 {
4364 NX_CRYPTO_EC_POINT_INITIALIZE(&pt, NX_CRYPTO_EC_POINT_AFFINE, scratch, buffer_size);
4365 chosen_curve -> nx_crypto_ec_multiple(chosen_curve, public_key, &chosen_curve -> nx_crypto_ec_n, &pt, scratch);
4366 if (!_nx_crypto_ec_point_is_infinite(&pt))
4367 {
4368 return(NX_CRYPTO_INVALID_KEY);
4369 }
4370 }
4371 */
4372
4373 return(NX_CRYPTO_SUCCESS);
4374 }
4375 #endif /* NX_CRYPTO_ECC_DISABLE_KEY_VALIDATION */
4376
4377 #ifdef NX_CRYPTO_ENABLE_CURVE25519_448
4378
4379 /* x25519 */
4380 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_x25519_p[] =
4381 {
4382
4383 /* p = 7fffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffed */
4384 HN_ULONG_TO_UBASE(0xFFFFFFED), HN_ULONG_TO_UBASE(0xFFFFFFFF),
4385 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
4386 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
4387 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0x7FFFFFFF),
4388 };
4389
4390 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_x25519_gx[] =
4391 {
4392
4393 /* U(P) = 9 */
4394 HN_ULONG_TO_UBASE(0x00000009)
4395 };
4396
4397
4398 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_x25519_h[] =
4399 {
4400
4401 /* h = 08 */
4402 HN_ULONG_TO_UBASE(0x00000008)
4403 };
4404
4405 /* x448 */
4406 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_x448_p[] =
4407 {
4408
4409 /* p = ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff */
4410 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
4411 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
4412 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
4413 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFE),
4414 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
4415 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
4416 HN_ULONG_TO_UBASE(0xFFFFFFFF), HN_ULONG_TO_UBASE(0xFFFFFFFF),
4417 };
4418
4419 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_x448_gx[] =
4420 {
4421
4422 /* U(P) = 5 */
4423 HN_ULONG_TO_UBASE(0x00000005)
4424 };
4425
4426
4427 static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_x448_h[] =
4428 {
4429
4430 /* h = 04 */
4431 HN_ULONG_TO_UBASE(0x00000004)
4432 };
4433
4434
4435 NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_x25519 =
4436 {
4437 "x25519",
4438 NX_CRYPTO_EC_X25519,
4439 5,
4440 255,
4441 {
4442 .fp =
4443 {
4444 (HN_UBASE *)_nx_crypto_ec_x25519_p,
4445 sizeof(_nx_crypto_ec_x25519_p) >> HN_SIZE_SHIFT,
4446 sizeof(_nx_crypto_ec_x25519_p),
4447 (UINT)NX_CRYPTO_FALSE
4448 }
4449 },
4450 {(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u},
4451 {(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u},
4452 {
4453 NX_CRYPTO_EC_POINT_AFFINE,
4454 {
4455 (HN_UBASE *)_nx_crypto_ec_x25519_gx,
4456 sizeof(_nx_crypto_ec_x25519_gx) >> HN_SIZE_SHIFT,
4457 sizeof(_nx_crypto_ec_x25519_gx),
4458 (UINT)NX_CRYPTO_FALSE
4459 },
4460 {(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u},
4461 {(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u}
4462 },
4463 {(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u},
4464 {
4465 (HN_UBASE *)_nx_crypto_ec_x25519_h,
4466 sizeof(_nx_crypto_ec_x25519_h) >> HN_SIZE_SHIFT,
4467 sizeof(_nx_crypto_ec_x25519_h),
4468 (UINT)NX_CRYPTO_FALSE
4469 },
4470 (NX_CRYPTO_EC_FIXED_POINTS *)NX_CRYPTO_NULL,
4471 NX_CRYPTO_NULL,
4472 NX_CRYPTO_NULL,
4473 _nx_crypto_ec_x25519_448_multiple,
4474 NX_CRYPTO_NULL
4475 };
4476
4477 NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_x448 =
4478 {
4479 "x448",
4480 NX_CRYPTO_EC_X448,
4481 5,
4482 448,
4483 {
4484 .fp =
4485 {
4486 (HN_UBASE *)_nx_crypto_ec_x448_p,
4487 sizeof(_nx_crypto_ec_x448_p) >> HN_SIZE_SHIFT,
4488 sizeof(_nx_crypto_ec_x448_p),
4489 (UINT)NX_CRYPTO_FALSE
4490 }
4491 },
4492 {(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u},
4493 {(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u},
4494 {
4495 NX_CRYPTO_EC_POINT_AFFINE,
4496 {
4497 (HN_UBASE *)_nx_crypto_ec_x448_gx,
4498 sizeof(_nx_crypto_ec_x448_gx) >> HN_SIZE_SHIFT,
4499 sizeof(_nx_crypto_ec_x448_gx),
4500 (UINT)NX_CRYPTO_FALSE
4501 },
4502 {(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u},
4503 {(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u}
4504 },
4505 {(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u},
4506 {
4507 (HN_UBASE *)_nx_crypto_ec_x448_h,
4508 sizeof(_nx_crypto_ec_x448_h) >> HN_SIZE_SHIFT,
4509 sizeof(_nx_crypto_ec_x448_h),
4510 (UINT)NX_CRYPTO_FALSE
4511 },
4512 (NX_CRYPTO_EC_FIXED_POINTS *)NX_CRYPTO_NULL,
4513 NX_CRYPTO_NULL,
4514 NX_CRYPTO_NULL,
4515 _nx_crypto_ec_x25519_448_multiple,
4516 NX_CRYPTO_NULL
4517 };
4518
4519
4520 /**************************************************************************/
4521 /* */
4522 /* FUNCTION RELEASE */
4523 /* */
4524 /* _nx_crypto_ec_x25519_448_multiple PORTABLE C */
4525 /* 6.1.12 */
4526 /* AUTHOR */
4527 /* */
4528 /* Yuxin Zhou, Microsoft Corporation */
4529 /* */
4530 /* DESCRIPTION */
4531 /* */
4532 /* This function performs the scalar multiplication on X25519 and X448 */
4533 /* curves. */
4534 /* */
4535 /* INPUT */
4536 /* */
4537 /* curve Pointer to curve */
4538 /* u U coordinate */
4539 /* k Scalar */
4540 /* r Result */
4541 /* scratch Pointer to scratch buffer */
4542 /* */
4543 /* OUTPUT */
4544 /* */
4545 /* status Completion status */
4546 /* */
4547 /* CALLS */
4548 /* */
4549 /* NX_CRYPTO_EC_POINT_INITIALIZE Initialize EC point */
4550 /* NX_CRYPTO_HUGE_NUMBER_COPY Copy huge number */
4551 /* _nx_crypto_ec_cswap Swap two huge numbers */
4552 /* _nx_crypto_huge_number_add Addition for huge numbers */
4553 /* _nx_crypto_huge_number_subtract Calculate subtraction for */
4554 /* huge numbers */
4555 /* _nx_crypto_huge_number_modulus Perform a modulus operation */
4556 /* _nx_crypto_huge_number_multiply Multiply two huge numbers */
4557 /* _nx_crypto_huge_number_square Compute the square of a value */
4558 /* _nx_crypto_huge_number_inverse_modulus_prime */
4559 /* Perform an inverse modulus */
4560 /* operation for prime number */
4561 /* */
4562 /* CALLED BY */
4563 /* */
4564 /* Application Code */
4565 /* */
4566 /* RELEASE HISTORY */
4567 /* */
4568 /* DATE NAME DESCRIPTION */
4569 /* */
4570 /* 04-25-2022 Yuxin Zhou Initial Version 6.1.11 */
4571 /* 07-29-2022 Yuxin Zhou Modified comment(s), */
4572 /* added x448 curve, */
4573 /* resulting in version 6.1.12 */
4574 /* */
4575 /**************************************************************************/
_nx_crypto_ec_x25519_448_multiple(NX_CRYPTO_EC * curve,NX_CRYPTO_EC_POINT * u,NX_CRYPTO_HUGE_NUMBER * k,NX_CRYPTO_EC_POINT * r,HN_UBASE * scratch)4576 NX_CRYPTO_KEEP VOID _nx_crypto_ec_x25519_448_multiple(NX_CRYPTO_EC* curve,
4577 NX_CRYPTO_EC_POINT* u,
4578 NX_CRYPTO_HUGE_NUMBER* k,
4579 NX_CRYPTO_EC_POINT* r,
4580 HN_UBASE* scratch)
4581 {
4582 NX_CRYPTO_HUGE_NUMBER k_2;
4583 NX_CRYPTO_HUGE_NUMBER x_1;
4584 NX_CRYPTO_HUGE_NUMBER x_2;
4585 NX_CRYPTO_HUGE_NUMBER z_2;
4586 NX_CRYPTO_HUGE_NUMBER x_3;
4587 NX_CRYPTO_HUGE_NUMBER z_3;
4588 NX_CRYPTO_HUGE_NUMBER t_1;
4589 NX_CRYPTO_HUGE_NUMBER t_2;
4590 INT t;
4591 UINT k_t;
4592 UINT swap;
4593 UINT clen;
4594 ULONG a24;
4595 HN_UBASE* k_buf;
4596
4597 clen = (curve -> nx_crypto_ec_bits + 7) >> 3;
4598
4599 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&k_2, scratch, clen);
4600 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&x_1, scratch, clen);
4601 clen = clen << 1;
4602 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&x_2, scratch, clen);
4603 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&z_2, scratch, clen);
4604 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&x_3, scratch, clen);
4605 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&z_3, scratch, clen);
4606 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&t_1, scratch, clen);
4607 NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&t_2, scratch, clen);
4608
4609 NX_CRYPTO_HUGE_NUMBER_COPY(&k_2, k);
4610 NX_CRYPTO_HUGE_NUMBER_COPY(&x_1, &u -> nx_crypto_ec_point_x);
4611
4612 if (curve -> nx_crypto_ec_id == NX_CRYPTO_EC_X25519)
4613 {
4614 /* x25519 */
4615 x_1.nx_crypto_huge_number_data[7] &= 0x7FFFFFFF;
4616
4617 k_buf = k_2.nx_crypto_huge_number_data;
4618
4619 k_buf[0] &= 0xFFFFFFF8;
4620 k_buf[7] &= 0x7FFFFFFF;
4621 k_buf[7] |= 0x40000000;
4622 a24 = 121665;
4623 }
4624 else
4625 {
4626 /* x448 */
4627
4628 k_buf = k_2.nx_crypto_huge_number_data;
4629
4630 k_buf[0] &= 0xFFFFFFFC;
4631 k_buf[13] |= 0x80000000;
4632 a24 = 39081;
4633 }
4634
4635 NX_CRYPTO_HUGE_NUMBER_SET_DIGIT(&x_2, 1);
4636 NX_CRYPTO_HUGE_NUMBER_COPY(&x_3, &x_1);
4637 NX_CRYPTO_HUGE_NUMBER_SET_DIGIT(&z_3, 1);
4638
4639 swap = 0;
4640
4641 for (t = (INT)(curve -> nx_crypto_ec_bits - 1); t >= 0; t--)
4642 {
4643 k_t = 1 & (k_buf[t >> 5] >> (t & 31));
4644 swap ^= k_t;
4645 _nx_crypto_ec_cswap(swap, &x_2, &x_3);
4646 _nx_crypto_ec_cswap(swap, &z_2, &z_3);
4647 swap = k_t;
4648
4649 /* A = x_2 + z_2 */
4650 NX_CRYPTO_HUGE_NUMBER_COPY(&t_1, &x_2);
4651 _nx_crypto_huge_number_add(&t_1, &z_2);
4652 _nx_crypto_huge_number_modulus(&t_1, &curve->nx_crypto_ec_field.fp);
4653
4654 /* B = x_2 - z_2 */
4655 _nx_crypto_huge_number_subtract(&x_2, &z_2);
4656
4657 /* C = x_3 + z_3 */
4658 NX_CRYPTO_HUGE_NUMBER_COPY(&t_2, &x_3);
4659 _nx_crypto_huge_number_add(&t_2, &z_3);
4660
4661 /* D = x_3 - z_3 */
4662 _nx_crypto_huge_number_subtract(&x_3, &z_3);
4663
4664 /* DA = D * A */
4665 _nx_crypto_huge_number_multiply(&x_3, &t_1, &z_3);
4666 _nx_crypto_huge_number_modulus(&z_3, &curve -> nx_crypto_ec_field.fp);
4667
4668 /* CB = C * B */
4669 _nx_crypto_huge_number_multiply(&x_2, &t_2, &z_2);
4670 _nx_crypto_huge_number_modulus(&z_2, &curve -> nx_crypto_ec_field.fp);
4671
4672 /* t_2 = DA + CB */
4673 NX_CRYPTO_HUGE_NUMBER_COPY(&t_2, &z_2);
4674 _nx_crypto_huge_number_add(&t_2, &z_3);
4675 _nx_crypto_huge_number_modulus(&t_2, &curve->nx_crypto_ec_field.fp);
4676
4677 /* z_3 = DA - CB */
4678 _nx_crypto_huge_number_subtract(&z_3, &z_2);
4679
4680 /* x_3 = (DA + CB)^2 */
4681 _nx_crypto_huge_number_square(&t_2, &x_3);
4682 _nx_crypto_huge_number_modulus(&x_3, &curve -> nx_crypto_ec_field.fp);
4683
4684 /* t_2 = (DA - CB)^2 */
4685 _nx_crypto_huge_number_square(&z_3, &t_2);
4686 _nx_crypto_huge_number_modulus(&t_2, &curve -> nx_crypto_ec_field.fp);
4687
4688 /* z_3 = x_1 * (DA - CB)^2 */
4689 _nx_crypto_huge_number_multiply(&t_2, &x_1, &z_3);
4690 _nx_crypto_huge_number_modulus(&z_3, &curve -> nx_crypto_ec_field.fp);
4691
4692 /* AA = A^2 */
4693 _nx_crypto_huge_number_square(&t_1, &z_2);
4694 _nx_crypto_huge_number_modulus(&z_2, &curve -> nx_crypto_ec_field.fp);
4695
4696 /* BB = B^2 */
4697 _nx_crypto_huge_number_square(&x_2, &t_1);
4698 _nx_crypto_huge_number_modulus(&t_1, &curve -> nx_crypto_ec_field.fp);
4699
4700 /* E = AA - BB */
4701 NX_CRYPTO_HUGE_NUMBER_COPY(&t_2, &z_2);
4702 _nx_crypto_huge_number_subtract(&t_2, &t_1);
4703
4704 /* x_2 = AA * BB */
4705 _nx_crypto_huge_number_multiply(&z_2, &t_1, &x_2);
4706 _nx_crypto_huge_number_modulus(&x_2, &curve -> nx_crypto_ec_field.fp);
4707
4708 /* z_2 = E * (AA + a24 * E) */
4709 _nx_crypto_huge_number_multiply_digit(&t_2, a24, &t_1);
4710
4711 _nx_crypto_huge_number_add(&t_1, &z_2);
4712 _nx_crypto_huge_number_modulus(&t_1, &curve -> nx_crypto_ec_field.fp);
4713
4714 _nx_crypto_huge_number_multiply(&t_1, &t_2, &z_2);
4715 _nx_crypto_huge_number_modulus(&z_2, &curve -> nx_crypto_ec_field.fp);
4716
4717 }
4718
4719 _nx_crypto_ec_cswap(swap, &x_2, &x_3);
4720 _nx_crypto_ec_cswap(swap, &z_2, &z_3);
4721
4722 /* Return x_2 * (z_2^(p - 2)) = x_2 * (z_2^-1) */
4723 _nx_crypto_huge_number_inverse_modulus_prime(&z_2, &curve -> nx_crypto_ec_field.fp, &t_1, scratch);
4724 _nx_crypto_huge_number_multiply(&x_2, &t_1, &r -> nx_crypto_ec_point_x);
4725 _nx_crypto_huge_number_modulus(&r -> nx_crypto_ec_point_x, &curve -> nx_crypto_ec_field.fp);
4726
4727 }
4728
4729 /**************************************************************************/
4730 /* */
4731 /* FUNCTION RELEASE */
4732 /* */
4733 /* _nx_crypto_ec_cswap PORTABLE C */
4734 /* 6.1.11 */
4735 /* AUTHOR */
4736 /* */
4737 /* Yuxin Zhou, Microsoft Corporation */
4738 /* */
4739 /* DESCRIPTION */
4740 /* */
4741 /* This function performs conditional swap of two huge number in */
4742 /* constant time. */
4743 /* */
4744 /* INPUT */
4745 /* */
4746 /* swap Swap condition */
4747 /* h1 First huge number */
4748 /* h2 Second huge number */
4749 /* */
4750 /* OUTPUT */
4751 /* */
4752 /* None */
4753 /* */
4754 /* CALLS */
4755 /* */
4756 /* None */
4757 /* */
4758 /* CALLED BY */
4759 /* */
4760 /* _nx_crypto_ec_x25519_448_multiple Scalar multiplication */
4761 /* */
4762 /* RELEASE HISTORY */
4763 /* */
4764 /* DATE NAME DESCRIPTION */
4765 /* */
4766 /* 04-25-2022 Yuxin Zhou Initial Version 6.1.11 */
4767 /* */
4768 /**************************************************************************/
_nx_crypto_ec_cswap(UINT swap,NX_CRYPTO_HUGE_NUMBER * h1,NX_CRYPTO_HUGE_NUMBER * h2)4769 NX_CRYPTO_KEEP VOID _nx_crypto_ec_cswap(UINT swap, NX_CRYPTO_HUGE_NUMBER *h1, NX_CRYPTO_HUGE_NUMBER *h2)
4770 {
4771 UINT i;
4772 HN_UBASE hswap = (HN_UBASE)(0 - swap);
4773 HN_UBASE dummy;
4774
4775
4776 for (i = 0; i < (h1 -> nx_crypto_huge_buffer_size >> HN_SIZE_SHIFT); i++)
4777 {
4778 dummy = hswap & (h1 -> nx_crypto_huge_number_data[i] ^ h2 -> nx_crypto_huge_number_data[i]);
4779 h1 -> nx_crypto_huge_number_data[i] = h1 -> nx_crypto_huge_number_data[i] ^ dummy;
4780 h2 -> nx_crypto_huge_number_data[i] = h2 -> nx_crypto_huge_number_data[i] ^ dummy;
4781 }
4782
4783 i = hswap & (h1 -> nx_crypto_huge_number_size ^ h2 -> nx_crypto_huge_number_size);
4784 h1 -> nx_crypto_huge_number_size ^= i;
4785 h2 -> nx_crypto_huge_number_size ^= i;
4786
4787 i = hswap & (h1 -> nx_crypto_huge_number_is_negative ^ h2 -> nx_crypto_huge_number_is_negative);
4788 h1 -> nx_crypto_huge_number_is_negative ^= i;
4789 h2 -> nx_crypto_huge_number_is_negative ^= i;
4790
4791 }
4792
4793
4794 /**************************************************************************/
4795 /* */
4796 /* FUNCTION RELEASE */
4797 /* */
4798 /* _nx_crypto_method_ec_x25519_operation PORTABLE C */
4799 /* 6.1.11 */
4800 /* AUTHOR */
4801 /* */
4802 /* Yuxin Zhou, Microsoft Corporation */
4803 /* */
4804 /* DESCRIPTION */
4805 /* */
4806 /* This function returns the x25519 curve. */
4807 /* */
4808 /* INPUT */
4809 /* */
4810 /* op Operation */
4811 /* handle Crypto handle */
4812 /* method Cryption Method Object */
4813 /* key Encryption Key */
4814 /* key_size_in_bits Key size in bits */
4815 /* input Input data */
4816 /* input_length_in_byte Input data size */
4817 /* iv_ptr Initial vector */
4818 /* output Output buffer */
4819 /* output_length_in_byte Output buffer size */
4820 /* crypto_metadata Metadata area */
4821 /* crypto_metadata_size Metadata area size */
4822 /* packet_ptr Pointer to packet */
4823 /* nx_crypto_hw_process_callback Callback function pointer */
4824 /* */
4825 /* OUTPUT */
4826 /* */
4827 /* status Completion status */
4828 /* */
4829 /* CALLS */
4830 /* */
4831 /* None */
4832 /* */
4833 /* CALLED BY */
4834 /* */
4835 /* Application Code */
4836 /* */
4837 /* RELEASE HISTORY */
4838 /* */
4839 /* DATE NAME DESCRIPTION */
4840 /* */
4841 /* 04-25-2022 Yuxin Zhou Initial Version 6.1.11 */
4842 /* */
4843 /**************************************************************************/
_nx_crypto_method_ec_x25519_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID *,UINT))4844 NX_CRYPTO_KEEP UINT _nx_crypto_method_ec_x25519_operation(UINT op,
4845 VOID *handle,
4846 struct NX_CRYPTO_METHOD_STRUCT *method,
4847 UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
4848 UCHAR *input, ULONG input_length_in_byte,
4849 UCHAR *iv_ptr,
4850 UCHAR *output, ULONG output_length_in_byte,
4851 VOID *crypto_metadata, ULONG crypto_metadata_size,
4852 VOID *packet_ptr,
4853 VOID (*nx_crypto_hw_process_callback)(VOID *, UINT))
4854 {
4855 NX_CRYPTO_PARAMETER_NOT_USED(handle);
4856 NX_CRYPTO_PARAMETER_NOT_USED(method);
4857 NX_CRYPTO_PARAMETER_NOT_USED(key);
4858 NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
4859 NX_CRYPTO_PARAMETER_NOT_USED(input);
4860 NX_CRYPTO_PARAMETER_NOT_USED(input_length_in_byte);
4861 NX_CRYPTO_PARAMETER_NOT_USED(iv_ptr);
4862 NX_CRYPTO_PARAMETER_NOT_USED(output);
4863 NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
4864 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata);
4865 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata_size);
4866 NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
4867 NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
4868
4869 if (op != NX_CRYPTO_EC_CURVE_GET)
4870 {
4871 return(NX_CRYPTO_NOT_SUCCESSFUL);
4872 }
4873
4874 *((NX_CRYPTO_EC **)output) = (NX_CRYPTO_EC *)&_nx_crypto_ec_x25519;
4875
4876 return(NX_CRYPTO_SUCCESS);
4877 }
4878
4879 /**************************************************************************/
4880 /* */
4881 /* FUNCTION RELEASE */
4882 /* */
4883 /* _nx_crypto_method_ec_x448_operation PORTABLE C */
4884 /* 6.1.12 */
4885 /* AUTHOR */
4886 /* */
4887 /* Yuxin Zhou, Microsoft Corporation */
4888 /* */
4889 /* DESCRIPTION */
4890 /* */
4891 /* This function returns the x448 curve. */
4892 /* */
4893 /* INPUT */
4894 /* */
4895 /* op Operation */
4896 /* handle Crypto handle */
4897 /* method Cryption Method Object */
4898 /* key Encryption Key */
4899 /* key_size_in_bits Key size in bits */
4900 /* input Input data */
4901 /* input_length_in_byte Input data size */
4902 /* iv_ptr Initial vector */
4903 /* output Output buffer */
4904 /* output_length_in_byte Output buffer size */
4905 /* crypto_metadata Metadata area */
4906 /* crypto_metadata_size Metadata area size */
4907 /* packet_ptr Pointer to packet */
4908 /* nx_crypto_hw_process_callback Callback function pointer */
4909 /* */
4910 /* OUTPUT */
4911 /* */
4912 /* status Completion status */
4913 /* */
4914 /* CALLS */
4915 /* */
4916 /* None */
4917 /* */
4918 /* CALLED BY */
4919 /* */
4920 /* Application Code */
4921 /* */
4922 /* RELEASE HISTORY */
4923 /* */
4924 /* DATE NAME DESCRIPTION */
4925 /* */
4926 /* 07-29-2022 Yuxin Zhou Initial Version 6.1.12 */
4927 /* */
4928 /**************************************************************************/
_nx_crypto_method_ec_x448_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID *,UINT))4929 NX_CRYPTO_KEEP UINT _nx_crypto_method_ec_x448_operation(UINT op,
4930 VOID *handle,
4931 struct NX_CRYPTO_METHOD_STRUCT *method,
4932 UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
4933 UCHAR *input, ULONG input_length_in_byte,
4934 UCHAR *iv_ptr,
4935 UCHAR *output, ULONG output_length_in_byte,
4936 VOID *crypto_metadata, ULONG crypto_metadata_size,
4937 VOID *packet_ptr,
4938 VOID (*nx_crypto_hw_process_callback)(VOID *, UINT))
4939 {
4940 NX_CRYPTO_PARAMETER_NOT_USED(handle);
4941 NX_CRYPTO_PARAMETER_NOT_USED(method);
4942 NX_CRYPTO_PARAMETER_NOT_USED(key);
4943 NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
4944 NX_CRYPTO_PARAMETER_NOT_USED(input);
4945 NX_CRYPTO_PARAMETER_NOT_USED(input_length_in_byte);
4946 NX_CRYPTO_PARAMETER_NOT_USED(iv_ptr);
4947 NX_CRYPTO_PARAMETER_NOT_USED(output);
4948 NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
4949 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata);
4950 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata_size);
4951 NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
4952 NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
4953
4954 if (op != NX_CRYPTO_EC_CURVE_GET)
4955 {
4956 return(NX_CRYPTO_NOT_SUCCESSFUL);
4957 }
4958
4959 *((NX_CRYPTO_EC **)output) = (NX_CRYPTO_EC *)&_nx_crypto_ec_x448;
4960
4961 return(NX_CRYPTO_SUCCESS);
4962 }
4963
4964 /**************************************************************************/
4965 /* */
4966 /* FUNCTION RELEASE */
4967 /* */
4968 /* _nx_crypto_ec_key_pair_generation_x25519_448 PORTABLE C */
4969 /* 6.1.12 */
4970 /* AUTHOR */
4971 /* */
4972 /* Yuxin Zhou, Microsoft Corporation */
4973 /* */
4974 /* DESCRIPTION */
4975 /* */
4976 /* This function generates an elliptic curve key pair. */
4977 /* */
4978 /* INPUT */
4979 /* */
4980 /* curve Pointer to curve */
4981 /* g Base point g */
4982 /* private_key Private key generated */
4983 /* public_key Public key generated */
4984 /* scratch Pointer to scratch buffer */
4985 /* */
4986 /* OUTPUT */
4987 /* */
4988 /* status Completion status */
4989 /* */
4990 /* CALLS */
4991 /* */
4992 /* NX_CRYPTO_RBG Generate random huge number */
4993 /* [nx_crypto_ec_multiple] Perform multiplication for EC */
4994 /* */
4995 /* CALLED BY */
4996 /* */
4997 /* _nx_crypto_ecdh_setup_x25519_448 Setup ECDH local key pair */
4998 /* */
4999 /* RELEASE HISTORY */
5000 /* */
5001 /* DATE NAME DESCRIPTION */
5002 /* */
5003 /* 04-25-2022 Yuxin Zhou Initial Version 6.1.11 */
5004 /* 07-29-2022 Yuxin Zhou Modified comment(s), */
5005 /* added x448 curve, */
5006 /* resulting in version 6.1.12 */
5007 /* */
5008 /**************************************************************************/
_nx_crypto_ec_key_pair_generation_x25519_448(NX_CRYPTO_EC * curve,NX_CRYPTO_EC_POINT * g,NX_CRYPTO_HUGE_NUMBER * private_key,NX_CRYPTO_EC_POINT * public_key,HN_UBASE * scratch)5009 NX_CRYPTO_KEEP UINT _nx_crypto_ec_key_pair_generation_x25519_448(NX_CRYPTO_EC *curve,
5010 NX_CRYPTO_EC_POINT *g,
5011 NX_CRYPTO_HUGE_NUMBER *private_key,
5012 NX_CRYPTO_EC_POINT *public_key,
5013 HN_UBASE *scratch)
5014 {
5015 UINT status;
5016 UINT buffer_size = (curve -> nx_crypto_ec_bits + 7) >> 3;
5017
5018 /* Get random number with specified length. */
5019 status = NX_CRYPTO_RBG(buffer_size << 3, (UCHAR*)private_key -> nx_crypto_huge_number_data);
5020
5021 if (status)
5022 {
5023 return(status);
5024 }
5025
5026 private_key -> nx_crypto_huge_number_size = buffer_size >> HN_SIZE_SHIFT;
5027
5028 /* Q = dG */
5029 curve -> nx_crypto_ec_multiple(curve, g, private_key, public_key, scratch);
5030
5031 return(NX_CRYPTO_SUCCESS);
5032 }
5033
5034 /**************************************************************************/
5035 /* */
5036 /* FUNCTION RELEASE */
5037 /* */
5038 /* _nx_crypto_ec_extract_fixed_size_le PORTABLE C */
5039 /* 6.1.11 */
5040 /* AUTHOR */
5041 /* */
5042 /* Yuxin Zhou, Microsoft Corporation */
5043 /* */
5044 /* DESCRIPTION */
5045 /* */
5046 /* This function extracts huge number in little-endian order to a */
5047 /* buffer with fixed size. */
5048 /* */
5049 /* INPUT */
5050 /* */
5051 /* number Huge number */
5052 /* byte_stream Output buffer */
5053 /* byte_stream_size Size of output buffer */
5054 /* */
5055 /* OUTPUT */
5056 /* */
5057 /* Status Operation result status */
5058 /* */
5059 /* CALLS */
5060 /* */
5061 /* NX_CRYPTO_MEMSET Copy the number data memory */
5062 /* NX_CRYPTO_MEMSET Set the memory */
5063 /* */
5064 /* CALLED BY */
5065 /* */
5066 /* _nx_crypto_ecdh_setup_x25519_448 Setup ECDH local key pair */
5067 /* _nx_crypto_ecdh_compute_secret_x25519_448 */
5068 /* Compute ECDH shared secret */
5069 /* */
5070 /* RELEASE HISTORY */
5071 /* */
5072 /* DATE NAME DESCRIPTION */
5073 /* */
5074 /* 04-25-2022 Yuxin Zhou Initial Version 6.1.11 */
5075 /* */
5076 /**************************************************************************/
_nx_crypto_ec_extract_fixed_size_le(NX_CRYPTO_HUGE_NUMBER * number,UCHAR * byte_stream,UINT byte_stream_size)5077 NX_CRYPTO_KEEP UINT _nx_crypto_ec_extract_fixed_size_le(NX_CRYPTO_HUGE_NUMBER *number,
5078 UCHAR *byte_stream, UINT byte_stream_size)
5079 {
5080 UINT number_size = number -> nx_crypto_huge_number_size << HN_SIZE_SHIFT;
5081
5082 if (number_size > byte_stream_size)
5083 {
5084
5085 /* User byte stream buffer too small. */
5086 return(NX_CRYPTO_SIZE_ERROR);
5087 }
5088
5089 NX_CRYPTO_MEMCPY(byte_stream, number -> nx_crypto_huge_number_data, number_size); /* Use case of memcpy is verified. */
5090
5091 if (byte_stream_size > number_size)
5092 {
5093 NX_CRYPTO_MEMSET(&byte_stream[number_size], 0, byte_stream_size - number_size);
5094 }
5095
5096 return(NX_CRYPTO_SUCCESS);
5097 }
5098 #endif /* NX_CRYPTO_ENABLE_CURVE25519_448 */
5099