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