Merge pull request #4556 from douzzer/updateFipsHash

This commit is contained in:
John Safranek 2021-11-11 14:23:01 -08:00 committed by GitHub
commit 4e20b93e72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 228 additions and 28 deletions

View File

@ -117,25 +117,17 @@ static int wolfssl_init(void)
{ {
int ret; int ret;
#if defined(CONFIG_MODULE_SIG_FORCE) || defined(WOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE) #ifdef WOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE
if (THIS_MODULE->sig_ok == false) { if (THIS_MODULE->sig_ok == false) {
pr_err("wolfSSL module load aborted -- bad or missing module signature with " pr_err("wolfSSL module load aborted -- bad or missing module signature with FIPS dynamic hash.\n");
#ifdef CONFIG_MODULE_SIG_FORCE
"CONFIG_MODULE_SIG_FORCE kernel"
#else
"FIPS dynamic hash"
#endif
".\n");
return -ECANCELED; return -ECANCELED;
} }
#ifdef WOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE
ret = updateFipsHash(); ret = updateFipsHash();
if (ret < 0) { if (ret < 0) {
pr_err("wolfSSL module load aborted -- updateFipsHash: %s\n",wc_GetErrorString(ret)); pr_err("wolfSSL module load aborted -- updateFipsHash: %s\n",wc_GetErrorString(ret));
return -ECANCELED; return -ECANCELED;
} }
#endif #endif
#endif
#ifdef USE_WOLFSSL_LINUXKM_PIE_REDIRECT_TABLE #ifdef USE_WOLFSSL_LINUXKM_PIE_REDIRECT_TABLE
ret = set_up_wolfssl_linuxkm_pie_redirect_table(); ret = set_up_wolfssl_linuxkm_pie_redirect_table();
@ -327,7 +319,7 @@ static int my_preempt_count(void) {
return preempt_count(); return preempt_count();
} }
#if defined(WOLFSSL_LINUXKM_SIMD_X86_IRQ_ALLOWED) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0)) #if defined(WOLFSSL_LINUXKM_SIMD_X86) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0))
static int my_copy_fpregs_to_fpstate(struct fpu *fpu) { static int my_copy_fpregs_to_fpstate(struct fpu *fpu) {
return copy_fpregs_to_fpstate(fpu); return copy_fpregs_to_fpstate(fpu);
} }
@ -422,18 +414,16 @@ static int set_up_wolfssl_linuxkm_pie_redirect_table(void) {
kernel_fpu_begin; kernel_fpu_begin;
#endif #endif
wolfssl_linuxkm_pie_redirect_table.kernel_fpu_end = kernel_fpu_end; wolfssl_linuxkm_pie_redirect_table.kernel_fpu_end = kernel_fpu_end;
#ifdef WOLFSSL_LINUXKM_SIMD_X86_IRQ_ALLOWED #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0)
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0) wolfssl_linuxkm_pie_redirect_table.copy_fpregs_to_fpstate = my_copy_fpregs_to_fpstate;
wolfssl_linuxkm_pie_redirect_table.copy_fpregs_to_fpstate = my_copy_fpregs_to_fpstate; wolfssl_linuxkm_pie_redirect_table.copy_kernel_to_fpregs = my_copy_kernel_to_fpregs;
wolfssl_linuxkm_pie_redirect_table.copy_kernel_to_fpregs = my_copy_kernel_to_fpregs; #else
#else wolfssl_linuxkm_pie_redirect_table.save_fpregs_to_fpstate = save_fpregs_to_fpstate;
wolfssl_linuxkm_pie_redirect_table.save_fpregs_to_fpstate = save_fpregs_to_fpstate; wolfssl_linuxkm_pie_redirect_table.__restore_fpregs_from_fpstate = __restore_fpregs_from_fpstate;
wolfssl_linuxkm_pie_redirect_table.__restore_fpregs_from_fpstate = __restore_fpregs_from_fpstate; wolfssl_linuxkm_pie_redirect_table.xfeatures_mask_all = &xfeatures_mask_all;
wolfssl_linuxkm_pie_redirect_table.xfeatures_mask_all = &xfeatures_mask_all; #endif
#endif wolfssl_linuxkm_pie_redirect_table.cpu_number = &cpu_number;
wolfssl_linuxkm_pie_redirect_table.cpu_number = &cpu_number; wolfssl_linuxkm_pie_redirect_table.nr_cpu_ids = &nr_cpu_ids;
wolfssl_linuxkm_pie_redirect_table.nr_cpu_ids = &nr_cpu_ids;
#endif /* WOLFSSL_LINUXKM_SIMD_X86_IRQ_ALLOWED */
#endif #endif
wolfssl_linuxkm_pie_redirect_table.__mutex_init = __mutex_init; wolfssl_linuxkm_pie_redirect_table.__mutex_init = __mutex_init;
@ -477,3 +467,213 @@ static int set_up_wolfssl_linuxkm_pie_redirect_table(void) {
} }
#endif /* USE_WOLFSSL_LINUXKM_PIE_REDIRECT_TABLE */ #endif /* USE_WOLFSSL_LINUXKM_PIE_REDIRECT_TABLE */
#ifdef WOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE
#include <wolfssl/wolfcrypt/coding.h>
PRAGMA_GCC_DIAG_PUSH;
PRAGMA_GCC("GCC diagnostic ignored \"-Wnested-externs\"");
PRAGMA_GCC("GCC diagnostic ignored \"-Wpointer-arith\"");
#include <crypto/hash.h>
PRAGMA_GCC_DIAG_POP;
extern char verifyCore[WC_SHA256_DIGEST_SIZE*2 + 1];
extern const char coreKey[WC_SHA256_DIGEST_SIZE*2 + 1];
extern const unsigned int wolfCrypt_FIPS_ro_start[];
extern const unsigned int wolfCrypt_FIPS_ro_end[];
#define FIPS_IN_CORE_KEY_SZ 32
#define FIPS_IN_CORE_VERIFY_SZ FIPS_IN_CORE_KEY_SZ
typedef int (*fips_address_function)(void);
#define MAX_FIPS_DATA_SZ 100000
#define MAX_FIPS_CODE_SZ 1000000
extern int GenBase16_Hash(const byte* in, int length, char* out, int outSz);
static int updateFipsHash(void)
{
struct crypto_shash *tfm = NULL;
struct shash_desc *desc = NULL;
word32 verifySz = FIPS_IN_CORE_VERIFY_SZ;
word32 binCoreSz = FIPS_IN_CORE_KEY_SZ;
int ret;
byte *hash = NULL;
char *base16_hash = NULL;
byte *binCoreKey = NULL;
byte *binVerify = NULL;
fips_address_function first = wolfCrypt_FIPS_first;
fips_address_function last = wolfCrypt_FIPS_last;
char* start = (char*)wolfCrypt_FIPS_ro_start;
char* end = (char*)wolfCrypt_FIPS_ro_end;
unsigned long code_sz = (unsigned long)last - (unsigned long)first;
unsigned long data_sz = (unsigned long)end - (unsigned long)start;
if (data_sz == 0 || data_sz > MAX_FIPS_DATA_SZ)
return BAD_FUNC_ARG; /* bad fips data size */
if (code_sz == 0 || code_sz > MAX_FIPS_CODE_SZ)
return BAD_FUNC_ARG; /* bad fips code size */
hash = XMALLOC(WC_SHA256_DIGEST_SIZE, 0, DYNAMIC_TYPE_TMP_BUFFER);
if (hash == NULL) {
ret = MEMORY_E;
goto out;
}
base16_hash = XMALLOC(WC_SHA256_DIGEST_SIZE*2 + 1, 0, DYNAMIC_TYPE_TMP_BUFFER);
if (base16_hash == NULL) {
ret = MEMORY_E;
goto out;
}
binCoreKey = XMALLOC(binCoreSz, 0, DYNAMIC_TYPE_TMP_BUFFER);
if (binCoreKey == NULL) {
ret = MEMORY_E;
goto out;
}
binVerify = XMALLOC(verifySz, 0, DYNAMIC_TYPE_TMP_BUFFER);
if (binVerify == NULL) {
ret = MEMORY_E;
goto out;
}
{
word32 base16_out_len = binCoreSz;
ret = Base16_Decode((const byte *)coreKey, sizeof coreKey - 1, binCoreKey, &base16_out_len);
if (ret != 0) {
pr_err("Base16_Decode for coreKey: %s\n", wc_GetErrorString(ret));
goto out;
}
if (base16_out_len != binCoreSz) {
pr_err("unexpected output length %u for coreKey from Base16_Decode.\n",base16_out_len);
ret = BAD_STATE_E;
goto out;
}
}
tfm = crypto_alloc_shash("hmac(sha256)", 0, 0);
if (IS_ERR(tfm)) {
if (PTR_ERR(tfm) == -ENOMEM) {
pr_err("crypto_alloc_shash failed: out of memory\n");
ret = MEMORY_E;
} else if (PTR_ERR(tfm) == -ENOENT) {
pr_err("crypto_alloc_shash failed: kernel is missing hmac(sha256) implementation\n");
pr_err("check for CONFIG_CRYPTO_SHA256 and CONFIG_CRYPTO_HMAC.\n");
ret = NOT_COMPILED_IN;
} else {
pr_err("crypto_alloc_shash failed with ret %ld\n",PTR_ERR(tfm));
ret = HASH_TYPE_E;
}
tfm = NULL;
goto out;
}
{
size_t desc_size = crypto_shash_descsize(tfm) + sizeof *desc;
desc = XMALLOC(desc_size, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (desc == NULL) {
pr_err("failed allocating desc.");
ret = MEMORY_E;
goto out;
}
XMEMSET(desc, 0, desc_size);
}
ret = crypto_shash_setkey(tfm, binCoreKey, binCoreSz);
if (ret) {
pr_err("crypto_ahash_setkey failed: err %d\n", ret);
ret = BAD_STATE_E;
goto out;
}
desc->tfm = tfm;
ret = crypto_shash_init(desc);
if (ret) {
pr_err("crypto_shash_init failed: err %d\n", ret);
ret = BAD_STATE_E;
goto out;
}
ret = crypto_shash_update(desc, (byte *)(wc_ptr_t)first, (word32)code_sz);
if (ret) {
pr_err("crypto_shash_update failed: err %d\n", ret);
ret = BAD_STATE_E;
goto out;
}
/* don't hash verifyCore or changing verifyCore will change hash */
if (verifyCore >= start && verifyCore < end) {
data_sz = (unsigned long)verifyCore - (unsigned long)start;
ret = crypto_shash_update(desc, (byte*)start, (word32)data_sz);
if (ret) {
pr_err("crypto_shash_update failed: err %d\n", ret);
ret = BAD_STATE_E;
goto out;
}
start = (char*)verifyCore + sizeof(verifyCore);
data_sz = (unsigned long)end - (unsigned long)start;
}
ret = crypto_shash_update(desc, (byte*)start, (word32)data_sz);
if (ret) {
pr_err("crypto_shash_update failed: err %d\n", ret);
ret = BAD_STATE_E;
goto out;
}
ret = crypto_shash_final(desc, hash);
if (ret) {
pr_err("crypto_shash_final failed: err %d\n", ret);
ret = BAD_STATE_E;
goto out;
}
ret = GenBase16_Hash(hash, WC_SHA256_DIGEST_SIZE, base16_hash, WC_SHA256_DIGEST_SIZE*2 + 1);
if (ret != 0) {
pr_err("GenBase16_Hash failed: %s\n", wc_GetErrorString(ret));
goto out;
}
{
word32 base16_out_len = verifySz;
ret = Base16_Decode((const byte *)verifyCore, sizeof verifyCore - 1, binVerify, &base16_out_len);
if (ret != 0) {
pr_err("Base16_Decode for verifyCore: %s\n", wc_GetErrorString(ret));
goto out;
}
if (base16_out_len != binCoreSz) {
pr_err("unexpected output length %u for verifyCore from Base16_Decode.\n",base16_out_len);
ret = BAD_STATE_E;
goto out;
}
}
if (XMEMCMP(hash, binVerify, WC_SHA256_DIGEST_SIZE) == 0)
pr_info("updateFipsHash: verifyCore already matches.\n");
else {
XMEMCPY(verifyCore, base16_hash, WC_SHA256_DIGEST_SIZE*2 + 1);
pr_info("updateFipsHash: verifyCore updated.\n");
}
ret = 0;
out:
if (tfm != NULL)
crypto_free_shash(tfm);
if (desc != NULL)
XFREE(desc, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (hash != NULL)
XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (base16_hash != NULL)
XFREE(base16_hash, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (binCoreKey != NULL)
XFREE(binCoreKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (binVerify != NULL)
XFREE(binVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}
#endif /* WOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE */

View File

@ -29018,7 +29018,7 @@ void wolfSSL_ASN1_TYPE_set(WOLFSSL_ASN1_TYPE *a, int type, void *value)
} }
switch (type) { switch (type) {
case V_ASN1_NULL: case V_ASN1_NULL:
a->value.ptr = value; a->value.ptr = (char *)value;
break; break;
case V_ASN1_SEQUENCE: case V_ASN1_SEQUENCE:
a->value.asn1_string = (WOLFSSL_ASN1_STRING*)value; a->value.asn1_string = (WOLFSSL_ASN1_STRING*)value;
@ -29276,9 +29276,9 @@ int wolfSSL_X509_PUBKEY_set(WOLFSSL_X509_PUBKEY **x, WOLFSSL_EVP_PKEY *key)
if (!wolfSSL_X509_ALGOR_set0(pk->algor, wolfSSL_OBJ_nid2obj(key->type), ptype, pval)) { if (!wolfSSL_X509_ALGOR_set0(pk->algor, wolfSSL_OBJ_nid2obj(key->type), ptype, pval)) {
WOLFSSL_MSG("Failed to create algorithm object"); WOLFSSL_MSG("Failed to create algorithm object");
if (ptype == V_ASN1_OBJECT) if (ptype == V_ASN1_OBJECT)
ASN1_OBJECT_free(pval); ASN1_OBJECT_free((WOLFSSL_ASN1_OBJECT *)pval);
else else
ASN1_STRING_free(pval); ASN1_STRING_free((WOLFSSL_ASN1_STRING *)pval);
goto error; goto error;
} }
@ -55956,7 +55956,7 @@ static int GetStaticEphemeralKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
if (keySz) *keySz = 0; if (keySz) *keySz = 0;
#ifndef SINGLE_THREADED #ifndef SINGLE_THREADED
if (ctx->staticKELockInit && if (ctx->staticKELockInit &&
(ret = wc_LockMutex(&ctx->staticKELock)) != 0) { (ret = wc_LockMutex(&ctx->staticKELock)) != 0) {
return ret; return ret;
} }

View File

@ -13679,7 +13679,7 @@ static int MatchBaseName(int type, const char* name, int nameSz,
if (base == NULL || baseSz <= 0 || name == NULL || nameSz <= 0 || if (base == NULL || baseSz <= 0 || name == NULL || nameSz <= 0 ||
name[0] == '.' || nameSz < baseSz || name[0] == '.' || nameSz < baseSz ||
(type != ASN_RFC822_TYPE && type != ASN_DNS_TYPE && (type != ASN_RFC822_TYPE && type != ASN_DNS_TYPE &&
type != ASN_DIR_TYPE)) { type != ASN_DIR_TYPE)) {
return 0; return 0;
} }