Line | Count | Source |
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 "OsslCryptoEngine.h" |
11 | | #ifdef TPM_ALG_RSA |
12 | | // |
13 | | // |
14 | | // Local Functions |
15 | | // |
16 | | // RsaPrivateExponent() |
17 | | // |
18 | | // This function computes the private exponent de = 1 mod (p-1)*(q-1) The inputs are the public modulus |
19 | | // and one of the primes. |
20 | | // The results are returned in the key->private structure. The size of that structure is expanded to hold the |
21 | | // private exponent. If the computed value is smaller than the public modulus, the private exponent is de- |
22 | | // normalized. |
23 | | // |
24 | | // Return Value Meaning |
25 | | // |
26 | | // CRYPT_SUCCESS private exponent computed |
27 | | // CRYPT_PARAMETER prime is not half the size of the modulus, or the modulus is not evenly |
28 | | // divisible by the prime, or no private exponent could be computed |
29 | | // from the input parameters |
30 | | // |
31 | | CRYPT_RESULT |
32 | | RsaPrivateExponent( |
33 | | RSA_KEY *key // IN: the key to augment with the private |
34 | | // exponent |
35 | | ) |
36 | 0 | { |
37 | 0 | BN_CTX *context; |
38 | 0 | BIGNUM *bnD; |
39 | 0 | BIGNUM *bnN; |
40 | 0 | BIGNUM *bnP; |
41 | 0 | BIGNUM *bnE; |
42 | 0 | BIGNUM *bnPhi; |
43 | 0 | BIGNUM *bnQ; |
44 | 0 | BIGNUM *bnQr; |
45 | 0 | UINT32 fill; |
46 | 0 | CRYPT_RESULT retVal = CRYPT_SUCCESS; // Assume success |
47 | 0 | pAssert(key != NULL && key->privateKey != NULL && key->publicKey != NULL); |
48 | 0 | context = BN_CTX_new(); |
49 | 0 | if(context == NULL) |
50 | 0 | FAIL(FATAL_ERROR_ALLOCATION); |
51 | 0 | BN_CTX_start(context); |
52 | 0 | bnE = BN_CTX_get(context); |
53 | 0 | bnD = BN_CTX_get(context); |
54 | 0 | bnN = BN_CTX_get(context); |
55 | 0 | bnP = BN_CTX_get(context); |
56 | 0 | bnPhi = BN_CTX_get(context); |
57 | 0 | bnQ = BN_CTX_get(context); |
58 | 0 | bnQr = BN_CTX_get(context); |
59 | 0 | if(bnQr == NULL) |
60 | 0 | FAIL(FATAL_ERROR_ALLOCATION); |
61 | | // Assume the size of the public key value is within range |
62 | 0 | pAssert(key->publicKey->size <= MAX_RSA_KEY_BYTES); |
63 | 0 | if( BN_bin2bn(key->publicKey->buffer, key->publicKey->size, bnN) == NULL |
64 | 0 | || BN_bin2bn(key->privateKey->buffer, key->privateKey->size, bnP) == NULL) |
65 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
66 | | // If P size is not 1/2 of n size, then this is not a valid value for this |
67 | | // implementation. This will also catch the case were P is input as zero. |
68 | | // This generates a return rather than an assert because the key being loaded |
69 | | // might be SW generated and wrong. |
70 | 0 | if(BN_num_bits(bnP) < BN_num_bits(bnN)/2) |
71 | 0 | { |
72 | 0 | retVal = CRYPT_PARAMETER; |
73 | 0 | goto Cleanup; |
74 | 0 | } |
75 | | // Get q = n/p; |
76 | 0 | if (BN_div(bnQ, bnQr, bnN, bnP, context) != 1) |
77 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
78 | | // If there is a remainder, then this is not a valid n |
79 | 0 | if(BN_num_bytes(bnQr) != 0 || BN_num_bits(bnQ) != BN_num_bits(bnP)) |
80 | 0 | { |
81 | 0 | retVal = CRYPT_PARAMETER; // problem may be recoverable |
82 | 0 | goto Cleanup; |
83 | 0 | } |
84 | | // Get compute Phi = (p - 1)(q - 1) = pq - p - q + 1 = n - p - q + 1 |
85 | 0 | if( BN_copy(bnPhi, bnN) == NULL |
86 | 0 | || !BN_sub(bnPhi, bnPhi, bnP) |
87 | 0 | || !BN_sub(bnPhi, bnPhi, bnQ) |
88 | 0 | || !BN_add_word(bnPhi, 1)) |
89 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
90 | | // Compute the multiplicative inverse |
91 | 0 | BN_set_word(bnE, key->exponent); |
92 | 0 | if(BN_mod_inverse(bnD, bnE, bnPhi, context) == NULL) |
93 | 0 | { |
94 | | // Going to assume that the error is caused by a bad |
95 | | // set of parameters. Specifically, an exponent that is |
96 | | // not compatible with the primes. In an implementation that |
97 | | // has better visibility to the error codes, this might be |
98 | | // refined so that failures in the library would return |
99 | | // a more informative value. Should not assume here that |
100 | | // the error codes will remain unchanged. |
101 | 0 | retVal = CRYPT_PARAMETER; |
102 | 0 | goto Cleanup; |
103 | 0 | } |
104 | 0 | fill = key->publicKey->size - BN_num_bytes(bnD); |
105 | 0 | BN_bn2bin(bnD, &key->privateKey->buffer[fill]); |
106 | 0 | memset(key->privateKey->buffer, 0, fill); |
107 | | // Change the size of the private key so that it is known to contain |
108 | | // a private exponent rather than a prime. |
109 | 0 | key->privateKey->size = key->publicKey->size; |
110 | 0 | Cleanup: |
111 | 0 | BN_CTX_end(context); |
112 | 0 | BN_CTX_free(context); |
113 | 0 | return retVal; |
114 | 0 | } |
115 | | // |
116 | | // |
117 | | // _cpri__TestKeyRSA() |
118 | | // |
119 | | // This function computes the private exponent de = 1 mod (p-1)*(q-1) The inputs are the public modulus |
120 | | // and one of the primes or two primes. |
121 | | // If both primes are provided, the public modulus is computed. If only one prime is provided, the second |
122 | | // prime is computed. In either case, a private exponent is produced and placed in d. |
123 | | // If no modular inverse exists, then CRYPT_PARAMETER is returned. |
124 | | // |
125 | | // Return Value Meaning |
126 | | // |
127 | | // CRYPT_SUCCESS private exponent (d) was generated |
128 | | // CRYPT_PARAMETER one or more parameters are invalid |
129 | | // |
130 | | LIB_EXPORT CRYPT_RESULT |
131 | | _cpri__TestKeyRSA( |
132 | | TPM2B *d, // OUT: the address to receive the private |
133 | | // exponent |
134 | | UINT32 exponent, // IN: the public modulu |
135 | | TPM2B *publicKey, // IN/OUT: an input if only one prime is |
136 | | // provided. an output if both primes are |
137 | | // provided |
138 | | TPM2B *prime1, // IN: a first prime |
139 | | TPM2B *prime2 // IN: an optional second prime |
140 | | ) |
141 | 35 | { |
142 | 35 | BN_CTX *context; |
143 | 35 | BIGNUM *bnD; |
144 | 35 | BIGNUM *bnN; |
145 | 35 | BIGNUM *bnP; |
146 | 35 | BIGNUM *bnE; |
147 | 35 | BIGNUM *bnPhi; |
148 | 35 | BIGNUM *bnQ; |
149 | 35 | BIGNUM *bnQr; |
150 | 35 | UINT32 fill; |
151 | 35 | CRYPT_RESULT retVal = CRYPT_SUCCESS; // Assume success |
152 | 35 | pAssert(publicKey != NULL && prime1 != NULL); |
153 | | // Make sure that the sizes are within range |
154 | 35 | pAssert( prime1->size <= MAX_RSA_KEY_BYTES/2 |
155 | 35 | && publicKey->size <= MAX_RSA_KEY_BYTES); |
156 | 35 | pAssert( prime2 == NULL || prime2->size < MAX_RSA_KEY_BYTES/2); |
157 | 35 | if(publicKey->size/2 != prime1->size) |
158 | 0 | return CRYPT_PARAMETER; |
159 | 35 | context = BN_CTX_new(); |
160 | 35 | if(context == NULL) |
161 | 0 | FAIL(FATAL_ERROR_ALLOCATION); |
162 | 35 | BN_CTX_start(context); |
163 | 35 | bnE = BN_CTX_get(context); // public exponent (e) |
164 | 35 | bnD = BN_CTX_get(context); // private exponent (d) |
165 | 35 | bnN = BN_CTX_get(context); // public modulus (n) |
166 | 35 | bnP = BN_CTX_get(context); // prime1 (p) |
167 | 35 | bnPhi = BN_CTX_get(context); // (p-1)(q-1) |
168 | 35 | bnQ = BN_CTX_get(context); // prime2 (q) |
169 | 35 | bnQr = BN_CTX_get(context); // n mod p |
170 | 35 | if(bnQr == NULL) |
171 | 0 | FAIL(FATAL_ERROR_ALLOCATION); |
172 | 35 | if(BN_bin2bn(prime1->buffer, prime1->size, bnP) == NULL) |
173 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
174 | | // If prime2 is provided, then compute n |
175 | 35 | if(prime2 != NULL) |
176 | 0 | { |
177 | | // Two primes provided so use them to compute n |
178 | 0 | if(BN_bin2bn(prime2->buffer, prime2->size, bnQ) == NULL) |
179 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
180 | | // Make sure that the sizes of the primes are compatible |
181 | 0 | if(BN_num_bits(bnQ) != BN_num_bits(bnP)) |
182 | 0 | { |
183 | 0 | retVal = CRYPT_PARAMETER; |
184 | 0 | goto Cleanup; |
185 | 0 | } |
186 | | // Multiply the primes to get the public modulus |
187 | 0 | if(BN_mul(bnN, bnP, bnQ, context) != 1) |
188 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
189 | | // if the space provided for the public modulus is large enough, |
190 | | // save the created value |
191 | 0 | if(BN_num_bits(bnN) != (publicKey->size * 8)) |
192 | 0 | { |
193 | 0 | retVal = CRYPT_PARAMETER; |
194 | 0 | goto Cleanup; |
195 | 0 | } |
196 | 0 | BN_bn2bin(bnN, publicKey->buffer); |
197 | 0 | } |
198 | 35 | else |
199 | 35 | { |
200 | 35 | if (BN_is_zero(bnP)) |
201 | 2 | { |
202 | 2 | retVal = CRYPT_PARAMETER; |
203 | 2 | goto Cleanup; |
204 | 2 | } |
205 | | // One prime provided so find the second prime by division |
206 | 33 | BN_bin2bn(publicKey->buffer, publicKey->size, bnN); |
207 | | // Get q = n/p; |
208 | 33 | if(BN_div(bnQ, bnQr, bnN, bnP, context) != 1) |
209 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
210 | | // If there is a remainder, then this is not a valid n |
211 | 33 | if(BN_num_bytes(bnQr) != 0 || BN_num_bits(bnQ) != BN_num_bits(bnP)) |
212 | 31 | { |
213 | 31 | retVal = CRYPT_PARAMETER; // problem may be recoverable |
214 | 31 | goto Cleanup; |
215 | 31 | } |
216 | 33 | } |
217 | | // Get compute Phi = (p - 1)(q - 1) = pq - p - q + 1 = n - p - q + 1 |
218 | 2 | BN_copy(bnPhi, bnN); |
219 | 2 | BN_sub(bnPhi, bnPhi, bnP); |
220 | 2 | BN_sub(bnPhi, bnPhi, bnQ); |
221 | 2 | BN_add_word(bnPhi, 1); |
222 | | // Compute the multiplicative inverse |
223 | 2 | BN_set_word(bnE, exponent); |
224 | 2 | if(BN_mod_inverse(bnD, bnE, bnPhi, context) == NULL) |
225 | 1 | { |
226 | | // Going to assume that the error is caused by a bad set of parameters. |
227 | | // Specifically, an exponent that is not compatible with the primes. |
228 | | // In an implementation that has better visibility to the error codes, |
229 | | // this might be refined so that failures in the library would return |
230 | | // a more informative value. |
231 | | // Do not assume that the error codes will remain unchanged. |
232 | 1 | retVal = CRYPT_PARAMETER; |
233 | 1 | goto Cleanup; |
234 | 1 | } |
235 | | // Return the private exponent. |
236 | | // Make sure it is normalized to have the correct size. |
237 | 1 | d->size = publicKey->size; |
238 | 1 | fill = d->size - BN_num_bytes(bnD); |
239 | 1 | BN_bn2bin(bnD, &d->buffer[fill]); |
240 | 1 | memset(d->buffer, 0, fill); |
241 | 35 | Cleanup: |
242 | 35 | BN_CTX_end(context); |
243 | 35 | BN_CTX_free(context); |
244 | 35 | return retVal; |
245 | 1 | } |
246 | | // |
247 | | // |
248 | | // RSAEP() |
249 | | // |
250 | | // This function performs the RSAEP operation defined in PKCS#1v2.1. It is an exponentiation of a value |
251 | | // (m) with the public exponent (e), modulo the public (n). |
252 | | // |
253 | | // Return Value Meaning |
254 | | // |
255 | | // CRYPT_SUCCESS encryption complete |
256 | | // CRYPT_PARAMETER number to exponentiate is larger than the modulus |
257 | | // |
258 | | static CRYPT_RESULT |
259 | | RSAEP ( |
260 | | UINT32 dInOutSize, // OUT size of the encrypted block |
261 | | BYTE *dInOut, // OUT: the encrypted data |
262 | | RSA_KEY *key // IN: the key to use |
263 | | ) |
264 | 0 | { |
265 | 0 | UINT32 e; |
266 | 0 | BYTE exponent[4]; |
267 | 0 | CRYPT_RESULT retVal; |
268 | 0 | e = key->exponent; |
269 | 0 | if(e == 0) |
270 | 0 | e = RSA_DEFAULT_PUBLIC_EXPONENT; |
271 | 0 | UINT32_TO_BYTE_ARRAY(e, exponent); |
272 | | //!!! Can put check for test of RSA here |
273 | 0 | retVal = _math__ModExp(dInOutSize, dInOut, dInOutSize, dInOut, 4, exponent, |
274 | 0 | key->publicKey->size, key->publicKey->buffer); |
275 | | // Exponentiation result is stored in-place, thus no space shortage is possible. |
276 | 0 | pAssert(retVal != CRYPT_UNDERFLOW); |
277 | 0 | return retVal; |
278 | 0 | } |
279 | | // |
280 | | // |
281 | | // RSADP() |
282 | | // |
283 | | // This function performs the RSADP operation defined in PKCS#1v2.1. It is an exponentiation of a value (c) |
284 | | // with the private exponent (d), modulo the public modulus (n). The decryption is in place. |
285 | | // |
286 | | // This function also checks the size of the private key. If the size indicates that only a prime value is |
287 | | // present, the key is converted to being a private exponent. |
288 | | // |
289 | | // Return Value Meaning |
290 | | // |
291 | | // CRYPT_SUCCESS decryption succeeded |
292 | | // CRYPT_PARAMETER the value to decrypt is larger than the modulus |
293 | | // |
294 | | static CRYPT_RESULT |
295 | | RSADP ( |
296 | | UINT32 dInOutSize, // IN/OUT: size of decrypted data |
297 | | BYTE *dInOut, // IN/OUT: the decrypted data |
298 | | RSA_KEY *key // IN: the key |
299 | | ) |
300 | 0 | { |
301 | 0 | CRYPT_RESULT retVal; |
302 | | //!!! Can put check for RSA tested here |
303 | | // Make sure that the pointers are provided and that the private key is present |
304 | | // If the private key is present it is assumed to have been created by |
305 | | // so is presumed good _cpri__PrivateExponent |
306 | 0 | pAssert(key != NULL && dInOut != NULL && |
307 | 0 | key->publicKey->size == key->publicKey->size); |
308 | | // make sure that the value to be decrypted is smaller than the modulus |
309 | | // note: this check is redundant as is also performed by _math__ModExp() |
310 | | // which is optimized for use in RSA operations |
311 | 0 | if(_math__uComp(key->publicKey->size, key->publicKey->buffer, |
312 | 0 | dInOutSize, dInOut) <= 0) |
313 | 0 | return CRYPT_PARAMETER; |
314 | | // _math__ModExp can return CRYPT_PARAMTER or CRYPT_UNDERFLOW but actual |
315 | | // underflow is not possible because everything is in the same buffer. |
316 | 0 | retVal = _math__ModExp(dInOutSize, dInOut, dInOutSize, dInOut, |
317 | 0 | key->privateKey->size, key->privateKey->buffer, |
318 | 0 | key->publicKey->size, key->publicKey->buffer); |
319 | | // Exponentiation result is stored in-place, thus no space shortage is possible. |
320 | 0 | pAssert(retVal != CRYPT_UNDERFLOW); |
321 | 0 | return retVal; |
322 | 0 | } |
323 | | // |
324 | | // |
325 | | // OaepEncode() |
326 | | // |
327 | | // This function performs OAEP padding. The size of the buffer to receive the OAEP padded data must |
328 | | // equal the size of the modulus |
329 | | // |
330 | | // Return Value Meaning |
331 | | // |
332 | | // CRYPT_SUCCESS encode successful |
333 | | // CRYPT_PARAMETER hashAlg is not valid |
334 | | // CRYPT_FAIL message size is too large |
335 | | // |
336 | | static CRYPT_RESULT |
337 | | OaepEncode( |
338 | | UINT32 paddedSize, // IN: pad value size |
339 | | BYTE *padded, // OUT: the pad data |
340 | | TPM_ALG_ID hashAlg, // IN: algorithm to use for padding |
341 | | const char *label, // IN: null-terminated string (may be NULL) |
342 | | UINT32 messageSize, // IN: the message size |
343 | | BYTE *message // IN: the message being padded |
344 | | #ifdef TEST_RSA // |
345 | | , BYTE *testSeed // IN: optional seed used for testing. |
346 | | #endif // TEST_RSA // |
347 | | ) |
348 | 0 | { |
349 | 0 | UINT32 padLen; |
350 | 0 | UINT32 dbSize; |
351 | 0 | UINT32 i; |
352 | 0 | BYTE mySeed[MAX_DIGEST_SIZE]; |
353 | 0 | BYTE *seed = mySeed; |
354 | 0 | INT32 hLen = _cpri__GetDigestSize(hashAlg); |
355 | 0 | BYTE mask[MAX_RSA_KEY_BYTES]; |
356 | 0 | BYTE *pp; |
357 | 0 | BYTE *pm; |
358 | 0 | UINT32 lSize = 0; |
359 | 0 | CRYPT_RESULT retVal = CRYPT_SUCCESS; |
360 | 0 | pAssert(padded != NULL && message != NULL); |
361 | | // A value of zero is not allowed because the KDF can't produce a result |
362 | | // if the digest size is zero. |
363 | 0 | if(hLen <= 0) |
364 | 0 | return CRYPT_PARAMETER; |
365 | | // If a label is provided, get the length of the string, including the |
366 | | // terminator |
367 | 0 | if(label != NULL) |
368 | 0 | lSize = (UINT32)strlen(label) + 1; |
369 | | // Basic size check |
370 | | // messageSize <= k 2hLen 2 |
371 | 0 | if(messageSize > paddedSize - 2 * hLen - 2) |
372 | 0 | return CRYPT_FAIL; |
373 | | // Hash L even if it is null |
374 | | // Offset into padded leaving room for masked seed and byte of zero |
375 | 0 | pp = &padded[hLen + 1]; |
376 | 0 | retVal = _cpri__HashBlock(hashAlg, lSize, (BYTE *)label, hLen, pp); |
377 | | // concatenate PS of k mLen 2hLen 2 |
378 | 0 | padLen = paddedSize - messageSize - (2 * hLen) - 2; |
379 | 0 | memset(&pp[hLen], 0, padLen); |
380 | 0 | pp[hLen+padLen] = 0x01; |
381 | 0 | padLen += 1; |
382 | 0 | memcpy(&pp[hLen+padLen], message, messageSize); |
383 | | // The total size of db = hLen + pad + mSize; |
384 | 0 | dbSize = hLen+padLen+messageSize; |
385 | | // If testing, then use the provided seed. Otherwise, use values |
386 | | // from the RNG |
387 | | #ifdef TEST_RSA |
388 | | if(testSeed != NULL) |
389 | | seed = testSeed; |
390 | | else |
391 | | #endif // TEST_RSA |
392 | 0 | _cpri__GenerateRandom(hLen, mySeed); |
393 | | // mask = MGF1 (seed, nSize hLen 1) |
394 | 0 | if((retVal = _cpri__MGF1(dbSize, mask, hashAlg, hLen, seed)) < 0) |
395 | 0 | return retVal; // Don't expect an error because hash size is not zero |
396 | | // was detected in the call to _cpri__HashBlock() above. |
397 | | // Create the masked db |
398 | 0 | pm = mask; |
399 | 0 | for(i = dbSize; i > 0; i--) |
400 | 0 | *pp++ ^= *pm++; |
401 | 0 | pp = &padded[hLen + 1]; |
402 | | // Run the masked data through MGF1 |
403 | 0 | if((retVal = _cpri__MGF1(hLen, &padded[1], hashAlg, dbSize, pp)) < 0) |
404 | 0 | return retVal; // Don't expect zero here as the only case for zero |
405 | | // was detected in the call to _cpri__HashBlock() above. |
406 | | // Now XOR the seed to create masked seed |
407 | 0 | pp = &padded[1]; |
408 | 0 | pm = seed; |
409 | 0 | for(i = hLen; i > 0; i--) |
410 | 0 | *pp++ ^= *pm++; |
411 | | // Set the first byte to zero |
412 | 0 | *padded = 0x00; |
413 | 0 | return CRYPT_SUCCESS; |
414 | 0 | } |
415 | | // |
416 | | // |
417 | | // OaepDecode() |
418 | | // |
419 | | // This function performs OAEP padding checking. The size of the buffer to receive the recovered data. If |
420 | | // the padding is not valid, the dSize size is set to zero and the function returns CRYPT_NO_RESULTS. |
421 | | // The dSize parameter is used as an input to indicate the size available in the buffer. If insufficient space is |
422 | | // available, the size is not changed and the return code is CRYPT_FAIL. |
423 | | // |
424 | | // Return Value Meaning |
425 | | // |
426 | | // CRYPT_SUCCESS decode complete |
427 | | // CRYPT_PARAMETER the value to decode was larger than the modulus |
428 | | // CRYPT_FAIL the padding is wrong or the buffer to receive the results is too small |
429 | | // |
430 | | static CRYPT_RESULT |
431 | | OaepDecode( |
432 | | UINT32 *dataOutSize, // IN/OUT: the recovered data size |
433 | | BYTE *dataOut, // OUT: the recovered data |
434 | | TPM_ALG_ID hashAlg, // IN: algorithm to use for padding |
435 | | const char *label, // IN: null-terminated string (may be NULL) |
436 | | UINT32 paddedSize, // IN: the size of the padded data |
437 | | BYTE *padded // IN: the padded data |
438 | | ) |
439 | 0 | { |
440 | 0 | UINT32 dSizeSave; |
441 | 0 | UINT32 i; |
442 | 0 | BYTE seedMask[MAX_DIGEST_SIZE]; |
443 | 0 | INT32 hLen = _cpri__GetDigestSize(hashAlg); |
444 | 0 | BYTE mask[MAX_RSA_KEY_BYTES]; |
445 | 0 | BYTE *pp; |
446 | 0 | BYTE *pm; |
447 | 0 | UINT32 lSize = 0; |
448 | 0 | CRYPT_RESULT retVal = CRYPT_SUCCESS; |
449 | | // Unknown hash |
450 | 0 | pAssert(hLen > 0 && dataOutSize != NULL && dataOut != NULL && padded != NULL); |
451 | | // If there is a label, get its size including the terminating 0x00 |
452 | 0 | if(label != NULL) |
453 | 0 | lSize = (UINT32)strlen(label) + 1; |
454 | | // Set the return size to zero so that it doesn't have to be done on each |
455 | | // failure |
456 | 0 | dSizeSave = *dataOutSize; |
457 | 0 | *dataOutSize = 0; |
458 | | // Strange size (anything smaller can't be an OAEP padded block) |
459 | | // Also check for no leading 0 |
460 | 0 | if(paddedSize < (unsigned)((2 * hLen) + 2) || *padded != 0) |
461 | 0 | return CRYPT_FAIL; |
462 | | // Use the hash size to determine what to put through MGF1 in order |
463 | | // to recover the seedMask |
464 | 0 | if((retVal = _cpri__MGF1(hLen, seedMask, hashAlg, |
465 | 0 | paddedSize-hLen-1, &padded[hLen+1])) < 0) |
466 | 0 | return retVal; |
467 | | // Recover the seed into seedMask |
468 | 0 | pp = &padded[1]; |
469 | 0 | pm = seedMask; |
470 | 0 | for(i = hLen; i > 0; i--) |
471 | 0 | *pm++ ^= *pp++; |
472 | | // Use the seed to generate the data mask |
473 | 0 | if((retVal = _cpri__MGF1(paddedSize-hLen-1, mask, hashAlg, |
474 | 0 | hLen, seedMask)) < 0) |
475 | 0 | return retVal; |
476 | | // Use the mask generated from seed to recover the padded data |
477 | 0 | pp = &padded[hLen+1]; |
478 | 0 | pm = mask; |
479 | 0 | for(i = paddedSize-hLen-1; i > 0; i--) |
480 | 0 | *pm++ ^= *pp++; |
481 | | // Make sure that the recovered data has the hash of the label |
482 | | // Put trial value in the seed mask |
483 | 0 | if((retVal=_cpri__HashBlock(hashAlg, lSize,(BYTE *)label, hLen, seedMask)) < 0) |
484 | 0 | return retVal; |
485 | 0 | if(memcmp(seedMask, mask, hLen) != 0) |
486 | 0 | return CRYPT_FAIL; |
487 | | // find the start of the data |
488 | 0 | pm = &mask[hLen]; |
489 | 0 | for(i = paddedSize-(2*hLen)-1; i > 0; i--) |
490 | 0 | { |
491 | 0 | if(*pm++ != 0) |
492 | 0 | break; |
493 | 0 | } |
494 | | |
495 | | // Magic value in the end of the fill area must be 1, anything else must be |
496 | | // rejected. |
497 | 0 | if (pm[-1] != 1) |
498 | 0 | return CRYPT_FAIL; |
499 | | |
500 | 0 | if(i == 0) |
501 | 0 | return CRYPT_PARAMETER; |
502 | | // pm should be pointing at the first part of the data |
503 | | // and i is one greater than the number of bytes to move |
504 | 0 | i--; |
505 | 0 | if(i > dSizeSave) |
506 | 0 | { |
507 | | // Restore dSize |
508 | 0 | *dataOutSize = dSizeSave; |
509 | 0 | return CRYPT_FAIL; |
510 | 0 | } |
511 | 0 | memcpy(dataOut, pm, i); |
512 | 0 | *dataOutSize = i; |
513 | 0 | return CRYPT_SUCCESS; |
514 | 0 | } |
515 | | // |
516 | | // |
517 | | // PKSC1v1_5Encode() |
518 | | // |
519 | | // This function performs the encoding for RSAES-PKCS1-V1_5-ENCRYPT as defined in PKCS#1V2.1 |
520 | | // |
521 | | // Return Value Meaning |
522 | | // |
523 | | // CRYPT_SUCCESS data encoded |
524 | | // CRYPT_PARAMETER message size is too large |
525 | | // |
526 | | static CRYPT_RESULT |
527 | | RSAES_PKSC1v1_5Encode( |
528 | | UINT32 paddedSize, // IN: pad value size |
529 | | BYTE *padded, // OUT: the pad data |
530 | | UINT32 messageSize, // IN: the message size |
531 | | BYTE *message // IN: the message being padded |
532 | | ) |
533 | 0 | { |
534 | 0 | UINT32 ps = paddedSize - messageSize - 3; |
535 | 0 | if(messageSize > paddedSize - 11) |
536 | 0 | return CRYPT_PARAMETER; |
537 | | // move the message to the end of the buffer |
538 | 0 | memcpy(&padded[paddedSize - messageSize], message, messageSize); |
539 | | // Set the first byte to 0x00 and the second to 0x02 |
540 | 0 | *padded = 0; |
541 | 0 | padded[1] = 2; |
542 | | // Fill with random bytes |
543 | 0 | _cpri__GenerateRandom(ps, &padded[2]); |
544 | | // Set the delimiter for the random field to 0 |
545 | 0 | padded[2+ps] = 0; |
546 | | // Now, the only messy part. Make sure that all the ps bytes are non-zero |
547 | | // In this implementation, use the value of the current index |
548 | 0 | for(ps++; ps > 1; ps--) |
549 | 0 | { |
550 | 0 | if(padded[ps] == 0) |
551 | 0 | padded[ps] = 0x55; // In the < 0.5% of the cases that the random |
552 | | // value is 0, just pick a value to put into |
553 | | // the spot. |
554 | 0 | } |
555 | 0 | return CRYPT_SUCCESS; |
556 | 0 | } |
557 | | // |
558 | | // |
559 | | // RSAES_Decode() |
560 | | // |
561 | | // This function performs the decoding for RSAES-PKCS1-V1_5-ENCRYPT as defined in PKCS#1V2.1 |
562 | | // |
563 | | // Return Value Meaning |
564 | | // |
565 | | // CRYPT_SUCCESS decode successful |
566 | | // CRYPT_FAIL decoding error or results would no fit into provided buffer |
567 | | // |
568 | | static CRYPT_RESULT |
569 | | RSAES_Decode( |
570 | | UINT32 *messageSize, // IN/OUT: recovered message size |
571 | | BYTE *message, // OUT: the recovered message |
572 | | UINT32 codedSize, // IN: the encoded message size |
573 | | BYTE *coded // IN: the encoded message |
574 | | ) |
575 | 0 | { |
576 | 0 | BOOL fail = FALSE; |
577 | 0 | UINT32 ps; |
578 | 0 | fail = (codedSize < 11); |
579 | 0 | fail |= (coded[0] != 0x00) || (coded[1] != 0x02); |
580 | 0 | for(ps = 2; ps < codedSize; ps++) |
581 | 0 | { |
582 | 0 | if(coded[ps] == 0) |
583 | 0 | break; |
584 | 0 | } |
585 | 0 | ps++; |
586 | | // Make sure that ps has not gone over the end and that there are at least 8 |
587 | | // bytes of pad data. |
588 | 0 | fail |= ((ps >= codedSize) || ((ps-2) < 8)); |
589 | 0 | if((*messageSize < codedSize - ps) || fail) |
590 | 0 | return CRYPT_FAIL; |
591 | 0 | *messageSize = codedSize - ps; |
592 | 0 | memcpy(message, &coded[ps], codedSize - ps); |
593 | 0 | return CRYPT_SUCCESS; |
594 | 0 | } |
595 | | // |
596 | | // |
597 | | // PssEncode() |
598 | | // |
599 | | // This function creates an encoded block of data that is the size of modulus. The function uses the |
600 | | // maximum salt size that will fit in the encoded block. |
601 | | // |
602 | | // Return Value Meaning |
603 | | // |
604 | | // CRYPT_SUCCESS encode successful |
605 | | // CRYPT_PARAMETER hashAlg is not a supported hash algorithm |
606 | | // |
607 | | static CRYPT_RESULT |
608 | | PssEncode ( |
609 | | UINT32 eOutSize, // IN: size of the encode data buffer |
610 | | BYTE *eOut, // OUT: encoded data buffer |
611 | | TPM_ALG_ID hashAlg, // IN: hash algorithm to use for the encoding |
612 | | UINT32 hashInSize, // IN: size of digest to encode |
613 | | BYTE *hashIn // IN: the digest |
614 | | #ifdef TEST_RSA // |
615 | | , BYTE *saltIn // IN: optional parameter for testing |
616 | | #endif // TEST_RSA // |
617 | | ) |
618 | 0 | { |
619 | 0 | INT32 hLen = _cpri__GetDigestSize(hashAlg); |
620 | 0 | BYTE salt[MAX_RSA_KEY_BYTES - 1]; |
621 | 0 | UINT16 saltSize; |
622 | 0 | BYTE *ps = salt; |
623 | 0 | CRYPT_RESULT retVal; |
624 | 0 | UINT16 mLen; |
625 | 0 | CPRI_HASH_STATE hashState; |
626 | | // These are fatal errors indicating bad TPM firmware |
627 | 0 | pAssert(eOut != NULL && hLen > 0 && hashIn != NULL ); |
628 | | // Get the size of the mask |
629 | 0 | mLen = (UINT16)(eOutSize - hLen - 1); |
630 | | // Maximum possible salt size is mask length - 1 |
631 | 0 | saltSize = mLen - 1; |
632 | | // Use the maximum salt size allowed by FIPS 186-4 |
633 | 0 | if(saltSize > hLen) |
634 | 0 | saltSize = (UINT16)hLen; |
635 | | //using eOut for scratch space |
636 | | // Set the first 8 bytes to zero |
637 | 0 | memset(eOut, 0, 8); |
638 | | // Get set the salt |
639 | | #ifdef TEST_RSA |
640 | | if(saltIn != NULL) |
641 | | { |
642 | | saltSize = hLen; |
643 | | memcpy(salt, saltIn, hLen); |
644 | | } |
645 | | else |
646 | | #endif // TEST_RSA |
647 | 0 | _cpri__GenerateRandom(saltSize, salt); |
648 | | // Create the hash of the pad || input hash || salt |
649 | 0 | _cpri__StartHash(hashAlg, FALSE, &hashState); |
650 | 0 | _cpri__UpdateHash(&hashState, 8, eOut); |
651 | 0 | _cpri__UpdateHash(&hashState, hashInSize, hashIn); |
652 | 0 | _cpri__UpdateHash(&hashState, saltSize, salt); |
653 | 0 | _cpri__CompleteHash(&hashState, hLen, &eOut[eOutSize - hLen - 1]); |
654 | | // Create a mask |
655 | 0 | if((retVal = _cpri__MGF1(mLen, eOut, hashAlg, hLen, &eOut[mLen])) < 0) |
656 | 0 | { |
657 | | // Currently _cpri__MGF1 is not expected to return a CRYPT_RESULT error. |
658 | 0 | pAssert(0); |
659 | 0 | } |
660 | | // Since this implementation uses key sizes that are all even multiples of |
661 | | // 8, just need to make sure that the most significant bit is CLEAR |
662 | 0 | eOut[0] &= 0x7f; |
663 | | // Before we mess up the eOut value, set the last byte to 0xbc |
664 | 0 | eOut[eOutSize - 1] = 0xbc; |
665 | | // XOR a byte of 0x01 at the position just before where the salt will be XOR'ed |
666 | 0 | eOut = &eOut[mLen - saltSize - 1]; |
667 | 0 | *eOut++ ^= 0x01; |
668 | | // XOR the salt data into the buffer |
669 | 0 | for(; saltSize > 0; saltSize--) |
670 | 0 | *eOut++ ^= *ps++; |
671 | | // and we are done |
672 | 0 | return CRYPT_SUCCESS; |
673 | 0 | } |
674 | | // |
675 | | // |
676 | | // PssDecode() |
677 | | // |
678 | | // This function checks that the PSS encoded block was built from the provided digest. If the check is |
679 | | // successful, CRYPT_SUCCESS is returned. Any other value indicates an error. |
680 | | // This implementation of PSS decoding is intended for the reference TPM implementation and is not at all |
681 | | // generalized. It is used to check signatures over hashes and assumptions are made about the sizes of |
682 | | // values. Those assumptions are enforce by this implementation. This implementation does allow for a |
683 | | // variable size salt value to have been used by the creator of the signature. |
684 | | // |
685 | | // |
686 | | // |
687 | | // |
688 | | // Return Value Meaning |
689 | | // |
690 | | // CRYPT_SUCCESS decode successful |
691 | | // CRYPT_SCHEME hashAlg is not a supported hash algorithm |
692 | | // CRYPT_FAIL decode operation failed |
693 | | // |
694 | | static CRYPT_RESULT |
695 | | PssDecode( |
696 | | TPM_ALG_ID hashAlg, // IN: hash algorithm to use for the encoding |
697 | | UINT32 dInSize, // IN: size of the digest to compare |
698 | | BYTE *dIn, // In: the digest to compare |
699 | | UINT32 eInSize, // IN: size of the encoded data |
700 | | BYTE *eIn, // IN: the encoded data |
701 | | UINT32 saltSize // IN: the expected size of the salt |
702 | | ) |
703 | 0 | { |
704 | 0 | INT32 hLen = _cpri__GetDigestSize(hashAlg); |
705 | 0 | BYTE mask[MAX_RSA_KEY_BYTES]; |
706 | 0 | BYTE *pm = mask; |
707 | 0 | BYTE pad[8] = {0}; |
708 | 0 | UINT32 i; |
709 | 0 | UINT32 mLen; |
710 | 0 | BOOL fail = FALSE; |
711 | 0 | CRYPT_RESULT retVal; |
712 | 0 | CPRI_HASH_STATE hashState; |
713 | | // These errors are indicative of failures due to programmer error |
714 | 0 | pAssert(dIn != NULL && eIn != NULL); |
715 | | // check the hash scheme |
716 | 0 | if(hLen == 0) |
717 | 0 | return CRYPT_SCHEME; |
718 | | // most significant bit must be zero |
719 | 0 | fail = ((eIn[0] & 0x80) != 0); |
720 | | // last byte must be 0xbc |
721 | 0 | fail |= (eIn[eInSize - 1] != 0xbc); |
722 | | // Use the hLen bytes at the end of the buffer to generate a mask |
723 | | // Doesn't start at the end which is a flag byte |
724 | 0 | mLen = eInSize - hLen - 1; |
725 | 0 | if((retVal = _cpri__MGF1(mLen, mask, hashAlg, hLen, &eIn[mLen])) < 0) |
726 | 0 | return retVal; |
727 | 0 | if(retVal == 0) |
728 | 0 | return CRYPT_FAIL; |
729 | | // Clear the MSO of the mask to make it consistent with the encoding. |
730 | 0 | mask[0] &= 0x7F; |
731 | | // XOR the data into the mask to recover the salt. This sequence |
732 | | // advances eIn so that it will end up pointing to the seed data |
733 | | // which is the hash of the signature data |
734 | 0 | for(i = mLen; i > 0; i--) |
735 | 0 | *pm++ ^= *eIn++; |
736 | | // Find the first byte of 0x01 after a string of all 0x00 |
737 | 0 | for(pm = mask, i = mLen; i > 0; i--) |
738 | 0 | { |
739 | 0 | if(*pm == 0x01) |
740 | 0 | break; |
741 | 0 | else |
742 | 0 | fail |= (*pm++ != 0); |
743 | 0 | } |
744 | 0 | fail |= (i == 0); |
745 | | // if we have failed, will continue using the entire mask as the salt value so |
746 | | // that the timing attacks will not disclose anything (I don't think that this |
747 | | // is a problem for TPM applications but, usually, we don't fail so this |
748 | | // doesn't cost anything). |
749 | 0 | if(fail) |
750 | 0 | { |
751 | 0 | i = mLen; |
752 | 0 | pm = mask; |
753 | 0 | } |
754 | 0 | else |
755 | 0 | { |
756 | 0 | pm++; |
757 | 0 | i--; |
758 | 0 | } |
759 | | // If the salt size was provided, then the recovered size must match |
760 | 0 | fail |= (saltSize != 0 && i != saltSize); |
761 | | // i contains the salt size and pm points to the salt. Going to use the input |
762 | | // hash and the seed to recreate the hash in the lower portion of eIn. |
763 | 0 | _cpri__StartHash(hashAlg, FALSE, &hashState); |
764 | | // add the pad of 8 zeros |
765 | 0 | _cpri__UpdateHash(&hashState, 8, pad); |
766 | | // add the provided digest value |
767 | 0 | _cpri__UpdateHash(&hashState, dInSize, dIn); |
768 | | // and the salt |
769 | 0 | _cpri__UpdateHash(&hashState, i, pm); |
770 | | // get the result |
771 | 0 | retVal = _cpri__CompleteHash(&hashState, MAX_DIGEST_SIZE, mask); |
772 | | // retVal will be the size of the digest or zero. If not equal to the indicated |
773 | | // digest size, then the signature doesn't match |
774 | 0 | fail |= (retVal != hLen); |
775 | 0 | fail |= (memcmp(mask, eIn, hLen) != 0); |
776 | 0 | if(fail) |
777 | 0 | return CRYPT_FAIL; |
778 | 0 | else |
779 | 0 | return CRYPT_SUCCESS; |
780 | 0 | } |
781 | | // |
782 | | // |
783 | | // PKSC1v1_5SignEncode() |
784 | | // |
785 | | // Encode a message using PKCS1v1().5 method. |
786 | | // |
787 | | // Return Value Meaning |
788 | | // |
789 | | // CRYPT_SUCCESS encode complete |
790 | | // CRYPT_SCHEME hashAlg is not a supported hash algorithm |
791 | | // CRYPT_PARAMETER eOutSize is not large enough or hInSize does not match the digest |
792 | | // size of hashAlg |
793 | | // |
794 | | static CRYPT_RESULT |
795 | | RSASSA_Encode( |
796 | | UINT32 eOutSize, // IN: the size of the resulting block |
797 | | BYTE *eOut, // OUT: the encoded block |
798 | | TPM_ALG_ID hashAlg, // IN: hash algorithm for PKSC1v1_5 |
799 | | UINT32 hInSize, // IN: size of hash to be signed |
800 | | BYTE *hIn // IN: hash buffer |
801 | | ) |
802 | 0 | { |
803 | 0 | const BYTE *der; |
804 | 0 | INT32 derSize = _cpri__GetHashDER(hashAlg, &der); |
805 | 0 | INT32 fillSize; |
806 | 0 | pAssert(eOut != NULL && hIn != NULL); |
807 | | // Can't use this scheme if the algorithm doesn't have a DER string defined. |
808 | 0 | if( |
809 | 0 | #if defined(SUPPORT_PADDING_ONLY_RSASSA) && SUPPORT_PADDING_ONLY_RSASSA == YES |
810 | 0 | hashAlg != TPM_ALG_NULL && |
811 | 0 | #endif |
812 | 0 | derSize == 0) |
813 | 0 | return CRYPT_SCHEME; |
814 | | // If the digest size of 'hashAl' doesn't match the input digest size, then |
815 | | // the DER will misidentify the digest so return an error |
816 | 0 | if( |
817 | 0 | #if defined(SUPPORT_PADDING_ONLY_RSASSA) && SUPPORT_PADDING_ONLY_RSASSA == YES |
818 | 0 | hashAlg != TPM_ALG_NULL && |
819 | 0 | #endif |
820 | 0 | (unsigned)_cpri__GetDigestSize(hashAlg) != hInSize) |
821 | 0 | return CRYPT_PARAMETER; |
822 | 0 | fillSize = eOutSize - derSize - hInSize - 3; |
823 | | // Make sure that this combination will fit in the provided space |
824 | 0 | if(fillSize < 8) |
825 | 0 | return CRYPT_PARAMETER; |
826 | | // Start filling |
827 | 0 | *eOut++ = 0; // initial byte of zero |
828 | 0 | *eOut++ = 1; // byte of 0x01 |
829 | 0 | for(; fillSize > 0; fillSize--) |
830 | 0 | *eOut++ = 0xff; // bunch of 0xff |
831 | 0 | *eOut++ = 0; // another 0 |
832 | 0 | for(; derSize > 0; derSize--) |
833 | 0 | *eOut++ = *der++; // copy the DER |
834 | 0 | for(; hInSize > 0; hInSize--) |
835 | 0 | *eOut++ = *hIn++; // copy the hash |
836 | 0 | return CRYPT_SUCCESS; |
837 | 0 | } |
838 | | // |
839 | | // |
840 | | // RSASSA_Decode() |
841 | | // |
842 | | // This function performs the RSASSA decoding of a signature. |
843 | | // |
844 | | // Return Value Meaning |
845 | | // |
846 | | // CRYPT_SUCCESS decode successful |
847 | | // CRYPT_FAIL decode unsuccessful |
848 | | // CRYPT_SCHEME haslAlg is not supported |
849 | | // |
850 | | static CRYPT_RESULT |
851 | | RSASSA_Decode( |
852 | | TPM_ALG_ID hashAlg, // IN: hash algorithm to use for the encoding |
853 | | UINT32 hInSize, // IN: size of the digest to compare |
854 | | BYTE *hIn, // In: the digest to compare |
855 | | UINT32 eInSize, // IN: size of the encoded data |
856 | | BYTE *eIn // IN: the encoded data |
857 | | ) |
858 | 0 | { |
859 | 0 | BOOL fail = FALSE; |
860 | 0 | const BYTE *der; |
861 | 0 | INT32 derSize = _cpri__GetHashDER(hashAlg, &der); |
862 | 0 | INT32 hashSize = _cpri__GetDigestSize(hashAlg); |
863 | 0 | INT32 fillSize; |
864 | 0 | pAssert(hIn != NULL && eIn != NULL); |
865 | | // Can't use this scheme if the algorithm doesn't have a DER string |
866 | | // defined or if the provided hash isn't the right size |
867 | 0 | if(derSize == 0 || (unsigned)hashSize != hInSize) |
868 | 0 | return CRYPT_SCHEME; |
869 | | // Make sure that this combination will fit in the provided space |
870 | | // Since no data movement takes place, can just walk though this |
871 | | // and accept nearly random values. This can only be called from |
872 | | // _cpri__ValidateSignature() so eInSize is known to be in range. |
873 | 0 | fillSize = eInSize - derSize - hashSize - 3; |
874 | | // Start checking |
875 | 0 | fail |= (*eIn++ != 0); // initial byte of zero |
876 | 0 | fail |= (*eIn++ != 1); // byte of 0x01 |
877 | 0 | for(; fillSize > 0; fillSize--) |
878 | 0 | fail |= (*eIn++ != 0xff); // bunch of 0xff |
879 | 0 | fail |= (*eIn++ != 0); // another 0 |
880 | 0 | for(; derSize > 0; derSize--) |
881 | 0 | fail |= (*eIn++ != *der++); // match the DER |
882 | 0 | for(; hInSize > 0; hInSize--) |
883 | 0 | fail |= (*eIn++ != *hIn++); // match the hash |
884 | 0 | if(fail) |
885 | 0 | return CRYPT_FAIL; |
886 | 0 | return CRYPT_SUCCESS; |
887 | 0 | } |
888 | | // |
889 | | // |
890 | | // Externally Accessible Functions |
891 | | // |
892 | | // _cpri__RsaStartup() |
893 | | // |
894 | | // Function that is called to initialize the hash service. In this implementation, this function does nothing but |
895 | | // it is called by the CryptUtilStartup() function and must be present. |
896 | | // |
897 | | LIB_EXPORT BOOL |
898 | | _cpri__RsaStartup( |
899 | | void |
900 | | ) |
901 | 495 | { |
902 | 495 | return TRUE; |
903 | 495 | } |
904 | | // |
905 | | // |
906 | | // _cpri__EncryptRSA() |
907 | | // |
908 | | // This is the entry point for encryption using RSA. Encryption is use of the public exponent. The padding |
909 | | // parameter determines what padding will be used. |
910 | | // The cOutSize parameter must be at least as large as the size of the key. |
911 | | // If the padding is RSA_PAD_NONE, dIn is treaded as a number. It must be lower in value than the key |
912 | | // modulus. |
913 | | // |
914 | | // |
915 | | // |
916 | | // NOTE: If dIn has fewer bytes than cOut, then we don't add low-order zeros to dIn to make it the size of the RSA key for |
917 | | // the call to RSAEP. This is because the high order bytes of dIn might have a numeric value that is greater than |
918 | | // the value of the key modulus. If this had low-order zeros added, it would have a numeric value larger than the |
919 | | // modulus even though it started out with a lower numeric value. |
920 | | // |
921 | | // |
922 | | // Return Value Meaning |
923 | | // |
924 | | // CRYPT_SUCCESS encryption complete |
925 | | // CRYPT_PARAMETER cOutSize is too small (must be the size of the modulus) |
926 | | // CRYPT_SCHEME padType is not a supported scheme |
927 | | // |
928 | | LIB_EXPORT CRYPT_RESULT |
929 | | _cpri__EncryptRSA( |
930 | | UINT32 *cOutSize, // OUT: the size of the encrypted data |
931 | | BYTE *cOut, // OUT: the encrypted data |
932 | | RSA_KEY *key, // IN: the key to use for encryption |
933 | | TPM_ALG_ID padType, // IN: the type of padding |
934 | | UINT32 dInSize, // IN: the amount of data to encrypt |
935 | | BYTE *dIn, // IN: the data to encrypt |
936 | | TPM_ALG_ID hashAlg, // IN: in case this is needed |
937 | | const char *label // IN: in case it is needed |
938 | | ) |
939 | 0 | { |
940 | 0 | CRYPT_RESULT retVal = CRYPT_SUCCESS; |
941 | 0 | pAssert(cOutSize != NULL); |
942 | | // All encryption schemes return the same size of data |
943 | 0 | if(*cOutSize < key->publicKey->size) |
944 | 0 | return CRYPT_PARAMETER; |
945 | 0 | *cOutSize = key->publicKey->size; |
946 | 0 | switch (padType) |
947 | 0 | { |
948 | 0 | case TPM_ALG_NULL: // 'raw' encryption |
949 | 0 | { |
950 | | // dIn can have more bytes than cOut as long as the extra bytes |
951 | | // are zero |
952 | 0 | for(; dInSize > *cOutSize; dInSize--) |
953 | 0 | { |
954 | 0 | if(*dIn++ != 0) |
955 | 0 | return CRYPT_PARAMETER; |
956 | 0 | } |
957 | | // If dIn is smaller than cOut, fill cOut with zeros |
958 | 0 | if(dInSize < *cOutSize) |
959 | 0 | memset(cOut, 0, *cOutSize - dInSize); |
960 | | // Copy the rest of the value |
961 | 0 | memcpy(&cOut[*cOutSize-dInSize], dIn, dInSize); |
962 | | // If the size of dIn is the same as cOut dIn could be larger than |
963 | | // the modulus. If it is, then RSAEP() will catch it. |
964 | 0 | } |
965 | 0 | break; |
966 | 0 | case TPM_ALG_RSAES: |
967 | 0 | retVal = RSAES_PKSC1v1_5Encode(*cOutSize, cOut, dInSize, dIn); |
968 | 0 | break; |
969 | 0 | case TPM_ALG_OAEP: |
970 | 0 | retVal = OaepEncode(*cOutSize, cOut, hashAlg, label, dInSize, dIn |
971 | | #ifdef TEST_RSA |
972 | | ,NULL |
973 | | #endif |
974 | 0 | ); |
975 | 0 | break; |
976 | 0 | default: |
977 | 0 | return CRYPT_SCHEME; |
978 | 0 | } |
979 | | // All the schemes that do padding will come here for the encryption step |
980 | | // Check that the Encoding worked |
981 | 0 | if(retVal != CRYPT_SUCCESS) |
982 | 0 | return retVal; |
983 | | // Padding OK so do the encryption |
984 | 0 | return RSAEP(*cOutSize, cOut, key); |
985 | 0 | } |
986 | | // |
987 | | // |
988 | | // _cpri__DecryptRSA() |
989 | | // |
990 | | // This is the entry point for decryption using RSA. Decryption is use of the private exponent. The padType |
991 | | // parameter determines what padding was used. |
992 | | // |
993 | | // Return Value Meaning |
994 | | // |
995 | | // CRYPT_SUCCESS successful completion |
996 | | // CRYPT_PARAMETER cInSize is not the same as the size of the public modulus of key; or |
997 | | // numeric value of the encrypted data is greater than the modulus |
998 | | // CRYPT_FAIL dOutSize is not large enough for the result |
999 | | // CRYPT_SCHEME padType is not supported |
1000 | | // |
1001 | | LIB_EXPORT CRYPT_RESULT |
1002 | | _cpri__DecryptRSA( |
1003 | | UINT32 *dOutSize, // OUT: the size of the decrypted data |
1004 | | BYTE *dOut, // OUT: the decrypted data |
1005 | | RSA_KEY *key, // IN: the key to use for decryption |
1006 | | TPM_ALG_ID padType, // IN: the type of padding |
1007 | | UINT32 cInSize, // IN: the amount of data to decrypt |
1008 | | BYTE *cIn, // IN: the data to decrypt |
1009 | | TPM_ALG_ID hashAlg, // IN: in case this is needed for the scheme |
1010 | | const char *label // IN: in case it is needed for the scheme |
1011 | | ) |
1012 | 0 | { |
1013 | 0 | CRYPT_RESULT retVal; |
1014 | | // Make sure that the necessary parameters are provided |
1015 | 0 | pAssert(cIn != NULL && dOut != NULL && dOutSize != NULL && key != NULL); |
1016 | | // Size is checked to make sure that the decryption works properly |
1017 | 0 | if(cInSize != key->publicKey->size) |
1018 | 0 | return CRYPT_PARAMETER; |
1019 | | // For others that do padding, do the decryption in place and then |
1020 | | // go handle the decoding. |
1021 | 0 | if((retVal = RSADP(cInSize, cIn, key)) != CRYPT_SUCCESS) |
1022 | 0 | return retVal; // Decryption failed |
1023 | | // Remove padding |
1024 | 0 | switch (padType) |
1025 | 0 | { |
1026 | 0 | case TPM_ALG_NULL: |
1027 | 0 | if(*dOutSize < key->publicKey->size) |
1028 | 0 | return CRYPT_FAIL; |
1029 | 0 | *dOutSize = key->publicKey->size; |
1030 | 0 | memcpy(dOut, cIn, *dOutSize); |
1031 | 0 | return CRYPT_SUCCESS; |
1032 | 0 | case TPM_ALG_RSAES: |
1033 | 0 | return RSAES_Decode(dOutSize, dOut, cInSize, cIn); |
1034 | 0 | break; |
1035 | 0 | case TPM_ALG_OAEP: |
1036 | 0 | return OaepDecode(dOutSize, dOut, hashAlg, label, cInSize, cIn); |
1037 | 0 | break; |
1038 | 0 | default: |
1039 | 0 | return CRYPT_SCHEME; |
1040 | 0 | break; |
1041 | 0 | } |
1042 | 0 | } |
1043 | | // |
1044 | | // |
1045 | | // _cpri__SignRSA() |
1046 | | // |
1047 | | // This function is used to generate an RSA signature of the type indicated in scheme. |
1048 | | // |
1049 | | // Return Value Meaning |
1050 | | // |
1051 | | // CRYPT_SUCCESS sign operation completed normally |
1052 | | // CRYPT_SCHEME scheme or hashAlg are not supported |
1053 | | // CRYPT_PARAMETER hInSize does not match hashAlg (for RSASSA) |
1054 | | // |
1055 | | LIB_EXPORT CRYPT_RESULT |
1056 | | _cpri__SignRSA( |
1057 | | UINT32 *sigOutSize, // OUT: size of signature |
1058 | | BYTE *sigOut, // OUT: signature |
1059 | | RSA_KEY *key, // IN: key to use |
1060 | | TPM_ALG_ID scheme, // IN: the scheme to use |
1061 | | TPM_ALG_ID hashAlg, // IN: hash algorithm for PKSC1v1_5 |
1062 | | UINT32 hInSize, // IN: size of digest to be signed |
1063 | | BYTE *hIn // IN: digest buffer |
1064 | | ) |
1065 | 0 | { |
1066 | 0 | CRYPT_RESULT retVal; |
1067 | | // Parameter checks |
1068 | 0 | pAssert(sigOutSize != NULL && sigOut != NULL && key != NULL && hIn != NULL); |
1069 | | // For all signatures the size is the size of the key modulus |
1070 | 0 | *sigOutSize = key->publicKey->size; |
1071 | 0 | switch (scheme) |
1072 | 0 | { |
1073 | 0 | case TPM_ALG_NULL: |
1074 | 0 | *sigOutSize = 0; |
1075 | 0 | return CRYPT_SUCCESS; |
1076 | 0 | case TPM_ALG_RSAPSS: |
1077 | | // PssEncode can return CRYPT_PARAMETER |
1078 | 0 | retVal = PssEncode(*sigOutSize, sigOut, hashAlg, hInSize, hIn |
1079 | | #ifdef TEST_RSA |
1080 | | , NULL |
1081 | | #endif |
1082 | 0 | ); |
1083 | 0 | break; |
1084 | 0 | case TPM_ALG_RSASSA: |
1085 | | // RSASSA_Encode can return CRYPT_PARAMETER or CRYPT_SCHEME |
1086 | 0 | retVal = RSASSA_Encode(*sigOutSize, sigOut, hashAlg, hInSize, hIn); |
1087 | 0 | break; |
1088 | 0 | default: |
1089 | 0 | return CRYPT_SCHEME; |
1090 | 0 | } |
1091 | 0 | if(retVal != CRYPT_SUCCESS) |
1092 | 0 | return retVal; |
1093 | | // Do the encryption using the private key |
1094 | | // RSADP can return CRYPT_PARAMETR |
1095 | 0 | return RSADP(*sigOutSize,sigOut, key); |
1096 | 0 | } |
1097 | | // |
1098 | | // |
1099 | | // _cpri__ValidateSignatureRSA() |
1100 | | // |
1101 | | // This function is used to validate an RSA signature. If the signature is valid CRYPT_SUCCESS is |
1102 | | // returned. If the signature is not valid, CRYPT_FAIL is returned. Other return codes indicate either |
1103 | | // parameter problems or fatal errors. |
1104 | | // |
1105 | | // Return Value Meaning |
1106 | | // |
1107 | | // CRYPT_SUCCESS the signature checks |
1108 | | // CRYPT_FAIL the signature does not check |
1109 | | // CRYPT_SCHEME unsupported scheme or hash algorithm |
1110 | | // |
1111 | | LIB_EXPORT CRYPT_RESULT |
1112 | | _cpri__ValidateSignatureRSA( |
1113 | | RSA_KEY *key, // IN: key to use |
1114 | | TPM_ALG_ID scheme, // IN: the scheme to use |
1115 | | TPM_ALG_ID hashAlg, // IN: hash algorithm |
1116 | | UINT32 hInSize, // IN: size of digest to be checked |
1117 | | BYTE *hIn, // IN: digest buffer |
1118 | | UINT32 sigInSize, // IN: size of signature |
1119 | | BYTE *sigIn, // IN: signature |
1120 | | UINT16 saltSize // IN: salt size for PSS |
1121 | | ) |
1122 | 0 | { |
1123 | 0 | CRYPT_RESULT retVal; |
1124 | | // Fatal programming errors |
1125 | 0 | pAssert(key != NULL && sigIn != NULL && hIn != NULL); |
1126 | | // Errors that might be caused by calling parameters |
1127 | 0 | if(sigInSize != key->publicKey->size) |
1128 | 0 | return CRYPT_FAIL; |
1129 | | // Decrypt the block |
1130 | 0 | if((retVal = RSAEP(sigInSize, sigIn, key)) != CRYPT_SUCCESS) |
1131 | 0 | return CRYPT_FAIL; |
1132 | 0 | switch (scheme) |
1133 | 0 | { |
1134 | 0 | case TPM_ALG_NULL: |
1135 | 0 | return CRYPT_SCHEME; |
1136 | 0 | break; |
1137 | 0 | case TPM_ALG_RSAPSS: |
1138 | 0 | return PssDecode(hashAlg, hInSize, hIn, sigInSize, sigIn, saltSize); |
1139 | 0 | break; |
1140 | 0 | case TPM_ALG_RSASSA: |
1141 | 0 | return RSASSA_Decode(hashAlg, hInSize, hIn, sigInSize, sigIn); |
1142 | 0 | break; |
1143 | 0 | default: |
1144 | 0 | break; |
1145 | 0 | } |
1146 | 0 | return CRYPT_SCHEME; |
1147 | 0 | } |
1148 | | #ifndef RSA_KEY_SIEVE |
1149 | | // |
1150 | | // |
1151 | | // _cpri__GenerateKeyRSA() |
1152 | | // |
1153 | | // Generate an RSA key from a provided seed |
1154 | | // |
1155 | | // |
1156 | | // |
1157 | | // |
1158 | | // Return Value Meaning |
1159 | | // |
1160 | | // CRYPT_FAIL exponent is not prime or is less than 3; or could not find a prime using |
1161 | | // the provided parameters |
1162 | | // CRYPT_CANCEL operation was canceled |
1163 | | // |
1164 | | LIB_EXPORT CRYPT_RESULT |
1165 | | _cpri__GenerateKeyRSA( |
1166 | | TPM2B *n, // OUT: The public modulu |
1167 | | TPM2B *p, // OUT: One of the prime factors of n |
1168 | | UINT16 keySizeInBits, // IN: Size of the public modulus in bit |
1169 | | UINT32 e, // IN: The public exponent |
1170 | | TPM_ALG_ID hashAlg, // IN: hash algorithm to use in the key |
1171 | | // generation proce |
1172 | | TPM2B *seed, // IN: the seed to use |
1173 | | const char *label, // IN: A label for the generation process. |
1174 | | TPM2B *extra, // IN: Party 1 data for the KDF |
1175 | | UINT32 *counter // IN/OUT: Counter value to allow KFD iteration |
1176 | | // to be propagated across multiple routine |
1177 | | ) |
1178 | 3 | { |
1179 | 3 | UINT32 lLen; // length of the label |
1180 | | // (counting the terminating 0); |
1181 | 3 | UINT16 digestSize = _cpri__GetDigestSize(hashAlg); |
1182 | 3 | TPM2B_HASH_BLOCK oPadKey; |
1183 | 3 | UINT32 outer; |
1184 | 3 | UINT32 inner; |
1185 | 3 | BYTE swapped[4]; |
1186 | 3 | CRYPT_RESULT retVal; |
1187 | 3 | int i, fill; |
1188 | 3 | const static char defaultLabel[] = "RSA key"; |
1189 | 3 | BYTE *pb; |
1190 | 3 | CPRI_HASH_STATE h1; // contains the hash of the |
1191 | | // HMAC key w/ iPad |
1192 | 3 | CPRI_HASH_STATE h2; // contains the hash of the |
1193 | | // HMAC key w/ oPad |
1194 | 3 | CPRI_HASH_STATE h; // the working hash context |
1195 | 3 | BIGNUM *bnP; |
1196 | 3 | BIGNUM *bnQ; |
1197 | 3 | BIGNUM *bnT; |
1198 | 3 | BIGNUM *bnE; |
1199 | 3 | BIGNUM *bnN; |
1200 | 3 | BN_CTX *context; |
1201 | 3 | UINT32 rem; |
1202 | | // Make sure that hashAlg is valid hash |
1203 | 3 | pAssert(digestSize != 0); |
1204 | | // if present, use externally provided counter |
1205 | 3 | if(counter != NULL) |
1206 | 3 | outer = *counter; |
1207 | 0 | else |
1208 | 0 | outer = 1; |
1209 | | // Validate exponent |
1210 | 3 | UINT32_TO_BYTE_ARRAY(e, swapped); |
1211 | | // Need to check that the exponent is prime and not less than 3 |
1212 | 3 | if( e != 0 && (e < 3 || !_math__IsPrime(e))) |
1213 | 0 | return CRYPT_FAIL; |
1214 | | // Get structures for the big number representations |
1215 | 3 | context = BN_CTX_new(); |
1216 | 3 | if(context == NULL) |
1217 | 0 | FAIL(FATAL_ERROR_ALLOCATION); |
1218 | 3 | BN_CTX_start(context); |
1219 | 3 | bnP = BN_CTX_get(context); |
1220 | 3 | bnQ = BN_CTX_get(context); |
1221 | 3 | bnT = BN_CTX_get(context); |
1222 | 3 | bnE = BN_CTX_get(context); |
1223 | 3 | bnN = BN_CTX_get(context); |
1224 | 3 | if(bnN == NULL) |
1225 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
1226 | | // Set Q to zero. This is used as a flag. The prime is computed in P. When a |
1227 | | // new prime is found, Q is checked to see if it is zero. If so, P is copied |
1228 | | // to Q and a new P is found. When both P and Q are non-zero, the modulus and |
1229 | | // private exponent are computed and a trial encryption/decryption is |
1230 | | // performed. If the encrypt/decrypt fails, assume that at least one of the |
1231 | | // primes is composite. Since we don't know which one, set Q to zero and start |
1232 | | // over and find a new pair of primes. |
1233 | 3 | BN_zero(bnQ); |
1234 | | // Need to have some label |
1235 | 3 | if(label == NULL) |
1236 | 0 | label = (const char *)&defaultLabel; |
1237 | | // Get the label size |
1238 | 54 | for(lLen = 0; label[lLen++] != 0;); |
1239 | | // Start the hash using the seed and get the intermediate hash value |
1240 | 3 | _cpri__StartHMAC(hashAlg, FALSE, &h1, seed->size, seed->buffer, &oPadKey.b); |
1241 | 3 | _cpri__StartHash(hashAlg, FALSE, &h2); |
1242 | 3 | _cpri__UpdateHash(&h2, oPadKey.b.size, oPadKey.b.buffer); |
1243 | 3 | n->size = (keySizeInBits +7)/8; |
1244 | 3 | pAssert(n->size <= MAX_RSA_KEY_BYTES); |
1245 | 3 | p->size = n->size / 2; |
1246 | 3 | if(e == 0) |
1247 | 0 | e = RSA_DEFAULT_PUBLIC_EXPONENT; |
1248 | 3 | BN_set_word(bnE, e); |
1249 | | // The first test will increment the counter from zero. |
1250 | 1.19k | for(outer += 1; outer != 0; outer++) |
1251 | 1.19k | { |
1252 | 1.19k | if(_plat__IsCanceled()) |
1253 | 0 | { |
1254 | 0 | retVal = CRYPT_CANCEL; |
1255 | 0 | goto Cleanup; |
1256 | 0 | } |
1257 | | // Need to fill in the candidate with the hash |
1258 | 1.19k | fill = digestSize; |
1259 | 1.19k | pb = p->buffer; |
1260 | | // Reset the inner counter |
1261 | 1.19k | inner = 0; |
1262 | 5.73k | for(i = p->size; i > 0; i -= digestSize) |
1263 | 4.53k | { |
1264 | 4.53k | inner++; |
1265 | | // Initialize the HMAC with saved state |
1266 | 4.53k | _cpri__CopyHashState(&h, &h1); |
1267 | | // Hash the inner counter (the one that changes on each HMAC iteration) |
1268 | 4.53k | UINT32_TO_BYTE_ARRAY(inner, swapped); |
1269 | 4.53k | _cpri__UpdateHash(&h, 4, swapped); |
1270 | 4.53k | _cpri__UpdateHash(&h, lLen, (BYTE *)label); |
1271 | | // Is there any party 1 data |
1272 | 4.53k | if(extra != NULL) |
1273 | 4.53k | _cpri__UpdateHash(&h, extra->size, extra->buffer); |
1274 | | // Include the outer counter (the one that changes on each prime |
1275 | | // prime candidate generation |
1276 | 4.53k | UINT32_TO_BYTE_ARRAY(outer, swapped); |
1277 | 4.53k | _cpri__UpdateHash(&h, 4, swapped); |
1278 | 4.53k | _cpri__UpdateHash(&h, 2, (BYTE *)&keySizeInBits); |
1279 | 4.53k | if(i < fill) |
1280 | 0 | fill = i; |
1281 | 4.53k | _cpri__CompleteHash(&h, fill, pb); |
1282 | | // Restart the oPad hash |
1283 | 4.53k | _cpri__CopyHashState(&h, &h2); |
1284 | | // Add the last hashed data |
1285 | 4.53k | _cpri__UpdateHash(&h, fill, pb); |
1286 | | // gives a completed HMAC |
1287 | 4.53k | _cpri__CompleteHash(&h, fill, pb); |
1288 | 4.53k | pb += fill; |
1289 | 4.53k | } |
1290 | | // Set the Most significant 2 bits and the low bit of the candidate |
1291 | 1.19k | p->buffer[0] |= 0xC0; |
1292 | 1.19k | p->buffer[p->size - 1] |= 1; |
1293 | | // Convert the candidate to a BN |
1294 | 1.19k | BN_bin2bn(p->buffer, p->size, bnP); |
1295 | | // If this is the second prime, make sure that it differs from the |
1296 | | // first prime by at least 2^100 |
1297 | 1.19k | if(!BN_is_zero(bnQ)) |
1298 | 407 | { |
1299 | | // bnQ is non-zero if we already found it |
1300 | 407 | if(BN_ucmp(bnP, bnQ) < 0) |
1301 | 38 | BN_sub(bnT, bnQ, bnP); |
1302 | 369 | else |
1303 | 369 | BN_sub(bnT, bnP, bnQ); |
1304 | 407 | if(BN_num_bits(bnT) < 100) // Difference has to be at least 100 bits |
1305 | 0 | continue; |
1306 | 407 | } |
1307 | | // Make sure that the prime candidate (p) is not divisible by the exponent |
1308 | | // and that (p-1) is not divisible by the exponent |
1309 | | // Get the remainder after dividing by the modulus |
1310 | 1.19k | rem = BN_mod_word(bnP, e); |
1311 | 1.19k | if(rem == 0) // evenly divisible so add two keeping the number odd and |
1312 | | // making sure that 1 != p mod e |
1313 | 0 | BN_add_word(bnP, 2); |
1314 | 1.19k | else if(rem == 1) // leaves a remainder of 1 so subtract two keeping the |
1315 | | // number odd and making (e-1) = p mod e |
1316 | 0 | BN_sub_word(bnP, 2); |
1317 | | // Have a candidate, check for primality |
1318 | 1.19k | if((retVal = (CRYPT_RESULT)BN_is_prime_ex(bnP, |
1319 | 1.19k | BN_prime_checks, NULL, NULL)) < 0) |
1320 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
1321 | 1.19k | if(retVal != 1) |
1322 | 1.19k | continue; |
1323 | | // Found a prime, is this the first or second. |
1324 | 6 | if(BN_is_zero(bnQ)) |
1325 | 3 | { |
1326 | | // copy p to q and compute another prime in p |
1327 | 3 | BN_copy(bnQ, bnP); |
1328 | 3 | continue; |
1329 | 3 | } |
1330 | | //Form the public modulus |
1331 | 3 | BN_mul(bnN, bnP, bnQ, context); |
1332 | 3 | if(BN_num_bits(bnN) != keySizeInBits) |
1333 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
1334 | | // Save the public modulus |
1335 | 3 | BnTo2B(n, bnN, n->size); // Will pad the buffer to the correct size |
1336 | 3 | pAssert((n->buffer[0] & 0x80) != 0); |
1337 | | // And one prime |
1338 | 3 | BnTo2B(p, bnP, p->size); |
1339 | 3 | pAssert((p->buffer[0] & 0x80) != 0); |
1340 | | // Finish by making sure that we can form the modular inverse of PHI |
1341 | | // with respect to the public exponent |
1342 | | // Compute PHI = (p - 1)(q - 1) = n - p - q + 1 |
1343 | | // Make sure that we can form the modular inverse |
1344 | 3 | BN_sub(bnT, bnN, bnP); |
1345 | 3 | BN_sub(bnT, bnT, bnQ); |
1346 | 3 | BN_add_word(bnT, 1); |
1347 | | // find d such that (Phi * d) mod e ==1 |
1348 | | // If there isn't then we are broken because we took the step |
1349 | | // of making sure that the prime != 1 mod e so the modular inverse |
1350 | | // must exist |
1351 | 3 | if(BN_mod_inverse(bnT, bnE, bnT, context) == NULL || BN_is_zero(bnT)) |
1352 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
1353 | | // And, finally, do a trial encryption decryption |
1354 | 3 | { |
1355 | 3 | TPM2B_TYPE(RSA_KEY, MAX_RSA_KEY_BYTES); |
1356 | 3 | TPM2B_RSA_KEY r; |
1357 | 3 | r.t.size = sizeof(n->size); |
1358 | | // If we are using a seed, then results must be reproducible on each |
1359 | | // call. Otherwise, just get a random number |
1360 | 3 | if(seed == NULL) |
1361 | 0 | _cpri__GenerateRandom(n->size, r.t.buffer); |
1362 | 3 | else |
1363 | 3 | { |
1364 | | // this this version does not have a deterministic RNG, XOR the |
1365 | | // public key and private exponent to get a deterministic value |
1366 | | // for testing. |
1367 | 3 | int i; |
1368 | | // Generate a random-ish number starting with the public modulus |
1369 | | // XORed with the MSO of the seed |
1370 | 643 | for(i = 0; i < n->size; i++) |
1371 | 640 | r.t.buffer[i] = n->buffer[i] ^ seed->buffer[0]; |
1372 | 3 | } |
1373 | | // Make sure that the number is smaller than the public modulus |
1374 | 3 | r.t.buffer[0] &= 0x7F; |
1375 | | // Convert |
1376 | 3 | if( BN_bin2bn(r.t.buffer, r.t.size, bnP) == NULL |
1377 | | // Encrypt with the public exponent |
1378 | 3 | || BN_mod_exp(bnQ, bnP, bnE, bnN, context) != 1 |
1379 | | // Decrypt with the private exponent |
1380 | 3 | || BN_mod_exp(bnQ, bnQ, bnT, bnN, context) != 1) |
1381 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
1382 | | // If the starting and ending values are not the same, start over )-; |
1383 | 3 | if(BN_ucmp(bnP, bnQ) != 0) |
1384 | 0 | { |
1385 | 0 | BN_zero(bnQ); |
1386 | 0 | continue; |
1387 | 0 | } |
1388 | 3 | } |
1389 | 3 | retVal = CRYPT_SUCCESS; |
1390 | 3 | goto Cleanup; |
1391 | 3 | } |
1392 | 0 | retVal = CRYPT_FAIL; |
1393 | 3 | Cleanup: |
1394 | | // Close out the hash sessions |
1395 | 3 | _cpri__CompleteHash(&h2, 0, NULL); |
1396 | 3 | _cpri__CompleteHash(&h1, 0, NULL); |
1397 | | // Free up allocated BN values |
1398 | 3 | BN_CTX_end(context); |
1399 | 3 | BN_CTX_free(context); |
1400 | 3 | if(counter != NULL) |
1401 | 3 | *counter = outer; |
1402 | 3 | return retVal; |
1403 | 0 | } |
1404 | | #endif // RSA_KEY_SIEVE |
1405 | | #endif // TPM_ALG_RSA |