Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions linuxkm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ else
QFLAG := --quiet
endif

# Some versions and invocations of Gnu make have glitched on --quiet builds,
# due to a bug around $(MAKEFLAGS), like so:
# "No rule to make target 's'. Stop."
# If you encounter this, try uncommenting the below line, which is supported on
# Gnu make 4.3+:
# NO_SILENT := --no-silent

ifndef LIBWOLFSSL_NAME
LIBWOLFSSL_NAME := libwolfssl
endif
Expand Down Expand Up @@ -331,21 +338,19 @@ ifeq "$(ENABLED_LINUXKM_PIE)" "yes"
@RELOC_TMP=$$(mktemp "$(MAKE_TMPDIR)/wc_linuxkm_pie_reloc_tab.c.XXXXXX")
@trap 'rm "$$RELOC_TMP"' EXIT
@if [[ -f "$@" ]]; then touch -r "$@" "$$RELOC_TMP"; fi
# --no-silent works around make bug that otherwise leads to "No rule to make target 's'. Stop." (due to a bug around $(MAKEFLAGS)) in --quiet builds.
+$(MAKE) $(QFLAG) --no-print-directory --no-silent ARCH='$(KERNEL_ARCH)' $(OVERRIDE_PATHS) $(CROSS_COMPILE) -C '$(KERNEL_ROOT)' M='$(MODULE_TOP)' $(KBUILD_EXTRA_FLAGS) CC_FLAGS_FTRACE=
+$(MAKE) $(QFLAG) $(NO_SILENT) --no-print-directory ARCH='$(KERNEL_ARCH)' $(OVERRIDE_PATHS) $(CROSS_COMPILE) -C '$(KERNEL_ROOT)' M='$(MODULE_TOP)' $(KBUILD_EXTRA_FLAGS) CC_FLAGS_FTRACE=
# if the above make didn't build a fresh libwolfssl.ko, then the module is already up to date and we leave it untouched, assuring stability for purposes of module-update-fips-hash.
@if [[ ! "$@" -nt "$$RELOC_TMP" ]]; then echo ' Module already up-to-date.'; exit 0; fi
@SECTION_MAP=$$(mktemp)
@trap 'rm "$$RELOC_TMP" "$$SECTION_MAP"' EXIT
@export SECTION_MAP
@$(READELF) --wide --sections --symbols "$@" | $(GENERATE_SECTION_MAP)
@$(READELF) --wide --relocs "$@" | $(GENERATE_RELOC_TAB) >| '$(MODULE_TOP)/linuxkm/wc_linuxkm_pie_reloc_tab.c'
+$(MAKE) $(QFLAG) --no-print-directory --no-silent ARCH='$(KERNEL_ARCH)' $(OVERRIDE_PATHS) $(CROSS_COMPILE) -C '$(KERNEL_ROOT)' M='$(MODULE_TOP)' $(KBUILD_EXTRA_FLAGS) CC_FLAGS_FTRACE=
+$(MAKE) $(QFLAG) --no-print-directory $(NO_SILENT) ARCH='$(KERNEL_ARCH)' $(OVERRIDE_PATHS) $(CROSS_COMPILE) -C '$(KERNEL_ROOT)' M='$(MODULE_TOP)' $(KBUILD_EXTRA_FLAGS) CC_FLAGS_FTRACE=
@$(READELF) --wide --relocs "$@" | $(GENERATE_RELOC_TAB) >| "$$RELOC_TMP"
@if diff '$(MODULE_TOP)/linuxkm/wc_linuxkm_pie_reloc_tab.c' "$$RELOC_TMP"; then echo " Relocation table is stable."; else echo "PIE failed: relocation table is unstable." 1>&2; exit 1; fi
else
# --no-silent works around make bug that otherwise leads to "No rule to make target 's'. Stop." (due to a bug around $(MAKEFLAGS)) in --quiet builds.
+$(MAKE) $(QFLAG) --no-print-directory --no-silent ARCH='$(KERNEL_ARCH)' $(OVERRIDE_PATHS) $(CROSS_COMPILE) -C '$(KERNEL_ROOT)' M='$(MODULE_TOP)' $(KBUILD_EXTRA_FLAGS)
+$(MAKE) $(QFLAG) --no-print-directory $(NO_SILENT) ARCH='$(KERNEL_ARCH)' $(OVERRIDE_PATHS) $(CROSS_COMPILE) -C '$(KERNEL_ROOT)' M='$(MODULE_TOP)' $(KBUILD_EXTRA_FLAGS)
endif

$(MODULE_TOP)/$(LIBWOLFSSL_NAME).ko: $(LIBWOLFSSL_NAME).ko
Expand All @@ -368,7 +373,7 @@ module-update-fips-hash: $(LIBWOLFSSL_NAME).ko
if [[ '$(FIPS_HASH)' == "$$current_verifyCore" ]]; then echo ' Supplied FIPS_HASH matches existing verifyCore -- no update needed.'; exit 0; fi; \
echo -n '$(FIPS_HASH)' | dd bs=1 conv=notrunc of="$<" seek=$$verifyCore_offset count=64 status=none && \
echo " FIPS verifyCore updated successfully." && \
if [[ -f '$(LIBWOLFSSL_NAME).ko.signed' ]]; then $(MAKE) $(QFLAG) --no-print-directory --no-silent -C . '$(LIBWOLFSSL_NAME).ko.signed'; fi
if [[ -f '$(LIBWOLFSSL_NAME).ko.signed' ]]; then $(MAKE) $(QFLAG) --no-print-directory $(NO_SILENT) -C . '$(LIBWOLFSSL_NAME).ko.signed'; fi


# linuxkm-fips-hash implements offline (no-load) FIPS hash calculation and graft-in.
Expand Down Expand Up @@ -431,7 +436,7 @@ linuxkm-fips-hash: $(MODULE_TOP)/libwolfssl-user-build/src/.libs/libwolfssl.so l
module-with-matching-fips-hash: $(LIBWOLFSSL_NAME).ko linuxkm-fips-hash
@set -e
@./linuxkm-fips-hash-wrapper.sh "$<" $(QFLAG) $(VFLAG)
+$(MAKE) $(QFLAG) --no-print-directory --no-silent -C . '$(LIBWOLFSSL_NAME).ko.signed'
+$(MAKE) $(QFLAG) --no-print-directory $(NO_SILENT) -C . '$(LIBWOLFSSL_NAME).ko.signed'

.PHONY: module-with-matching-fips-hash-no-sign
module-with-matching-fips-hash-no-sign: $(LIBWOLFSSL_NAME).ko linuxkm-fips-hash
Expand Down Expand Up @@ -482,13 +487,13 @@ endif

.PHONY: install modules_install
install modules_install:
+$(MAKE) $(QFLAG) --no-silent -C $(KERNEL_ROOT) M=$(MODULE_TOP) src=$(SRC_TOP) INSTALL_MOD_DIR=wolfssl modules_install
+$(MAKE) $(QFLAG) $(NO_SILENT) -C $(KERNEL_ROOT) M=$(MODULE_TOP) src=$(SRC_TOP) INSTALL_MOD_DIR=wolfssl modules_install

.PHONY: clean
# note, must supply $(MODULE_TOP) as the src value for clean so that Kbuild is included, else
# the top Makefile (which is not for the kernel build) would be included here.
clean:
+$(MAKE) $(QFLAG) --no-silent -C $(KERNEL_ROOT) M=$(MODULE_TOP) src=$(MODULE_TOP) clean
+$(MAKE) $(QFLAG) $(NO_SILENT) -C $(KERNEL_ROOT) M=$(MODULE_TOP) src=$(MODULE_TOP) clean
$(RM) -rf '$(MODULE_TOP)/linuxkm'
$(RM) -rf '$(MODULE_TOP)/wolfcrypt'
$(RM) -rf '$(MODULE_TOP)/src'
Expand Down
21 changes: 15 additions & 6 deletions linuxkm/lkcapi_aes_glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -1489,21 +1489,30 @@ static int AesGcmCrypt_1(struct aead_request *req, int decrypt_p, int rfc4106_p)
}
}
else {
err = wc_AesGcmEncrypt(aes_copy, out_text, in_text, req->cryptlen,
err = wc_AesGcmSetExtIV(aes_copy,
#ifdef LINUXKM_LKCAPI_REGISTER_AESGCM_RFC4106
rfc4106_p ? rfc4106_iv :
rfc4106_p ? rfc4106_iv :
#endif
sk_walk.iv, GCM_NONCE_MID_SZ,
authTag, tfm->authsize,
assoc, assoclen);
sk_walk.iv, GCM_NONCE_MID_SZ);
if (unlikely(err)) {
pr_err("%s: wc_AesGcmSetExtIV() failed: %d\n",
crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err);
err = -EINVAL;
goto out;
}

{
byte ivOut[GCM_NONCE_MID_SZ];
err = wc_AesGcmEncrypt_ex(aes_copy, out_text, in_text, req->cryptlen, ivOut, GCM_NONCE_MID_SZ, authTag,
tfm->authsize, assoc, assoclen);
}

if (unlikely(err)) {
pr_err("%s: wc_AesGcmEncrypt failed: %d\n",
crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err);
err = -EINVAL;
goto out;
}

}

if (sg_buf) {
Expand Down
8 changes: 4 additions & 4 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -30477,10 +30477,10 @@ static int test_wc_CryptoCb_registry(void)
NULL), 0);
ExpectIntEQ(wc_CryptoCb_GetDevIdAtIndex(0), devId);

/* Re-registering the same device id updates the entry instead of growing
* the device table. */
ExpectIntEQ(wc_CryptoCb_RegisterDevice(devId, NULL, (void*)1), 0);
ExpectIntEQ(wc_CryptoCb_GetDevIdAtIndex(0), devId);
/* Re-registering the same device id used to (5.9.2-) update the entry
* instead of growing the device table. Now it just returns ALREADY_E --
* the way to update it is to unregister and freshly register. */
ExpectIntEQ(wc_CryptoCb_RegisterDevice(devId, NULL, (void*)1), ALREADY_E);

wc_CryptoCb_UnRegisterDevice(INVALID_DEVID);
ExpectIntEQ(wc_CryptoCb_GetDevIdAtIndex(0), devId);
Expand Down
5 changes: 3 additions & 2 deletions tests/api/test_aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@
* (e.g. WOLFSSL_ARMASM on ARMv8 with crypto extensions).
* In all these cases the corrupted struct is ignored and the op returns 0. */
#if defined(WOLF_CRYPTO_CB_FIND) || defined(WOLF_CRYPTO_CB_ONLY_AES) || \
defined(WOLFSSL_ARMASM) || defined(HAVE_FIPS) || defined(HAVE_SELFTEST)
defined(WOLFSSL_ARMASM) || defined(HAVE_FIPS) || defined(HAVE_SELFTEST) || \
defined(WOLFSSL_AFALG)
/* The aes->rounds=0 corruption trick relies on the pure-C AesEncryptBlocks_C
* guard (if r==0 return KEYUSAGE_E). When AES is offloaded (crypto-cb / asm)
* or provided by the FIPS/self-test module, that guard is absent: rounds=0
Expand Down Expand Up @@ -9910,7 +9911,7 @@ int test_wc_AesKeyExportArgMcdc(void)
byte id[4] = { 1, 2, 3, 4 };
const char* label = "test-label";

#ifndef WC_NO_CONSTRUCTORS
#if !defined(WC_NO_CONSTRUCTORS) && !defined(WOLFSSL_KCAPI)
/*
* _AesNew_common() (aes.c ~14766, ~14774, ~14783) validates its
* id/idLen/label arguments differently per construction path. Each
Expand Down
96 changes: 70 additions & 26 deletions wolfcrypt/src/port/af_alg/afalg_aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@

static const char WC_TYPE_SYMKEY[] = "skcipher";

#ifdef HAVE_AESGCM
#ifdef WOLFSSL_AFALG_XILINX_AES
static const char WC_NAME_AESGCM[] = "xilinx-zynqmp-aes";
static const char* WC_TYPE_AEAD = WC_TYPE_SYMKEY;
#else
static const char WC_NAME_AESGCM[] = "gcm(aes)";
static const char WC_TYPE_AEAD[] = "aead";
#endif
#endif

static int wc_AesSetup(Aes* aes, const char* type, const char* name, int ivSz, int aadSz)
{
#ifdef WOLFSSL_AFALG_XILINX_AES
Expand Down Expand Up @@ -88,12 +98,20 @@ static int wc_AesSetup(Aes* aes, const char* type, const char* name, int ivSz, i
(void)aadSz;
#else
aes->msg.msg_controllen = CMSG_SPACE(4);
if (aadSz > 0) {
aes->msg.msg_controllen += CMSG_SPACE(4);
}
if (ivSz > 0) {
aes->msg.msg_controllen += CMSG_SPACE((sizeof(struct af_alg_iv) + ivSz));
}
/* Always reserve ASSOCLEN slot for AEAD (gcm(aes)). Value may be 0 on any
* given call. skcipher paths (CBC etc.) simply won't use the 3rd cmsg. */
if ((aadSz > 0)
#ifdef HAVE_AESGCM
|| (strcmp(type, WC_TYPE_AEAD) == 0)
#endif
)
{
aes->msg.msg_controllen += CMSG_SPACE(4);
}

#endif

if (wc_Afalg_SetOp(CMSG_FIRSTHDR(&(aes->msg)), aes->dir) < 0) {
Expand Down Expand Up @@ -174,6 +192,10 @@ int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
}
#endif

if (aes->dir != AES_ENCRYPTION) {
return KEYUSAGE_E;
}

if (aes->rdFd == WC_SOCK_NOTSET) {
if ((ret = wc_AesSetup(aes, WC_TYPE_SYMKEY, WC_NAME_AESCBC,
AES_IV_SIZE, 0)) != 0) {
Expand Down Expand Up @@ -239,6 +261,10 @@ int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
#endif
}

if (aes->dir != AES_DECRYPTION) {
return KEYUSAGE_E;
}

if (aes->rdFd == WC_SOCK_NOTSET) {
if ((ret = wc_AesSetup(aes, WC_TYPE_SYMKEY, WC_NAME_AESCBC,
AES_IV_SIZE, 0)) != 0) {
Expand Down Expand Up @@ -336,12 +362,20 @@ static int wc_Afalg_AesDirect(Aes* aes, byte* out, const byte* in, word32 sz)
#if defined(WOLFSSL_AES_DIRECT) && defined(WOLFSSL_AFALG)
int wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
{
if (aes && (aes->dir != AES_ENCRYPTION)) {
return KEYUSAGE_E;
}

return wc_Afalg_AesDirect(aes, out, in, WC_AES_BLOCK_SIZE);
}


int wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
{
if (aes && (aes->dir != AES_DECRYPTION)) {
return KEYUSAGE_E;
}

return wc_Afalg_AesDirect(aes, out, in, WC_AES_BLOCK_SIZE);
}

Expand Down Expand Up @@ -380,6 +414,10 @@ int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
return BAD_FUNC_ARG;
}

if (aes->dir != AES_ENCRYPTION) {
return KEYUSAGE_E;
}

/* consume any unused bytes left in aes->tmp */
tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
while (aes->left && sz) {
Expand Down Expand Up @@ -478,15 +516,6 @@ int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,

#ifdef HAVE_AESGCM


#ifdef WOLFSSL_AFALG_XILINX_AES
static const char WC_NAME_AESGCM[] = "xilinx-zynqmp-aes";
static const char* WC_TYPE_AEAD = WC_TYPE_SYMKEY;
#else
static const char WC_NAME_AESGCM[] = "gcm(aes)";
static const char WC_TYPE_AEAD[] = "aead";
#endif

#ifndef WC_SYSTEM_AESGCM_IV
/* size of IV allowed on system for AES-GCM */
#define WC_SYSTEM_AESGCM_IV 12
Expand Down Expand Up @@ -526,6 +555,7 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
#endif
aes->keylen = len;
aes->rounds = len/4 + 6;
aes->dir = AES_ENCRYPTION;

if (aes->rdFd > WC_SOCK_NOTSET) {
(void)close(aes->rdFd);
Expand Down Expand Up @@ -573,7 +603,10 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
byte scratch[WC_AES_BLOCK_SIZE];

/* argument checks */
if (aes == NULL || authTagSz > WC_AES_BLOCK_SIZE) {
if (aes == NULL || authTagSz > WC_AES_BLOCK_SIZE ||
(sz > 0 && (in == NULL || out == NULL)) ||
authTag == NULL || (authInSz > 0 && authIn == NULL))
{
return BAD_FUNC_ARG;
}

Expand Down Expand Up @@ -696,13 +729,14 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
xorbuf(authTag, scratch, authTagSz);
}
#else
if (authInSz > 0) {
cmsg = CMSG_NXTHDR(msg, cmsg);
ret = wc_Afalg_SetAad(cmsg, authInSz);
if (ret < 0) {
WOLFSSL_MSG("Unable to set AAD size");
return ret;
}
/* Always set AAD length (even 0). This is required by the AF_ALG AEAD interface
* and prevents kernel state mismatch when switching between AAD and no-AAD
* operations on the same rdFd. */
cmsg = CMSG_NXTHDR(msg, cmsg);
ret = wc_Afalg_SetAad(cmsg, authInSz);
if (ret < 0) {
WOLFSSL_MSG("Unable to set AAD size");
return ret;
}

/* set data to be encrypted*/
Expand Down Expand Up @@ -901,12 +935,14 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
}

#else
if (authInSz > 0) {
cmsg = CMSG_NXTHDR(msg, cmsg);
ret = wc_Afalg_SetAad(cmsg, authInSz);
if (ret < 0) {
return ret;
}
/* Always set AAD length (even 0). This is required by the AF_ALG AEAD interface
* and prevents kernel state mismatch when switching between AAD and no-AAD
* operations on the same rdFd. */

cmsg = CMSG_NXTHDR(msg, cmsg);
ret = wc_Afalg_SetAad(cmsg, authInSz);
if (ret < 0) {
return ret;
}

/* set data to be decrypted*/
Expand Down Expand Up @@ -955,12 +991,20 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
#ifdef HAVE_AES_ECB
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
if (aes && (aes->dir != AES_ENCRYPTION)) {
return KEYUSAGE_E;
}

return wc_Afalg_AesDirect(aes, out, in, sz);
}


int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
if (aes && (aes->dir != AES_DECRYPTION)) {
return KEYUSAGE_E;
}

return wc_Afalg_AesDirect(aes, out, in, sz);
}
#endif /* HAVE_AES_ECB */
Expand Down
2 changes: 1 addition & 1 deletion wolfcrypt/src/port/kcapi/kcapi_aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
if (ret == -EBADMSG)
ret = AES_GCM_AUTH_E;
}
else if (ret != outbuflen) {
else if (ret > outbuflen) {
WOLFSSL_MSG("GcmDecrypt produced wrong output length");
ret = BAD_FUNC_ARG;
}
Expand Down
Loading