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