/src/tpm2/MathFunctions.c
Line | Count | Source (jump to first uncovered line) |
1 | | // This file was extracted from the TCG Published |
2 | | // Trusted Platform Module Library |
3 | | // Part 4: Supporting Routines |
4 | | // Family "2.0" |
5 | | // Level 00 Revision 01.16 |
6 | | // October 30, 2014 |
7 | | |
8 | | #include <string.h> |
9 | | |
10 | | #include "CryptoEngine.h" |
11 | | |
12 | | #ifndef EMBEDDED_MODE |
13 | | #include "OsslCryptoEngine.h" |
14 | | // |
15 | | // |
16 | | // Externally Accessible Functions |
17 | | // |
18 | | // _math__Normalize2B() |
19 | | // |
20 | | // This function will normalize the value in a TPM2B. If there are leading bytes of zero, the first non-zero |
21 | | // byte is shifted up. |
22 | | // |
23 | | // Return Value Meaning |
24 | | // |
25 | | // 0 no significant bytes, value is zero |
26 | | // >0 number of significant bytes |
27 | | // |
28 | | LIB_EXPORT UINT16 |
29 | | _math__Normalize2B( |
30 | | TPM2B *b // IN/OUT: number to normalize |
31 | | ) |
32 | 0 | { |
33 | 0 | UINT16 from; |
34 | 0 | UINT16 to; |
35 | 0 | UINT16 size = b->size; |
36 | 0 | for(from = 0; b->buffer[from] == 0 && from < size; from++); |
37 | 0 | b->size -= from; |
38 | 0 | for(to = 0; from < size; to++, from++ ) |
39 | 0 | b->buffer[to] = b->buffer[from]; |
40 | 0 | return b->size; |
41 | 0 | } |
42 | | // |
43 | | // |
44 | | // |
45 | | // _math__Denormalize2B() |
46 | | // |
47 | | // This function is used to adjust a TPM2B so that the number has the desired number of bytes. This is |
48 | | // accomplished by adding bytes of zero at the start of the number. |
49 | | // |
50 | | // Return Value Meaning |
51 | | // |
52 | | // TRUE number de-normalized |
53 | | // FALSE number already larger than the desired size |
54 | | // |
55 | | LIB_EXPORT BOOL |
56 | | _math__Denormalize2B( |
57 | | TPM2B *in, // IN:OUT TPM2B number to de-normalize |
58 | | UINT32 size // IN: the desired size |
59 | | ) |
60 | 0 | { |
61 | 0 | UINT32 to; |
62 | 0 | UINT32 from; |
63 | | // If the current size is greater than the requested size, see if this can be |
64 | | // normalized to a value smaller than the requested size and then de-normalize |
65 | 0 | if(in->size > size) |
66 | 0 | { |
67 | 0 | _math__Normalize2B(in); |
68 | 0 | if(in->size > size) |
69 | 0 | return FALSE; |
70 | 0 | } |
71 | | // If the size is already what is requested, leave |
72 | 0 | if(in->size == size) |
73 | 0 | return TRUE; |
74 | | // move the bytes to the 'right' |
75 | 0 | for(from = in->size, to = size; from > 0;) |
76 | 0 | in->buffer[--to] = in->buffer[--from]; |
77 | | // 'to' will always be greater than 0 because we checked for equal above. |
78 | 0 | for(; to > 0;) |
79 | 0 | in->buffer[--to] = 0; |
80 | 0 | in->size = (UINT16)size; |
81 | 0 | return TRUE; |
82 | 0 | } |
83 | | // |
84 | | // |
85 | | // _math__sub() |
86 | | // |
87 | | // This function to subtract one unsigned value from another c = a - b. c may be the same as a or b. |
88 | | // |
89 | | // Return Value Meaning |
90 | | // |
91 | | // 1 if (a > b) so no borrow |
92 | | // 0 if (a = b) so no borrow and b == a |
93 | | // -1 if (a < b) so there was a borrow |
94 | | // |
95 | | LIB_EXPORT int |
96 | | _math__sub( |
97 | | const UINT32 aSize, // IN: size of a |
98 | | const BYTE *a, // IN: a |
99 | | const UINT32 bSize, // IN: size of b |
100 | | const BYTE *b, // IN: b |
101 | | UINT16 *cSize, // OUT: set to MAX(aSize, bSize) |
102 | | BYTE *c // OUT: the difference |
103 | | ) |
104 | 0 | { |
105 | 0 | int borrow = 0; |
106 | 0 | int notZero = 0; |
107 | 0 | int i; |
108 | 0 | int i2; |
109 | | // set c to the longer of a or b |
110 | 0 | *cSize = (UINT16)((aSize > bSize) ? aSize : bSize); |
111 | | // pick the shorter of a and b |
112 | 0 | i = (aSize > bSize) ? bSize : aSize; |
113 | 0 | i2 = *cSize - i; |
114 | 0 | a = &a[aSize - 1]; |
115 | 0 | b = &b[bSize - 1]; |
116 | 0 | c = &c[*cSize - 1]; |
117 | 0 | for(; i > 0; i--) |
118 | 0 | { |
119 | 0 | borrow = *a-- - *b-- + borrow; |
120 | 0 | *c-- = (BYTE)borrow; |
121 | 0 | notZero = notZero || borrow; |
122 | 0 | borrow >>= 8; |
123 | 0 | } |
124 | 0 | if(aSize > bSize) |
125 | 0 | { |
126 | 0 | for(;i2 > 0; i2--) |
127 | 0 | { |
128 | 0 | borrow = *a-- + borrow; |
129 | 0 | *c-- = (BYTE)borrow; |
130 | 0 | notZero = notZero || borrow; |
131 | 0 | borrow >>= 8; |
132 | 0 | } |
133 | 0 | } |
134 | 0 | else if(aSize < bSize) |
135 | 0 | { |
136 | 0 | for(;i2 > 0; i2--) |
137 | 0 | { |
138 | 0 | borrow = 0 - *b-- + borrow; |
139 | 0 | *c-- = (BYTE)borrow; |
140 | 0 | notZero = notZero || borrow; |
141 | 0 | borrow >>= 8; |
142 | 0 | } |
143 | 0 | } |
144 | | // if there is a borrow, then b > a |
145 | 0 | if(borrow) |
146 | 0 | return -1; |
147 | | // either a > b or they are the same |
148 | 0 | return notZero; |
149 | 0 | } |
150 | | // |
151 | | // |
152 | | // _math__Inc() |
153 | | // |
154 | | // This function increments a large, big-endian number value by one. |
155 | | // |
156 | | // Return Value Meaning |
157 | | // |
158 | | // 0 result is zero |
159 | | // !0 result is not zero |
160 | | // |
161 | | LIB_EXPORT int |
162 | | _math__Inc( |
163 | | UINT32 aSize, // IN: size of a |
164 | | BYTE *a // IN: a |
165 | | ) |
166 | 0 | { |
167 | | // |
168 | 0 | for(a = &a[aSize-1];aSize > 0; aSize--) |
169 | 0 | { |
170 | 0 | if((*a-- += 1) != 0) |
171 | 0 | return 1; |
172 | 0 | } |
173 | 0 | return 0; |
174 | 0 | } |
175 | | // |
176 | | // |
177 | | // _math__Dec() |
178 | | // |
179 | | // This function decrements a large, ENDIAN value by one. |
180 | | // |
181 | | LIB_EXPORT void |
182 | | _math__Dec( |
183 | | UINT32 aSize, // IN: size of a |
184 | | BYTE *a // IN: a |
185 | | ) |
186 | 0 | { |
187 | 0 | for(a = &a[aSize-1]; aSize > 0; aSize--) |
188 | 0 | { |
189 | 0 | if((*a-- -= 1) != 0xff) |
190 | 0 | return; |
191 | 0 | } |
192 | 0 | return; |
193 | 0 | } |
194 | | // |
195 | | // |
196 | | // _math__Mul() |
197 | | // |
198 | | // This function is used to multiply two large integers: p = a* b. If the size of p is not specified (pSize == |
199 | | // NULL), the size of the results p is assumed to be aSize + bSize and the results are de-normalized so that |
200 | | // the resulting size is exactly aSize + bSize. If pSize is provided, then the actual size of the result is |
201 | | // returned. The initial value for pSize must be at least aSize + pSize. |
202 | | // |
203 | | // Return Value Meaning |
204 | | // |
205 | | // <0 indicates an error |
206 | | // >= 0 the size of the product |
207 | | // |
208 | | LIB_EXPORT int |
209 | | _math__Mul( |
210 | | const UINT32 aSize, // IN: size of a |
211 | | const BYTE *a, // IN: a |
212 | | const UINT32 bSize, // IN: size of b |
213 | | const BYTE *b, // IN: b |
214 | | UINT32 *pSize, // IN/OUT: size of the product |
215 | | BYTE *p // OUT: product. length of product = aSize + |
216 | | // bSize |
217 | | ) |
218 | 0 | { |
219 | 0 | BIGNUM *bnA; |
220 | 0 | BIGNUM *bnB; |
221 | 0 | BIGNUM *bnP; |
222 | 0 | BN_CTX *context; |
223 | 0 | int retVal = 0; |
224 | | // First check that pSize is large enough if present |
225 | 0 | if((pSize != NULL) && (*pSize < (aSize + bSize))) |
226 | 0 | return CRYPT_PARAMETER; |
227 | 0 | pAssert(pSize == NULL || *pSize <= MAX_2B_BYTES); |
228 | | // |
229 | | // |
230 | | // Allocate space for BIGNUM context |
231 | | // |
232 | 0 | context = BN_CTX_new(); |
233 | 0 | if(context == NULL) |
234 | 0 | FAIL(FATAL_ERROR_ALLOCATION); |
235 | 0 | bnA = BN_CTX_get(context); |
236 | 0 | bnB = BN_CTX_get(context); |
237 | 0 | bnP = BN_CTX_get(context); |
238 | 0 | if (bnP == NULL) |
239 | 0 | FAIL(FATAL_ERROR_ALLOCATION); |
240 | | // Convert the inputs to BIGNUMs |
241 | | // |
242 | 0 | if (BN_bin2bn(a, aSize, bnA) == NULL || BN_bin2bn(b, bSize, bnB) == NULL) |
243 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
244 | | // Perform the multiplication |
245 | | // |
246 | 0 | if (BN_mul(bnP, bnA, bnB, context) != 1) |
247 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
248 | | // If the size of the results is allowed to float, then set the return |
249 | | // size. Otherwise, it might be necessary to de-normalize the results |
250 | 0 | retVal = BN_num_bytes(bnP); |
251 | 0 | if(pSize == NULL) |
252 | 0 | { |
253 | 0 | BN_bn2bin(bnP, &p[aSize + bSize - retVal]); |
254 | 0 | memset(p, 0, aSize + bSize - retVal); |
255 | 0 | retVal = aSize + bSize; |
256 | 0 | } |
257 | 0 | else |
258 | 0 | { |
259 | 0 | BN_bn2bin(bnP, p); |
260 | 0 | *pSize = retVal; |
261 | 0 | } |
262 | 0 | BN_CTX_end(context); |
263 | 0 | BN_CTX_free(context); |
264 | 0 | return retVal; |
265 | 0 | } |
266 | | // |
267 | | // |
268 | | // _math__Div() |
269 | | // |
270 | | // Divide an integer (n) by an integer (d) producing a quotient (q) and a remainder (r). If q or r is not needed, |
271 | | // then the pointer to them may be set to NULL. |
272 | | // |
273 | | // Return Value Meaning |
274 | | // |
275 | | // CRYPT_SUCCESS operation complete |
276 | | // CRYPT_UNDERFLOW q or r is too small to receive the result |
277 | | // |
278 | | LIB_EXPORT CRYPT_RESULT |
279 | | _math__Div( |
280 | | const TPM2B *n, // IN: numerator |
281 | | const TPM2B *d, // IN: denominator |
282 | | TPM2B *q, // OUT: quotient |
283 | | TPM2B *r // OUT: remainder |
284 | | ) |
285 | 0 | { |
286 | 0 | BIGNUM *bnN; |
287 | 0 | BIGNUM *bnD; |
288 | 0 | BIGNUM *bnQ; |
289 | 0 | BIGNUM *bnR; |
290 | 0 | BN_CTX *context; |
291 | 0 | CRYPT_RESULT retVal = CRYPT_SUCCESS; |
292 | | // Get structures for the big number representations |
293 | 0 | context = BN_CTX_new(); |
294 | 0 | if(context == NULL) |
295 | 0 | FAIL(FATAL_ERROR_ALLOCATION); |
296 | 0 | BN_CTX_start(context); |
297 | 0 | bnN = BN_CTX_get(context); |
298 | 0 | bnD = BN_CTX_get(context); |
299 | 0 | bnQ = BN_CTX_get(context); |
300 | 0 | bnR = BN_CTX_get(context); |
301 | | // Errors in BN_CTX_get() are sticky so only need to check the last allocation |
302 | 0 | if ( bnR == NULL |
303 | 0 | || BN_bin2bn(n->buffer, n->size, bnN) == NULL |
304 | 0 | || BN_bin2bn(d->buffer, d->size, bnD) == NULL) |
305 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
306 | | // Check for divide by zero. |
307 | 0 | if(BN_num_bits(bnD) == 0) |
308 | 0 | FAIL(FATAL_ERROR_DIVIDE_ZERO); |
309 | | // Perform the division |
310 | 0 | if (BN_div(bnQ, bnR, bnN, bnD, context) != 1) |
311 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
312 | | // Convert the BIGNUM result back to our format |
313 | 0 | if(q != NULL) // If the quotient is being returned |
314 | 0 | { |
315 | 0 | if(!BnTo2B(q, bnQ, q->size)) |
316 | 0 | { |
317 | 0 | retVal = CRYPT_UNDERFLOW; |
318 | 0 | goto Done; |
319 | 0 | } |
320 | 0 | } |
321 | 0 | if(r != NULL) // If the remainder is being returned |
322 | 0 | { |
323 | 0 | if(!BnTo2B(r, bnR, r->size)) |
324 | 0 | retVal = CRYPT_UNDERFLOW; |
325 | 0 | } |
326 | 0 | Done: |
327 | 0 | BN_CTX_end(context); |
328 | 0 | BN_CTX_free(context); |
329 | 0 | return retVal; |
330 | 0 | } |
331 | | #endif // ! EMBEDDED_MODE |
332 | | // |
333 | | // |
334 | | // _math__uComp() |
335 | | // |
336 | | // This function compare two unsigned values. |
337 | | // |
338 | | // Return Value Meaning |
339 | | // |
340 | | // 1 if (a > b) |
341 | | // 0 if (a = b) |
342 | | // -1 if (a < b) |
343 | | // |
344 | | LIB_EXPORT int |
345 | | _math__uComp( |
346 | | const UINT32 aSize, // IN: size of a |
347 | | const BYTE *a, // IN: a |
348 | | const UINT32 bSize, // IN: size of b |
349 | | const BYTE *b // IN: b |
350 | | ) |
351 | 0 | { |
352 | 0 | int borrow = 0; |
353 | 0 | int notZero = 0; |
354 | 0 | int i; |
355 | | // If a has more digits than b, then a is greater than b if |
356 | | // any of the more significant bytes is non zero |
357 | 0 | if((i = (int)aSize - (int)bSize) > 0) |
358 | 0 | for(; i > 0; i--) |
359 | 0 | if(*a++) // means a > b |
360 | 0 | return 1; |
361 | | // If b has more digits than a, then b is greater if any of the |
362 | | // more significant bytes is non zero |
363 | 0 | if(i < 0) // Means that b is longer than a |
364 | 0 | for(; i < 0; i++) |
365 | 0 | if(*b++) // means that b > a |
366 | 0 | return -1; |
367 | | // Either the vales are the same size or the upper bytes of a or b are |
368 | | // all zero, so compare the rest |
369 | 0 | i = (aSize > bSize) ? bSize : aSize; |
370 | 0 | a = &a[i-1]; |
371 | 0 | b = &b[i-1]; |
372 | 0 | for(; i > 0; i--) |
373 | 0 | { |
374 | 0 | borrow = *a-- - *b-- + borrow; |
375 | 0 | notZero = notZero || borrow; |
376 | 0 | borrow >>= 8; |
377 | 0 | } |
378 | | // if there is a borrow, then b > a |
379 | 0 | if(borrow) |
380 | 0 | return -1; |
381 | | // either a > b or they are the same |
382 | 0 | return notZero; |
383 | 0 | } |
384 | | // |
385 | | // |
386 | | // _math__Comp() |
387 | | // |
388 | | // Compare two signed integers: |
389 | | // |
390 | | // Return Value Meaning |
391 | | // |
392 | | // 1 if a > b |
393 | | // 0 if a = b |
394 | | // -1 if a < b |
395 | | // |
396 | | LIB_EXPORT int |
397 | | _math__Comp( |
398 | | const UINT32 aSize, // IN: size of a |
399 | | const BYTE *a, // IN: a buffer |
400 | | const UINT32 bSize, // IN: size of b |
401 | | const BYTE *b // IN: b buffer |
402 | | ) |
403 | 0 | { |
404 | 0 | int signA, signB; // sign of a and b |
405 | | // For positive or 0, sign_a is 1 |
406 | | // for negative, sign_a is 0 |
407 | 0 | signA = ((a[0] & 0x80) == 0) ? 1 : 0; |
408 | | // For positive or 0, sign_b is 1 |
409 | | // for negative, sign_b is 0 |
410 | 0 | signB = ((b[0] & 0x80) == 0) ? 1 : 0; |
411 | 0 | if(signA != signB) |
412 | 0 | { |
413 | 0 | return signA - signB; |
414 | 0 | } |
415 | 0 | if(signA == 1) |
416 | | // do unsigned compare function |
417 | 0 | return _math__uComp(aSize, a, bSize, b); |
418 | 0 | else |
419 | | // do unsigned compare the other way |
420 | 0 | return 0 - _math__uComp(aSize, a, bSize, b); |
421 | 0 | } |
422 | | // |
423 | | // |
424 | | // _math__ModExp |
425 | | // |
426 | | // This function is used to do modular exponentiation in support of RSA. The most typical uses are: c = m^e |
427 | | // mod n (RSA encrypt) and m = c^d mod n (RSA decrypt). When doing decryption, the e parameter of the |
428 | | // function will contain the private exponent d instead of the public exponent e. |
429 | | // If the results will not fit in the provided buffer, an error is returned (CRYPT_ERROR_UNDERFLOW). If |
430 | | // the results is smaller than the buffer, the results is de-normalized. |
431 | | // This version is intended for use with RSA and requires that m be less than n. |
432 | | // |
433 | | // Return Value Meaning |
434 | | // |
435 | | // CRYPT_SUCCESS exponentiation succeeded |
436 | | // CRYPT_PARAMETER number to exponentiate is larger than the modulus |
437 | | // CRYPT_UNDERFLOW result will not fit into the provided buffer |
438 | | // |
439 | | #ifndef EMBEDDED_MODE |
440 | | LIB_EXPORT CRYPT_RESULT |
441 | | _math__ModExp( |
442 | | UINT32 cSize, // IN: size of the result |
443 | | BYTE *c, // OUT: results buffer |
444 | | const UINT32 mSize, // IN: size of number to be exponentiated |
445 | | const BYTE *m, // IN: number to be exponentiated |
446 | | const UINT32 eSize, // IN: size of power |
447 | | const BYTE *e, // IN: power |
448 | | const UINT32 nSize, // IN: modulus size |
449 | | const BYTE *n // IN: modulu |
450 | | ) |
451 | 0 | { |
452 | 0 | CRYPT_RESULT retVal = CRYPT_SUCCESS; |
453 | 0 | BN_CTX *context; |
454 | 0 | BIGNUM *bnC; |
455 | 0 | BIGNUM *bnM; |
456 | 0 | BIGNUM *bnE; |
457 | 0 | BIGNUM *bnN; |
458 | 0 | INT32 i; |
459 | 0 | context = BN_CTX_new(); |
460 | 0 | if(context == NULL) |
461 | 0 | FAIL(FATAL_ERROR_ALLOCATION); |
462 | 0 | BN_CTX_start(context); |
463 | 0 | bnC = BN_CTX_get(context); |
464 | 0 | bnM = BN_CTX_get(context); |
465 | 0 | bnE = BN_CTX_get(context); |
466 | 0 | bnN = BN_CTX_get(context); |
467 | | // Errors for BN_CTX_get are sticky so only need to check last allocation |
468 | 0 | if(bnN == NULL) |
469 | 0 | FAIL(FATAL_ERROR_ALLOCATION); |
470 | | //convert arguments |
471 | 0 | if ( BN_bin2bn(m, mSize, bnM) == NULL |
472 | 0 | || BN_bin2bn(e, eSize, bnE) == NULL |
473 | 0 | || BN_bin2bn(n, nSize, bnN) == NULL) |
474 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
475 | | // Don't do exponentiation if the number being exponentiated is |
476 | | // larger than the modulus. |
477 | 0 | if(BN_ucmp(bnM, bnN) >= 0) |
478 | 0 | { |
479 | 0 | retVal = CRYPT_PARAMETER; |
480 | 0 | goto Cleanup; |
481 | 0 | } |
482 | | // Perform the exponentiation |
483 | 0 | if(!(BN_mod_exp(bnC, bnM, bnE, bnN, context))) |
484 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
485 | | // Convert the results |
486 | | // Make sure that the results will fit in the provided buffer. |
487 | 0 | if((unsigned)BN_num_bytes(bnC) > cSize) |
488 | 0 | { |
489 | 0 | retVal = CRYPT_UNDERFLOW; |
490 | 0 | goto Cleanup; |
491 | 0 | } |
492 | 0 | i = cSize - BN_num_bytes(bnC); |
493 | 0 | BN_bn2bin(bnC, &c[i]); |
494 | 0 | memset(c, 0, i); |
495 | 0 | Cleanup: |
496 | | // Free up allocated BN values |
497 | 0 | BN_CTX_end(context); |
498 | 0 | BN_CTX_free(context); |
499 | 0 | return retVal; |
500 | 0 | } |
501 | | // |
502 | | // |
503 | | // _math__IsPrime() |
504 | | // |
505 | | // Check if an 32-bit integer is a prime. |
506 | | // |
507 | | // Return Value Meaning |
508 | | // |
509 | | // TRUE if the integer is probably a prime |
510 | | // FALSE if the integer is definitely not a prime |
511 | | // |
512 | | LIB_EXPORT BOOL |
513 | | _math__IsPrime( |
514 | | const UINT32 prime |
515 | | ) |
516 | 3 | { |
517 | 3 | int isPrime; |
518 | 3 | BIGNUM *p; |
519 | | // Assume the size variables are not overflow, which should not happen in |
520 | | // the contexts that this function will be called. |
521 | 3 | if((p = BN_new()) == NULL) |
522 | 0 | FAIL(FATAL_ERROR_ALLOCATION); |
523 | 3 | if(!BN_set_word(p, prime)) |
524 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
525 | | // |
526 | | // BN_is_prime returning -1 means that it ran into an error. |
527 | | // |
528 | | // It should only return 0 or 1 |
529 | | // |
530 | 3 | if((isPrime = BN_is_prime_ex(p, BN_prime_checks, NULL, NULL)) < 0) |
531 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
532 | 3 | if(p != NULL) |
533 | 3 | BN_clear_free(p); |
534 | 3 | return (isPrime == 1); |
535 | 3 | } |
536 | | #endif // ! EMBEDDED_MODE |