mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-12 03:18:26 -06:00
wolfCrypt as crypto backend for VeraCrypt (#1227)
* wolfCrypt as crypto backend for VeraCrypt * Refactor to use EncryptionModeWolfCryptXTS class
This commit is contained in:
@@ -35,6 +35,11 @@
|
||||
|
||||
#include "Common/Tcdefs.h"
|
||||
|
||||
#ifdef WOLFCRYPT_BACKEND
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/wolfcrypt/aes.h>
|
||||
#endif
|
||||
|
||||
#ifndef EXIT_SUCCESS
|
||||
#define EXIT_SUCCESS 0
|
||||
#define EXIT_FAILURE 1
|
||||
@@ -93,11 +98,19 @@ typedef union
|
||||
typedef struct
|
||||
{ uint_32t ks[KS_LENGTH];
|
||||
aes_inf inf;
|
||||
#ifdef WOLFCRYPT_BACKEND
|
||||
XtsAes wc_enc_xts;
|
||||
Aes wc_enc_aes;
|
||||
#endif
|
||||
} aes_encrypt_ctx;
|
||||
|
||||
typedef struct
|
||||
{ uint_32t ks[KS_LENGTH];
|
||||
aes_inf inf;
|
||||
#ifdef WOLFCRYPT_BACKEND
|
||||
XtsAes wc_dec_xts;
|
||||
Aes wc_dec_aes;
|
||||
#endif
|
||||
} aes_decrypt_ctx;
|
||||
|
||||
/* This routine must be called before first use if non-static */
|
||||
@@ -152,6 +165,13 @@ AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_de
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef WOLFCRYPT_BACKEND
|
||||
AES_RETURN xts_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
AES_RETURN xts_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
AES_RETURN xts_encrypt(const unsigned char *in, unsigned char *out, word64 length, word64 sector, const aes_encrypt_ctx cx[1]);
|
||||
AES_RETURN xts_decrypt(const unsigned char *in, unsigned char *out, word64 length, word64 sector, const aes_decrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined(AES_MODES)
|
||||
|
||||
/* Multiple calls to the following subroutines for multiple block */
|
||||
|
||||
@@ -12,6 +12,13 @@
|
||||
#include "Common/Endian.h"
|
||||
#include "Crypto/config.h"
|
||||
|
||||
#ifdef WOLFCRYPT_BACKEND
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/wolfcrypt/sha256.h>
|
||||
#include <wolfssl/wolfcrypt/sha512.h>
|
||||
#include <wolfssl/wolfcrypt/hash.h>
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -28,6 +35,10 @@ extern "C" {
|
||||
#define SHA2_ALIGN CRYPTOPP_ALIGN_DATA(16)
|
||||
#endif
|
||||
|
||||
#ifdef WOLFCRYPT_BACKEND
|
||||
typedef struct wc_Sha512 sha512_ctx;
|
||||
typedef struct wc_Sha256 sha256_ctx;
|
||||
#else
|
||||
typedef struct
|
||||
{ uint_64t count[2];
|
||||
SHA2_ALIGN uint_64t hash[8];
|
||||
@@ -39,6 +50,7 @@ typedef struct
|
||||
SHA2_ALIGN uint_32t hash[8];
|
||||
SHA2_ALIGN uint_32t wbuf[16];
|
||||
} sha256_ctx;
|
||||
#endif
|
||||
|
||||
|
||||
void sha512_begin(sha512_ctx* ctx);
|
||||
|
||||
@@ -214,7 +214,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define CRYPTOPP_CPUID_AVAILABLE
|
||||
#ifndef CRYPTOPP_DISABLE_AESNI
|
||||
#if !defined(CRYPTOPP_DISABLE_AESNI) && !defined(WOLFCRYPT_BACKEND)
|
||||
#define TC_AES_HW_CPU
|
||||
#endif
|
||||
|
||||
|
||||
243
src/Crypto/wolfCrypt.c
Normal file
243
src/Crypto/wolfCrypt.c
Normal file
@@ -0,0 +1,243 @@
|
||||
/* See src/Crypto/wolfCrypt.md */
|
||||
|
||||
#include "Aes.h"
|
||||
#include "Sha2.h"
|
||||
#include "../Common/Crypto.h"
|
||||
#include <wolfssl/wolfcrypt/hmac.h>
|
||||
|
||||
|
||||
AES_RETURN aes_init()
|
||||
{
|
||||
#if defined( AES_ERR_CHK )
|
||||
return EXIT_SUCCESS;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = wc_AesInit(&cx->wc_enc_aes, NULL, INVALID_DEVID);
|
||||
|
||||
if (key_len == 128 || key_len == 192 || key_len == 256)
|
||||
key_len = key_len/8;
|
||||
|
||||
if (ret == 0) {
|
||||
ret = wc_AesSetKey(&cx->wc_enc_aes, key, key_len, NULL, AES_ENCRYPTION);
|
||||
}
|
||||
|
||||
#if defined( AES_ERR_CHK )
|
||||
return ret ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = wc_AesInit(&cx->wc_dec_aes, NULL, INVALID_DEVID);
|
||||
|
||||
if (key_len == 128 || key_len == 192 || key_len == 256)
|
||||
key_len = key_len/8;
|
||||
|
||||
if (ret == 0) {
|
||||
ret = wc_AesSetKey(&cx->wc_dec_aes, key, key_len, NULL, AES_DECRYPTION);
|
||||
}
|
||||
|
||||
#if defined( AES_ERR_CHK )
|
||||
return ret ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
{
|
||||
return aes_encrypt_key(key, 128, cx);
|
||||
}
|
||||
|
||||
AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
{
|
||||
return aes_encrypt_key(key, 192, cx);
|
||||
}
|
||||
|
||||
AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
{
|
||||
return aes_encrypt_key(key, 256, cx);
|
||||
}
|
||||
|
||||
AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
{
|
||||
return aes_decrypt_key(key, 128, cx);
|
||||
}
|
||||
|
||||
AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
{
|
||||
return aes_decrypt_key(key, 192, cx);
|
||||
}
|
||||
|
||||
AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
{
|
||||
return aes_decrypt_key(key, 256, cx);
|
||||
}
|
||||
|
||||
AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
|
||||
{
|
||||
int ret = wc_AesEncryptDirect(&cx->wc_enc_aes, out, in);
|
||||
#if defined( AES_ERR_CHK )
|
||||
return ret ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
|
||||
{
|
||||
int ret = wc_AesDecryptDirect(&cx->wc_dec_aes, out, in);
|
||||
#if defined( AES_ERR_CHK )
|
||||
return ret ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
AES_RETURN xts_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
cx->wc_enc_xts.aes = cx->wc_enc_aes;
|
||||
|
||||
ret = wc_AesInit(&cx->wc_enc_xts.tweak, NULL, INVALID_DEVID);
|
||||
|
||||
if (key_len == 128 || key_len == 192 || key_len == 256)
|
||||
key_len = key_len/8;
|
||||
|
||||
if (ret == 0) {
|
||||
ret = wc_AesSetKey(&cx->wc_enc_xts.tweak, key, key_len, NULL, AES_ENCRYPTION);
|
||||
}
|
||||
#if defined( AES_ERR_CHK )
|
||||
return ret ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
AES_RETURN xts_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
cx->wc_dec_xts.aes = cx->wc_dec_aes;
|
||||
|
||||
ret = wc_AesInit(&cx->wc_dec_xts.tweak, NULL, INVALID_DEVID);
|
||||
|
||||
if (key_len == 128 || key_len == 192 || key_len == 256)
|
||||
key_len = key_len/8;
|
||||
|
||||
if (ret == 0) {
|
||||
ret = wc_AesSetKey(&cx->wc_dec_xts.tweak, key, key_len, NULL, AES_ENCRYPTION);
|
||||
}
|
||||
|
||||
#if defined( AES_ERR_CHK )
|
||||
return ret ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
AES_RETURN xts_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
{
|
||||
return xts_encrypt_key(key, 256, cx);
|
||||
}
|
||||
|
||||
AES_RETURN xts_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
{
|
||||
return xts_decrypt_key(key, 256, cx);
|
||||
}
|
||||
|
||||
AES_RETURN xts_encrypt(const unsigned char *in, unsigned char *out, word64 length, word64 sector, const aes_encrypt_ctx cx[1])
|
||||
{
|
||||
int ret = wc_AesXtsEncryptConsecutiveSectors(&cx->wc_enc_xts, out, in, length, sector, ENCRYPTION_DATA_UNIT_SIZE);
|
||||
|
||||
#if defined( AES_ERR_CHK )
|
||||
return ret ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
AES_RETURN xts_decrypt(const unsigned char *in, unsigned char *out, word64 length, word64 sector, const aes_decrypt_ctx cx[1])
|
||||
{
|
||||
int ret = wc_AesXtsDecryptConsecutiveSectors(&cx->wc_dec_xts, out, in, length, sector, ENCRYPTION_DATA_UNIT_SIZE);
|
||||
|
||||
#if defined( AES_ERR_CHK )
|
||||
return ret ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void sha256_begin(sha256_ctx* ctx)
|
||||
{
|
||||
wc_InitSha256(ctx);
|
||||
}
|
||||
|
||||
void sha256_hash(const unsigned char * source, uint_32t sourceLen, sha256_ctx *ctx)
|
||||
{
|
||||
wc_Sha256Update(ctx, source, sourceLen);
|
||||
}
|
||||
|
||||
void sha256_end(unsigned char * result, sha256_ctx* ctx)
|
||||
{
|
||||
wc_Sha256Final(ctx, result);
|
||||
}
|
||||
|
||||
void sha256(unsigned char * result, const unsigned char* source, uint_32t sourceLen)
|
||||
{
|
||||
wc_Sha256 sha256;
|
||||
wc_InitSha256(&sha256);
|
||||
wc_Sha256Update(&sha256, source, sourceLen);
|
||||
wc_Sha256Final(&sha256, result);
|
||||
wc_Sha256Free(&sha256);
|
||||
}
|
||||
|
||||
void sha512_begin(sha512_ctx* ctx)
|
||||
{
|
||||
wc_InitSha512(ctx);
|
||||
}
|
||||
|
||||
void sha512_hash(const unsigned char * source, uint_64t sourceLen, sha512_ctx *ctx)
|
||||
{
|
||||
wc_Sha512Update(ctx, source, sourceLen);
|
||||
}
|
||||
|
||||
void sha512_end(unsigned char * result, sha512_ctx* ctx)
|
||||
{
|
||||
wc_Sha512Final(ctx, result);
|
||||
}
|
||||
|
||||
void sha512(unsigned char * result, const unsigned char* source, uint_64t sourceLen)
|
||||
{
|
||||
wc_Sha512 sha512;
|
||||
wc_InitSha512(&sha512);
|
||||
wc_Sha512Update(&sha512, source, sourceLen);
|
||||
wc_Sha512Final(&sha512, result);
|
||||
wc_Sha512Free(&sha512);
|
||||
}
|
||||
|
||||
void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen) {
|
||||
(void) iterations;
|
||||
wc_HKDF(WC_SHA512, (byte*)pwd, (word32)pwd_len, (byte*)salt, (word32)salt_len, NULL, 0, (byte*)dk, (word32)dklen);
|
||||
}
|
||||
|
||||
void derive_key_sha256 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen) {
|
||||
(void) iterations;
|
||||
wc_HKDF(WC_SHA256, (byte*)pwd, (word32)pwd_len, (byte*)salt, (word32)salt_len, NULL, 0, (byte*)dk, (word32)dklen);
|
||||
}
|
||||
25
src/Crypto/wolfCrypt.md
Normal file
25
src/Crypto/wolfCrypt.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# wolfSSL as crypto provider for VeraCrypt
|
||||
|
||||
[wolfCrypt](https://www.wolfssl.com/products/wolfcrypt/) is wolfSSL's cutting edge crypto engine and a
|
||||
potential FIPS solution for users of VeraCrypt. Follow the steps below to setup VeraCrypt with wolfCrypt.
|
||||
|
||||
## Building wolfSSL
|
||||
|
||||
Clone wolfSSL and build it as shown below.
|
||||
|
||||
```
|
||||
git clone https://github.com/wolfssl/wolfssl && cd wolfssl
|
||||
./autogen.sh
|
||||
./configure --enable-xts CFLAGS="-DNO_OLD_WC_NAMES"
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
## Building VeraCrypt with wolfSSL
|
||||
|
||||
Build VeraCrypt with the `WOLFCRYPT` command line option.
|
||||
|
||||
```
|
||||
make WXSTATIC=1 wxbuild && make WXSTATIC=1 clean && make WXSTATIC=1 WOLFCRYPT=1 && make WXSTATIC=1 WOLFCRYPT=1 package
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user