diff options
author | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2022-03-07 00:45:30 +0100 |
---|---|---|
committer | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2022-03-08 00:29:26 +0100 |
commit | 36795a688fd1d5bb9f497970938d9fcb08cfc330 (patch) | |
tree | 24ffb2320c1f72c16b96c13fa4dddda4267065ee /src/Common/Pkcs5.c | |
parent | 2dee49d3c8422aa1aa11c8630823aab3028cccd5 (diff) | |
download | VeraCrypt-36795a688fd1d5bb9f497970938d9fcb08cfc330.tar.gz VeraCrypt-36795a688fd1d5bb9f497970938d9fcb08cfc330.zip |
Implement support of Blake2s-256 hash algorithm and remove deprecated algorithms RIPEMD-160 and GOST89.
Diffstat (limited to 'src/Common/Pkcs5.c')
-rw-r--r-- | src/Common/Pkcs5.c | 294 |
1 files changed, 173 insertions, 121 deletions
diff --git a/src/Common/Pkcs5.c b/src/Common/Pkcs5.c index 3ac3cc2c..10d33ff0 100644 --- a/src/Common/Pkcs5.c +++ b/src/Common/Pkcs5.c @@ -16,7 +16,7 @@ #include <memory.h> #include <stdlib.h> #endif -#include "Rmd160.h" +#include "blake2.h" #ifndef TC_WINDOWS_BOOT #include "Sha2.h" #include "Whirlpool.h" @@ -550,100 +550,131 @@ void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 #endif // TC_WINDOWS_BOOT -#if !defined(TC_WINDOWS_BOOT) || defined(TC_WINDOWS_BOOT_RIPEMD160) +#if !defined(TC_WINDOWS_BOOT) || defined(TC_WINDOWS_BOOT_BLAKE2S) -typedef struct hmac_ripemd160_ctx_struct +typedef struct hmac_blake2s_ctx_struct { - RMD160_CTX context; - RMD160_CTX inner_digest_ctx; /*pre-computed inner digest context */ - RMD160_CTX outer_digest_ctx; /*pre-computed outer digest context */ - char k[PKCS5_SALT_SIZE + 4]; /* enough to hold (salt_len + 4) and also the RIPEMD-160 hash */ - char u[RIPEMD160_DIGESTSIZE]; -} hmac_ripemd160_ctx; - -void hmac_ripemd160_internal (char *input_digest, int len, hmac_ripemd160_ctx* hmac) + blake2s_state ctx; + blake2s_state inner_digest_ctx; /*pre-computed inner digest context */ + blake2s_state outer_digest_ctx; /*pre-computed outer digest context */ + char k[PKCS5_SALT_SIZE + 4]; /* enough to hold (salt_len + 4) and also the SHA256 hash */ + char u[BLAKE2S_DIGESTSIZE]; +} hmac_blake2s_ctx; + +void hmac_blake2s_internal +( + char *d, /* input data. d pointer is guaranteed to be at least 32-bytes long */ + int ld, /* length of input data in bytes */ + hmac_blake2s_ctx* hmac /* HMAC-SHA256 context which holds temporary variables */ +) { - RMD160_CTX* context = &(hmac->context); + blake2s_state* ctx = &(hmac->ctx); /**** Restore Precomputed Inner Digest Context ****/ - memcpy (context, &(hmac->inner_digest_ctx), sizeof (RMD160_CTX)); + memcpy (ctx, &(hmac->inner_digest_ctx), sizeof (blake2s_state)); - RMD160Update(context, (const unsigned char *) input_digest, len); /* then text of datagram */ - RMD160Final((unsigned char *) input_digest, context); /* finish up 1st pass */ + blake2s_update (ctx, d, ld); + + blake2s_final (ctx, (unsigned char*) d); /* d = inner digest */ /**** Restore Precomputed Outer Digest Context ****/ - memcpy (context, &(hmac->outer_digest_ctx), sizeof (RMD160_CTX)); + memcpy (ctx, &(hmac->outer_digest_ctx), sizeof (blake2s_state)); + + blake2s_update (ctx, d, SHA256_DIGESTSIZE); - /* results of 1st hash */ - RMD160Update(context, (const unsigned char *) input_digest, RIPEMD160_DIGESTSIZE); - RMD160Final((unsigned char *) input_digest, context); /* finish up 2nd pass */ + blake2s_final (ctx, (unsigned char *) d); /* d = outer digest */ } #ifndef TC_WINDOWS_BOOT -void hmac_ripemd160 (char *key, int keylen, char *input_digest, int len) +void hmac_blake2s +( + char *k, /* secret key */ + int lk, /* length of the key in bytes */ + char *d, /* data */ + int ld /* length of data in bytes */ +) { - hmac_ripemd160_ctx hmac; - RMD160_CTX* ctx; - unsigned char* k_pad = (unsigned char*) hmac.k; /* inner/outer padding - key XORd with ipad */ - unsigned char tk[RIPEMD160_DIGESTSIZE]; - int i; - - /* If the key is longer than the hash algorithm block size, - let key = ripemd160(key), as per HMAC specifications. */ - if (keylen > RIPEMD160_BLOCKSIZE) + hmac_blake2s_ctx hmac; + blake2s_state* ctx; + char* buf = hmac.k; + int b; + char key[BLAKE2S_DIGESTSIZE]; +#if defined (DEVICE_DRIVER) + NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; +#ifdef _WIN64 + XSTATE_SAVE SaveState; + if (IsCpuIntel() && HasSAVX()) + saveStatus = KeSaveExtendedProcessorStateVC(XSTATE_MASK_GSSE, &SaveState); +#else + KFLOATING_SAVE floatingPointState; + if (HasSSE2()) + saveStatus = KeSaveFloatingPointState (&floatingPointState); +#endif +#endif + /* If the key is longer than the hash algorithm block size, + let key = blake2s(key), as per HMAC specifications. */ + if (lk > BLAKE2S_BLOCKSIZE) { - RMD160_CTX tctx; + blake2s_state tctx; - RMD160Init(&tctx); - RMD160Update(&tctx, (const unsigned char *) key, keylen); - RMD160Final(tk, &tctx); + blake2s_init (&tctx); + blake2s_update (&tctx, k, lk); + blake2s_final (&tctx, (unsigned char *) key); - key = (char *) tk; - keylen = RIPEMD160_DIGESTSIZE; + k = key; + lk = BLAKE2S_DIGESTSIZE; - burn (&tctx, sizeof(tctx)); // Prevent leaks - } + burn (&tctx, sizeof(tctx)); // Prevent leaks + } + + /**** Precompute HMAC Inner Digest ****/ - /* perform inner RIPEMD-160 */ ctx = &(hmac.inner_digest_ctx); - /* start out by storing key in pads */ - memset(k_pad, 0x36, 64); - /* XOR key with ipad and opad values */ - for (i=0; i<keylen; i++) - { - k_pad[i] ^= key[i]; - } + blake2s_init (ctx); - RMD160Init(ctx); /* init context for 1st pass */ - RMD160Update(ctx, k_pad, RIPEMD160_BLOCKSIZE); /* start with inner pad */ + /* Pad the key for inner digest */ + for (b = 0; b < lk; ++b) + buf[b] = (char) (k[b] ^ 0x36); + memset (&buf[lk], 0x36, BLAKE2S_BLOCKSIZE - lk); + + blake2s_update (ctx, (unsigned char *) buf, BLAKE2S_BLOCKSIZE); + + /**** Precompute HMAC Outer Digest ****/ - /* perform outer RIPEMD-160 */ ctx = &(hmac.outer_digest_ctx); - memset(k_pad, 0x5c, 64); - for (i=0; i<keylen; i++) - { - k_pad[i] ^= key[i]; - } + blake2s_init (ctx); - RMD160Init(ctx); /* init context for 2nd pass */ - RMD160Update(ctx, k_pad, RIPEMD160_BLOCKSIZE); /* start with outer pad */ + for (b = 0; b < lk; ++b) + buf[b] = (char) (k[b] ^ 0x5C); + memset (&buf[lk], 0x5C, SHA256_BLOCKSIZE - lk); - hmac_ripemd160_internal (input_digest, len, &hmac); + blake2s_update (ctx, (unsigned char *) buf, BLAKE2S_BLOCKSIZE); - burn (&hmac, sizeof(hmac)); - burn (tk, sizeof(tk)); -} + hmac_blake2s_internal(d, ld, &hmac); + +#if defined (DEVICE_DRIVER) + if (NT_SUCCESS (saveStatus)) +#ifdef _WIN64 + KeRestoreExtendedProcessorStateVC(&SaveState); +#else + KeRestoreFloatingPointState (&floatingPointState); +#endif #endif + /* Prevent leaks */ + burn(&hmac, sizeof(hmac)); + burn(key, sizeof(key)); +} +#endif -static void derive_u_ripemd160 (char *salt, int salt_len, uint32 iterations, int b, hmac_ripemd160_ctx* hmac) +static void derive_u_blake2s (char *salt, int salt_len, uint32 iterations, int b, hmac_blake2s_ctx* hmac) { char* k = hmac->k; char* u = hmac->u; uint32 c; - int i; + int i; #ifdef TC_WINDOWS_BOOT /* In bootloader mode, least significant bit of iterations is a boolean (TRUE for boot derivation mode, FALSE otherwise) @@ -653,11 +684,11 @@ static void derive_u_ripemd160 (char *salt, int salt_len, uint32 iterations, int c = iterations >> 16; i = ((int) iterations) & 0x01; if (i) - c = (c == 0)? 327661 : c << 11; + c = (c == 0)? 200000 : c << 11; else - c = (c == 0)? 655331 : 15000 + c * 1000; + c = (c == 0)? 500000 : 15000 + c * 1000; #else - c = iterations; + c = iterations; #endif /* iteration 1 */ @@ -665,7 +696,7 @@ static void derive_u_ripemd160 (char *salt, int salt_len, uint32 iterations, int /* big-endian block number */ #ifdef TC_WINDOWS_BOOT - /* specific case of 16-bit bootloader: b is a 16-bit integer that is always < 256*/ + /* specific case of 16-bit bootloader: b is a 16-bit integer that is always < 256 */ memset (&k[salt_len], 0, 3); k[salt_len + 3] = (char) b; #else @@ -673,14 +704,14 @@ static void derive_u_ripemd160 (char *salt, int salt_len, uint32 iterations, int memcpy (&k[salt_len], &b, 4); #endif - hmac_ripemd160_internal (k, salt_len + 4, hmac); - memcpy (u, k, RIPEMD160_DIGESTSIZE); + hmac_blake2s_internal (k, salt_len + 4, hmac); + memcpy (u, k, BLAKE2S_DIGESTSIZE); /* remaining iterations */ - while ( c > 1) + while (c > 1) { - hmac_ripemd160_internal (k, RIPEMD160_DIGESTSIZE, hmac); - for (i = 0; i < RIPEMD160_DIGESTSIZE; i++) + hmac_blake2s_internal (k, BLAKE2S_DIGESTSIZE, hmac); + for (i = 0; i < BLAKE2S_DIGESTSIZE; i++) { u[i] ^= k[i]; } @@ -688,86 +719,107 @@ static void derive_u_ripemd160 (char *salt, int salt_len, uint32 iterations, int } } -void derive_key_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen) + +void derive_key_blake2s (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen) { + hmac_blake2s_ctx hmac; + blake2s_state* ctx; + char* buf = hmac.k; int b, l, r; - hmac_ripemd160_ctx hmac; - RMD160_CTX* ctx; - unsigned char* k_pad = (unsigned char*) hmac.k; #ifndef TC_WINDOWS_BOOT - unsigned char tk[RIPEMD160_DIGESTSIZE]; + char key[BLAKE2S_DIGESTSIZE]; +#if defined (DEVICE_DRIVER) + NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; +#ifdef _WIN64 + XSTATE_SAVE SaveState; + if (IsCpuIntel() && HasSAVX()) + saveStatus = KeSaveExtendedProcessorStateVC(XSTATE_MASK_GSSE, &SaveState); +#else + KFLOATING_SAVE floatingPointState; + if (HasSSE2()) + saveStatus = KeSaveFloatingPointState (&floatingPointState); +#endif +#endif /* If the password is longer than the hash algorithm block size, - let password = ripemd160(password), as per HMAC specifications. */ - if (pwd_len > RIPEMD160_BLOCKSIZE) + let pwd = blake2s(pwd), as per HMAC specifications. */ + if (pwd_len > BLAKE2S_BLOCKSIZE) { - RMD160_CTX tctx; + blake2s_state tctx; - RMD160Init(&tctx); - RMD160Update(&tctx, (const unsigned char *) pwd, pwd_len); - RMD160Final(tk, &tctx); + blake2s_init (&tctx); + blake2s_update (&tctx, pwd, pwd_len); + blake2s_final (&tctx, (unsigned char *) key); - pwd = (char *) tk; - pwd_len = RIPEMD160_DIGESTSIZE; + pwd = key; + pwd_len = SHA256_DIGESTSIZE; - burn (&tctx, sizeof(tctx)); // Prevent leaks - } + burn (&tctx, sizeof(tctx)); // Prevent leaks + } #endif - if (dklen % RIPEMD160_DIGESTSIZE) + if (dklen % BLAKE2S_DIGESTSIZE) { - l = 1 + dklen / RIPEMD160_DIGESTSIZE; + l = 1 + dklen / BLAKE2S_DIGESTSIZE; } else { - l = dklen / RIPEMD160_DIGESTSIZE; + l = dklen / BLAKE2S_DIGESTSIZE; } - r = dklen - (l - 1) * RIPEMD160_DIGESTSIZE; + r = dklen - (l - 1) * BLAKE2S_DIGESTSIZE; + + /**** Precompute HMAC Inner Digest ****/ - /* perform inner RIPEMD-160 */ ctx = &(hmac.inner_digest_ctx); - /* start out by storing key in pads */ - memset(k_pad, 0x36, 64); - /* XOR key with ipad and opad values */ - for (b=0; b<pwd_len; b++) - { - k_pad[b] ^= pwd[b]; - } + blake2s_init (ctx); + + /* Pad the key for inner digest */ + for (b = 0; b < pwd_len; ++b) + buf[b] = (char) (pwd[b] ^ 0x36); + memset (&buf[pwd_len], 0x36, BLAKE2S_BLOCKSIZE - pwd_len); + + blake2s_update (ctx, buf, BLAKE2S_BLOCKSIZE); - RMD160Init(ctx); /* init context for 1st pass */ - RMD160Update(ctx, k_pad, RIPEMD160_BLOCKSIZE); /* start with inner pad */ + /**** Precompute HMAC Outer Digest ****/ - /* perform outer RIPEMD-160 */ ctx = &(hmac.outer_digest_ctx); - memset(k_pad, 0x5c, 64); - for (b=0; b<pwd_len; b++) - { - k_pad[b] ^= pwd[b]; - } + blake2s_init (ctx); + + for (b = 0; b < pwd_len; ++b) + buf[b] = (char) (pwd[b] ^ 0x5C); + memset (&buf[pwd_len], 0x5C, BLAKE2S_BLOCKSIZE - pwd_len); - RMD160Init(ctx); /* init context for 2nd pass */ - RMD160Update(ctx, k_pad, RIPEMD160_BLOCKSIZE); /* start with outer pad */ + blake2s_update (ctx, buf, BLAKE2S_BLOCKSIZE); /* first l - 1 blocks */ for (b = 1; b < l; b++) { - derive_u_ripemd160 (salt, salt_len, iterations, b, &hmac); - memcpy (dk, hmac.u, RIPEMD160_DIGESTSIZE); - dk += RIPEMD160_DIGESTSIZE; + derive_u_blake2s (salt, salt_len, iterations, b, &hmac); + memcpy (dk, hmac.u, BLAKE2S_DIGESTSIZE); + dk += BLAKE2S_DIGESTSIZE; } /* last block */ - derive_u_ripemd160 (salt, salt_len, iterations, b, &hmac); + derive_u_blake2s (salt, salt_len, iterations, b, &hmac); memcpy (dk, hmac.u, r); +#if defined (DEVICE_DRIVER) + if (NT_SUCCESS (saveStatus)) +#ifdef _WIN64 + KeRestoreExtendedProcessorStateVC(&SaveState); +#else + KeRestoreFloatingPointState (&floatingPointState); +#endif +#endif /* Prevent possible leaks. */ burn (&hmac, sizeof(hmac)); #ifndef TC_WINDOWS_BOOT - burn (tk, sizeof(tk)); + burn (key, sizeof(key)); #endif } -#endif // TC_WINDOWS_BOOT + +#endif #ifndef TC_WINDOWS_BOOT @@ -1210,8 +1262,8 @@ wchar_t *get_pkcs5_prf_name (int pkcs5_prf_id) case SHA256: return L"HMAC-SHA-256"; - case RIPEMD160: - return L"HMAC-RIPEMD-160"; + case BLAKE2S: + return L"HMAC-BLAKE2s"; case WHIRLPOOL: return L"HMAC-Whirlpool"; @@ -1238,11 +1290,11 @@ int get_pkcs5_iteration_count (int pkcs5_prf_id, int pim, BOOL truecryptMode, BO switch (pkcs5_prf_id) { - case RIPEMD160: + case BLAKE2S: if (truecryptMode) - return bBoot ? 1000 : 2000; + return 0; // BLAKE2s not supported by TrueCrypt else if (pim == 0) - return bBoot? 327661 : 655331; + return bBoot? 200000 : 500000; else { return bBoot? pim * 2048 : 15000 + pim * 1000; @@ -1290,14 +1342,14 @@ int is_pkcs5_prf_supported (int pkcs5_prf_id, BOOL truecryptMode, PRF_BOOT_TYPE if (truecryptMode) { if ( (bootType == PRF_BOOT_GPT) - || (bootType == PRF_BOOT_MBR && pkcs5_prf_id != RIPEMD160) - || (bootType == PRF_BOOT_NO && pkcs5_prf_id != SHA512 && pkcs5_prf_id != WHIRLPOOL && pkcs5_prf_id != RIPEMD160) + || (bootType == PRF_BOOT_MBR) + || (bootType == PRF_BOOT_NO && pkcs5_prf_id != SHA512 && pkcs5_prf_id != WHIRLPOOL) ) return 0; } else { - if ( (bootType == PRF_BOOT_MBR && pkcs5_prf_id != RIPEMD160 && pkcs5_prf_id != SHA256) + if ( (bootType == PRF_BOOT_MBR && pkcs5_prf_id != BLAKE2S && pkcs5_prf_id != SHA256) || (bootType != PRF_BOOT_MBR && (pkcs5_prf_id < FIRST_PRF_ID || pkcs5_prf_id > LAST_PRF_ID)) ) return 0; |