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