"Fossies" - the Fresh Open Source Software Archive 
1 /*
2 Legal Notice: Some portions of the source code contained in this file were
3 derived from the source code of TrueCrypt 7.1a, which is
4 Copyright (c) 2003-2012 TrueCrypt Developers Association and which is
5 governed by the TrueCrypt License 3.0, also from the source code of
6 Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux
7 and which is governed by the 'License Agreement for Encryption for the Masses'
8 Modifications and additions to the original source code (contained in this file)
9 and all other portions of this file are Copyright (c) 2013-2017 IDRIX
10 and are governed by the Apache License 2.0 the full text of which is
11 contained in the file License.txt included in VeraCrypt binary and source
12 code distribution packages. */
13
14 #include "Tcdefs.h"
15 #if !defined(_UEFI)
16 #include <memory.h>
17 #include <stdlib.h>
18 #endif
19 #include "Rmd160.h"
20 #ifndef TC_WINDOWS_BOOT
21 #include "Sha2.h"
22 #include "Whirlpool.h"
23 #include "cpu.h"
24 #include "misc.h"
25 #else
26 #pragma optimize ("t", on)
27 #include <string.h>
28 #if defined( _MSC_VER )
29 # ifndef DEBUG
30 # pragma intrinsic( memcpy )
31 # pragma intrinsic( memset )
32 # endif
33 #endif
34 #include "Sha2Small.h"
35 #endif
36 #include "Pkcs5.h"
37 #include "Crypto.h"
38
39 #if !defined(TC_WINDOWS_BOOT) || defined(TC_WINDOWS_BOOT_SHA2)
40
41 typedef struct hmac_sha256_ctx_struct
42 {
43 sha256_ctx ctx;
44 sha256_ctx inner_digest_ctx; /*pre-computed inner digest context */
45 sha256_ctx outer_digest_ctx; /*pre-computed outer digest context */
46 char k[PKCS5_SALT_SIZE + 4]; /* enough to hold (salt_len + 4) and also the SHA256 hash */
47 char u[SHA256_DIGESTSIZE];
48 } hmac_sha256_ctx;
49
50 void hmac_sha256_internal
51 (
52 char *d, /* input data. d pointer is guaranteed to be at least 32-bytes long */
53 int ld, /* length of input data in bytes */
54 hmac_sha256_ctx* hmac /* HMAC-SHA256 context which holds temporary variables */
55 )
56 {
57 sha256_ctx* ctx = &(hmac->ctx);
58
59 /**** Restore Precomputed Inner Digest Context ****/
60
61 memcpy (ctx, &(hmac->inner_digest_ctx), sizeof (sha256_ctx));
62
63 sha256_hash ((unsigned char *) d, ld, ctx);
64
65 sha256_end ((unsigned char *) d, ctx); /* d = inner digest */
66
67 /**** Restore Precomputed Outer Digest Context ****/
68
69 memcpy (ctx, &(hmac->outer_digest_ctx), sizeof (sha256_ctx));
70
71 sha256_hash ((unsigned char *) d, SHA256_DIGESTSIZE, ctx);
72
73 sha256_end ((unsigned char *) d, ctx); /* d = outer digest */
74 }
75
76 #ifndef TC_WINDOWS_BOOT
77 void hmac_sha256
78 (
79 char *k, /* secret key */
80 int lk, /* length of the key in bytes */
81 char *d, /* data */
82 int ld /* length of data in bytes */
83 )
84 {
85 hmac_sha256_ctx hmac;
86 sha256_ctx* ctx;
87 char* buf = hmac.k;
88 int b;
89 char key[SHA256_DIGESTSIZE];
90 #if defined (DEVICE_DRIVER)
91 NTSTATUS saveStatus = STATUS_INVALID_PARAMETER;
92 #ifdef _WIN64
93 XSTATE_SAVE SaveState;
94 if (g_isIntel && HasSAVX())
95 saveStatus = KeSaveExtendedProcessorState(XSTATE_MASK_GSSE, &SaveState);
96 #else
97 KFLOATING_SAVE floatingPointState;
98 if (HasSSE2())
99 saveStatus = KeSaveFloatingPointState (&floatingPointState);
100 #endif
101 #endif
102 /* If the key is longer than the hash algorithm block size,
103 let key = sha256(key), as per HMAC specifications. */
104 if (lk > SHA256_BLOCKSIZE)
105 {
106 sha256_ctx tctx;
107
108 sha256_begin (&tctx);
109 sha256_hash ((unsigned char *) k, lk, &tctx);
110 sha256_end ((unsigned char *) key, &tctx);
111
112 k = key;
113 lk = SHA256_DIGESTSIZE;
114
115 burn (&tctx, sizeof(tctx)); // Prevent leaks
116 }
117
118 /**** Precompute HMAC Inner Digest ****/
119
120 ctx = &(hmac.inner_digest_ctx);
121 sha256_begin (ctx);
122
123 /* Pad the key for inner digest */
124 for (b = 0; b < lk; ++b)
125 buf[b] = (char) (k[b] ^ 0x36);
126 memset (&buf[lk], 0x36, SHA256_BLOCKSIZE - lk);
127
128 sha256_hash ((unsigned char *) buf, SHA256_BLOCKSIZE, ctx);
129
130 /**** Precompute HMAC Outer Digest ****/
131
132 ctx = &(hmac.outer_digest_ctx);
133 sha256_begin (ctx);
134
135 for (b = 0; b < lk; ++b)
136 buf[b] = (char) (k[b] ^ 0x5C);
137 memset (&buf[lk], 0x5C, SHA256_BLOCKSIZE - lk);
138
139 sha256_hash ((unsigned char *) buf, SHA256_BLOCKSIZE, ctx);
140
141 hmac_sha256_internal(d, ld, &hmac);
142
143 #if defined (DEVICE_DRIVER)
144 if (NT_SUCCESS (saveStatus))
145 #ifdef _WIN64
146 KeRestoreExtendedProcessorState(&SaveState);
147 #else
148 KeRestoreFloatingPointState (&floatingPointState);
149 #endif
150 #endif
151
152 /* Prevent leaks */
153 burn(&hmac, sizeof(hmac));
154 burn(key, sizeof(key));
155 }
156 #endif
157
158 static void derive_u_sha256 (char *salt, int salt_len, uint32 iterations, int b, hmac_sha256_ctx* hmac)
159 {
160 char* k = hmac->k;
161 char* u = hmac->u;
162 uint32 c;
163 int i;
164
165 #ifdef TC_WINDOWS_BOOT
166 /* In bootloader mode, least significant bit of iterations is a boolean (TRUE for boot derivation mode, FALSE otherwise)
167 * and the most significant 16 bits hold the pim value
168 * This enables us to save code space needed for implementing other features.
169 */
170 c = iterations >> 16;
171 i = ((int) iterations) & 0x01;
172 if (i)
173 c = (c == 0)? 200000 : c << 11;
174 else
175 c = (c == 0)? 500000 : 15000 + c * 1000;
176 #else
177 c = iterations;
178 #endif
179
180 /* iteration 1 */
181 memcpy (k, salt, salt_len); /* salt */
182
183 /* big-endian block number */
184 #ifdef TC_WINDOWS_BOOT
185 /* specific case of 16-bit bootloader: b is a 16-bit integer that is always < 256 */
186 memset (&k[salt_len], 0, 3);
187 k[salt_len + 3] = (char) b;
188 #else
189 b = bswap_32 (b);
190 memcpy (&k[salt_len], &b, 4);
191 #endif
192
193 hmac_sha256_internal (k, salt_len + 4, hmac);
194 memcpy (u, k, SHA256_DIGESTSIZE);
195
196 /* remaining iterations */
197 while (c > 1)
198 {
199 hmac_sha256_internal (k, SHA256_DIGESTSIZE, hmac);
200 for (i = 0; i < SHA256_DIGESTSIZE; i++)
201 {
202 u[i] ^= k[i];
203 }
204 c--;
205 }
206 }
207
208
209 void derive_key_sha256 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen)
210 {
211 hmac_sha256_ctx hmac;
212 sha256_ctx* ctx;
213 char* buf = hmac.k;
214 int b, l, r;
215 #ifndef TC_WINDOWS_BOOT
216 char key[SHA256_DIGESTSIZE];
217 #if defined (DEVICE_DRIVER)
218 NTSTATUS saveStatus = STATUS_INVALID_PARAMETER;
219 #ifdef _WIN64
220 XSTATE_SAVE SaveState;
221 if (g_isIntel && HasSAVX())
222 saveStatus = KeSaveExtendedProcessorState(XSTATE_MASK_GSSE, &SaveState);
223 #else
224 KFLOATING_SAVE floatingPointState;
225 if (HasSSE2())
226 saveStatus = KeSaveFloatingPointState (&floatingPointState);
227 #endif
228 #endif
229 /* If the password is longer than the hash algorithm block size,
230 let pwd = sha256(pwd), as per HMAC specifications. */
231 if (pwd_len > SHA256_BLOCKSIZE)
232 {
233 sha256_ctx tctx;
234
235 sha256_begin (&tctx);
236 sha256_hash ((unsigned char *) pwd, pwd_len, &tctx);
237 sha256_end ((unsigned char *) key, &tctx);
238
239 pwd = key;
240 pwd_len = SHA256_DIGESTSIZE;
241
242 burn (&tctx, sizeof(tctx)); // Prevent leaks
243 }
244 #endif
245
246 if (dklen % SHA256_DIGESTSIZE)
247 {
248 l = 1 + dklen / SHA256_DIGESTSIZE;
249 }
250 else
251 {
252 l = dklen / SHA256_DIGESTSIZE;
253 }
254
255 r = dklen - (l - 1) * SHA256_DIGESTSIZE;
256
257 /**** Precompute HMAC Inner Digest ****/
258
259 ctx = &(hmac.inner_digest_ctx);
260 sha256_begin (ctx);
261
262 /* Pad the key for inner digest */
263 for (b = 0; b < pwd_len; ++b)
264 buf[b] = (char) (pwd[b] ^ 0x36);
265 memset (&buf[pwd_len], 0x36, SHA256_BLOCKSIZE - pwd_len);
266
267 sha256_hash ((unsigned char *) buf, SHA256_BLOCKSIZE, ctx);
268
269 /**** Precompute HMAC Outer Digest ****/
270
271 ctx = &(hmac.outer_digest_ctx);
272 sha256_begin (ctx);
273
274 for (b = 0; b < pwd_len; ++b)
275 buf[b] = (char) (pwd[b] ^ 0x5C);
276 memset (&buf[pwd_len], 0x5C, SHA256_BLOCKSIZE - pwd_len);
277
278 sha256_hash ((unsigned char *) buf, SHA256_BLOCKSIZE, ctx);
279
280 /* first l - 1 blocks */
281 for (b = 1; b < l; b++)
282 {
283 derive_u_sha256 (salt, salt_len, iterations, b, &hmac);
284 memcpy (dk, hmac.u, SHA256_DIGESTSIZE);
285 dk += SHA256_DIGESTSIZE;
286 }
287
288 /* last block */
289 derive_u_sha256 (salt, salt_len, iterations, b, &hmac);
290 memcpy (dk, hmac.u, r);
291
292 #if defined (DEVICE_DRIVER)
293 if (NT_SUCCESS (saveStatus))
294 #ifdef _WIN64
295 KeRestoreExtendedProcessorState(&SaveState);
296 #else
297 KeRestoreFloatingPointState (&floatingPointState);
298 #endif
299 #endif
300
301 /* Prevent possible leaks. */
302 burn (&hmac, sizeof(hmac));
303 #ifndef TC_WINDOWS_BOOT
304 burn (key, sizeof(key));
305 #endif
306 }
307
308 #endif
309
310 #ifndef TC_WINDOWS_BOOT
311
312 typedef struct hmac_sha512_ctx_struct
313 {
314 sha512_ctx ctx;
315 sha512_ctx inner_digest_ctx; /*pre-computed inner digest context */
316 sha512_ctx outer_digest_ctx; /*pre-computed outer digest context */
317 char k[SHA512_BLOCKSIZE]; /* enough to hold (salt_len + 4) and also the SHA512 hash */
318 char u[SHA512_DIGESTSIZE];
319 } hmac_sha512_ctx;
320
321 void hmac_sha512_internal
322 (
323 char *d, /* data and also output buffer of at least 64 bytes */
324 int ld, /* length of data in bytes */
325 hmac_sha512_ctx* hmac
326 )
327 {
328 sha512_ctx* ctx = &(hmac->ctx);
329
330 /**** Restore Precomputed Inner Digest Context ****/
331
332 memcpy (ctx, &(hmac->inner_digest_ctx), sizeof (sha512_ctx));
333
334 sha512_hash ((unsigned char *) d, ld, ctx);
335
336 sha512_end ((unsigned char *) d, ctx);
337
338 /**** Restore Precomputed Outer Digest Context ****/
339
340 memcpy (ctx, &(hmac->outer_digest_ctx), sizeof (sha512_ctx));
341
342 sha512_hash ((unsigned char *) d, SHA512_DIGESTSIZE, ctx);
343
344 sha512_end ((unsigned char *) d, ctx);
345 }
346
347 void hmac_sha512
348 (
349 char *k, /* secret key */
350 int lk, /* length of the key in bytes */
351 char *d, /* data and also output buffer of at least 64 bytes */
352 int ld /* length of data in bytes */
353 )
354 {
355 hmac_sha512_ctx hmac;
356 sha512_ctx* ctx;
357 char* buf = hmac.k;
358 int b;
359 char key[SHA512_DIGESTSIZE];
360 #if defined (DEVICE_DRIVER)
361 NTSTATUS saveStatus = STATUS_INVALID_PARAMETER;
362 #ifdef _WIN64
363 XSTATE_SAVE SaveState;
364 if (g_isIntel && HasSAVX())
365 saveStatus = KeSaveExtendedProcessorState(XSTATE_MASK_GSSE, &SaveState);
366 #else
367 KFLOATING_SAVE floatingPointState;
368 if (HasSSSE3() && HasMMX())
369 saveStatus = KeSaveFloatingPointState (&floatingPointState);
370 #endif
371 #endif
372
373 /* If the key is longer than the hash algorithm block size,
374 let key = sha512(key), as per HMAC specifications. */
375 if (lk > SHA512_BLOCKSIZE)
376 {
377 sha512_ctx tctx;
378
379 sha512_begin (&tctx);
380 sha512_hash ((unsigned char *) k, lk, &tctx);
381 sha512_end ((unsigned char *) key, &tctx);
382
383 k = key;
384 lk = SHA512_DIGESTSIZE;
385
386 burn (&tctx, sizeof(tctx)); // Prevent leaks
387 }
388
389 /**** Precompute HMAC Inner Digest ****/
390
391 ctx = &(hmac.inner_digest_ctx);
392 sha512_begin (ctx);
393
394 /* Pad the key for inner digest */
395 for (b = 0; b < lk; ++b)
396 buf[b] = (char) (k[b] ^ 0x36);
397 memset (&buf[lk], 0x36, SHA512_BLOCKSIZE - lk);
398
399 sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, ctx);
400
401 /**** Precompute HMAC Outer Digest ****/
402
403 ctx = &(hmac.outer_digest_ctx);
404 sha512_begin (ctx);
405
406 for (b = 0; b < lk; ++b)
407 buf[b] = (char) (k[b] ^ 0x5C);
408 memset (&buf[lk], 0x5C, SHA512_BLOCKSIZE - lk);
409
410 sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, ctx);
411
412 hmac_sha512_internal (d, ld, &hmac);
413
414 #if defined (DEVICE_DRIVER)
415 if (NT_SUCCESS (saveStatus))
416 #ifdef _WIN64
417 KeRestoreExtendedProcessorState(&SaveState);
418 #else
419 KeRestoreFloatingPointState (&floatingPointState);
420 #endif
421 #endif
422
423 /* Prevent leaks */
424 burn (&hmac, sizeof(hmac));
425 burn (key, sizeof(key));
426 }
427
428 static void derive_u_sha512 (char *salt, int salt_len, uint32 iterations, int b, hmac_sha512_ctx* hmac)
429 {
430 char* k = hmac->k;
431 char* u = hmac->u;
432 uint32 c, i;
433
434 /* iteration 1 */
435 memcpy (k, salt, salt_len); /* salt */
436 /* big-endian block number */
437 b = bswap_32 (b);
438 memcpy (&k[salt_len], &b, 4);
439
440 hmac_sha512_internal (k, salt_len + 4, hmac);
441 memcpy (u, k, SHA512_DIGESTSIZE);
442
443 /* remaining iterations */
444 for (c = 1; c < iterations; c++)
445 {
446 hmac_sha512_internal (k, SHA512_DIGESTSIZE, hmac);
447 for (i = 0; i < SHA512_DIGESTSIZE; i++)
448 {
449 u[i] ^= k[i];
450 }
451 }
452 }
453
454
455 void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen)
456 {
457 hmac_sha512_ctx hmac;
458 sha512_ctx* ctx;
459 char* buf = hmac.k;
460 int b, l, r;
461 char key[SHA512_DIGESTSIZE];
462 #if defined (DEVICE_DRIVER)
463 NTSTATUS saveStatus = STATUS_INVALID_PARAMETER;
464 #ifdef _WIN64
465 XSTATE_SAVE SaveState;
466 if (g_isIntel && HasSAVX())
467 saveStatus = KeSaveExtendedProcessorState(XSTATE_MASK_GSSE, &SaveState);
468 #else
469 KFLOATING_SAVE floatingPointState;
470 if (HasSSSE3() && HasMMX())
471 saveStatus = KeSaveFloatingPointState (&floatingPointState);
472 #endif
473 #endif
474
475 /* If the password is longer than the hash algorithm block size,
476 let pwd = sha512(pwd), as per HMAC specifications. */
477 if (pwd_len > SHA512_BLOCKSIZE)
478 {
479 sha512_ctx tctx;
480
481 sha512_begin (&tctx);
482 sha512_hash ((unsigned char *) pwd, pwd_len, &tctx);
483 sha512_end ((unsigned char *) key, &tctx);
484
485 pwd = key;
486 pwd_len = SHA512_DIGESTSIZE;
487
488 burn (&tctx, sizeof(tctx)); // Prevent leaks
489 }
490
491 if (dklen % SHA512_DIGESTSIZE)
492 {
493 l = 1 + dklen / SHA512_DIGESTSIZE;
494 }
495 else
496 {
497 l = dklen / SHA512_DIGESTSIZE;
498 }
499
500 r = dklen - (l - 1) * SHA512_DIGESTSIZE;
501
502 /**** Precompute HMAC Inner Digest ****/
503
504 ctx = &(hmac.inner_digest_ctx);
505 sha512_begin (ctx);
506
507 /* Pad the key for inner digest */
508 for (b = 0; b < pwd_len; ++b)
509 buf[b] = (char) (pwd[b] ^ 0x36);
510 memset (&buf[pwd_len], 0x36, SHA512_BLOCKSIZE - pwd_len);
511
512 sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, ctx);
513
514 /**** Precompute HMAC Outer Digest ****/
515
516 ctx = &(hmac.outer_digest_ctx);
517 sha512_begin (ctx);
518
519 for (b = 0; b < pwd_len; ++b)
520 buf[b] = (char) (pwd[b] ^ 0x5C);
521 memset (&buf[pwd_len], 0x5C, SHA512_BLOCKSIZE - pwd_len);
522
523 sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, ctx);
524
525 /* first l - 1 blocks */
526 for (b = 1; b < l; b++)
527 {
528 derive_u_sha512 (salt, salt_len, iterations, b, &hmac);
529 memcpy (dk, hmac.u, SHA512_DIGESTSIZE);
530 dk += SHA512_DIGESTSIZE;
531 }
532
533 /* last block */
534 derive_u_sha512 (salt, salt_len, iterations, b, &hmac);
535 memcpy (dk, hmac.u, r);
536
537 #if defined (DEVICE_DRIVER)
538 if (NT_SUCCESS (saveStatus))
539 #ifdef _WIN64
540 KeRestoreExtendedProcessorState(&SaveState);
541 #else
542 KeRestoreFloatingPointState (&floatingPointState);
543 #endif
544 #endif
545
546 /* Prevent possible leaks. */
547 burn (&hmac, sizeof(hmac));
548 burn (key, sizeof(key));
549 }
550
551 #endif // TC_WINDOWS_BOOT
552
553 #if !defined(TC_WINDOWS_BOOT) || defined(TC_WINDOWS_BOOT_RIPEMD160)
554
555 typedef struct hmac_ripemd160_ctx_struct
556 {
557 RMD160_CTX context;
558 RMD160_CTX inner_digest_ctx; /*pre-computed inner digest context */
559 RMD160_CTX outer_digest_ctx; /*pre-computed outer digest context */
560 char k[PKCS5_SALT_SIZE + 4]; /* enough to hold (salt_len + 4) and also the RIPEMD-160 hash */
561 char u[RIPEMD160_DIGESTSIZE];
562 } hmac_ripemd160_ctx;
563
564 void hmac_ripemd160_internal (char *input_digest, int len, hmac_ripemd160_ctx* hmac)
565 {
566 RMD160_CTX* context = &(hmac->context);
567
568 /**** Restore Precomputed Inner Digest Context ****/
569
570 memcpy (context, &(hmac->inner_digest_ctx), sizeof (RMD160_CTX));
571
572 RMD160Update(context, (const unsigned char *) input_digest, len); /* then text of datagram */
573 RMD160Final((unsigned char *) input_digest, context); /* finish up 1st pass */
574
575 /**** Restore Precomputed Outer Digest Context ****/
576
577 memcpy (context, &(hmac->outer_digest_ctx), sizeof (RMD160_CTX));
578
579 /* results of 1st hash */
580 RMD160Update(context, (const unsigned char *) input_digest, RIPEMD160_DIGESTSIZE);
581 RMD160Final((unsigned char *) input_digest, context); /* finish up 2nd pass */
582 }
583
584 #ifndef TC_WINDOWS_BOOT
585 void hmac_ripemd160 (char *key, int keylen, char *input_digest, int len)
586 {
587 hmac_ripemd160_ctx hmac;
588 RMD160_CTX* ctx;
589 unsigned char* k_pad = (unsigned char*) hmac.k; /* inner/outer padding - key XORd with ipad */
590 unsigned char tk[RIPEMD160_DIGESTSIZE];
591 int i;
592
593 /* If the key is longer than the hash algorithm block size,
594 let key = ripemd160(key), as per HMAC specifications. */
595 if (keylen > RIPEMD160_BLOCKSIZE)
596 {
597 RMD160_CTX tctx;
598
599 RMD160Init(&tctx);
600 RMD160Update(&tctx, (const unsigned char *) key, keylen);
601 RMD160Final(tk, &tctx);
602
603 key = (char *) tk;
604 keylen = RIPEMD160_DIGESTSIZE;
605
606 burn (&tctx, sizeof(tctx)); // Prevent leaks
607 }
608
609 /* perform inner RIPEMD-160 */
610 ctx = &(hmac.inner_digest_ctx);
611 /* start out by storing key in pads */
612 memset(k_pad, 0x36, 64);
613 /* XOR key with ipad and opad values */
614 for (i=0; i<keylen; i++)
615 {
616 k_pad[i] ^= key[i];
617 }
618
619 RMD160Init(ctx); /* init context for 1st pass */
620 RMD160Update(ctx, k_pad, RIPEMD160_BLOCKSIZE); /* start with inner pad */
621
622 /* perform outer RIPEMD-160 */
623 ctx = &(hmac.outer_digest_ctx);
624 memset(k_pad, 0x5c, 64);
625 for (i=0; i<keylen; i++)
626 {
627 k_pad[i] ^= key[i];
628 }
629
630 RMD160Init(ctx); /* init context for 2nd pass */
631 RMD160Update(ctx, k_pad, RIPEMD160_BLOCKSIZE); /* start with outer pad */
632
633 hmac_ripemd160_internal (input_digest, len, &hmac);
634
635 burn (&hmac, sizeof(hmac));
636 burn (tk, sizeof(tk));
637 }
638 #endif
639
640
641 static void derive_u_ripemd160 (char *salt, int salt_len, uint32 iterations, int b, hmac_ripemd160_ctx* hmac)
642 {
643 char* k = hmac->k;
644 char* u = hmac->u;
645 uint32 c;
646 int i;
647
648 #ifdef TC_WINDOWS_BOOT
649 /* In bootloader mode, least significant bit of iterations is a boolean (TRUE for boot derivation mode, FALSE otherwise)
650 * and the most significant 16 bits hold the pim value
651 * This enables us to save code space needed for implementing other features.
652 */
653 c = iterations >> 16;
654 i = ((int) iterations) & 0x01;
655 if (i)
656 c = (c == 0)? 327661 : c << 11;
657 else
658 c = (c == 0)? 655331 : 15000 + c * 1000;
659 #else
660 c = iterations;
661 #endif
662
663 /* iteration 1 */
664 memcpy (k, salt, salt_len); /* salt */
665
666 /* big-endian block number */
667 #ifdef TC_WINDOWS_BOOT
668 /* specific case of 16-bit bootloader: b is a 16-bit integer that is always < 256*/
669 memset (&k[salt_len], 0, 3);
670 k[salt_len + 3] = (char) b;
671 #else
672 b = bswap_32 (b);
673 memcpy (&k[salt_len], &b, 4);
674 #endif
675
676 hmac_ripemd160_internal (k, salt_len + 4, hmac);
677 memcpy (u, k, RIPEMD160_DIGESTSIZE);
678
679 /* remaining iterations */
680 while ( c > 1)
681 {
682 hmac_ripemd160_internal (k, RIPEMD160_DIGESTSIZE, hmac);
683 for (i = 0; i < RIPEMD160_DIGESTSIZE; i++)
684 {
685 u[i] ^= k[i];
686 }
687 c--;
688 }
689 }
690
691 void derive_key_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen)
692 {
693 int b, l, r;
694 hmac_ripemd160_ctx hmac;
695 RMD160_CTX* ctx;
696 unsigned char* k_pad = (unsigned char*) hmac.k;
697 #ifndef TC_WINDOWS_BOOT
698 unsigned char tk[RIPEMD160_DIGESTSIZE];
699 /* If the password is longer than the hash algorithm block size,
700 let password = ripemd160(password), as per HMAC specifications. */
701 if (pwd_len > RIPEMD160_BLOCKSIZE)
702 {
703 RMD160_CTX tctx;
704
705 RMD160Init(&tctx);
706 RMD160Update(&tctx, (const unsigned char *) pwd, pwd_len);
707 RMD160Final(tk, &tctx);
708
709 pwd = (char *) tk;
710 pwd_len = RIPEMD160_DIGESTSIZE;
711
712 burn (&tctx, sizeof(tctx)); // Prevent leaks
713 }
714 #endif
715
716 if (dklen % RIPEMD160_DIGESTSIZE)
717 {
718 l = 1 + dklen / RIPEMD160_DIGESTSIZE;
719 }
720 else
721 {
722 l = dklen / RIPEMD160_DIGESTSIZE;
723 }
724
725 r = dklen - (l - 1) * RIPEMD160_DIGESTSIZE;
726
727 /* perform inner RIPEMD-160 */
728 ctx = &(hmac.inner_digest_ctx);
729 /* start out by storing key in pads */
730 memset(k_pad, 0x36, 64);
731 /* XOR key with ipad and opad values */
732 for (b=0; b<pwd_len; b++)
733 {
734 k_pad[b] ^= pwd[b];
735 }
736
737 RMD160Init(ctx); /* init context for 1st pass */
738 RMD160Update(ctx, k_pad, RIPEMD160_BLOCKSIZE); /* start with inner pad */
739
740 /* perform outer RIPEMD-160 */
741 ctx = &(hmac.outer_digest_ctx);
742 memset(k_pad, 0x5c, 64);
743 for (b=0; b<pwd_len; b++)
744 {
745 k_pad[b] ^= pwd[b];
746 }
747
748 RMD160Init(ctx); /* init context for 2nd pass */
749 RMD160Update(ctx, k_pad, RIPEMD160_BLOCKSIZE); /* start with outer pad */
750
751 /* first l - 1 blocks */
752 for (b = 1; b < l; b++)
753 {
754 derive_u_ripemd160 (salt, salt_len, iterations, b, &hmac);
755 memcpy (dk, hmac.u, RIPEMD160_DIGESTSIZE);
756 dk += RIPEMD160_DIGESTSIZE;
757 }
758
759 /* last block */
760 derive_u_ripemd160 (salt, salt_len, iterations, b, &hmac);
761 memcpy (dk, hmac.u, r);
762
763
764 /* Prevent possible leaks. */
765 burn (&hmac, sizeof(hmac));
766 #ifndef TC_WINDOWS_BOOT
767 burn (tk, sizeof(tk));
768 #endif
769 }
770 #endif // TC_WINDOWS_BOOT
771
772 #ifndef TC_WINDOWS_BOOT
773
774 typedef struct hmac_whirlpool_ctx_struct
775 {
776 WHIRLPOOL_CTX ctx;
777 WHIRLPOOL_CTX inner_digest_ctx; /*pre-computed inner digest context */
778 WHIRLPOOL_CTX outer_digest_ctx; /*pre-computed outer digest context */
779 CRYPTOPP_ALIGN_DATA(16) char k[PKCS5_SALT_SIZE + 4]; /* enough to hold (salt_len + 4) and also the Whirlpool hash */
780 char u[WHIRLPOOL_DIGESTSIZE];
781 } hmac_whirlpool_ctx;
782
783 void hmac_whirlpool_internal
784 (
785 char *d, /* input/output data. d pointer is guaranteed to be at least 64-bytes long */
786 int ld, /* length of input data in bytes */
787 hmac_whirlpool_ctx* hmac /* HMAC-Whirlpool context which holds temporary variables */
788 )
789 {
790 WHIRLPOOL_CTX* ctx = &(hmac->ctx);
791
792 /**** Restore Precomputed Inner Digest Context ****/
793
794 memcpy (ctx, &(hmac->inner_digest_ctx), sizeof (WHIRLPOOL_CTX));
795
796 WHIRLPOOL_add ((unsigned char *) d, ld, ctx);
797
798 WHIRLPOOL_finalize (ctx, (unsigned char *) d);
799
800 /**** Restore Precomputed Outer Digest Context ****/
801
802 memcpy (ctx, &(hmac->outer_digest_ctx), sizeof (WHIRLPOOL_CTX));
803
804 WHIRLPOOL_add ((unsigned char *) d, WHIRLPOOL_DIGESTSIZE, ctx);
805
806 WHIRLPOOL_finalize (ctx, (unsigned char *) d);
807 }
808
809 void hmac_whirlpool
810 (
811 char *k, /* secret key */
812 int lk, /* length of the key in bytes */
813 char *d, /* input data. d pointer is guaranteed to be at least 32-bytes long */
814 int ld /* length of data in bytes */
815 )
816 {
817 hmac_whirlpool_ctx hmac;
818 WHIRLPOOL_CTX* ctx;
819 char* buf = hmac.k;
820 int b;
821 char key[WHIRLPOOL_DIGESTSIZE];
822 #if defined (DEVICE_DRIVER) && !defined (_WIN64)
823 KFLOATING_SAVE floatingPointState;
824 NTSTATUS saveStatus = STATUS_INVALID_PARAMETER;
825 if (HasISSE())
826 saveStatus = KeSaveFloatingPointState (&floatingPointState);
827 #endif
828 /* If the key is longer than the hash algorithm block size,
829 let key = whirlpool(key), as per HMAC specifications. */
830 if (lk > WHIRLPOOL_BLOCKSIZE)
831 {
832 WHIRLPOOL_CTX tctx;
833
834 WHIRLPOOL_init (&tctx);
835 WHIRLPOOL_add ((unsigned char *) k, lk, &tctx);
836 WHIRLPOOL_finalize (&tctx, (unsigned char *) key);
837
838 k = key;
839 lk = WHIRLPOOL_DIGESTSIZE;
840
841 burn (&tctx, sizeof(tctx)); // Prevent leaks
842 }
843
844 /**** Precompute HMAC Inner Digest ****/
845
846 ctx = &(hmac.inner_digest_ctx);
847 WHIRLPOOL_init (ctx);
848
849 /* Pad the key for inner digest */
850 for (b = 0; b < lk; ++b)
851 buf[b] = (char) (k[b] ^ 0x36);
852 memset (&buf[lk], 0x36, WHIRLPOOL_BLOCKSIZE - lk);
853
854 WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE, ctx);
855
856 /**** Precompute HMAC Outer Digest ****/
857
858 ctx = &(hmac.outer_digest_ctx);
859 WHIRLPOOL_init (ctx);
860
861 for (b = 0; b < lk; ++b)
862 buf[b] = (char) (k[b] ^ 0x5C);
863 memset (&buf[lk], 0x5C, WHIRLPOOL_BLOCKSIZE - lk);
864
865 WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE, ctx);
866
867 hmac_whirlpool_internal(d, ld, &hmac);
868
869 #if defined (DEVICE_DRIVER) && !defined (_WIN64)
870 if (NT_SUCCESS (saveStatus))
871 KeRestoreFloatingPointState (&floatingPointState);
872 #endif
873 /* Prevent leaks */
874 burn(&hmac, sizeof(hmac));
875 }
876
877 static void derive_u_whirlpool (char *salt, int salt_len, uint32 iterations, int b, hmac_whirlpool_ctx* hmac)
878 {
879 char* u = hmac->u;
880 char* k = hmac->k;
881 uint32 c, i;
882
883 /* iteration 1 */
884 memcpy (k, salt, salt_len); /* salt */
885 /* big-endian block number */
886 b = bswap_32 (b);
887 memcpy (&k[salt_len], &b, 4);
888
889 hmac_whirlpool_internal (k, salt_len + 4, hmac);
890 memcpy (u, k, WHIRLPOOL_DIGESTSIZE);
891
892 /* remaining iterations */
893 for (c = 1; c < iterations; c++)
894 {
895 hmac_whirlpool_internal (k, WHIRLPOOL_DIGESTSIZE, hmac);
896 for (i = 0; i < WHIRLPOOL_DIGESTSIZE; i++)
897 {
898 u[i] ^= k[i];
899 }
900 }
901 }
902
903 void derive_key_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen)
904 {
905 hmac_whirlpool_ctx hmac;
906 WHIRLPOOL_CTX* ctx;
907 char* buf = hmac.k;
908 char key[WHIRLPOOL_DIGESTSIZE];
909 int b, l, r;
910 #if defined (DEVICE_DRIVER) && !defined (_WIN64)
911 KFLOATING_SAVE floatingPointState;
912 NTSTATUS saveStatus = STATUS_INVALID_PARAMETER;
913 if (HasISSE())
914 saveStatus = KeSaveFloatingPointState (&floatingPointState);
915 #endif
916 /* If the password is longer than the hash algorithm block size,
917 let pwd = whirlpool(pwd), as per HMAC specifications. */
918 if (pwd_len > WHIRLPOOL_BLOCKSIZE)
919 {
920 WHIRLPOOL_CTX tctx;
921
922 WHIRLPOOL_init (&tctx);
923 WHIRLPOOL_add ((unsigned char *) pwd, pwd_len, &tctx);
924 WHIRLPOOL_finalize (&tctx, (unsigned char *) key);
925
926 pwd = key;
927 pwd_len = WHIRLPOOL_DIGESTSIZE;
928
929 burn (&tctx, sizeof(tctx)); // Prevent leaks
930 }
931
932 if (dklen % WHIRLPOOL_DIGESTSIZE)
933 {
934 l = 1 + dklen / WHIRLPOOL_DIGESTSIZE;
935 }
936 else
937 {
938 l = dklen / WHIRLPOOL_DIGESTSIZE;
939 }
940
941 r = dklen - (l - 1) * WHIRLPOOL_DIGESTSIZE;
942
943 /**** Precompute HMAC Inner Digest ****/
944
945 ctx = &(hmac.inner_digest_ctx);
946 WHIRLPOOL_init (ctx);
947
948 /* Pad the key for inner digest */
949 for (b = 0; b < pwd_len; ++b)
950 buf[b] = (char) (pwd[b] ^ 0x36);
951 memset (&buf[pwd_len], 0x36, WHIRLPOOL_BLOCKSIZE - pwd_len);
952
953 WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE, ctx);
954
955 /**** Precompute HMAC Outer Digest ****/
956
957 ctx = &(hmac.outer_digest_ctx);
958 WHIRLPOOL_init (ctx);
959
960 for (b = 0; b < pwd_len; ++b)
961 buf[b] = (char) (pwd[b] ^ 0x5C);
962 memset (&buf[pwd_len], 0x5C, WHIRLPOOL_BLOCKSIZE - pwd_len);
963
964 WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE, ctx);
965
966 /* first l - 1 blocks */
967 for (b = 1; b < l; b++)
968 {
969 derive_u_whirlpool (salt, salt_len, iterations, b, &hmac);
970 memcpy (dk, hmac.u, WHIRLPOOL_DIGESTSIZE);
971 dk += WHIRLPOOL_DIGESTSIZE;
972 }
973
974 /* last block */
975 derive_u_whirlpool (salt, salt_len, iterations, b, &hmac);
976 memcpy (dk, hmac.u, r);
977
978 #if defined (DEVICE_DRIVER) && !defined (_WIN64)
979 if (NT_SUCCESS (saveStatus))
980 KeRestoreFloatingPointState (&floatingPointState);
981 #endif
982
983 /* Prevent possible leaks. */
984 burn (&hmac, sizeof(hmac));
985 burn (key, sizeof(key));
986 }
987
988
989 typedef struct hmac_streebog_ctx_struct
990 {
991 STREEBOG_CTX ctx;
992 STREEBOG_CTX inner_digest_ctx; /*pre-computed inner digest context */
993 STREEBOG_CTX outer_digest_ctx; /*pre-computed outer digest context */
994 CRYPTOPP_ALIGN_DATA(16) char k[PKCS5_SALT_SIZE + 4]; /* enough to hold (salt_len + 4) and also the Streebog hash */
995 char u[STREEBOG_DIGESTSIZE];
996 } hmac_streebog_ctx;
997
998 void hmac_streebog_internal
999 (
1000 char *d, /* input/output data. d pointer is guaranteed to be at least 64-bytes long */
1001 int ld, /* length of input data in bytes */
1002 hmac_streebog_ctx* hmac /* HMAC-Whirlpool context which holds temporary variables */
1003 )
1004 {
1005 STREEBOG_CTX* ctx = &(hmac->ctx);
1006
1007 /**** Restore Precomputed Inner Digest Context ****/
1008
1009 memcpy (ctx, &(hmac->inner_digest_ctx), sizeof (STREEBOG_CTX));
1010
1011 STREEBOG_add (ctx, (unsigned char *) d, ld);
1012
1013 STREEBOG_finalize (ctx, (unsigned char *) d);
1014
1015 /**** Restore Precomputed Outer Digest Context ****/
1016
1017 memcpy (ctx, &(hmac->outer_digest_ctx), sizeof (STREEBOG_CTX));
1018
1019 STREEBOG_add (ctx, (unsigned char *) d, STREEBOG_DIGESTSIZE);
1020
1021 STREEBOG_finalize (ctx, (unsigned char *) d);
1022 }
1023
1024 void hmac_streebog
1025 (
1026 char *k, /* secret key */
1027 int lk, /* length of the key in bytes */
1028 char *d, /* input data. d pointer is guaranteed to be at least 32-bytes long */
1029 int ld /* length of data in bytes */
1030 )
1031 {
1032 hmac_streebog_ctx hmac;
1033 STREEBOG_CTX* ctx;
1034 char* buf = hmac.k;
1035 int b;
1036 CRYPTOPP_ALIGN_DATA(16) char key[STREEBOG_DIGESTSIZE];
1037 #if defined (DEVICE_DRIVER) && !defined (_WIN64)
1038 KFLOATING_SAVE floatingPointState;
1039 NTSTATUS saveStatus = STATUS_INVALID_PARAMETER;
1040 if (HasSSE2() || HasSSE41())
1041 saveStatus = KeSaveFloatingPointState (&floatingPointState);
1042 #endif
1043 /* If the key is longer than the hash algorithm block size,
1044 let key = streebog(key), as per HMAC specifications. */
1045 if (lk > STREEBOG_BLOCKSIZE)
1046 {
1047 STREEBOG_CTX tctx;
1048
1049 STREEBOG_init (&tctx);
1050 STREEBOG_add (&tctx, (unsigned char *) k, lk);
1051 STREEBOG_finalize (&tctx, (unsigned char *) key);
1052
1053 k = key;
1054 lk = STREEBOG_DIGESTSIZE;
1055
1056 burn (&tctx, sizeof(tctx)); // Prevent leaks
1057 }
1058
1059 /**** Precompute HMAC Inner Digest ****/
1060
1061 ctx = &(hmac.inner_digest_ctx);
1062 STREEBOG_init (ctx);
1063
1064 /* Pad the key for inner digest */
1065 for (b = 0; b < lk; ++b)
1066 buf[b] = (char) (k[b] ^ 0x36);
1067 memset (&buf[lk], 0x36, STREEBOG_BLOCKSIZE - lk);
1068
1069 STREEBOG_add (ctx, (unsigned char *) buf, STREEBOG_BLOCKSIZE);
1070
1071 /**** Precompute HMAC Outer Digest ****/
1072
1073 ctx = &(hmac.outer_digest_ctx);
1074 STREEBOG_init (ctx);
1075
1076 for (b = 0; b < lk; ++b)
1077 buf[b] = (char) (k[b] ^ 0x5C);
1078 memset (&buf[lk], 0x5C, STREEBOG_BLOCKSIZE - lk);
1079
1080 STREEBOG_add (ctx, (unsigned char *) buf, STREEBOG_BLOCKSIZE);
1081
1082 hmac_streebog_internal(d, ld, &hmac);
1083
1084 #if defined (DEVICE_DRIVER) && !defined (_WIN64)
1085 if (NT_SUCCESS (saveStatus))
1086 KeRestoreFloatingPointState (&floatingPointState);
1087 #endif
1088 /* Prevent leaks */
1089 burn(&hmac, sizeof(hmac));
1090 }
1091
1092 static void derive_u_streebog (char *salt, int salt_len, uint32 iterations, int b, hmac_streebog_ctx* hmac)
1093 {
1094 char* u = hmac->u;
1095 char* k = hmac->k;
1096 uint32 c, i;
1097
1098 /* iteration 1 */
1099 memcpy (k, salt, salt_len); /* salt */
1100 /* big-endian block number */
1101 b = bswap_32 (b);
1102 memcpy (&k[salt_len], &b, 4);
1103
1104 hmac_streebog_internal (k, salt_len + 4, hmac);
1105 memcpy (u, k, STREEBOG_DIGESTSIZE);
1106
1107 /* remaining iterations */
1108 for (c = 1; c < iterations; c++)
1109 {
1110 hmac_streebog_internal (k, STREEBOG_DIGESTSIZE, hmac);
1111 for (i = 0; i < STREEBOG_DIGESTSIZE; i++)
1112 {
1113 u[i] ^= k[i];
1114 }
1115 }
1116 }
1117
1118 void derive_key_streebog (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen)
1119 {
1120 hmac_streebog_ctx hmac;
1121 STREEBOG_CTX* ctx;
1122 char* buf = hmac.k;
1123 char key[STREEBOG_DIGESTSIZE];
1124 int b, l, r;
1125 #if defined (DEVICE_DRIVER) && !defined (_WIN64)
1126 KFLOATING_SAVE floatingPointState;
1127 NTSTATUS saveStatus = STATUS_INVALID_PARAMETER;
1128 if (HasSSE2() || HasSSE41())
1129 saveStatus = KeSaveFloatingPointState (&floatingPointState);
1130 #endif
1131 /* If the password is longer than the hash algorithm block size,
1132 let pwd = streebog(pwd), as per HMAC specifications. */
1133 if (pwd_len > STREEBOG_BLOCKSIZE)
1134 {
1135 STREEBOG_CTX tctx;
1136
1137 STREEBOG_init (&tctx);
1138 STREEBOG_add (&tctx, (unsigned char *) pwd, pwd_len);
1139 STREEBOG_finalize (&tctx, (unsigned char *) key);
1140
1141 pwd = key;
1142 pwd_len = STREEBOG_DIGESTSIZE;
1143
1144 burn (&tctx, sizeof(tctx)); // Prevent leaks
1145 }
1146
1147 if (dklen % STREEBOG_DIGESTSIZE)
1148 {
1149 l = 1 + dklen / STREEBOG_DIGESTSIZE;
1150 }
1151 else
1152 {
1153 l = dklen / STREEBOG_DIGESTSIZE;
1154 }
1155
1156 r = dklen - (l - 1) * STREEBOG_DIGESTSIZE;
1157
1158 /**** Precompute HMAC Inner Digest ****/
1159
1160 ctx = &(hmac.inner_digest_ctx);
1161 STREEBOG_init (ctx);
1162
1163 /* Pad the key for inner digest */
1164 for (b = 0; b < pwd_len; ++b)
1165 buf[b] = (char) (pwd[b] ^ 0x36);
1166 memset (&buf[pwd_len], 0x36, STREEBOG_BLOCKSIZE - pwd_len);
1167
1168 STREEBOG_add (ctx, (unsigned char *) buf, STREEBOG_BLOCKSIZE);
1169
1170 /**** Precompute HMAC Outer Digest ****/
1171
1172 ctx = &(hmac.outer_digest_ctx);
1173 STREEBOG_init (ctx);
1174
1175 for (b = 0; b < pwd_len; ++b)
1176 buf[b] = (char) (pwd[b] ^ 0x5C);
1177 memset (&buf[pwd_len], 0x5C, STREEBOG_BLOCKSIZE - pwd_len);
1178
1179 STREEBOG_add (ctx, (unsigned char *) buf, STREEBOG_BLOCKSIZE);
1180
1181 /* first l - 1 blocks */
1182 for (b = 1; b < l; b++)
1183 {
1184 derive_u_streebog (salt, salt_len, iterations, b, &hmac);
1185 memcpy (dk, hmac.u, STREEBOG_DIGESTSIZE);
1186 dk += STREEBOG_DIGESTSIZE;
1187 }
1188
1189 /* last block */
1190 derive_u_streebog (salt, salt_len, iterations, b, &hmac);
1191 memcpy (dk, hmac.u, r);
1192
1193 #if defined (DEVICE_DRIVER) && !defined (_WIN64)
1194 if (NT_SUCCESS (saveStatus))
1195 KeRestoreFloatingPointState (&floatingPointState);
1196 #endif
1197
1198 /* Prevent possible leaks. */
1199 burn (&hmac, sizeof(hmac));
1200 burn (key, sizeof(key));
1201 }
1202
1203 wchar_t *get_pkcs5_prf_name (int pkcs5_prf_id)
1204 {
1205 switch (pkcs5_prf_id)
1206 {
1207 case SHA512:
1208 return L"HMAC-SHA-512";
1209
1210 case SHA256:
1211 return L"HMAC-SHA-256";
1212
1213 case RIPEMD160:
1214 return L"HMAC-RIPEMD-160";
1215
1216 case WHIRLPOOL:
1217 return L"HMAC-Whirlpool";
1218
1219 case STREEBOG:
1220 return L"HMAC-STREEBOG";
1221
1222 default:
1223 return L"(Unknown)";
1224 }
1225 }
1226
1227
1228
1229 int get_pkcs5_iteration_count (int pkcs5_prf_id, int pim, BOOL truecryptMode, BOOL bBoot)
1230 {
1231 if ( (pim < 0)
1232 || (truecryptMode && pim > 0) /* No PIM for TrueCrypt mode */
1233 )
1234 {
1235 return 0;
1236 }
1237
1238 switch (pkcs5_prf_id)
1239 {
1240
1241 case RIPEMD160:
1242 if (truecryptMode)
1243 return bBoot ? 1000 : 2000;
1244 else if (pim == 0)
1245 return bBoot? 327661 : 655331;
1246 else
1247 {
1248 return bBoot? pim * 2048 : 15000 + pim * 1000;
1249 }
1250
1251 case SHA512:
1252 return truecryptMode? 1000 : ((pim == 0)? 500000 : 15000 + pim * 1000);
1253
1254 case WHIRLPOOL:
1255 return truecryptMode? 1000 : ((pim == 0)? 500000 : 15000 + pim * 1000);
1256
1257 case SHA256:
1258 if (truecryptMode)
1259 return 0; // SHA-256 not supported by TrueCrypt
1260 else if (pim == 0)
1261 return bBoot? 200000 : 500000;
1262 else
1263 {
1264 return bBoot? pim * 2048 : 15000 + pim * 1000;
1265 }
1266
1267 case STREEBOG:
1268 if (truecryptMode)
1269 return 1000;
1270 else if (pim == 0)
1271 return bBoot? 200000 : 500000;
1272 else
1273 {
1274 return bBoot? pim * 2048 : 15000 + pim * 1000;
1275 }
1276
1277 default:
1278 TC_THROW_FATAL_EXCEPTION; // Unknown/wrong ID
1279 }
1280 return 0;
1281 }
1282
1283 int is_pkcs5_prf_supported (int pkcs5_prf_id, BOOL truecryptMode, PRF_BOOT_TYPE bootType)
1284 {
1285 if (pkcs5_prf_id == 0) // auto-detection always supported
1286 return 1;
1287
1288 if (truecryptMode)
1289 {
1290 if ( (bootType == PRF_BOOT_GPT)
1291 || (bootType == PRF_BOOT_MBR && pkcs5_prf_id != RIPEMD160)
1292 || (bootType == PRF_BOOT_NO && pkcs5_prf_id != SHA512 && pkcs5_prf_id != WHIRLPOOL && pkcs5_prf_id != RIPEMD160)
1293 )
1294 return 0;
1295 }
1296 else
1297 {
1298 if ( (bootType == PRF_BOOT_MBR && pkcs5_prf_id != RIPEMD160 && pkcs5_prf_id != SHA256)
1299 || (bootType != PRF_BOOT_MBR && (pkcs5_prf_id < FIRST_PRF_ID || pkcs5_prf_id > LAST_PRF_ID))
1300 )
1301 return 0;
1302 }
1303
1304 return 1;
1305
1306 }
1307
1308 #endif //!TC_WINDOWS_BOOT