diff --git a/configure.ac b/configure.ac index 0c44b6aed..68cc4f0a4 100644 --- a/configure.ac +++ b/configure.ac @@ -9421,6 +9421,20 @@ then 'ofb(aes)') test "$ENABLED_AESOFB" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: AES-OFB implementation not enabled.]) AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_AESOFB" ;; 'ecb(aes)') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_AESECB -DHAVE_AES_ECB" ;; + 'sha1') test "$ENABLED_SHA" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: SHA-1 implementation not enabled.]) + AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_SHA1" ;; + 'sha2') test "$ENABLED_SHA224" != "no" || test "$ENABLED_SHA256" != "no" || test "$ENABLED_SHA384" != "no" || test "$ENABLED_SHA512" != "no" || \ + AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: No SHA-2 implementations are enabled.]) + AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_SHA2" ;; + 'sha3') test "$ENABLED_SHA3" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: SHA-3 implementation not enabled.]) + AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_SHA3" ;; + 'hmac(sha1)') test "$ENABLED_SHA" != "no" && test "$ENABLED_HMAC" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: SHA-1 HMAC implementation not enabled.]) + AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_SHA1_HMAC" ;; + 'hmac(sha2)') (test "$ENABLED_SHA224" != "no" || test "$ENABLED_SHA256" != "no" || test "$ENABLED_SHA384" != "no" || test "$ENABLED_SHA512" != "no") && \ + test "$ENABLED_HMAC" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: No SHA-2 HMAC implementations are enabled.]) + AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_SHA2_HMAC" ;; + 'hmac(sha3)') test "$ENABLED_SHA3" != "no" && test "$ENABLED_HMAC" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: SHA-3 HMAC implementation not enabled.]) + AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_SHA3_HMAC" ;; 'ecdsa') test "$ENABLED_ECC" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: ECDSA implementation not enabled.]) AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_ECDSA" ;; 'ecdh') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_ECDH" ;; @@ -9436,6 +9450,12 @@ then '-ctr(aes)') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_DONT_REGISTER_AESCTR" ;; '-ofb(aes)') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_DONT_REGISTER_AESOFB" ;; '-ecb(aes)') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_DONT_REGISTER_AESECB" ;; + '-sha1') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_DONT_REGISTER_SHA1" ;; + '-sha2') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_DONT_REGISTER_SHA2" ;; + '-sha3') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_DONT_REGISTER_SHA3" ;; + '-hmac(sha1)') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_DONT_REGISTER_SHA1_HMAC" ;; + '-hmac(sha2)') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_DONT_REGISTER_SHA2_HMAC" ;; + '-hmac(sha3)') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_DONT_REGISTER_SHA3_HMAC" ;; '-ecdsa') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_DONT_REGISTER_ECDSA" ;; '-ecdh') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_DONT_REGISTER_ECDH" ;; '-rsa') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_DONT_REGISTER_RSA" ;; diff --git a/linuxkm/linuxkm_wc_port.h b/linuxkm/linuxkm_wc_port.h index f0afd004d..81f4efa52 100644 --- a/linuxkm/linuxkm_wc_port.h +++ b/linuxkm/linuxkm_wc_port.h @@ -293,6 +293,7 @@ #include #include #include + #include #include #include #include diff --git a/linuxkm/lkcapi_aes_glue.c b/linuxkm/lkcapi_aes_glue.c index 3b101283f..d4b13fd47 100644 --- a/linuxkm/lkcapi_aes_glue.c +++ b/linuxkm/lkcapi_aes_glue.c @@ -25,12 +25,12 @@ #error lkcapi_aes_glue.c compiled with NO_AES. #endif +#include + #if defined(WC_LINUXKM_C_FALLBACK_IN_SHIMS) && !defined(WC_FLAG_DONT_USE_AESNI) #error WC_LINUXKM_C_FALLBACK_IN_SHIMS is defined but WC_FLAG_DONT_USE_AESNI is missing. #endif -#include - /* note the FIPS code will be returned on failure even in non-FIPS builds. */ #define LINUXKM_LKCAPI_AES_KAT_MISMATCH_E AES_KAT_FIPS_E #define LINUXKM_LKCAPI_AESGCM_KAT_MISMATCH_E AESGCM_KAT_FIPS_E @@ -1001,7 +1001,12 @@ static int AesGcmCrypt_1(struct aead_request *req, int decrypt_p, int rfc4106_p) if (req->src->length >= assoclen && req->src->length) { scatterwalk_start(&assocSgWalk, req->src); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) + scatterwalk_map(&assocSgWalk); + assoc = assocSgWalk.addr; +#else assoc = scatterwalk_map(&assocSgWalk); +#endif if (unlikely(IS_ERR(assoc))) { pr_err("%s: scatterwalk_map failed: %ld\n", crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), @@ -1033,8 +1038,13 @@ static int AesGcmCrypt_1(struct aead_request *req, int decrypt_p, int rfc4106_p) if (assocmem) free(assocmem); - else + else { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) + scatterwalk_unmap(&assocSgWalk); +#else scatterwalk_unmap(assoc); +#endif + } if (unlikely(err)) { pr_err("%s: %s failed: %d\n", @@ -1184,7 +1194,12 @@ static int AesGcmCrypt_1(struct aead_request *req, int decrypt_p, int rfc4106_p) (req->dst->length >= req->assoclen + req->cryptlen)) { scatterwalk_start(&in_walk, req->src); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) + scatterwalk_map(&in_walk); + in_map = in_walk.addr; +#else in_map = scatterwalk_map(&in_walk); +#endif if (unlikely(IS_ERR(in_map))) { pr_err("%s: scatterwalk_map failed: %ld\n", crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), @@ -1195,7 +1210,12 @@ static int AesGcmCrypt_1(struct aead_request *req, int decrypt_p, int rfc4106_p) in_text = in_map + req->assoclen; scatterwalk_start(&out_walk, req->dst); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) + scatterwalk_map(&out_walk); + out_map = out_walk.addr; +#else out_map = scatterwalk_map(&out_walk); +#endif if (unlikely(IS_ERR(out_map))) { pr_err("%s: scatterwalk_map failed: %ld\n", crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), @@ -1281,10 +1301,20 @@ out: free(sg_buf); } else { - if (in_map) + if (in_map) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) + scatterwalk_unmap(&in_walk); +#else scatterwalk_unmap(in_map); - if (out_map) +#endif + } + if (out_map) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) + scatterwalk_unmap(&out_walk); +#else scatterwalk_unmap(out_map); +#endif + } } km_AesFree(&aes_copy); diff --git a/linuxkm/lkcapi_glue.c b/linuxkm/lkcapi_glue.c index dc5aa8fa3..985f06c3d 100644 --- a/linuxkm/lkcapi_glue.c +++ b/linuxkm/lkcapi_glue.c @@ -176,10 +176,45 @@ WC_MAYBE_UNUSED static int check_aead_driver_masking(struct crypto_aead *tfm, co #endif } +WC_MAYBE_UNUSED static int check_shash_driver_masking(struct crypto_shash *tfm, const char *alg_name, const char *expected_driver_name) { +#ifdef LINUXKM_LKCAPI_PRIORITY_ALLOW_MASKING + (void)tfm; (void)alg_name; (void)expected_driver_name; + return 0; +#else + const char *actual_driver_name; + int ret; + int alloced_tfm = 0; + + if (! tfm) { + alloced_tfm = 1; + tfm = crypto_alloc_shash(alg_name, 0, 0); + } + if (IS_ERR(tfm)) { + pr_err("error: allocating shash algorithm %s failed: %ld\n", + alg_name, PTR_ERR(tfm)); + return -EINVAL; + } + actual_driver_name = crypto_tfm_alg_driver_name(crypto_shash_tfm(tfm)); + if (strcmp(actual_driver_name, expected_driver_name)) { + pr_err("error: unexpected implementation for %s: %s (expected %s)\n", + alg_name, actual_driver_name, expected_driver_name); + ret = -ENOENT; + } else + ret = 0; + + if (alloced_tfm) + crypto_free_shash(tfm); + + return ret; +#endif +} + #ifndef NO_AES #include "lkcapi_aes_glue.c" #endif +#include "lkcapi_sha_glue.c" + #ifdef HAVE_ECC #if (defined(LINUXKM_LKCAPI_REGISTER_ALL) && !defined(LINUXKM_LKCAPI_DONT_REGISTER_ECDSA)) && \ !defined(LINUXKM_LKCAPI_REGISTER_ECDSA) @@ -350,6 +385,64 @@ static int linuxkm_lkcapi_register(void) REGISTER_ALG(ecbAesAlg, crypto_register_skcipher, linuxkm_test_aesecb); #endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA1 + REGISTER_ALG(sha1_alg, crypto_register_shash, linuxkm_test_sha1); +#endif + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_224 + REGISTER_ALG(sha2_224_alg, crypto_register_shash, linuxkm_test_sha2_224); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_256 + REGISTER_ALG(sha2_256_alg, crypto_register_shash, linuxkm_test_sha2_256); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_384 + REGISTER_ALG(sha2_384_alg, crypto_register_shash, linuxkm_test_sha2_384); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_512 + REGISTER_ALG(sha2_512_alg, crypto_register_shash, linuxkm_test_sha2_512); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_224 + REGISTER_ALG(sha3_224_alg, crypto_register_shash, linuxkm_test_sha3_224); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_256 + REGISTER_ALG(sha3_256_alg, crypto_register_shash, linuxkm_test_sha3_256); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_384 + REGISTER_ALG(sha3_384_alg, crypto_register_shash, linuxkm_test_sha3_384); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_512 + REGISTER_ALG(sha3_512_alg, crypto_register_shash, linuxkm_test_sha3_512); +#endif + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA1_HMAC + REGISTER_ALG(sha1_hmac_alg, crypto_register_shash, linuxkm_test_sha1_hmac); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_224_HMAC + REGISTER_ALG(sha2_224_hmac_alg, crypto_register_shash, linuxkm_test_sha2_224_hmac); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_256_HMAC + REGISTER_ALG(sha2_256_hmac_alg, crypto_register_shash, linuxkm_test_sha2_256_hmac); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_384_HMAC + REGISTER_ALG(sha2_384_hmac_alg, crypto_register_shash, linuxkm_test_sha2_384_hmac); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_512_HMAC + REGISTER_ALG(sha2_512_hmac_alg, crypto_register_shash, linuxkm_test_sha2_512_hmac); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_224_HMAC + REGISTER_ALG(sha3_224_hmac_alg, crypto_register_shash, linuxkm_test_sha3_224_hmac); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_256_HMAC + REGISTER_ALG(sha3_256_hmac_alg, crypto_register_shash, linuxkm_test_sha3_256_hmac); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_384_HMAC + REGISTER_ALG(sha3_384_hmac_alg, crypto_register_shash, linuxkm_test_sha3_384_hmac); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_512_HMAC + REGISTER_ALG(sha3_512_hmac_alg, crypto_register_shash, linuxkm_test_sha3_512_hmac); +#endif + + #ifdef LINUXKM_LKCAPI_REGISTER_ECDSA #if defined(LINUXKM_ECC192) REGISTER_ALG(ecdsa_nist_p192, crypto_register_akcipher, @@ -445,6 +538,64 @@ static void linuxkm_lkcapi_unregister(void) UNREGISTER_ALG(ecbAesAlg, crypto_unregister_skcipher); #endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA1 + UNREGISTER_ALG(sha1_alg, crypto_unregister_shash); +#endif + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_224 + UNREGISTER_ALG(sha2_224_alg, crypto_unregister_shash); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_256 + UNREGISTER_ALG(sha2_256_alg, crypto_unregister_shash); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_384 + UNREGISTER_ALG(sha2_384_alg, crypto_unregister_shash); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_512 + UNREGISTER_ALG(sha2_512_alg, crypto_unregister_shash); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_224 + UNREGISTER_ALG(sha3_224_alg, crypto_unregister_shash); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_256 + UNREGISTER_ALG(sha3_256_alg, crypto_unregister_shash); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_384 + UNREGISTER_ALG(sha3_384_alg, crypto_unregister_shash); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_512 + UNREGISTER_ALG(sha3_512_alg, crypto_unregister_shash); +#endif + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA1 + UNREGISTER_ALG(sha1_hmac_alg, crypto_unregister_shash); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_224_HMAC + UNREGISTER_ALG(sha2_224_hmac_alg, crypto_unregister_shash); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_256_HMAC + UNREGISTER_ALG(sha2_256_hmac_alg, crypto_unregister_shash); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_384_HMAC + UNREGISTER_ALG(sha2_384_hmac_alg, crypto_unregister_shash); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_512_HMAC + UNREGISTER_ALG(sha2_512_hmac_alg, crypto_unregister_shash); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_224_HMAC + UNREGISTER_ALG(sha3_224_hmac_alg, crypto_unregister_shash); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_256_HMAC + UNREGISTER_ALG(sha3_256_hmac_alg, crypto_unregister_shash); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_384_HMAC + UNREGISTER_ALG(sha3_384_hmac_alg, crypto_unregister_shash); +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_512_HMAC + UNREGISTER_ALG(sha3_512_hmac_alg, crypto_unregister_shash); +#endif + + #ifdef LINUXKM_LKCAPI_REGISTER_ECDSA #if defined(LINUXKM_ECC192) UNREGISTER_ALG(ecdsa_nist_p192, crypto_unregister_akcipher); diff --git a/linuxkm/lkcapi_sha_glue.c b/linuxkm/lkcapi_sha_glue.c index 977dde21c..fbe0a44a2 100644 --- a/linuxkm/lkcapi_sha_glue.c +++ b/linuxkm/lkcapi_sha_glue.c @@ -21,6 +21,9 @@ /* included by linuxkm/lkcapi_glue.c */ +#include +#include + #define WOLFKM_SHA1_NAME "sha1" #define WOLFKM_SHA2_224_NAME "sha224" #define WOLFKM_SHA2_256_NAME "sha256" @@ -58,26 +61,87 @@ #define WOLFKM_SHA3_256_DRIVER ("sha3-256" WOLFKM_SHA_DRIVER_SUFFIX) #define WOLFKM_SHA3_384_DRIVER ("sha3-384" WOLFKM_SHA_DRIVER_SUFFIX) #define WOLFKM_SHA3_512_DRIVER ("sha3-512" WOLFKM_SHA_DRIVER_SUFFIX) -#define WOLFKM_SHA1_HMAC_DRIVER ("hmac(sha1)" WOLFKM_SHA_DRIVER_SUFFIX) -#define WOLFKM_SHA2_224_HMAC_DRIVER ("hmac(sha224)" WOLFKM_SHA_DRIVER_SUFFIX) -#define WOLFKM_SHA2_256_HMAC_DRIVER ("hmac(sha256)" WOLFKM_SHA_DRIVER_SUFFIX) -#define WOLFKM_SHA2_384_HMAC_DRIVER ("hmac(sha384)" WOLFKM_SHA_DRIVER_SUFFIX) -#define WOLFKM_SHA2_512_HMAC_DRIVER ("hmac(sha512)" WOLFKM_SHA_DRIVER_SUFFIX) -#define WOLFKM_SHA3_224_HMAC_DRIVER ("hmac(sha3-224)" WOLFKM_SHA_DRIVER_SUFFIX) -#define WOLFKM_SHA3_256_HMAC_DRIVER ("hmac(sha3-256)" WOLFKM_SHA_DRIVER_SUFFIX) -#define WOLFKM_SHA3_384_HMAC_DRIVER ("hmac(sha3-384)" WOLFKM_SHA_DRIVER_SUFFIX) -#define WOLFKM_SHA3_512_HMAC_DRIVER ("hmac(sha3-512)" WOLFKM_SHA_DRIVER_SUFFIX) + +#define WOLFKM_SHA1_HMAC_DRIVER ("hmac-sha1" WOLFKM_SHA_DRIVER_SUFFIX) +#define WOLFKM_SHA2_224_HMAC_DRIVER ("hmac-sha224" WOLFKM_SHA_DRIVER_SUFFIX) +#define WOLFKM_SHA2_256_HMAC_DRIVER ("hmac-sha256" WOLFKM_SHA_DRIVER_SUFFIX) +#define WOLFKM_SHA2_384_HMAC_DRIVER ("hmac-sha384" WOLFKM_SHA_DRIVER_SUFFIX) +#define WOLFKM_SHA2_512_HMAC_DRIVER ("hmac-sha512" WOLFKM_SHA_DRIVER_SUFFIX) +#define WOLFKM_SHA3_224_HMAC_DRIVER ("hmac-sha3-224" WOLFKM_SHA_DRIVER_SUFFIX) +#define WOLFKM_SHA3_256_HMAC_DRIVER ("hmac-sha3-256" WOLFKM_SHA_DRIVER_SUFFIX) +#define WOLFKM_SHA3_384_HMAC_DRIVER ("hmac-sha3-384" WOLFKM_SHA_DRIVER_SUFFIX) +#define WOLFKM_SHA3_512_HMAC_DRIVER ("hmac-sha3-512" WOLFKM_SHA_DRIVER_SUFFIX) + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2 + #define LINUXKM_LKCAPI_REGISTER_SHA2_224 + #define LINUXKM_LKCAPI_REGISTER_SHA2_256 + #define LINUXKM_LKCAPI_REGISTER_SHA2_384 + #define LINUXKM_LKCAPI_REGISTER_SHA2_512 +#endif + +#ifdef LINUXKM_LKCAPI_DONT_REGISTER_SHA2 + #define LINUXKM_LKCAPI_DONT_REGISTER_SHA2_224 + #define LINUXKM_LKCAPI_DONT_REGISTER_SHA2_256 + #define LINUXKM_LKCAPI_DONT_REGISTER_SHA2_384 + #define LINUXKM_LKCAPI_DONT_REGISTER_SHA2_512 +#endif + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_HMAC + #define LINUXKM_LKCAPI_REGISTER_SHA2_224_HMAC + #define LINUXKM_LKCAPI_REGISTER_SHA2_256_HMAC + #define LINUXKM_LKCAPI_REGISTER_SHA2_384_HMAC + #define LINUXKM_LKCAPI_REGISTER_SHA2_512_HMAC +#endif + +#ifdef LINUXKM_LKCAPI_DONT_REGISTER_SHA2_HMAC + #define LINUXKM_LKCAPI_DONT_REGISTER_SHA2_224_HMAC + #define LINUXKM_LKCAPI_DONT_REGISTER_SHA2_256_HMAC + #define LINUXKM_LKCAPI_DONT_REGISTER_SHA2_384_HMAC + #define LINUXKM_LKCAPI_DONT_REGISTER_SHA2_512_HMAC +#endif + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3 + #define LINUXKM_LKCAPI_REGISTER_SHA3_224 + #define LINUXKM_LKCAPI_REGISTER_SHA3_256 + #define LINUXKM_LKCAPI_REGISTER_SHA3_384 + #define LINUXKM_LKCAPI_REGISTER_SHA3_512 +#endif + +#ifdef LINUXKM_LKCAPI_DONT_REGISTER_SHA3 + #define LINUXKM_LKCAPI_DONT_REGISTER_SHA3_224 + #define LINUXKM_LKCAPI_DONT_REGISTER_SHA3_256 + #define LINUXKM_LKCAPI_DONT_REGISTER_SHA3_384 + #define LINUXKM_LKCAPI_DONT_REGISTER_SHA3_512 +#endif + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_HMAC + #define LINUXKM_LKCAPI_REGISTER_SHA3_224_HMAC + #define LINUXKM_LKCAPI_REGISTER_SHA3_256_HMAC + #define LINUXKM_LKCAPI_REGISTER_SHA3_384_HMAC + #define LINUXKM_LKCAPI_REGISTER_SHA3_512_HMAC +#endif + +#ifdef LINUXKM_LKCAPI_DONT_REGISTER_SHA3_HMAC + #define LINUXKM_LKCAPI_DONT_REGISTER_SHA3_224_HMAC + #define LINUXKM_LKCAPI_DONT_REGISTER_SHA3_256_HMAC + #define LINUXKM_LKCAPI_DONT_REGISTER_SHA3_384_HMAC + #define LINUXKM_LKCAPI_DONT_REGISTER_SHA3_512_HMAC +#endif #ifndef NO_SHA #if (defined(LINUXKM_LKCAPI_REGISTER_ALL) && !defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA1)) && \ !defined(LINUXKM_LKCAPI_REGISTER_SHA1) #define LINUXKM_LKCAPI_REGISTER_SHA1 #endif + #ifdef NO_HMAC + #undef LINUXKM_LKCAPI_REGISTER_SHA1_HMAC + #elif (defined(LINUXKM_LKCAPI_REGISTER_ALL) && !defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA1_HMAC)) && \ + !defined(LINUXKM_LKCAPI_REGISTER_SHA1_HMAC) + #define LINUXKM_LKCAPI_REGISTER_SHA1_HMAC + #endif #else - #undef LINUXKM_LKCAPI_REGISTER_SHA1 -#endif -#if defined(LINUXKM_LKCAPI_REGISTER_SHA1) && !defined(NO_HMAC) - #define LINUXKM_LKCAPI_REGISTER_SHA1_HMAC + #undef LINUXKM_LKCAPI_REGISTER_SHA1 + #undef LINUXKM_LKCAPI_REGISTER_SHA1_HMAC #endif #ifdef WOLFSSL_SHA224 @@ -85,11 +149,15 @@ !defined(LINUXKM_LKCAPI_REGISTER_SHA2_224) #define LINUXKM_LKCAPI_REGISTER_SHA2_224 #endif + #ifdef NO_HMAC + #undef LINUXKM_LKCAPI_REGISTER_SHA2_224_HMAC + #elif (defined(LINUXKM_LKCAPI_REGISTER_ALL) && !defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA2_224_HMAC)) && \ + !defined(LINUXKM_LKCAPI_REGISTER_SHA2_224_HMAC) + #define LINUXKM_LKCAPI_REGISTER_SHA2_224_HMAC + #endif #else - #undef LINUXKM_LKCAPI_REGISTER_SHA2_224 -#endif -#if defined(LINUXKM_LKCAPI_REGISTER_SHA2_224) && !defined(NO_HMAC) - #define LINUXKM_LKCAPI_REGISTER_SHA2_224_HMAC + #undef LINUXKM_LKCAPI_REGISTER_SHA2_224 + #undef LINUXKM_LKCAPI_REGISTER_SHA2_224_HMAC #endif #ifndef NO_SHA256 @@ -97,11 +165,15 @@ !defined(LINUXKM_LKCAPI_REGISTER_SHA2_256) #define LINUXKM_LKCAPI_REGISTER_SHA2_256 #endif + #ifdef NO_HMAC + #undef LINUXKM_LKCAPI_REGISTER_SHA2_256_HMAC + #elif (defined(LINUXKM_LKCAPI_REGISTER_ALL) && !defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA2_256_HMAC)) && \ + !defined(LINUXKM_LKCAPI_REGISTER_SHA2_256_HMAC) + #define LINUXKM_LKCAPI_REGISTER_SHA2_256_HMAC + #endif #else - #undef LINUXKM_LKCAPI_REGISTER_SHA2_256 -#endif -#if defined(LINUXKM_LKCAPI_REGISTER_SHA2_256) && !defined(NO_HMAC) - #define LINUXKM_LKCAPI_REGISTER_SHA2_256_HMAC + #undef LINUXKM_LKCAPI_REGISTER_SHA2_256 + #undef LINUXKM_LKCAPI_REGISTER_SHA2_256_HMAC #endif #ifdef WOLFSSL_SHA384 @@ -109,11 +181,15 @@ !defined(LINUXKM_LKCAPI_REGISTER_SHA2_384) #define LINUXKM_LKCAPI_REGISTER_SHA2_384 #endif + #ifdef NO_HMAC + #undef LINUXKM_LKCAPI_REGISTER_SHA2_384_HMAC + #elif (defined(LINUXKM_LKCAPI_REGISTER_ALL) && !defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA2_384_HMAC)) && \ + !defined(LINUXKM_LKCAPI_REGISTER_SHA2_384_HMAC) + #define LINUXKM_LKCAPI_REGISTER_SHA2_384_HMAC + #endif #else - #undef LINUXKM_LKCAPI_REGISTER_SHA2_384 -#endif -#if defined(LINUXKM_LKCAPI_REGISTER_SHA2_384) && !defined(NO_HMAC) - #define LINUXKM_LKCAPI_REGISTER_SHA2_384_HMAC + #undef LINUXKM_LKCAPI_REGISTER_SHA2_384 + #undef LINUXKM_LKCAPI_REGISTER_SHA2_384_HMAC #endif #ifdef WOLFSSL_SHA512 @@ -121,11 +197,15 @@ !defined(LINUXKM_LKCAPI_REGISTER_SHA2_512) #define LINUXKM_LKCAPI_REGISTER_SHA2_512 #endif + #ifdef NO_HMAC + #undef LINUXKM_LKCAPI_REGISTER_SHA2_512_HMAC + #elif (defined(LINUXKM_LKCAPI_REGISTER_ALL) && !defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA2_512_HMAC)) && \ + !defined(LINUXKM_LKCAPI_REGISTER_SHA2_512_HMAC) + #define LINUXKM_LKCAPI_REGISTER_SHA2_512_HMAC + #endif #else - #undef LINUXKM_LKCAPI_REGISTER_SHA2_512 -#endif -#if defined(LINUXKM_LKCAPI_REGISTER_SHA2_512) && !defined(NO_HMAC) - #define LINUXKM_LKCAPI_REGISTER_SHA2_512_HMAC + #undef LINUXKM_LKCAPI_REGISTER_SHA2_512 + #undef LINUXKM_LKCAPI_REGISTER_SHA2_512_HMAC #endif #ifdef WOLFSSL_SHA3 @@ -145,58 +225,575 @@ !defined(LINUXKM_LKCAPI_REGISTER_SHA3_512) #define LINUXKM_LKCAPI_REGISTER_SHA3_512 #endif + #ifdef NO_HMAC + #undef LINUXKM_LKCAPI_REGISTER_SHA3_224_HMAC + #undef LINUXKM_LKCAPI_REGISTER_SHA3_256_HMAC + #undef LINUXKM_LKCAPI_REGISTER_SHA3_384_HMAC + #undef LINUXKM_LKCAPI_REGISTER_SHA3_512_HMAC + #else + #if (defined(LINUXKM_LKCAPI_REGISTER_ALL) && !defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA3_224_HMAC)) && \ + !defined(LINUXKM_LKCAPI_REGISTER_SHA3_224_HMAC) + #define LINUXKM_LKCAPI_REGISTER_SHA3_224_HMAC + #endif + #if (defined(LINUXKM_LKCAPI_REGISTER_ALL) && !defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA3_256_HMAC)) && \ + !defined(LINUXKM_LKCAPI_REGISTER_SHA3_256_HMAC) + #define LINUXKM_LKCAPI_REGISTER_SHA3_256_HMAC + #endif + #if (defined(LINUXKM_LKCAPI_REGISTER_ALL) && !defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA3_384_HMAC)) && \ + !defined(LINUXKM_LKCAPI_REGISTER_SHA3_384_HMAC) + #define LINUXKM_LKCAPI_REGISTER_SHA3_384_HMAC + #endif + #if (defined(LINUXKM_LKCAPI_REGISTER_ALL) && !defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA3_512_HMAC)) && \ + !defined(LINUXKM_LKCAPI_REGISTER_SHA3_512_HMAC) + #define LINUXKM_LKCAPI_REGISTER_SHA3_512_HMAC + #endif + #endif #else - #undef LINUXKM_LKCAPI_REGISTER_SHA3_224 - #undef LINUXKM_LKCAPI_REGISTER_SHA3_256 - #undef LINUXKM_LKCAPI_REGISTER_SHA3_384 - #undef LINUXKM_LKCAPI_REGISTER_SHA3_512 + #undef LINUXKM_LKCAPI_REGISTER_SHA3_224 + #undef LINUXKM_LKCAPI_REGISTER_SHA3_256 + #undef LINUXKM_LKCAPI_REGISTER_SHA3_384 + #undef LINUXKM_LKCAPI_REGISTER_SHA3_512 + #undef LINUXKM_LKCAPI_REGISTER_SHA3_224_HMAC + #undef LINUXKM_LKCAPI_REGISTER_SHA3_256_HMAC + #undef LINUXKM_LKCAPI_REGISTER_SHA3_384_HMAC + #undef LINUXKM_LKCAPI_REGISTER_SHA3_512_HMAC #endif + +struct km_sha_state { + union { +#ifdef LINUXKM_LKCAPI_REGISTER_SHA1 + struct wc_Sha sha1_state; +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_224 + struct wc_Sha256 sha2_224_state; +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_256 + struct wc_Sha256 sha2_256_state; +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_384 + struct wc_Sha512 sha2_384_state; +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_512 + struct wc_Sha512 sha2_512_state; +#endif + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_224 + struct wc_Sha3 *sha3_224_state; +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_256 + struct wc_Sha3 *sha3_256_state; +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_384 + struct wc_Sha3 *sha3_384_state; +#endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_512 + struct wc_Sha3 *sha3_512_state; +#endif +#ifdef WOLFSSL_SHA3 + void *sha3_ptr; +#endif + }; +}; + +#ifdef WOLFSSL_SHA3 +WC_MAYBE_UNUSED static void km_sha3_free_tstate(struct km_sha_state *t_ctx) { + free(t_ctx->sha3_ptr); + t_ctx->sha3_ptr = NULL; +} + +WC_MAYBE_UNUSED static int sha3_test_once(void) { + static int once = 0; + static int ret; + if (! once) { + ret = sha3_test(); + once = 1; + } + return ret; +} +#endif + +#define WC_LINUXKM_SHA_IMPLEMENT(name, digest_size, block_size, \ + this_cra_name, this_cra_driver_name, \ + init_f, update_f, final_f, \ + test_routine) \ + \ + \ +static int km_ ## name ## _init(struct shash_desc *desc) { \ + struct km_sha_state *ctx = (struct km_sha_state *)shash_desc_ctx(desc);\ + \ + int ret = init_f(&ctx-> name ## _state); \ + if (ret == 0) \ + return 0; \ + else \ + return -EINVAL; \ + } \ + \ +static int km_ ## name ## _update(struct shash_desc *desc, const u8 *data, \ + unsigned int len) \ +{ \ + struct km_sha_state *ctx = (struct km_sha_state *)shash_desc_ctx(desc);\ + \ + int ret = update_f(&ctx-> name ## _state, data, len); \ + \ + if (ret == 0) \ + return 0; \ + else \ + return -EINVAL; \ + } \ + \ +static int km_ ## name ## _final(struct shash_desc *desc, u8 *out) { \ + struct km_sha_state *ctx = (struct km_sha_state *)shash_desc_ctx(desc);\ + \ + int ret = final_f(&ctx-> name ## _state, out); \ + \ + if (ret == 0) \ + return 0; \ + else \ + return -EINVAL; \ +} \ + \ +static int km_ ## name ## _finup(struct shash_desc *desc, const u8 *data, \ + unsigned int len, u8 *out) \ +{ \ + struct km_sha_state *ctx = (struct km_sha_state *)shash_desc_ctx(desc);\ + \ + int ret = update_f(&ctx-> name ## _state, data, len); \ + \ + if (ret != 0) \ + return -EINVAL; \ + \ + return km_ ## name ## _final(desc, out); \ +} \ + \ +static int km_ ## name ## _digest(struct shash_desc *desc, const u8 *data, \ + unsigned int len, u8 *out) \ +{ \ + int ret = km_ ## name ## _init(desc); \ + if (ret != 0) \ + return ret; \ + return km_ ## name ## _finup(desc, data, len, out); \ +} \ + \ + \ +static struct shash_alg name ## _alg = \ +{ \ + .digestsize = (digest_size), \ + .init = km_ ## name ## _init, \ + .update = km_ ## name ## _update, \ + .final = km_ ## name ## _final, \ + .finup = km_ ## name ## _finup, \ + .digest = km_ ## name ## _digest, \ + .descsize = sizeof(struct km_sha_state), \ + .base = { \ + .cra_name = this_cra_name, \ + .cra_driver_name = this_cra_driver_name, \ + .cra_priority = WOLFSSL_LINUXKM_LKCAPI_PRIORITY, \ + .cra_blocksize = (block_size), \ + .cra_module = THIS_MODULE \ + } \ +}; \ +static int name ## _alg_loaded = 0; \ + \ +static int linuxkm_test_ ## name(void) { \ + wc_test_ret_t ret = test_routine(); \ + if (ret >= 0) \ + return check_shash_driver_masking(NULL /* tfm */, this_cra_name, \ + this_cra_driver_name); \ + else { \ + wc_test_render_error_message("linuxkm_test_" #name " failed: ", \ + ret); \ + return -EINVAL; \ + } \ +} \ + \ +struct wc_swallow_the_semicolon + +#define WC_LINUXKM_SHA3_IMPLEMENT(name, digest_size, block_size, \ + this_cra_name, this_cra_driver_name, \ + init_f, update_f, final_f, \ + test_routine) \ + \ + \ +static int km_ ## name ## _init(struct shash_desc *desc) { \ + struct km_sha_state *ctx = (struct km_sha_state *)shash_desc_ctx(desc);\ + int ret; \ + \ + \ + ctx-> name ## _state = malloc(sizeof *ctx-> name ## _state); \ + if (! ctx-> name ## _state) \ + return -ENOMEM; \ + ret = init_f(ctx-> name ## _state, NULL, INVALID_DEVID); \ + if (ret == 0) \ + return 0; \ + else \ + return -EINVAL; \ +} \ + \ +static int km_ ## name ## _update(struct shash_desc *desc, const u8 *data, \ + unsigned int len) \ +{ \ + struct km_sha_state *ctx = (struct km_sha_state *)shash_desc_ctx(desc);\ + \ + int ret = update_f(ctx-> name ## _state, data, len); \ + \ + if (ret == 0) \ + return 0; \ + else { \ + km_sha3_free_tstate(ctx); \ + return -EINVAL; \ + } \ +} \ + \ +static int km_ ## name ## _final(struct shash_desc *desc, u8 *out) { \ + struct km_sha_state *ctx = (struct km_sha_state *)shash_desc_ctx(desc);\ + \ + int ret = final_f(ctx-> name ## _state, out); \ + \ + km_sha3_free_tstate(ctx); \ + if (ret == 0) \ + return 0; \ + else \ + return -EINVAL; \ +} \ + \ +static int km_ ## name ## _finup(struct shash_desc *desc, const u8 *data, \ + unsigned int len, u8 *out) \ +{ \ + struct km_sha_state *ctx = (struct km_sha_state *)shash_desc_ctx(desc);\ + \ + int ret = update_f(ctx-> name ## _state, data, len); \ + \ + if (ret != 0) \ + return -EINVAL; \ + \ + return km_ ## name ## _final(desc, out); \ +} \ + \ +static int km_ ## name ## _digest(struct shash_desc *desc, const u8 *data, \ + unsigned int len, u8 *out) \ +{ \ + int ret = km_ ## name ## _init(desc); \ + if (ret != 0) \ + return ret; \ + return km_ ## name ## _finup(desc, data, len, out); \ +} \ + \ +static struct shash_alg name ## _alg = \ +{ \ + .digestsize = (digest_size), \ + .init = km_ ## name ## _init, \ + .update = km_ ## name ## _update, \ + .final = km_ ## name ## _final, \ + .finup = km_ ## name ## _finup, \ + .digest = km_ ## name ## _digest, \ + .descsize = sizeof(struct km_sha_state), \ + .base = { \ + .cra_name = this_cra_name, \ + .cra_driver_name = this_cra_driver_name, \ + .cra_priority = WOLFSSL_LINUXKM_LKCAPI_PRIORITY, \ + .cra_blocksize = (block_size), \ + .cra_module = THIS_MODULE \ + } \ +}; \ +static int name ## _alg_loaded = 0; \ + \ +static int linuxkm_test_ ## name(void) { \ + wc_test_ret_t ret = test_routine(); \ + if (ret >= 0) \ + return check_shash_driver_masking(NULL /* tfm */, this_cra_name, \ + this_cra_driver_name); \ + else { \ + wc_test_render_error_message("linuxkm_test_" #name " failed: ", \ + ret); \ + return -EINVAL; \ + } \ +} \ + \ +struct wc_swallow_the_semicolon + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA1 + WC_LINUXKM_SHA_IMPLEMENT(sha1, WC_SHA_DIGEST_SIZE, WC_SHA_BLOCK_SIZE, + WOLFKM_SHA1_NAME, WOLFKM_SHA1_DRIVER, + wc_InitSha, wc_ShaUpdate, wc_ShaFinal, + sha_test); +#endif + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_224 + WC_LINUXKM_SHA_IMPLEMENT(sha2_224, WC_SHA224_DIGEST_SIZE, WC_SHA224_BLOCK_SIZE, + WOLFKM_SHA2_224_NAME, WOLFKM_SHA2_224_DRIVER, + wc_InitSha224, wc_Sha224Update, wc_Sha224Final, + sha224_test); +#endif + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_256 + WC_LINUXKM_SHA_IMPLEMENT(sha2_256, WC_SHA256_DIGEST_SIZE, WC_SHA256_BLOCK_SIZE, + WOLFKM_SHA2_256_NAME, WOLFKM_SHA2_256_DRIVER, + wc_InitSha256, wc_Sha256Update, wc_Sha256Final, + sha256_test); +#endif + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_384 + WC_LINUXKM_SHA_IMPLEMENT(sha2_384, WC_SHA384_DIGEST_SIZE, WC_SHA384_BLOCK_SIZE, + WOLFKM_SHA2_384_NAME, WOLFKM_SHA2_384_DRIVER, + wc_InitSha384, wc_Sha384Update, wc_Sha384Final, + sha384_test); +#endif + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_512 + WC_LINUXKM_SHA_IMPLEMENT(sha2_512, WC_SHA512_DIGEST_SIZE, WC_SHA512_BLOCK_SIZE, + WOLFKM_SHA2_512_NAME, WOLFKM_SHA2_512_DRIVER, + wc_InitSha512, wc_Sha512Update, wc_Sha512Final, + sha512_test); +#endif + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_224 + WC_LINUXKM_SHA3_IMPLEMENT(sha3_224, WC_SHA3_224_DIGEST_SIZE, WC_SHA3_224_BLOCK_SIZE, + WOLFKM_SHA3_224_NAME, WOLFKM_SHA3_224_DRIVER, + wc_InitSha3_224, wc_Sha3_224_Update, wc_Sha3_224_Final, + sha3_test_once); +#endif + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_256 + WC_LINUXKM_SHA3_IMPLEMENT(sha3_256, WC_SHA3_256_DIGEST_SIZE, WC_SHA3_256_BLOCK_SIZE, + WOLFKM_SHA3_256_NAME, WOLFKM_SHA3_256_DRIVER, + wc_InitSha3_256, wc_Sha3_256_Update, wc_Sha3_256_Final, + sha3_test_once); +#endif + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_384 + WC_LINUXKM_SHA3_IMPLEMENT(sha3_384, WC_SHA3_384_DIGEST_SIZE, WC_SHA3_384_BLOCK_SIZE, + WOLFKM_SHA3_384_NAME, WOLFKM_SHA3_384_DRIVER, + wc_InitSha3_384, wc_Sha3_384_Update, wc_Sha3_384_Final, + sha3_test_once); +#endif + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_512 + WC_LINUXKM_SHA3_IMPLEMENT(sha3_512, WC_SHA3_512_DIGEST_SIZE, WC_SHA3_512_BLOCK_SIZE, + WOLFKM_SHA3_512_NAME, WOLFKM_SHA3_512_DRIVER, + wc_InitSha3_512, wc_Sha3_512_Update, wc_Sha3_512_Final, + sha3_test_once); +#endif + +struct km_sha_hmac_pstate { + struct Hmac wc_hmac; +}; +struct km_sha_hmac_state { + struct Hmac *wc_hmac; /* HASH_MAX_DESCSIZE is 368, but sizeof(struct Hmac) is 832 */ +}; + #ifndef NO_HMAC - #ifdef LINUXKM_LKCAPI_REGISTER_SHA3_224 - #define LINUXKM_LKCAPI_REGISTER_SHA3_224_HMAC - #endif - #ifdef LINUXKM_LKCAPI_REGISTER_SHA3_256 - #define LINUXKM_LKCAPI_REGISTER_SHA3_256_HMAC - #endif - #ifdef LINUXKM_LKCAPI_REGISTER_SHA3_384 - #define LINUXKM_LKCAPI_REGISTER_SHA3_384_HMAC - #endif - #ifdef LINUXKM_LKCAPI_REGISTER_SHA3_512 - #define LINUXKM_LKCAPI_REGISTER_SHA3_512_HMAC - #endif + +WC_MAYBE_UNUSED static int linuxkm_hmac_setkey_common(struct crypto_shash *tfm, int type, const byte* key, word32 length) +{ + struct km_sha_hmac_pstate *p_ctx = (struct km_sha_hmac_pstate *)crypto_shash_ctx(tfm); + int ret; + +#ifdef HAVE_FIPS + ret = wc_HmacSetKey(&p_ctx->wc_hmac, type, key, length); +#else + ret = wc_HmacSetKey_ex(&p_ctx->wc_hmac, type, key, length, 1 /* allowFlag */); #endif + if (ret == 0) + return 0; + else + return -EINVAL; +} -#if defined(LINUXKM_LKCAPI_REGISTER_SHA1) && !defined(NO_HMAC) +WC_MAYBE_UNUSED static void km_hmac_free_tstate(struct km_sha_hmac_state *t_ctx) { + free(t_ctx->wc_hmac); + t_ctx->wc_hmac = NULL; +} +WC_MAYBE_UNUSED static int km_hmac_init_tfm(struct crypto_shash *tfm) +{ + struct km_sha_hmac_pstate *p_ctx = (struct km_sha_hmac_pstate *)crypto_shash_ctx(tfm); + int ret = wc_HmacInit(&p_ctx->wc_hmac, NULL /* heap */, INVALID_DEVID); + if (ret == 0) + return 0; + else + return -EINVAL; +} + +WC_MAYBE_UNUSED static void km_hmac_exit_tfm(struct crypto_shash *tfm) +{ + struct km_sha_hmac_pstate *p_ctx = (struct km_sha_hmac_pstate *)crypto_shash_ctx(tfm); + wc_HmacFree(&p_ctx->wc_hmac); + return; +} + +WC_MAYBE_UNUSED static int km_hmac_init(struct shash_desc *desc) { + struct km_sha_hmac_state *t_ctx = (struct km_sha_hmac_state *)shash_desc_ctx(desc); + struct km_sha_hmac_pstate *p_ctx = (struct km_sha_hmac_pstate *)crypto_shash_ctx(desc->tfm); + + t_ctx->wc_hmac = malloc(sizeof *t_ctx->wc_hmac); + if (! t_ctx->wc_hmac) + return -ENOMEM; + + XMEMCPY(t_ctx->wc_hmac, &p_ctx->wc_hmac, sizeof *t_ctx->wc_hmac); + + return 0; +} + +WC_MAYBE_UNUSED static int km_hmac_update(struct shash_desc *desc, const u8 *data, + unsigned int len) +{ + struct km_sha_hmac_state *ctx = (struct km_sha_hmac_state *)shash_desc_ctx(desc); + + int ret = wc_HmacUpdate(ctx->wc_hmac, data, len); + + if (ret == 0) + return 0; + else { + km_hmac_free_tstate(ctx); + return -EINVAL; + } +} + +WC_MAYBE_UNUSED static int km_hmac_final(struct shash_desc *desc, u8 *out) { + struct km_sha_hmac_state *ctx = (struct km_sha_hmac_state *)shash_desc_ctx(desc); + + int ret = wc_HmacFinal(ctx->wc_hmac, out); + + km_hmac_free_tstate(ctx); + + if (ret == 0) + return 0; + else + return -EINVAL; +} + +WC_MAYBE_UNUSED static int km_hmac_finup(struct shash_desc *desc, const u8 *data, + unsigned int len, u8 *out) +{ + struct km_sha_hmac_state *ctx = (struct km_sha_hmac_state *)shash_desc_ctx(desc); + + int ret = wc_HmacUpdate(ctx->wc_hmac, data, len); + + if (ret != 0) + return -EINVAL; + + return km_hmac_final(desc, out); +} + +WC_MAYBE_UNUSED static int km_hmac_digest(struct shash_desc *desc, const u8 *data, + unsigned int len, u8 *out) +{ + int ret = km_hmac_init(desc); + if (ret != 0) + return ret; + return km_hmac_finup(desc, data, len, out); +} + +WC_MAYBE_UNUSED static int hmac_sha3_test_once(void) { + static int once = 0; + static int ret; + if (! once) { + ret = hmac_sha3_test(); + once = 1; + } + return ret; +} + +#define WC_LINUXKM_HMAC_IMPLEMENT(name, id, digest_size, block_size, \ + this_cra_name, this_cra_driver_name, \ + test_routine) \ + \ +static int km_ ## name ## _setkey(struct crypto_shash *tfm, const u8 *key,\ + unsigned int keylen) \ +{ \ + return linuxkm_hmac_setkey_common(tfm, id, key, keylen); \ +} \ + \ +static struct shash_alg name ## _alg = \ +{ \ + .digestsize = (digest_size), \ + .init = km_hmac_init, \ + .update = km_hmac_update, \ + .final = km_hmac_final, \ + .finup = km_hmac_finup, \ + .digest = km_hmac_digest, \ + .setkey = km_ ## name ## _setkey, \ + .init_tfm = km_hmac_init_tfm, \ + .exit_tfm = km_hmac_exit_tfm, \ + .descsize = sizeof(struct km_sha_hmac_state), \ + .base = { \ + .cra_name = this_cra_name, \ + .cra_driver_name = this_cra_driver_name, \ + .cra_priority = WOLFSSL_LINUXKM_LKCAPI_PRIORITY, \ + .cra_blocksize = (block_size), \ + .cra_ctxsize = sizeof(struct km_sha_hmac_pstate), \ + .cra_module = THIS_MODULE \ + } \ +}; \ +static int name ## _alg_loaded = 0; \ + \ +static int linuxkm_test_ ## name(void) { \ + wc_test_ret_t ret = test_routine(); \ + if (ret >= 0) \ + return check_shash_driver_masking(NULL /* tfm */, this_cra_name, \ + this_cra_driver_name); \ + else { \ + wc_test_render_error_message("linuxkm_test_" #name " failed: ", \ + ret); \ + return -EINVAL; \ + } \ +} \ + \ +struct wc_swallow_the_semicolon + +#endif /* !NO_HMAC */ + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA1_HMAC + WC_LINUXKM_HMAC_IMPLEMENT(sha1_hmac, WC_SHA, WC_SHA_DIGEST_SIZE, + WC_SHA_BLOCK_SIZE, WOLFKM_SHA1_HMAC_NAME, + WOLFKM_SHA1_HMAC_DRIVER, hmac_sha_test); +#endif /* LINUXKM_LKCAPI_REGISTER_SHA1_HMAC */ + +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_224_HMAC + WC_LINUXKM_HMAC_IMPLEMENT(sha2_224_hmac, WC_SHA224, WC_SHA224_DIGEST_SIZE, + WC_SHA224_BLOCK_SIZE, WOLFKM_SHA2_224_HMAC_NAME, + WOLFKM_SHA2_224_HMAC_DRIVER, hmac_sha224_test); #endif -#if defined(LINUXKM_LKCAPI_REGISTER_SHA2_224) && !defined(NO_HMAC) - +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_256_HMAC + WC_LINUXKM_HMAC_IMPLEMENT(sha2_256_hmac, WC_SHA256, WC_SHA256_DIGEST_SIZE, + WC_SHA256_BLOCK_SIZE, WOLFKM_SHA2_256_HMAC_NAME, + WOLFKM_SHA2_256_HMAC_DRIVER, hmac_sha256_test); #endif -#if defined(LINUXKM_LKCAPI_REGISTER_SHA2_256) && !defined(NO_HMAC) - +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_384_HMAC + WC_LINUXKM_HMAC_IMPLEMENT(sha2_384_hmac, WC_SHA384, WC_SHA384_DIGEST_SIZE, + WC_SHA384_BLOCK_SIZE, WOLFKM_SHA2_384_HMAC_NAME, + WOLFKM_SHA2_384_HMAC_DRIVER, hmac_sha384_test); #endif -#if defined(LINUXKM_LKCAPI_REGISTER_SHA2_384) && !defined(NO_HMAC) - +#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_512_HMAC + WC_LINUXKM_HMAC_IMPLEMENT(sha2_512_hmac, WC_SHA512, WC_SHA512_DIGEST_SIZE, + WC_SHA512_BLOCK_SIZE, WOLFKM_SHA2_512_HMAC_NAME, + WOLFKM_SHA2_512_HMAC_DRIVER, hmac_sha512_test); #endif -#if defined(LINUXKM_LKCAPI_REGISTER_SHA2_512) && !defined(NO_HMAC) - +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_224_HMAC + WC_LINUXKM_HMAC_IMPLEMENT(sha3_224_hmac, WC_SHA3_224, WC_SHA3_224_DIGEST_SIZE, + WC_SHA3_224_BLOCK_SIZE, WOLFKM_SHA3_224_HMAC_NAME, + WOLFKM_SHA3_224_HMAC_DRIVER, hmac_sha3_test_once); #endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_256_HMAC + WC_LINUXKM_HMAC_IMPLEMENT(sha3_256_hmac, WC_SHA3_256, WC_SHA3_256_DIGEST_SIZE, + WC_SHA3_256_BLOCK_SIZE, WOLFKM_SHA3_256_HMAC_NAME, + WOLFKM_SHA3_256_HMAC_DRIVER, hmac_sha3_test_once); +#endif - #ifdef LINUXKM_LKCAPI_REGISTER_SHA3_224 +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_384_HMAC + WC_LINUXKM_HMAC_IMPLEMENT(sha3_384_hmac, WC_SHA3_384, WC_SHA3_384_DIGEST_SIZE, + WC_SHA3_384_BLOCK_SIZE, WOLFKM_SHA3_384_HMAC_NAME, + WOLFKM_SHA3_384_HMAC_DRIVER, hmac_sha3_test_once); +#endif - #endif - #ifdef LINUXKM_LKCAPI_REGISTER_SHA3_256 - - #endif - #ifdef LINUXKM_LKCAPI_REGISTER_SHA3_384 - - #endif - #ifdef LINUXKM_LKCAPI_REGISTER_SHA3_512 - - #endif +#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_512_HMAC + WC_LINUXKM_HMAC_IMPLEMENT(sha3_512_hmac, WC_SHA3_512, WC_SHA3_512_DIGEST_SIZE, + WC_SHA3_512_BLOCK_SIZE, WOLFKM_SHA3_512_HMAC_NAME, + WOLFKM_SHA3_512_HMAC_DRIVER, hmac_sha3_test_once); +#endif