mirror of https://github.com/wolfSSL/wolfssl.git
linuxkm: various fixes for LKCAPI wrapper for AES-CBC (now passing kernel-native
self-test and crypto fuzzer), and de-experimentalize it. wolfssl/wolfcrypt/types.h: add definitions for WOLFSSL_WORD_SIZE_LOG2. wolfcrypt/src/misc.c: fix xorbuf() to make the XorWords() reachable; also, refactor integer division and modulus ops as masks and shifts, and add pragma to suppress linuxkm FORTIFY_SOURCE false positive -Wmaybe-uninitialized.pull/8534/head
parent
7d102a1816
commit
dc2e2631bc
|
@ -9065,7 +9065,6 @@ then
|
|||
all) test "$ENABLED_EXPERIMENTAL" = "yes" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: requires --enable-experimental.])
|
||||
AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_ALL" ;;
|
||||
'cbc(aes)') test "$ENABLED_AESCBC" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: AES-CBC implementation not enabled.])
|
||||
test "$ENABLED_EXPERIMENTAL" = "yes" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: requires --enable-experimental.])
|
||||
AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_AESCBC" ;;
|
||||
'cfb(aes)') test "$ENABLED_AESCFB" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: AES-CFB implementation not enabled.])
|
||||
test "$ENABLED_EXPERIMENTAL" = "yes" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: requires --enable-experimental.])
|
||||
|
|
|
@ -89,9 +89,6 @@ static int disable_setkey_warnings = 0;
|
|||
#if defined(HAVE_AES_CBC) && \
|
||||
(defined(LINUXKM_LKCAPI_REGISTER_ALL) || \
|
||||
defined(LINUXKM_LKCAPI_REGISTER_AESCBC))
|
||||
#ifndef WOLFSSL_EXPERIMENTAL_SETTINGS
|
||||
#error Experimental settings without WOLFSSL_EXPERIMENTAL_SETTINGS
|
||||
#endif
|
||||
static int linuxkm_test_aescbc(void);
|
||||
#endif
|
||||
#if defined(WOLFSSL_AES_CFB) && \
|
||||
|
@ -214,7 +211,7 @@ static int km_AesSetKeyCommon(struct km_AesCtx * ctx, const u8 *in_key,
|
|||
if (unlikely(err)) {
|
||||
if (! disable_setkey_warnings)
|
||||
pr_err("%s: wc_AesSetKey for encryption key failed: %d\n", name, err);
|
||||
return -ENOKEY;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctx->aes_decrypt) {
|
||||
|
@ -225,7 +222,7 @@ static int km_AesSetKeyCommon(struct km_AesCtx * ctx, const u8 *in_key,
|
|||
if (! disable_setkey_warnings)
|
||||
pr_err("%s: wc_AesSetKey for decryption key failed: %d\n",
|
||||
name, err);
|
||||
return -ENOKEY;
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,38 +275,34 @@ static int km_AesCbcEncrypt(struct skcipher_request *req)
|
|||
err = skcipher_walk_virt(&walk, req, false);
|
||||
|
||||
if (unlikely(err)) {
|
||||
pr_err("%s: skcipher_walk_virt failed: %d\n",
|
||||
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
|
||||
return err;
|
||||
}
|
||||
|
||||
while ((nbytes = walk.nbytes) != 0) {
|
||||
err = wc_AesSetIV(ctx->aes_encrypt, walk.iv);
|
||||
err = wc_AesSetIV(ctx->aes_encrypt, walk.iv);
|
||||
|
||||
if (unlikely(err)) {
|
||||
pr_err("%s: wc_AesSetIV failed: %d\n",
|
||||
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = wc_AesCbcEncrypt(ctx->aes_encrypt, walk.dst.virt.addr,
|
||||
walk.src.virt.addr, nbytes);
|
||||
|
||||
if (unlikely(err)) {
|
||||
pr_err("%s: wc_AesCbcEncrypt failed: %d\n",
|
||||
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
|
||||
|
||||
if (unlikely(err)) {
|
||||
pr_err("%s: skcipher_walk_done failed: %d\n",
|
||||
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
|
||||
return err;
|
||||
}
|
||||
if (unlikely(err)) {
|
||||
pr_err("%s: wc_AesSetIV failed: %d\n",
|
||||
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
while ((nbytes = walk.nbytes) != 0) {
|
||||
err = wc_AesCbcEncrypt(ctx->aes_encrypt, walk.dst.virt.addr,
|
||||
walk.src.virt.addr, nbytes & (~(WC_AES_BLOCK_SIZE - 1)));
|
||||
|
||||
if (unlikely(err)) {
|
||||
pr_err("%s: wc_AesCbcEncrypt failed for %u bytes: %d\n",
|
||||
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), nbytes, err);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nbytes &= WC_AES_BLOCK_SIZE - 1;
|
||||
err = skcipher_walk_done(&walk, nbytes);
|
||||
}
|
||||
|
||||
/* copy iv from wolfCrypt back to walk.iv */
|
||||
XMEMCPY(walk.iv, ctx->aes_encrypt->reg, WC_AES_BLOCK_SIZE);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -327,39 +320,35 @@ static int km_AesCbcDecrypt(struct skcipher_request *req)
|
|||
err = skcipher_walk_virt(&walk, req, false);
|
||||
|
||||
if (unlikely(err)) {
|
||||
pr_err("%s: skcipher_walk_virt failed: %d\n",
|
||||
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
|
||||
return err;
|
||||
}
|
||||
|
||||
while ((nbytes = walk.nbytes) != 0) {
|
||||
err = wc_AesSetIV(ctx->aes_decrypt, walk.iv);
|
||||
err = wc_AesSetIV(ctx->aes_decrypt, walk.iv);
|
||||
|
||||
if (unlikely(err)) {
|
||||
if (! disable_setkey_warnings)
|
||||
pr_err("%s: wc_AesSetKey failed: %d\n",
|
||||
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = wc_AesCbcDecrypt(ctx->aes_decrypt, walk.dst.virt.addr,
|
||||
walk.src.virt.addr, nbytes);
|
||||
|
||||
if (unlikely(err)) {
|
||||
pr_err("%s: wc_AesCbcDecrypt failed: %d\n",
|
||||
if (unlikely(err)) {
|
||||
if (! disable_setkey_warnings)
|
||||
pr_err("%s: wc_AesSetKey failed: %d\n",
|
||||
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
|
||||
|
||||
if (unlikely(err)) {
|
||||
pr_err("%s: skcipher_walk_done failed: %d\n",
|
||||
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
|
||||
return err;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
while ((nbytes = walk.nbytes) != 0) {
|
||||
err = wc_AesCbcDecrypt(ctx->aes_decrypt, walk.dst.virt.addr,
|
||||
walk.src.virt.addr, nbytes & (~(WC_AES_BLOCK_SIZE - 1)));
|
||||
|
||||
if (unlikely(err)) {
|
||||
pr_err("%s: wc_AesCbcDecrypt failed for %u bytes: %d\n",
|
||||
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), nbytes, err);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nbytes &= WC_AES_BLOCK_SIZE - 1;
|
||||
err = skcipher_walk_done(&walk, nbytes);
|
||||
}
|
||||
|
||||
/* copy iv from wolfCrypt back to walk.iv */
|
||||
XMEMCPY(walk.iv, ctx->aes_decrypt->reg, WC_AES_BLOCK_SIZE);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -556,7 +545,7 @@ static int km_AesGcmSetKey(struct crypto_aead *tfm, const u8 *in_key,
|
|||
if (! disable_setkey_warnings)
|
||||
pr_err("%s: wc_AesGcmSetKey failed: %d\n",
|
||||
crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err);
|
||||
return -ENOKEY;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -484,6 +484,9 @@ counts, placing the result in <*buf>. */
|
|||
|
||||
WC_MISC_STATIC WC_INLINE void xorbuf(void* buf, const void* mask, word32 count)
|
||||
{
|
||||
/* Leave no doubt that WOLFSSL_WORD_SIZE is a power of 2. */
|
||||
wc_static_assert((WOLFSSL_WORD_SIZE & (WOLFSSL_WORD_SIZE - 1)) == 0);
|
||||
|
||||
word32 i;
|
||||
byte* b;
|
||||
const byte* m;
|
||||
|
@ -491,8 +494,9 @@ WC_MISC_STATIC WC_INLINE void xorbuf(void* buf, const void* mask, word32 count)
|
|||
b = (byte*)buf;
|
||||
m = (const byte*)mask;
|
||||
|
||||
if (((wc_ptr_t)b) % WOLFSSL_WORD_SIZE ==
|
||||
((wc_ptr_t)m) % WOLFSSL_WORD_SIZE) {
|
||||
if ((((wc_ptr_t)b) & (WOLFSSL_WORD_SIZE - 1)) ==
|
||||
(((wc_ptr_t)m) & (WOLFSSL_WORD_SIZE - 1)))
|
||||
{
|
||||
/* type-punning helpers */
|
||||
union {
|
||||
byte* bp;
|
||||
|
@ -505,16 +509,25 @@ WC_MISC_STATIC WC_INLINE void xorbuf(void* buf, const void* mask, word32 count)
|
|||
/* Alignment checks out. Possible to XOR words. */
|
||||
/* Move alignment so that it lines up with a
|
||||
* WOLFSSL_WORD_SIZE boundary */
|
||||
while (((wc_ptr_t)buf) % WOLFSSL_WORD_SIZE != 0 && count > 0) {
|
||||
while ((((wc_ptr_t)b) & (WOLFSSL_WORD_SIZE - 1)) != 0 && count > 0)
|
||||
{
|
||||
*(b++) ^= *(m++);
|
||||
count--;
|
||||
}
|
||||
tpb.bp = b;
|
||||
tpm.bp = m;
|
||||
XorWords( &tpb.wp, &tpm.wp, count / WOLFSSL_WORD_SIZE);
|
||||
/* Work around false positives from linuxkm CONFIG_FORTIFY_SOURCE. */
|
||||
#if defined(WOLFSSL_LINUXKM) && defined(CONFIG_FORTIFY_SOURCE)
|
||||
PRAGMA_GCC_DIAG_PUSH;
|
||||
PRAGMA_GCC("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
|
||||
#endif
|
||||
XorWords(&tpb.wp, &tpm.wp, count >> WOLFSSL_WORD_SIZE_LOG2);
|
||||
#if defined(WOLFSSL_LINUXKM) && defined(CONFIG_FORTIFY_SOURCE)
|
||||
PRAGMA_GCC_DIAG_POP;
|
||||
#endif
|
||||
b = tpb.bp;
|
||||
m = tpm.bp;
|
||||
count %= WOLFSSL_WORD_SIZE;
|
||||
count &= (WOLFSSL_WORD_SIZE - 1);
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
|
@ -524,7 +537,7 @@ WC_MISC_STATIC WC_INLINE void xorbuf(void* buf, const void* mask, word32 count)
|
|||
|
||||
#ifndef WOLFSSL_NO_FORCE_ZERO
|
||||
/* This routine fills the first len bytes of the memory area pointed by mem
|
||||
with zeros. It ensures compiler optimizations doesn't skip it */
|
||||
with zeros. It ensures compiler optimization doesn't skip it */
|
||||
WC_MISC_STATIC WC_INLINE void ForceZero(void* mem, word32 len)
|
||||
{
|
||||
volatile byte* z = (volatile byte*)mem;
|
||||
|
|
|
@ -327,12 +327,15 @@ decouple library dependencies with standard string, memory and so on.
|
|||
|
||||
#if defined(NO_64BIT)
|
||||
typedef word32 wolfssl_word;
|
||||
#define WOLFSSL_WORD_SIZE_LOG2 2
|
||||
#undef WORD64_AVAILABLE
|
||||
#else
|
||||
#ifdef WC_64BIT_CPU
|
||||
typedef word64 wolfssl_word;
|
||||
#define WOLFSSL_WORD_SIZE_LOG2 3
|
||||
#else
|
||||
typedef word32 wolfssl_word;
|
||||
#define WOLFSSL_WORD_SIZE_LOG2 2
|
||||
#ifdef WORD64_AVAILABLE
|
||||
#define WOLFCRYPT_SLOW_WORD64
|
||||
#endif
|
||||
|
@ -344,12 +347,14 @@ decouple library dependencies with standard string, memory and so on.
|
|||
#undef WORD64_AVAILABLE
|
||||
#endif
|
||||
typedef word16 wolfssl_word;
|
||||
#define WOLFSSL_WORD_SIZE_LOG2 1
|
||||
#define MP_16BIT /* for mp_int, mp_word needs to be twice as big as \
|
||||
* mp_digit, no 64 bit type so make mp_digit 16 bit */
|
||||
|
||||
#else
|
||||
#undef WORD64_AVAILABLE
|
||||
typedef word32 wolfssl_word;
|
||||
#define WOLFSSL_WORD_SIZE_LOG2 2
|
||||
#define MP_16BIT /* for mp_int, mp_word needs to be twice as big as \
|
||||
* mp_digit, no 64 bit type so make mp_digit 16 bit */
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue