/src/ibmswtpm2/src/TpmToOsslMath.c
Line | Count | Source (jump to first uncovered line) |
1 | | /********************************************************************************/ |
2 | | /* */ |
3 | | /* TPM to OpenSSL BigNum Shim Layer */ |
4 | | /* Written by Ken Goldman */ |
5 | | /* IBM Thomas J. Watson Research Center */ |
6 | | /* $Id: TpmToOsslMath.c 1314 2018-08-28 14:25:12Z kgoldman $ */ |
7 | | /* */ |
8 | | /* Licenses and Notices */ |
9 | | /* */ |
10 | | /* 1. Copyright Licenses: */ |
11 | | /* */ |
12 | | /* - Trusted Computing Group (TCG) grants to the user of the source code in */ |
13 | | /* this specification (the "Source Code") a worldwide, irrevocable, */ |
14 | | /* nonexclusive, royalty free, copyright license to reproduce, create */ |
15 | | /* derivative works, distribute, display and perform the Source Code and */ |
16 | | /* derivative works thereof, and to grant others the rights granted herein. */ |
17 | | /* */ |
18 | | /* - The TCG grants to the user of the other parts of the specification */ |
19 | | /* (other than the Source Code) the rights to reproduce, distribute, */ |
20 | | /* display, and perform the specification solely for the purpose of */ |
21 | | /* developing products based on such documents. */ |
22 | | /* */ |
23 | | /* 2. Source Code Distribution Conditions: */ |
24 | | /* */ |
25 | | /* - Redistributions of Source Code must retain the above copyright licenses, */ |
26 | | /* this list of conditions and the following disclaimers. */ |
27 | | /* */ |
28 | | /* - Redistributions in binary form must reproduce the above copyright */ |
29 | | /* licenses, this list of conditions and the following disclaimers in the */ |
30 | | /* documentation and/or other materials provided with the distribution. */ |
31 | | /* */ |
32 | | /* 3. Disclaimers: */ |
33 | | /* */ |
34 | | /* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */ |
35 | | /* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */ |
36 | | /* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */ |
37 | | /* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */ |
38 | | /* Contact TCG Administration (admin@trustedcomputinggroup.org) for */ |
39 | | /* information on specification licensing rights available through TCG */ |
40 | | /* membership agreements. */ |
41 | | /* */ |
42 | | /* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */ |
43 | | /* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */ |
44 | | /* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */ |
45 | | /* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */ |
46 | | /* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */ |
47 | | /* */ |
48 | | /* - Without limitation, TCG and its members and licensors disclaim all */ |
49 | | /* liability, including liability for infringement of any proprietary */ |
50 | | /* rights, relating to use of information in this specification and to the */ |
51 | | /* implementation of this specification, and TCG disclaims all liability for */ |
52 | | /* cost of procurement of substitute goods or services, lost profits, loss */ |
53 | | /* of use, loss of data or any incidental, consequential, direct, indirect, */ |
54 | | /* or special damages, whether under contract, tort, warranty or otherwise, */ |
55 | | /* arising in any way out of use or reliance upon this specification or any */ |
56 | | /* information herein. */ |
57 | | /* */ |
58 | | /* (c) Copyright IBM Corp. and others, 2016 - 2018 */ |
59 | | /* */ |
60 | | /********************************************************************************/ |
61 | | |
62 | | /* B.2.3.2. TpmToOsslMath.c */ |
63 | | /* B.2.3.2.1. Introduction */ |
64 | | /* This file contains the math functions that are not implemented in the BnMath() library |
65 | | (yet). These math functions will call the OpenSSL() library to execute the operations. There is a |
66 | | difference between the internal format and the OpenSSL() format. To call the OpenSSL() function, |
67 | | a BIGNUM structure is created for each passed variable. The sizes in the bignum_t are copied and |
68 | | the d pointer in the BIGNUM is set to point to the d parameter of the bignum_t. On return, |
69 | | SetSizeOsslToTpm() is used for each returned variable to make sure that the pointers are not |
70 | | changed. The size of the returned BIGGNUM is copied to bignum_t. */ |
71 | | /* B.2.3.2.2. Includes and Defines */ |
72 | | #include "Tpm.h" |
73 | | #if MATH_LIB == OSSL |
74 | | #include "TpmToOsslMath_fp.h" |
75 | | /* B.2.3.2.3.1. OsslToTpmBn() */ |
76 | | /* This function converts an OpenSSL() BIGNUM to a TPM bignum. In this implementation it is assumed |
77 | | that OpenSSL() used the same format for a big number as does the TPM -- an array of native-endian |
78 | | words in little-endian order. */ |
79 | | /* If the array allocated for the OpenSSL() BIGNUM is not the space within the TPM bignum, then the |
80 | | data is copied. Otherwise, just the size field of the BIGNUM is copied. */ |
81 | | void |
82 | | OsslToTpmBn( |
83 | | bigNum bn, |
84 | | BIGNUM *osslBn |
85 | | ) |
86 | 0 | { |
87 | 0 | unsigned char buffer[LARGEST_NUMBER + 1]; |
88 | 0 | int buffer_len; |
89 | |
|
90 | 0 | if(bn != NULL) |
91 | 0 | { |
92 | 0 | pAssert(BN_num_bytes(osslBn) >= 0); |
93 | 0 | pAssert(sizeof(buffer) >= (size_t)BN_num_bytes(osslBn)); |
94 | 0 | buffer_len = BN_bn2bin(osslBn, buffer); /* ossl to bin */ |
95 | 0 | BnFromBytes(bn, buffer, buffer_len); /* bin to TPM */ |
96 | 0 | } |
97 | 0 | } |
98 | | /* B.2.3.2.3.2. BigInitialized() */ |
99 | | /* This function initializes an OSSL BIGNUM from a TPM bignum. */ |
100 | | BIGNUM * |
101 | | BigInitialized( |
102 | | bigConst initializer |
103 | | ) |
104 | 0 | { |
105 | 0 | BIGNUM *toInit = NULL; |
106 | 0 | unsigned char buffer[LARGEST_NUMBER + 1]; |
107 | 0 | NUMBYTES buffer_len = (NUMBYTES )sizeof(buffer); |
108 | | |
109 | 0 | if (initializer == NULL) { |
110 | 0 | return NULL; |
111 | 0 | } |
112 | 0 | BnToBytes(initializer, buffer, &buffer_len); /* TPM to bin */ |
113 | 0 | toInit = BN_bin2bn(buffer, buffer_len, NULL); /* bin to ossl */ |
114 | 0 | return toInit; |
115 | 0 | } |
116 | | |
117 | | #ifndef OSSL_DEBUG |
118 | | # define BIGNUM_PRINT(label, bn, eol) |
119 | | # define DEBUG_PRINT(x) |
120 | | #else |
121 | | # define DEBUG_PRINT(x) printf("%s", x) |
122 | | # define BIGNUM_PRINT(label, bn, eol) BIGNUM_print((label), (bn), (eol)) |
123 | | static |
124 | | void BIGNUM_print( |
125 | | const char *label, |
126 | | const BIGNUM *a, |
127 | | BOOL eol |
128 | | ) |
129 | | { |
130 | | BN_ULONG *d; |
131 | | int i; |
132 | | int notZero = FALSE; |
133 | | if(label != NULL) |
134 | | printf("%s", label); |
135 | | if(a == NULL) |
136 | | { |
137 | | printf("NULL"); |
138 | | goto done; |
139 | | } |
140 | | if (a->neg) |
141 | | printf("-"); |
142 | | for(i = a->top, d = &a->d[i - 1]; i > 0; i--) |
143 | | { |
144 | | int j; |
145 | | BN_ULONG l = *d--; |
146 | | for(j = BN_BITS2 - 8; j >= 0; j -= 8) |
147 | | { |
148 | | BYTE b = (BYTE)((l >> j) & 0xFF); |
149 | | notZero = notZero || (b != 0); |
150 | | if(notZero) |
151 | | printf("%02x", b); |
152 | | } |
153 | | if(!notZero) |
154 | | printf("0"); |
155 | | } |
156 | | done: |
157 | | if(eol) |
158 | | printf("\n"); |
159 | | return; |
160 | | } |
161 | | #endif |
162 | | #if LIBRARY_COMPATIBILITY_CHECK |
163 | | void |
164 | | MathLibraryCompatibilityCheck( |
165 | | void |
166 | | ) |
167 | | { |
168 | | OSSL_ENTER(); |
169 | | BIGNUM *osslTemp = BN_CTX_get(CTX); |
170 | | BN_VAR(tpmTemp, 64 * 8); // allocate some space for a test value |
171 | | crypt_uword_t i; |
172 | | TPM2B_TYPE(TEST, 16); |
173 | | TPM2B_TEST test = {{16, {0x0F, 0x0E, 0x0D, 0x0C, |
174 | | 0x0B, 0x0A, 0x09, 0x08, |
175 | | 0x07, 0x06, 0x05, 0x04, |
176 | | 0x03, 0x02, 0x01, 0x00}}}; |
177 | | // Convert the test TPM2B to a bigNum |
178 | | BnFrom2B(tpmTemp, &test.b); |
179 | | // Convert the test TPM2B to an OpenSSL BIGNUM |
180 | | BN_bin2bn(test.t.buffer, test.t.size, osslTemp); |
181 | | // Make sure the values are consistent |
182 | | cAssert(osslTemp->top == (int)tpmTemp->size); |
183 | | for(i = 0; i < tpmTemp->size; i++) |
184 | | cAssert(osslTemp->d[0] == tpmTemp->d[0]); |
185 | | OSSL_LEAVE(); |
186 | | } |
187 | | #endif |
188 | | /* B.2.3.2.3.2. BnModMult() */ |
189 | | /* Does multiply and divide returning the remainder of the divide. */ |
190 | | LIB_EXPORT BOOL |
191 | | BnModMult( |
192 | | bigNum result, |
193 | | bigConst op1, |
194 | | bigConst op2, |
195 | | bigConst modulus |
196 | | ) |
197 | 0 | { |
198 | 0 | OSSL_ENTER(); |
199 | 0 | BIG_INITIALIZED(bnResult, result); |
200 | 0 | BIG_INITIALIZED(bnOp1, op1); |
201 | 0 | BIG_INITIALIZED(bnOp2, op2); |
202 | 0 | BIG_INITIALIZED(bnMod, modulus); |
203 | 0 | BIG_VAR(bnTemp, (LARGEST_NUMBER_BITS * 4)); |
204 | 0 | BOOL OK; |
205 | 0 | pAssert(BnGetAllocated(result) >= BnGetSize(modulus)); |
206 | 0 | OK = BN_mul(bnTemp, bnOp1, bnOp2, CTX); |
207 | 0 | OK = OK && BN_div(NULL, bnResult, bnTemp, bnMod, CTX); |
208 | 0 | if(OK) |
209 | 0 | { |
210 | 0 | result->size = DIV_UP(BN_num_bytes(bnResult), |
211 | 0 | sizeof(crypt_uword_t)); |
212 | 0 | OsslToTpmBn(result, bnResult); |
213 | 0 | } |
214 | 0 | BN_free(bnTemp); |
215 | 0 | BN_free(bnMod); |
216 | 0 | BN_free(bnOp2); |
217 | 0 | BN_free(bnOp1); |
218 | 0 | BN_free(bnResult); |
219 | 0 | OSSL_LEAVE(); |
220 | 0 | return OK; |
221 | 0 | } |
222 | | /* B.2.3.2.3.3. BnMult() */ |
223 | | /* Multiplies two numbers */ |
224 | | LIB_EXPORT BOOL |
225 | | BnMult( |
226 | | bigNum result, |
227 | | bigConst multiplicand, |
228 | | bigConst multiplier |
229 | | ) |
230 | 0 | { |
231 | 0 | OSSL_ENTER(); |
232 | 0 | BN_VAR(temp, (LARGEST_NUMBER_BITS * 2)); |
233 | 0 | BIG_INITIALIZED(bnTemp, temp); |
234 | 0 | BIG_INITIALIZED(bnA, multiplicand); |
235 | 0 | BIG_INITIALIZED(bnB, multiplier); |
236 | 0 | BOOL OK; |
237 | 0 | pAssert(result->allocated >= |
238 | 0 | (BITS_TO_CRYPT_WORDS(BnSizeInBits(multiplicand) |
239 | 0 | + BnSizeInBits(multiplier)))); |
240 | 0 | OK = BN_mul(bnTemp, bnA, bnB, CTX); |
241 | 0 | if(OK) |
242 | 0 | { |
243 | 0 | OsslToTpmBn(temp, bnTemp); |
244 | 0 | BnCopy(result, temp); |
245 | 0 | } |
246 | 0 | BN_free(bnB); |
247 | 0 | BN_free(bnA); |
248 | 0 | BN_free(bnTemp); |
249 | 0 | OSSL_LEAVE(); |
250 | 0 | return OK; |
251 | 0 | } |
252 | | /* B.2.3.2.3.4. BnDiv() */ |
253 | | /* This function divides two bigNum values. The function returns FALSE if there is an error in the |
254 | | operation. */ |
255 | | LIB_EXPORT BOOL |
256 | | BnDiv( |
257 | | bigNum quotient, |
258 | | bigNum remainder, |
259 | | bigConst dividend, |
260 | | bigConst divisor |
261 | | ) |
262 | 0 | { |
263 | 0 | OSSL_ENTER(); |
264 | 0 | BIG_INITIALIZED(bnQ, quotient); |
265 | 0 | BIG_INITIALIZED(bnR, remainder); |
266 | 0 | BIG_INITIALIZED(bnDend, dividend); |
267 | 0 | BIG_INITIALIZED(bnSor, divisor); |
268 | 0 | BOOL OK; |
269 | 0 | pAssert(!BnEqualZero(divisor)); |
270 | 0 | if(BnGetSize(dividend) < BnGetSize(divisor)) |
271 | 0 | { |
272 | 0 | if(quotient) |
273 | 0 | BnSetWord(quotient, 0); |
274 | 0 | if(remainder) |
275 | 0 | BnCopy(remainder, dividend); |
276 | 0 | OK = TRUE; |
277 | 0 | } |
278 | 0 | else |
279 | 0 | { |
280 | 0 | pAssert((quotient == NULL) |
281 | 0 | || (quotient->allocated >= (unsigned)(dividend->size |
282 | 0 | - divisor->size))); |
283 | 0 | pAssert((remainder == NULL) |
284 | 0 | || (remainder->allocated >= divisor->size)); |
285 | 0 | OK = BN_div(bnQ, bnR, bnDend, bnSor, CTX); |
286 | 0 | if(OK) |
287 | 0 | { |
288 | 0 | OsslToTpmBn(quotient, bnQ); |
289 | 0 | OsslToTpmBn(remainder, bnR); |
290 | 0 | } |
291 | 0 | } |
292 | 0 | DEBUG_PRINT("In BnDiv:\n"); |
293 | 0 | BIGNUM_PRINT(" bnDividend: ", bnDend, TRUE); |
294 | 0 | BIGNUM_PRINT(" bnDivisor: ", bnSor, TRUE); |
295 | 0 | BIGNUM_PRINT(" bnQuotient: ", bnQ, TRUE); |
296 | 0 | BIGNUM_PRINT(" bnRemainder: ", bnR, TRUE); |
297 | 0 | BN_free(bnSor); |
298 | 0 | BN_free(bnDend); |
299 | 0 | BN_free(bnR); |
300 | 0 | BN_free(bnQ); |
301 | 0 | OSSL_LEAVE(); |
302 | 0 | return OK; |
303 | 0 | } |
304 | | |
305 | | #if ALG_RSA |
306 | | /* B.2.3.2.3.5. BnGcd() */ |
307 | | /* Get the greatest common divisor of two numbers */ |
308 | | LIB_EXPORT BOOL |
309 | | BnGcd( |
310 | | bigNum gcd, // OUT: the common divisor |
311 | | bigConst number1, // IN: |
312 | | bigConst number2 // IN: |
313 | | ) |
314 | 0 | { |
315 | 0 | OSSL_ENTER(); |
316 | 0 | BIG_INITIALIZED(bnGcd, gcd); |
317 | 0 | BIG_INITIALIZED(bn1, number1); |
318 | 0 | BIG_INITIALIZED(bn2, number2); |
319 | 0 | BOOL OK; |
320 | 0 | pAssert(gcd != NULL); |
321 | 0 | OK = BN_gcd(bnGcd, bn1, bn2, CTX); |
322 | 0 | if(OK) |
323 | 0 | { |
324 | 0 | OsslToTpmBn(gcd, bnGcd); |
325 | 0 | gcd->size = DIV_UP(BN_num_bytes(bnGcd), sizeof(crypt_uword_t)); |
326 | 0 | } |
327 | 0 | BN_free(bn2); |
328 | 0 | BN_free(bn1); |
329 | 0 | BN_free(bnGcd); |
330 | 0 | OSSL_LEAVE(); |
331 | 0 | return OK; |
332 | 0 | } |
333 | | /* B.2.3.2.3.6. BnModExp() */ |
334 | | /* Do modular exponentiation using bigNum values. The conversion from a bignum_t to a bigNum is |
335 | | trivial as they are based on the same structure */ |
336 | | LIB_EXPORT BOOL |
337 | | BnModExp( |
338 | | bigNum result, // OUT: the result |
339 | | bigConst number, // IN: number to exponentiate |
340 | | bigConst exponent, // IN: |
341 | | bigConst modulus // IN: |
342 | | ) |
343 | 0 | { |
344 | 0 | OSSL_ENTER(); |
345 | 0 | BIG_INITIALIZED(bnResult, result); |
346 | 0 | BIG_INITIALIZED(bnN, number); |
347 | 0 | BIG_INITIALIZED(bnE, exponent); |
348 | 0 | BIG_INITIALIZED(bnM, modulus); |
349 | 0 | BOOL OK; |
350 | | // |
351 | 0 | OK = BN_mod_exp(bnResult, bnN, bnE, bnM, CTX); |
352 | 0 | if(OK) |
353 | 0 | { |
354 | 0 | OsslToTpmBn(result, bnResult); |
355 | 0 | } |
356 | 0 | BN_free(bnM); |
357 | 0 | BN_free(bnE); |
358 | 0 | BN_free(bnN); |
359 | 0 | BN_free(bnResult); |
360 | 0 | OSSL_LEAVE(); |
361 | 0 | return OK; |
362 | 0 | } |
363 | | /* B.2.3.2.3.7. BnModInverse() */ |
364 | | /* Modular multiplicative inverse */ |
365 | | LIB_EXPORT BOOL |
366 | | BnModInverse( |
367 | | bigNum result, |
368 | | bigConst number, |
369 | | bigConst modulus |
370 | | ) |
371 | 0 | { |
372 | 0 | OSSL_ENTER(); |
373 | 0 | BIG_INITIALIZED(bnResult, result); |
374 | 0 | BIG_INITIALIZED(bnN, number); |
375 | 0 | BIG_INITIALIZED(bnM, modulus); |
376 | 0 | BOOL OK; |
377 | 0 | OK = (BN_mod_inverse(bnResult, bnN, bnM, CTX) != NULL); |
378 | 0 | if(OK) |
379 | 0 | { |
380 | 0 | OsslToTpmBn(result, bnResult); |
381 | 0 | } |
382 | 0 | BN_free(bnM); |
383 | 0 | BN_free(bnN); |
384 | 0 | BN_free(bnResult); |
385 | 0 | OSSL_LEAVE(); |
386 | 0 | return OK; |
387 | 0 | } |
388 | | #endif // TPM_ALG_RSA |
389 | | |
390 | | #if ALG_ECC |
391 | | /* B.2.3.2.3.8. PointFromOssl() */ |
392 | | /* Function to copy the point result from an OSSL function to a bigNum */ |
393 | | static BOOL |
394 | | PointFromOssl( |
395 | | bigPoint pOut, // OUT: resulting point |
396 | | EC_POINT *pIn, // IN: the point to return |
397 | | bigCurve E // IN: the curve |
398 | | ) |
399 | 0 | { |
400 | 0 | BIGNUM *x = NULL; |
401 | 0 | BIGNUM *y = NULL; |
402 | 0 | BOOL OK; |
403 | 0 | BN_CTX_start(E->CTX); |
404 | | // |
405 | 0 | x = BN_CTX_get(E->CTX); |
406 | 0 | y = BN_CTX_get(E->CTX); |
407 | 0 | if(y == NULL) |
408 | 0 | FAIL(FATAL_ERROR_ALLOCATION); |
409 | | // If this returns false, then the point is at infinity |
410 | 0 | OK = EC_POINT_get_affine_coordinates_GFp(E->G, pIn, x, y, E->CTX); |
411 | 0 | if(OK) |
412 | 0 | { |
413 | 0 | OsslToTpmBn(pOut->x, x); |
414 | 0 | OsslToTpmBn(pOut->y, y); |
415 | 0 | BnSetWord(pOut->z, 1); |
416 | 0 | } |
417 | 0 | else |
418 | 0 | BnSetWord(pOut->z, 0); |
419 | 0 | BN_CTX_end(E->CTX); |
420 | 0 | return OK; |
421 | 0 | } |
422 | | /* B.2.3.2.3.9. EcPointInitialized() */ |
423 | | /* Allocate and initialize a point. */ |
424 | | static EC_POINT * |
425 | | EcPointInitialized( |
426 | | pointConst initializer, |
427 | | bigCurve E |
428 | | ) |
429 | 0 | { |
430 | 0 | BIG_INITIALIZED(bnX, (initializer != NULL) ? initializer->x : NULL); |
431 | 0 | BIG_INITIALIZED(bnY, (initializer != NULL) ? initializer->y : NULL); |
432 | 0 | EC_POINT *P = (initializer != NULL && E != NULL) |
433 | 0 | ? EC_POINT_new(E->G) : NULL; |
434 | 0 | pAssert(E != NULL); |
435 | 0 | if(P != NULL) |
436 | 0 | EC_POINT_set_affine_coordinates_GFp(E->G, P, bnX, bnY, E->CTX); |
437 | 0 | BN_free(bnY); |
438 | 0 | BN_free(bnX); |
439 | 0 | return P; |
440 | 0 | } |
441 | | /* B.2.3.2.3.10. BnCurveInitialize() */ |
442 | | /* This function initializes the OpenSSL() group definition */ |
443 | | /* It is a fatal error if groupContext is not provided. */ |
444 | | /* Return Values Meaning */ |
445 | | /* NULL the TPM_ECC_CURVE is not valid */ |
446 | | /* non-NULL points to a structure in groupContext */ |
447 | | bigCurve |
448 | | BnCurveInitialize( |
449 | | bigCurve E, // IN: curve structure to initialize |
450 | | TPM_ECC_CURVE curveId // IN: curve identifier |
451 | | ) |
452 | 0 | { |
453 | 0 | EC_GROUP *group = NULL; |
454 | 0 | EC_POINT *P = NULL; |
455 | 0 | const ECC_CURVE_DATA *C = GetCurveData(curveId); |
456 | 0 | BN_CTX *CTX = NULL; |
457 | 0 | BIG_INITIALIZED(bnP, C != NULL ? C->prime : NULL); |
458 | 0 | BIG_INITIALIZED(bnA, C != NULL ? C->a : NULL); |
459 | 0 | BIG_INITIALIZED(bnB, C != NULL ? C->b : NULL); |
460 | 0 | BIG_INITIALIZED(bnX, C != NULL ? C->base.x : NULL); |
461 | 0 | BIG_INITIALIZED(bnY, C != NULL ? C->base.y : NULL); |
462 | 0 | BIG_INITIALIZED(bnN, C != NULL ? C->order : NULL); |
463 | 0 | BIG_INITIALIZED(bnH, C != NULL ? C->h : NULL); |
464 | 0 | int OK = (C != NULL); |
465 | | // |
466 | 0 | OK = OK && ((CTX = OsslContextEnter()) != NULL); |
467 | | // initialize EC group, associate a generator point and initialize the point |
468 | | // from the parameter data |
469 | | // Create a group structure |
470 | 0 | OK = OK && (group = EC_GROUP_new_curve_GFp(bnP, bnA, bnB, CTX)) != NULL; |
471 | | // Allocate a point in the group that will be used in setting the |
472 | | // generator. This is not needed after the generator is set. |
473 | 0 | OK = OK && ((P = EC_POINT_new(group)) != NULL); |
474 | | // Need to use this in case Montgomery method is being used |
475 | 0 | OK = OK |
476 | 0 | && EC_POINT_set_affine_coordinates_GFp(group, P, bnX, bnY, CTX); |
477 | | // Now set the generator |
478 | 0 | OK = OK && EC_GROUP_set_generator(group, P, bnN, bnH); |
479 | 0 | if(P != NULL) |
480 | 0 | EC_POINT_free(P); |
481 | 0 | if(!OK && group != NULL) |
482 | 0 | { |
483 | 0 | EC_GROUP_free(group); |
484 | 0 | group = NULL; |
485 | 0 | } |
486 | 0 | if(!OK && CTX != NULL) |
487 | 0 | { |
488 | 0 | OsslContextLeave(CTX); |
489 | 0 | CTX = NULL; |
490 | 0 | } |
491 | 0 | E->G = group; |
492 | 0 | E->CTX = CTX; |
493 | 0 | E->C = C; |
494 | 0 | BN_free(bnH); |
495 | 0 | BN_free(bnN); |
496 | 0 | BN_free(bnY); |
497 | 0 | BN_free(bnX); |
498 | 0 | BN_free(bnB); |
499 | 0 | BN_free(bnA); |
500 | 0 | BN_free(bnP); |
501 | 0 | return OK ? E : NULL; |
502 | 0 | } |
503 | | /* B.2.3.2.3.11. BnEccModMult() */ |
504 | | /* This function does a point multiply of the form R = [d]S */ |
505 | | /* Return Values Meaning */ |
506 | | /* FALSE failure in operation; treat as result being point at infinity */ |
507 | | LIB_EXPORT BOOL |
508 | | BnEccModMult( |
509 | | bigPoint R, // OUT: computed point |
510 | | pointConst S, // IN: point to multiply by 'd' (optional) |
511 | | bigConst d, // IN: scalar for [d]S |
512 | | bigCurve E |
513 | | ) |
514 | 0 | { |
515 | 0 | EC_POINT *pR = EC_POINT_new(E->G); |
516 | 0 | EC_POINT *pS = EcPointInitialized(S, E); |
517 | 0 | BIG_INITIALIZED(bnD, d); |
518 | 0 | if(S == NULL) |
519 | 0 | EC_POINT_mul(E->G, pR, bnD, NULL, NULL, E->CTX); |
520 | 0 | else |
521 | 0 | EC_POINT_mul(E->G, pR, NULL, pS, bnD, E->CTX); |
522 | 0 | PointFromOssl(R, pR, E); |
523 | 0 | EC_POINT_free(pR); |
524 | 0 | EC_POINT_free(pS); |
525 | 0 | BN_free(bnD); |
526 | 0 | return !BnEqualZero(R->z); |
527 | 0 | } |
528 | | /* B.2.3.2.3.12. BnEccModMult2() */ |
529 | | /* This function does a point multiply of the form R = [d]G + [u]Q */ |
530 | | /* FALSE failure in operation; treat as result being point at infinity */ |
531 | | LIB_EXPORT BOOL |
532 | | BnEccModMult2( |
533 | | bigPoint R, // OUT: computed point |
534 | | pointConst S, // IN: optional point |
535 | | bigConst d, // IN: scalar for [d]S or [d]G |
536 | | pointConst Q, // IN: second point |
537 | | bigConst u, // IN: second scalar |
538 | | bigCurve E // IN: curve |
539 | | ) |
540 | 0 | { |
541 | 0 | EC_POINT *pR = EC_POINT_new(E->G); |
542 | 0 | EC_POINT *pS = EcPointInitialized(S, E); |
543 | 0 | BIG_INITIALIZED(bnD, d); |
544 | 0 | EC_POINT *pQ = EcPointInitialized(Q, E); |
545 | 0 | BIG_INITIALIZED(bnU, u); |
546 | 0 | if(S == NULL || S == (pointConst)&(AccessCurveData(E)->base)) |
547 | 0 | EC_POINT_mul(E->G, pR, bnD, pQ, bnU, E->CTX); |
548 | 0 | else |
549 | 0 | { |
550 | 0 | const EC_POINT *points[2]; |
551 | 0 | const BIGNUM *scalars[2]; |
552 | 0 | points[0] = pS; |
553 | 0 | points[1] = pQ; |
554 | 0 | scalars[0] = bnD; |
555 | 0 | scalars[1] = bnU; |
556 | 0 | EC_POINTs_mul(E->G, pR, NULL, 2, points, scalars, E->CTX); |
557 | 0 | } |
558 | 0 | PointFromOssl(R, pR, E); |
559 | 0 | EC_POINT_free(pR); |
560 | 0 | EC_POINT_free(pS); |
561 | 0 | EC_POINT_free(pQ); |
562 | 0 | BN_free(bnD); |
563 | 0 | BN_free(bnU); |
564 | 0 | return !BnEqualZero(R->z); |
565 | 0 | } |
566 | | /* B.2.3.2.4. BnEccAdd() */ |
567 | | /* This function does addition of two points. */ |
568 | | /* Return Values Meaning */ |
569 | | /* FALSE failure in operation; treat as result being point at infinity */ |
570 | | LIB_EXPORT BOOL |
571 | | BnEccAdd( |
572 | | bigPoint R, // OUT: computed point |
573 | | pointConst S, // IN: point to multiply by 'd' |
574 | | pointConst Q, // IN: second point |
575 | | bigCurve E // IN: curve |
576 | | ) |
577 | 0 | { |
578 | 0 | EC_POINT *pR = EC_POINT_new(E->G); |
579 | 0 | EC_POINT *pS = EcPointInitialized(S, E); |
580 | 0 | EC_POINT *pQ = EcPointInitialized(Q, E); |
581 | | // |
582 | 0 | EC_POINT_add(E->G, pR, pS, pQ, E->CTX); |
583 | 0 | PointFromOssl(R, pR, E); |
584 | 0 | EC_POINT_free(pR); |
585 | 0 | EC_POINT_free(pS); |
586 | 0 | EC_POINT_free(pQ); |
587 | 0 | return !BnEqualZero(R->z); |
588 | 0 | } |
589 | | #endif // TPM_ALG_ECC |
590 | | #endif // MATHLIB OSSL |