mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-05 13:44:41 +02:00
linuxkm: support DRBG in LKCAPI shim set:
* Implement --enable-linuxkm-lkcapi-register=stdrng and =stdrng-default, LINUXKM_LKCAPI_REGISTER_HASH_DRBG, and LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT. With "_DEFAULT", the DRBG is installed as the systemwide default stdrng, necessitating deregister-on-command, described below. Note that get_random_bytes() and the associated /dev/random and /dev/urandom do not use the default stdrng, and their back end cannot currently be replaced by a module. * Add control nodes /sys/module/libwolfssl/install_algs and /sys/module/libwolfssl/deinstall_algs. * Add configure option --enable-linuxkm-lkcapi-register=sysfs-nodes-only, and macro LINUXKM_LKCAPI_REGISTER_ONLY_ON_COMMAND, to inhibit registration at module load time. In configure.ac ENABLED_LINUXKM_LKCAPI_REGISTER setup, don't define WOLFSSL_DH_GEN_PUB in old FIPS, but do define it for =all.
This commit is contained in:
@@ -868,6 +868,8 @@ _ABIO64
|
||||
_ARCH_PPC64
|
||||
_COMPILER_VERSION
|
||||
_INTPTR_T_DECLARED
|
||||
_LINUX_REFCOUNT_H
|
||||
_LINUX_REFCOUNT_TYPES_H
|
||||
_LP64
|
||||
_MSC_VER
|
||||
_MSVC_LANG
|
||||
|
26
configure.ac
26
configure.ac
@@ -9405,7 +9405,10 @@ then
|
||||
for lkcapi_alg in $(echo "$ENABLED_LINUXKM_LKCAPI_REGISTER" | tr ',' ' ')
|
||||
do
|
||||
case "$lkcapi_alg" in
|
||||
all) AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_ALL -DWC_RSA_NO_PADDING" ;;
|
||||
all) AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_ALL -DWC_RSA_NO_PADDING -DWOLFSSL_DH_EXTRA"
|
||||
ENABLED_LINUXKM_LKCAPI_REGISTER_DH=yes
|
||||
;;
|
||||
sysfs-nodes-only) ENABLED_LINUXKM_LKCAPI_REGISTER_ONLY_ON_COMMAND=yes ;;
|
||||
'cbc(aes)') test "$ENABLED_AESCBC" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: AES-CBC implementation not enabled.])
|
||||
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.])
|
||||
@@ -9436,12 +9439,18 @@ then
|
||||
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" ;;
|
||||
'stdrng') test "$ENABLED_HASHDRBG" != "no" && AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: HASHDRBG implementation not enabled.])
|
||||
AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_HASH_DRBG" ;;
|
||||
'stdrng-default') test "$ENABLED_HASHDRBG" != "no" && AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: HASHDRBG implementation not enabled.])
|
||||
AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_HASH_DRBG -DLINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT" ;;
|
||||
'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" ;;
|
||||
'rsa') test "$ENABLED_RSA" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: RSA implementation not enabled.])
|
||||
AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_RSA -DWC_RSA_NO_PADDING" ;;
|
||||
'dh') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_DH -DWOLFSSL_DH_EXTRA -DWOLFSSL_DH_GEN_PUB" ;;
|
||||
'dh') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_DH -DWOLFSSL_DH_EXTRA"
|
||||
ENABLED_LINUXKM_LKCAPI_REGISTER_DH=yes
|
||||
;;
|
||||
# disable options
|
||||
'-cbc(aes)') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_DONT_REGISTER_AESCBC" ;;
|
||||
'-cfb(aes)') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_DONT_REGISTER_AESCFB" ;;
|
||||
@@ -9458,6 +9467,8 @@ then
|
||||
'-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" ;;
|
||||
'-stdrng') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_DONT_REGISTER_HASH_DRBG" ;;
|
||||
'-stdrng-default') AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_DONT_REGISTER_HASH_DRBG_DEFAULT" ;;
|
||||
'-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" ;;
|
||||
@@ -9465,6 +9476,17 @@ then
|
||||
*) AC_MSG_ERROR([Unsupported LKCAPI algorithm "$lkcapi_alg".]) ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if test "$ENABLED_LINUXKM_LKCAPI_REGISTER_DH" = "yes" &&
|
||||
(test "$ENABLED_FIPS" = "no" || test $HAVE_FIPS_VERSION -ge 7)
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DH_GEN_PUB"
|
||||
fi
|
||||
|
||||
if test "$ENABLED_LINUXKM_LKCAPI_REGISTER_ONLY_ON_COMMAND" = "yes"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_ONLY_ON_COMMAND"
|
||||
fi
|
||||
fi
|
||||
AC_SUBST([ENABLED_LINUXKM_LKCAPI_REGISTER])
|
||||
|
||||
|
@@ -294,6 +294,7 @@
|
||||
#include <crypto/scatterwalk.h>
|
||||
#include <crypto/internal/aead.h>
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <crypto/internal/rng.h>
|
||||
#include <crypto/internal/skcipher.h>
|
||||
#include <crypto/internal/akcipher.h>
|
||||
#include <crypto/internal/kpp.h>
|
||||
@@ -301,7 +302,7 @@
|
||||
/* the LKCAPI assumes that expanded encrypt and decrypt keys will stay
|
||||
* loaded simultaneously, and the Linux in-tree implementations have two
|
||||
* AES key structs in each context, one for each direction. in
|
||||
* linuxkm/lkcapi_glue.c (used for CBC, CFB, and GCM), we do the same
|
||||
* linuxkm/lkcapi_aes_glue.c, we do the same
|
||||
* thing with "struct km_AesCtx". however, wolfCrypt struct AesXts
|
||||
* already has two AES expanded keys, the main and tweak, and the tweak
|
||||
* is always used in the encrypt direction regardless of the main
|
||||
@@ -314,6 +315,12 @@
|
||||
#ifndef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
|
||||
#define WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
|
||||
#endif
|
||||
|
||||
#if defined(_LINUX_REFCOUNT_H) || defined(_LINUX_REFCOUNT_TYPES_H)
|
||||
#define WC_LKM_REFCOUNT_TO_INT(refcount) (atomic_read(&(refcount.refs)))
|
||||
#else
|
||||
#define WC_LKM_REFCOUNT_TO_INT(refcount) (atomic_read(&(refcount)))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_AESNI) || defined(USE_INTEL_SPEEDUP) || \
|
||||
@@ -930,7 +937,7 @@
|
||||
#define WC_LINUXKM_ROUND_UP_P_OF_2(x) ( \
|
||||
{ \
|
||||
size_t _alloc_sz = (x); \
|
||||
if (_alloc_sz < 8192) \
|
||||
if ((_alloc_sz < 8192) && (_alloc_sz != 0)) \
|
||||
_alloc_sz = 1UL << \
|
||||
((sizeof(_alloc_sz) * 8UL) - __builtin_clzl(_alloc_sz - 1)); \
|
||||
_alloc_sz; \
|
||||
|
@@ -80,6 +80,13 @@
|
||||
|
||||
#define WOLFKM_DRIVER_SUFFIX_BASE "-wolfcrypt" WOLFKM_DRIVER_FIPS
|
||||
|
||||
#define WOLFKM_INSTALL_NOTICE(alg) \
|
||||
pr_info("%s self-test OK -- " \
|
||||
"registered for %s with priority %d.\n", \
|
||||
(alg).base.cra_driver_name, \
|
||||
(alg).base.cra_name, \
|
||||
(alg).base.cra_priority); \
|
||||
|
||||
#ifdef WOLFSSL_DEBUG_TRACE_ERROR_CODES
|
||||
enum linux_errcodes {
|
||||
my_EINVAL = EINVAL,
|
||||
@@ -249,10 +256,10 @@ WC_MAYBE_UNUSED static int check_shash_driver_masking(struct crypto_shash *tfm,
|
||||
#if defined (LINUXKM_LKCAPI_REGISTER_ECDSA)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && \
|
||||
defined(CONFIG_CRYPTO_FIPS) && defined(CONFIG_CRYPTO_MANAGER)
|
||||
/**
|
||||
/*
|
||||
* note: ecdsa was not recognized as fips_allowed before linux v6.3
|
||||
* in kernel crypto/testmgr.c, and will not pass the tests.
|
||||
* */
|
||||
*/
|
||||
#undef LINUXKM_LKCAPI_REGISTER_ECDSA
|
||||
#endif /* linux < 6.3.0 && CONFIG_CRYPTO_FIPS && CONFIG_CRYPTO_MANAGER */
|
||||
|
||||
@@ -271,7 +278,7 @@ WC_MAYBE_UNUSED static int check_shash_driver_masking(struct crypto_shash *tfm,
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)
|
||||
/**
|
||||
/*
|
||||
* notes:
|
||||
* - ecdsa supported with linux 6.12 and earlier for now, only.
|
||||
* - pkcs1pad rsa supported both before and after linux 6.13, but
|
||||
@@ -283,7 +290,7 @@ WC_MAYBE_UNUSED static int check_shash_driver_masking(struct crypto_shash *tfm,
|
||||
*
|
||||
* pkcs1pad rsa remained a struct akcipher_alg, but without sign/verify
|
||||
* functionality.
|
||||
* */
|
||||
*/
|
||||
#if defined (LINUXKM_LKCAPI_REGISTER_ECDSA)
|
||||
#undef LINUXKM_LKCAPI_REGISTER_ECDSA
|
||||
#endif /* LINUXKM_LKCAPI_REGISTER_ECDSA */
|
||||
@@ -307,10 +314,10 @@ WC_MAYBE_UNUSED static int check_shash_driver_masking(struct crypto_shash *tfm,
|
||||
|
||||
#if defined (LINUXKM_LKCAPI_REGISTER_DH) && defined(CONFIG_CRYPTO_FIPS) && \
|
||||
defined(CONFIG_CRYPTO_MANAGER)
|
||||
/**
|
||||
* note: normal dh not fips_allowed in in kernel crypto/testmgr.c,
|
||||
/*
|
||||
* note: normal dh not fips_allowed in kernel crypto/testmgr.c,
|
||||
* and will not pass the tests.
|
||||
* */
|
||||
*/
|
||||
#undef LINUXKM_DH
|
||||
#endif /* LINUXKM_LKCAPI_REGISTER_DH */
|
||||
|
||||
@@ -330,14 +337,100 @@ WC_MAYBE_UNUSED static int check_shash_driver_masking(struct crypto_shash *tfm,
|
||||
#include "linuxkm/lkcapi_dh_glue.c"
|
||||
#endif /* LINUXKM_LKCAPI_REGISTER_DH */
|
||||
|
||||
static int linuxkm_lkcapi_register(void);
|
||||
static int linuxkm_lkcapi_unregister(void);
|
||||
|
||||
static ssize_t install_algs_handler(struct kobject *kobj, struct kobj_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int arg;
|
||||
int ret;
|
||||
|
||||
(void)kobj;
|
||||
(void)attr;
|
||||
|
||||
if (kstrtoint(buf, 10, &arg) || arg != 1)
|
||||
return -EINVAL;
|
||||
|
||||
pr_info("wolfCrypt: Installing algorithms");
|
||||
|
||||
ret = linuxkm_lkcapi_register();
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t deinstall_algs_handler(struct kobject *kobj, struct kobj_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int arg;
|
||||
int ret;
|
||||
|
||||
(void)kobj;
|
||||
(void)attr;
|
||||
|
||||
if (kstrtoint(buf, 10, &arg) || arg != 1)
|
||||
return -EINVAL;
|
||||
|
||||
pr_info("wolfCrypt: Deinstalling algorithms");
|
||||
|
||||
ret = linuxkm_lkcapi_unregister();
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* create control channels at /sys/module/libwolfssl/parameters/{install_algs,deinstall_algs} */
|
||||
|
||||
static struct kobj_attribute install_algs_attr = __ATTR(install_algs, 0220, NULL, install_algs_handler);
|
||||
static struct kobj_attribute deinstall_algs_attr = __ATTR(deinstall_algs, 0220, NULL, deinstall_algs_handler);
|
||||
|
||||
static int installed_sysfs_files = 0;
|
||||
|
||||
static int linuxkm_lkcapi_sysfs_install(void) {
|
||||
int ret;
|
||||
if (! installed_sysfs_files) {
|
||||
installed_sysfs_files = 1;
|
||||
ret = sysfs_create_file(&THIS_MODULE->mkobj.kobj, &install_algs_attr.attr);
|
||||
if (ret) {
|
||||
pr_err("sysfs_create_file failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = sysfs_create_file(&THIS_MODULE->mkobj.kobj, &deinstall_algs_attr.attr);
|
||||
if (ret) {
|
||||
pr_err("sysfs_create_file failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int linuxkm_lkcapi_sysfs_deinstall(void) {
|
||||
if (installed_sysfs_files) {
|
||||
installed_sysfs_files = 0;
|
||||
sysfs_remove_file(&THIS_MODULE->mkobj.kobj, &install_algs_attr.attr);
|
||||
sysfs_remove_file(&THIS_MODULE->mkobj.kobj, &deinstall_algs_attr.attr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int linuxkm_lkcapi_registered = 0;
|
||||
|
||||
static int linuxkm_lkcapi_register(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = -1;
|
||||
int seen_err = 0;
|
||||
#if defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_MANAGER) && \
|
||||
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
|
||||
int enabled_fips = 0;
|
||||
#endif
|
||||
|
||||
ret = linuxkm_lkcapi_sysfs_install();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
|
||||
/* temporarily disable warnings around setkey failures, which are expected
|
||||
* from the crypto fuzzer in FIPS configs, and potentially in others.
|
||||
@@ -355,196 +448,191 @@ static int linuxkm_lkcapi_register(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#define REGISTER_ALG(alg, installer, tester) do { \
|
||||
if (alg ## _loaded) { \
|
||||
pr_err("ERROR: %s is already registered.\n", \
|
||||
(alg).base.cra_driver_name); \
|
||||
ret = -EEXIST; \
|
||||
goto out; \
|
||||
} \
|
||||
\
|
||||
ret = (installer)(&(alg)); \
|
||||
\
|
||||
if (ret) { \
|
||||
pr_err("ERROR: " #installer " for %s failed " \
|
||||
"with return code %d.\n", \
|
||||
(alg).base.cra_driver_name, ret); \
|
||||
goto out; \
|
||||
} \
|
||||
\
|
||||
alg ## _loaded = 1; \
|
||||
\
|
||||
ret = (tester()); \
|
||||
\
|
||||
if (ret) { \
|
||||
pr_err("ERROR: self-test for %s failed " \
|
||||
"with return code %d.\n", \
|
||||
(alg).base.cra_driver_name, ret); \
|
||||
goto out; \
|
||||
} \
|
||||
pr_info("%s self-test OK -- " \
|
||||
"registered for %s with priority %d.\n", \
|
||||
(alg).base.cra_driver_name, \
|
||||
(alg).base.cra_name, \
|
||||
(alg).base.cra_priority); \
|
||||
#define REGISTER_ALG(alg, alg_class, tester) do { \
|
||||
if (! alg ## _loaded) { \
|
||||
ret = (crypto_register_ ## alg_class)(&(alg)); \
|
||||
if (ret) { \
|
||||
seen_err = 1; \
|
||||
pr_err("ERROR: crypto_register_" #alg_class " for %s failed "\
|
||||
"with return code %d.\n", \
|
||||
(alg).base.cra_driver_name, ret); \
|
||||
} else { \
|
||||
ret = (tester()); \
|
||||
if (ret) { \
|
||||
seen_err = 1; \
|
||||
pr_err("ERROR: self-test for %s failed " \
|
||||
"with return code %d.\n", \
|
||||
(alg).base.cra_driver_name, ret); \
|
||||
(crypto_unregister_ ## alg_class)(&(alg)); \
|
||||
} else { \
|
||||
alg ## _loaded = 1; \
|
||||
WOLFKM_INSTALL_NOTICE(alg) \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_AESCBC
|
||||
REGISTER_ALG(cbcAesAlg, crypto_register_skcipher, linuxkm_test_aescbc);
|
||||
REGISTER_ALG(cbcAesAlg, skcipher, linuxkm_test_aescbc);
|
||||
#endif
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_AESCFB
|
||||
REGISTER_ALG(cfbAesAlg, crypto_register_skcipher, linuxkm_test_aescfb);
|
||||
REGISTER_ALG(cfbAesAlg, skcipher, linuxkm_test_aescfb);
|
||||
#endif
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_AESGCM
|
||||
REGISTER_ALG(gcmAesAead, crypto_register_aead, linuxkm_test_aesgcm);
|
||||
REGISTER_ALG(gcmAesAead, aead, linuxkm_test_aesgcm);
|
||||
#endif
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_AESGCM_RFC4106
|
||||
REGISTER_ALG(gcmAesAead_rfc4106, crypto_register_aead, linuxkm_test_aesgcm_rfc4106);
|
||||
REGISTER_ALG(gcmAesAead_rfc4106, aead, linuxkm_test_aesgcm_rfc4106);
|
||||
#endif
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_AESXTS
|
||||
REGISTER_ALG(xtsAesAlg, crypto_register_skcipher, linuxkm_test_aesxts);
|
||||
REGISTER_ALG(xtsAesAlg, skcipher, linuxkm_test_aesxts);
|
||||
#endif
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_AESCTR
|
||||
REGISTER_ALG(ctrAesAlg, crypto_register_skcipher, linuxkm_test_aesctr);
|
||||
REGISTER_ALG(ctrAesAlg, skcipher, linuxkm_test_aesctr);
|
||||
#endif
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_AESOFB
|
||||
REGISTER_ALG(ofbAesAlg, crypto_register_skcipher, linuxkm_test_aesofb);
|
||||
REGISTER_ALG(ofbAesAlg, skcipher, linuxkm_test_aesofb);
|
||||
#endif
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_AESECB
|
||||
REGISTER_ALG(ecbAesAlg, crypto_register_skcipher, linuxkm_test_aesecb);
|
||||
REGISTER_ALG(ecbAesAlg, skcipher, linuxkm_test_aesecb);
|
||||
#endif
|
||||
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_SHA1
|
||||
REGISTER_ALG(sha1_alg, crypto_register_shash, linuxkm_test_sha1);
|
||||
REGISTER_ALG(sha1_alg, shash, linuxkm_test_sha1);
|
||||
#endif
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_224
|
||||
REGISTER_ALG(sha2_224_alg, crypto_register_shash, linuxkm_test_sha2_224);
|
||||
REGISTER_ALG(sha2_224_alg, shash, linuxkm_test_sha2_224);
|
||||
#endif
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_256
|
||||
REGISTER_ALG(sha2_256_alg, crypto_register_shash, linuxkm_test_sha2_256);
|
||||
REGISTER_ALG(sha2_256_alg, shash, linuxkm_test_sha2_256);
|
||||
#endif
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_384
|
||||
REGISTER_ALG(sha2_384_alg, crypto_register_shash, linuxkm_test_sha2_384);
|
||||
REGISTER_ALG(sha2_384_alg, shash, linuxkm_test_sha2_384);
|
||||
#endif
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_SHA2_512
|
||||
REGISTER_ALG(sha2_512_alg, crypto_register_shash, linuxkm_test_sha2_512);
|
||||
REGISTER_ALG(sha2_512_alg, shash, linuxkm_test_sha2_512);
|
||||
#endif
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_224
|
||||
REGISTER_ALG(sha3_224_alg, crypto_register_shash, linuxkm_test_sha3_224);
|
||||
REGISTER_ALG(sha3_224_alg, shash, linuxkm_test_sha3_224);
|
||||
#endif
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_256
|
||||
REGISTER_ALG(sha3_256_alg, crypto_register_shash, linuxkm_test_sha3_256);
|
||||
REGISTER_ALG(sha3_256_alg, shash, linuxkm_test_sha3_256);
|
||||
#endif
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_384
|
||||
REGISTER_ALG(sha3_384_alg, crypto_register_shash, linuxkm_test_sha3_384);
|
||||
REGISTER_ALG(sha3_384_alg, shash, linuxkm_test_sha3_384);
|
||||
#endif
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_SHA3_512
|
||||
REGISTER_ALG(sha3_512_alg, crypto_register_shash, linuxkm_test_sha3_512);
|
||||
REGISTER_ALG(sha3_512_alg, shash, linuxkm_test_sha3_512);
|
||||
#endif
|
||||
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_SHA1_HMAC
|
||||
REGISTER_ALG(sha1_hmac_alg, crypto_register_shash, linuxkm_test_sha1_hmac);
|
||||
REGISTER_ALG(sha1_hmac_alg, 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);
|
||||
REGISTER_ALG(sha2_224_hmac_alg, 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);
|
||||
REGISTER_ALG(sha2_256_hmac_alg, 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);
|
||||
REGISTER_ALG(sha2_384_hmac_alg, 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);
|
||||
REGISTER_ALG(sha2_512_hmac_alg, 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);
|
||||
REGISTER_ALG(sha3_224_hmac_alg, 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);
|
||||
REGISTER_ALG(sha3_256_hmac_alg, 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);
|
||||
REGISTER_ALG(sha3_384_hmac_alg, 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);
|
||||
REGISTER_ALG(sha3_512_hmac_alg, shash, linuxkm_test_sha3_512_hmac);
|
||||
#endif
|
||||
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_HASH_DRBG
|
||||
/* special installation handler for wc_linuxkm_drbg, to conditionally
|
||||
* install it as the system-wide default rng.
|
||||
*/
|
||||
if (! wc_linuxkm_drbg_loaded)
|
||||
ret = wc_linuxkm_drbg_startup();
|
||||
#endif
|
||||
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_ECDSA
|
||||
#if defined(LINUXKM_ECC192)
|
||||
REGISTER_ALG(ecdsa_nist_p192, crypto_register_akcipher,
|
||||
REGISTER_ALG(ecdsa_nist_p192, akcipher,
|
||||
linuxkm_test_ecdsa_nist_p192);
|
||||
#endif /* LINUXKM_ECC192 */
|
||||
|
||||
REGISTER_ALG(ecdsa_nist_p256, crypto_register_akcipher,
|
||||
REGISTER_ALG(ecdsa_nist_p256, akcipher,
|
||||
linuxkm_test_ecdsa_nist_p256);
|
||||
|
||||
REGISTER_ALG(ecdsa_nist_p384, crypto_register_akcipher,
|
||||
REGISTER_ALG(ecdsa_nist_p384, akcipher,
|
||||
linuxkm_test_ecdsa_nist_p384);
|
||||
|
||||
#if defined(HAVE_ECC521)
|
||||
REGISTER_ALG(ecdsa_nist_p521, crypto_register_akcipher,
|
||||
REGISTER_ALG(ecdsa_nist_p521, akcipher,
|
||||
linuxkm_test_ecdsa_nist_p521);
|
||||
#endif /* HAVE_ECC521 */
|
||||
#endif /* LINUXKM_LKCAPI_REGISTER_ECDSA */
|
||||
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_ECDH
|
||||
#if defined(LINUXKM_ECC192)
|
||||
REGISTER_ALG(ecdh_nist_p192, crypto_register_kpp,
|
||||
REGISTER_ALG(ecdh_nist_p192, kpp,
|
||||
linuxkm_test_ecdh_nist_p192);
|
||||
#endif /* LINUXKM_ECC192 */
|
||||
|
||||
REGISTER_ALG(ecdh_nist_p256, crypto_register_kpp,
|
||||
REGISTER_ALG(ecdh_nist_p256, kpp,
|
||||
linuxkm_test_ecdh_nist_p256);
|
||||
|
||||
REGISTER_ALG(ecdh_nist_p384, crypto_register_kpp,
|
||||
REGISTER_ALG(ecdh_nist_p384, kpp,
|
||||
linuxkm_test_ecdh_nist_p384);
|
||||
#endif /* LINUXKM_LKCAPI_REGISTER_ECDH */
|
||||
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_RSA
|
||||
#if defined(LINUXKM_DIRECT_RSA)
|
||||
REGISTER_ALG(direct_rsa, crypto_register_akcipher, linuxkm_test_rsa);
|
||||
REGISTER_ALG(direct_rsa, akcipher, linuxkm_test_rsa);
|
||||
#endif /* LINUXKM_DIRECT_RSA */
|
||||
#ifndef NO_SHA256
|
||||
REGISTER_ALG(pkcs1_sha256, crypto_register_akcipher,
|
||||
REGISTER_ALG(pkcs1_sha256, akcipher,
|
||||
linuxkm_test_pkcs1_sha256);
|
||||
#endif /* !NO_SHA256 */
|
||||
#ifdef WOLFSSL_SHA512
|
||||
REGISTER_ALG(pkcs1_sha512, crypto_register_akcipher,
|
||||
REGISTER_ALG(pkcs1_sha512, akcipher,
|
||||
linuxkm_test_pkcs1_sha512);
|
||||
#endif /* WOLFSSL_SHA512 */
|
||||
#endif
|
||||
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_DH
|
||||
#ifdef LINUXKM_DH
|
||||
REGISTER_ALG(dh, crypto_register_kpp, linuxkm_test_dh);
|
||||
REGISTER_ALG(dh, kpp, linuxkm_test_dh);
|
||||
#endif /* LINUXKM_DH */
|
||||
#ifdef HAVE_FFDHE_2048
|
||||
REGISTER_ALG(ffdhe2048, crypto_register_kpp, linuxkm_test_ffdhe2048);
|
||||
REGISTER_ALG(ffdhe2048, kpp, linuxkm_test_ffdhe2048);
|
||||
#endif /* HAVE_FFDHE_2048 */
|
||||
|
||||
#ifdef HAVE_FFDHE_3072
|
||||
REGISTER_ALG(ffdhe3072, crypto_register_kpp, linuxkm_test_ffdhe3072);
|
||||
REGISTER_ALG(ffdhe3072, kpp, linuxkm_test_ffdhe3072);
|
||||
#endif /* HAVE_FFDHE_3072 */
|
||||
|
||||
#ifdef HAVE_FFDHE_4096
|
||||
REGISTER_ALG(ffdhe4096, crypto_register_kpp, linuxkm_test_ffdhe4096);
|
||||
REGISTER_ALG(ffdhe4096, kpp, linuxkm_test_ffdhe4096);
|
||||
#endif /* HAVE_FFDHE_4096 */
|
||||
|
||||
#ifdef HAVE_FFDHE_6144
|
||||
REGISTER_ALG(ffdhe6144, crypto_register_kpp, linuxkm_test_ffdhe6144);
|
||||
REGISTER_ALG(ffdhe6144, kpp, linuxkm_test_ffdhe6144);
|
||||
#endif /* HAVE_FFDHE_6144 */
|
||||
|
||||
#ifdef HAVE_FFDHE_8192
|
||||
REGISTER_ALG(ffdhe8192, crypto_register_kpp, linuxkm_test_ffdhe8192);
|
||||
REGISTER_ALG(ffdhe8192, kpp, linuxkm_test_ffdhe8192);
|
||||
#endif /* HAVE_FFDHE_8192 */
|
||||
#endif /* LINUXKM_LKCAPI_REGISTER_DH */
|
||||
|
||||
#undef REGISTER_ALG
|
||||
|
||||
out:
|
||||
|
||||
#if defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_MANAGER) && \
|
||||
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
|
||||
if (enabled_fips)
|
||||
@@ -554,16 +642,47 @@ static int linuxkm_lkcapi_register(void)
|
||||
disable_setkey_warnings = 0;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
if (ret == -1) {
|
||||
/* no installations occurred */
|
||||
if (linuxkm_lkcapi_registered)
|
||||
return -EEXIST;
|
||||
else {
|
||||
linuxkm_lkcapi_registered = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* flag that linuxkm_lkcapi_register has been called, even if an error
|
||||
* occurred.
|
||||
*/
|
||||
linuxkm_lkcapi_registered = 1;
|
||||
if (seen_err)
|
||||
return -EINVAL;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void linuxkm_lkcapi_unregister(void)
|
||||
static int linuxkm_lkcapi_unregister(void)
|
||||
{
|
||||
#define UNREGISTER_ALG(alg, uninstaller) do { \
|
||||
if (alg ## _loaded) { \
|
||||
(uninstaller)(&(alg)); \
|
||||
alg ## _loaded = 0; \
|
||||
} \
|
||||
int seen_err = 0;
|
||||
|
||||
if (! linuxkm_lkcapi_registered)
|
||||
return -ENOENT;
|
||||
|
||||
#define UNREGISTER_ALG(alg, uninstaller) do { \
|
||||
if (alg ## _loaded) { \
|
||||
int cur_refcnt = WC_LKM_REFCOUNT_TO_INT(alg.base.cra_refcnt);\
|
||||
if (cur_refcnt == 1) { \
|
||||
(uninstaller)(&(alg)); \
|
||||
alg ## _loaded = 0; \
|
||||
} \
|
||||
else { \
|
||||
pr_err("alg %s cannot be uninstalled (refcnt = %d)", \
|
||||
alg.base.cra_driver_name, cur_refcnt); \
|
||||
if (cur_refcnt > 0) { seen_err = 1; } \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_AESCBC
|
||||
@@ -647,6 +766,16 @@ static void linuxkm_lkcapi_unregister(void)
|
||||
UNREGISTER_ALG(sha3_512_hmac_alg, crypto_unregister_shash);
|
||||
#endif
|
||||
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_HASH_DRBG
|
||||
/* special deinstallation handler for wc_linuxkm_drbg, to deinstall it as
|
||||
* the system-wide default rng.
|
||||
*/
|
||||
if (wc_linuxkm_drbg_loaded) {
|
||||
if (wc_linuxkm_drbg_cleanup() != 0)
|
||||
seen_err = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_ECDSA
|
||||
#if defined(LINUXKM_ECC192)
|
||||
UNREGISTER_ALG(ecdsa_nist_p192, crypto_unregister_akcipher);
|
||||
@@ -705,4 +834,15 @@ static void linuxkm_lkcapi_unregister(void)
|
||||
#endif /* LINUXKM_LKCAPI_REGISTER_DH */
|
||||
|
||||
#undef UNREGISTER_ALG
|
||||
|
||||
/* only clear linuxkm_lkcapi_registered if no errors occurred, to allow
|
||||
* retries.
|
||||
*/
|
||||
|
||||
if (seen_err == 0) {
|
||||
linuxkm_lkcapi_registered = 0;
|
||||
pr_info("wolfCrypt: All algorithms deregistered successfully.");
|
||||
}
|
||||
|
||||
return seen_err ? -EINVAL : 0;
|
||||
}
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#define WOLFKM_SHA3_256_NAME "sha3-256"
|
||||
#define WOLFKM_SHA3_384_NAME "sha3-384"
|
||||
#define WOLFKM_SHA3_512_NAME "sha3-512"
|
||||
|
||||
#define WOLFKM_SHA1_HMAC_NAME "hmac(sha1)"
|
||||
#define WOLFKM_SHA2_224_HMAC_NAME "hmac(sha224)"
|
||||
#define WOLFKM_SHA2_256_HMAC_NAME "hmac(sha256)"
|
||||
@@ -43,6 +44,8 @@
|
||||
#define WOLFKM_SHA3_384_HMAC_NAME "hmac(sha3-384)"
|
||||
#define WOLFKM_SHA3_512_HMAC_NAME "hmac(sha3-512)"
|
||||
|
||||
#define WOLFKM_STDRNG_NAME "stdrng"
|
||||
|
||||
#if defined(USE_INTEL_SPEEDUP)
|
||||
#define WOLFKM_SHA_DRIVER_ISA_EXT "-avx"
|
||||
#else
|
||||
@@ -72,6 +75,8 @@
|
||||
#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_STDRNG_DRIVER ("sha2-256-drbg" WOLFKM_SHA_DRIVER_SUFFIX)
|
||||
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_SHA2
|
||||
#define LINUXKM_LKCAPI_REGISTER_SHA2_224
|
||||
#define LINUXKM_LKCAPI_REGISTER_SHA2_256
|
||||
@@ -274,6 +279,19 @@
|
||||
#error LINUXKM_LKCAPI_REGISTER for HMACs is supported only on Linux kernel versions >= 5.6.0.
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HASHDRBG
|
||||
#if (defined(LINUXKM_LKCAPI_REGISTER_ALL) && !defined(LINUXKM_LKCAPI_DONT_REGISTER_HASH_DRBG)) && \
|
||||
!defined(LINUXKM_LKCAPI_REGISTER_HASH_DRBG)
|
||||
#define LINUXKM_LKCAPI_REGISTER_HASH_DRBG
|
||||
#endif
|
||||
#if (defined(LINUXKM_LKCAPI_REGISTER_ALL) && !defined(LINUXKM_LKCAPI_DONT_REGISTER_HASH_DRBG_DEFAULT)) && \
|
||||
!defined(LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT)
|
||||
#define LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT
|
||||
#endif
|
||||
#else
|
||||
#undef LINUXKM_LKCAPI_REGISTER_HASH_DRBG
|
||||
#endif
|
||||
|
||||
struct km_sha_state {
|
||||
union {
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_SHA1
|
||||
@@ -811,3 +829,238 @@ struct wc_swallow_the_semicolon
|
||||
WC_SHA3_512_BLOCK_SIZE, WOLFKM_SHA3_512_HMAC_NAME,
|
||||
WOLFKM_SHA3_512_HMAC_DRIVER, hmac_sha3_test_once);
|
||||
#endif
|
||||
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_HASH_DRBG
|
||||
|
||||
#include <wolfssl/wolfcrypt/random.h>
|
||||
|
||||
struct wc_linuxkm_drbg_ctx {
|
||||
wolfSSL_Mutex lock;
|
||||
WC_RNG rng;
|
||||
};
|
||||
|
||||
static int wc_linuxkm_drbg_init_tfm(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_tfm_ctx(tfm);
|
||||
int ret;
|
||||
|
||||
ret = wc_InitMutex(&ctx->lock);
|
||||
if (ret != 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Note the new DRBG instance is seeded, and later reseeded, from system
|
||||
* get_random_bytes() via wc_GenerateSeed().
|
||||
*/
|
||||
ret = wc_InitRng(&ctx->rng);
|
||||
if (ret != 0) {
|
||||
(void)wc_FreeMutex(&ctx->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wc_linuxkm_drbg_exit_tfm(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_tfm_ctx(tfm);
|
||||
|
||||
wc_FreeRng(&ctx->rng);
|
||||
|
||||
(void)wc_FreeMutex(&ctx->lock);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int wc_linuxkm_drbg_generate(struct crypto_rng *tfm,
|
||||
const u8 *src, unsigned int slen,
|
||||
u8 *dst, unsigned int dlen)
|
||||
{
|
||||
struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_rng_ctx(tfm);
|
||||
int ret;
|
||||
|
||||
(void)tfm;
|
||||
|
||||
wc_LockMutex(&ctx->lock);
|
||||
|
||||
if (slen > 0) {
|
||||
ret = wc_RNG_DRBG_Reseed(&ctx->rng, src, slen);
|
||||
if (ret != 0) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = wc_RNG_GenerateBlock(&ctx->rng, dst, dlen);
|
||||
if (ret != 0)
|
||||
ret = -EINVAL;
|
||||
|
||||
out:
|
||||
|
||||
wc_UnLockMutex(&ctx->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wc_linuxkm_drbg_seed(struct crypto_rng *tfm,
|
||||
const u8 *seed, unsigned int slen)
|
||||
{
|
||||
struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_rng_ctx(tfm);
|
||||
int ret;
|
||||
|
||||
(void)tfm;
|
||||
|
||||
if (slen == 0)
|
||||
return 0;
|
||||
|
||||
wc_LockMutex(&ctx->lock);
|
||||
|
||||
ret = wc_RNG_DRBG_Reseed(&ctx->rng, seed, slen);
|
||||
if (ret != 0) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
wc_UnLockMutex(&ctx->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct rng_alg wc_linuxkm_drbg = {
|
||||
.generate = wc_linuxkm_drbg_generate,
|
||||
.seed = wc_linuxkm_drbg_seed,
|
||||
.seedsize = 0,
|
||||
.base = {
|
||||
.cra_name = WOLFKM_STDRNG_NAME,
|
||||
.cra_driver_name = WOLFKM_STDRNG_DRIVER,
|
||||
.cra_priority = WOLFSSL_LINUXKM_LKCAPI_PRIORITY,
|
||||
.cra_ctxsize = sizeof(struct wc_linuxkm_drbg_ctx),
|
||||
.cra_init = wc_linuxkm_drbg_init_tfm,
|
||||
.cra_exit = wc_linuxkm_drbg_exit_tfm,
|
||||
.cra_module = THIS_MODULE
|
||||
}
|
||||
};
|
||||
static int wc_linuxkm_drbg_loaded = 0;
|
||||
static int wc_linuxkm_drbg_default_instance_registered = 0;
|
||||
|
||||
WC_MAYBE_UNUSED static int wc_linuxkm_drbg_startup(void) {
|
||||
int ret;
|
||||
int cur_refcnt;
|
||||
|
||||
if (wc_linuxkm_drbg_loaded) {
|
||||
pr_err("wc_linuxkm_drbg_set_default called with wc_linuxkm_drbg_loaded.");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
ret = random_test();
|
||||
if (ret) {
|
||||
pr_err("ERROR: self-test for %s failed "
|
||||
"with return code %d.\n",
|
||||
wc_linuxkm_drbg.base.cra_driver_name, ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = crypto_register_rng(&wc_linuxkm_drbg);
|
||||
if (ret != 0) {
|
||||
pr_err("crypto_register_rng: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
wc_linuxkm_drbg_loaded = 1;
|
||||
|
||||
WOLFKM_INSTALL_NOTICE(wc_linuxkm_drbg);
|
||||
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT
|
||||
ret = crypto_del_default_rng();
|
||||
if (ret) {
|
||||
pr_err("crypto_del_default_rng returned %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = crypto_get_default_rng();
|
||||
if (ret) {
|
||||
pr_err("crypto_get_default_rng returned %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
cur_refcnt = WC_LKM_REFCOUNT_TO_INT(wc_linuxkm_drbg.base.cra_refcnt);
|
||||
if (cur_refcnt < 2) {
|
||||
pr_err("wc_linuxkm_drbg refcnt = %d after crypto_get_default_rng()", cur_refcnt);
|
||||
crypto_put_default_rng();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (! crypto_default_rng) {
|
||||
pr_err("crypto_default_rng is null");
|
||||
crypto_put_default_rng();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (strcmp(crypto_tfm_alg_driver_name(&crypto_default_rng->base), wc_linuxkm_drbg.base.cra_driver_name) == 0) {
|
||||
crypto_put_default_rng();
|
||||
wc_linuxkm_drbg_default_instance_registered = 1;
|
||||
pr_info("%s registered as systemwide default stdrng.", wc_linuxkm_drbg.base.cra_driver_name);
|
||||
pr_info("to unload module, first echo 1 > /sys/module/libwolfssl/deinstall_algs");
|
||||
}
|
||||
else {
|
||||
pr_err("%s NOT registered as systemwide default stdrng -- found \"%s\".", wc_linuxkm_drbg.base.cra_driver_name, crypto_tfm_alg_driver_name(&crypto_default_rng->base));
|
||||
crypto_put_default_rng();
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif /* LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WC_MAYBE_UNUSED static int wc_linuxkm_drbg_cleanup(void) {
|
||||
int cur_refcnt = WC_LKM_REFCOUNT_TO_INT(wc_linuxkm_drbg.base.cra_refcnt);
|
||||
int ret;
|
||||
|
||||
if (! wc_linuxkm_drbg_loaded) {
|
||||
pr_err("wc_linuxkm_drbg_cleanup called with ! wc_linuxkm_drbg_loaded");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cur_refcnt - wc_linuxkm_drbg_default_instance_registered != 1) {
|
||||
pr_err("wc_linuxkm_drbg_cleanup called with refcnt = %d, with wc_linuxkm_drbg %sset as default rng",
|
||||
cur_refcnt, wc_linuxkm_drbg_default_instance_registered ? "" : "not ");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* The below is racey, but the kernel doesn't provide any other way. It's
|
||||
* written to be retryable.
|
||||
*/
|
||||
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT
|
||||
if (wc_linuxkm_drbg_default_instance_registered) {
|
||||
ret = crypto_del_default_rng();
|
||||
if (ret) {
|
||||
pr_err("crypto_del_default_rng failed: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
cur_refcnt = WC_LKM_REFCOUNT_TO_INT(wc_linuxkm_drbg.base.cra_refcnt);
|
||||
if (cur_refcnt != 1) {
|
||||
pr_err("wc_linuxkm_drbg refcnt = %d after crypto_del_default_rng()", cur_refcnt);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
#endif /* LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT */
|
||||
|
||||
crypto_unregister_rng(&wc_linuxkm_drbg);
|
||||
|
||||
if (! (wc_linuxkm_drbg.base.cra_flags & CRYPTO_ALG_DEAD)) {
|
||||
pr_err("wc_linuxkm_drbg_cleanup: after crypto_unregister_rng, wc_linuxkm_drbg isn't dead.");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT
|
||||
wc_linuxkm_drbg_default_instance_registered = 0;
|
||||
#endif /* LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT */
|
||||
|
||||
wc_linuxkm_drbg_loaded = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* LINUXKM_LKCAPI_REGISTER_HASH_DRBG */
|
||||
|
@@ -316,6 +316,16 @@ static int wolfssl_init(void)
|
||||
#endif
|
||||
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER_ONLY_ON_COMMAND
|
||||
ret = linuxkm_lkcapi_sysfs_install();
|
||||
|
||||
if (ret) {
|
||||
pr_err("linuxkm_lkcapi_sysfs_install() failed with return code %d.\n", ret);
|
||||
(void)libwolfssl_cleanup();
|
||||
msleep(10);
|
||||
return -ECANCELED;
|
||||
}
|
||||
#else /* !LINUXKM_LKCAPI_REGISTER_ONLY_ON_COMMAND */
|
||||
ret = linuxkm_lkcapi_register();
|
||||
|
||||
if (ret) {
|
||||
@@ -325,7 +335,8 @@ static int wolfssl_init(void)
|
||||
msleep(10);
|
||||
return -ECANCELED;
|
||||
}
|
||||
#endif
|
||||
#endif /* !LINUXKM_LKCAPI_REGISTER_ONLY_ON_COMMAND */
|
||||
#endif /* LINUXKM_LKCAPI_REGISTER */
|
||||
|
||||
#ifdef WOLFSSL_LINUXKM_BENCHMARKS
|
||||
wolfcrypt_benchmark_main(0, (char**)NULL);
|
||||
@@ -365,7 +376,8 @@ static void wolfssl_exit(void)
|
||||
#endif
|
||||
{
|
||||
#ifdef LINUXKM_LKCAPI_REGISTER
|
||||
linuxkm_lkcapi_unregister();
|
||||
(void)linuxkm_lkcapi_unregister();
|
||||
(void)linuxkm_lkcapi_sysfs_deinstall();
|
||||
#endif
|
||||
|
||||
(void)libwolfssl_cleanup();
|
||||
|
@@ -3676,7 +3676,7 @@ extern void uITRON4_free(void *p) ;
|
||||
|
||||
#if defined(LINUXKM_LKCAPI_REGISTER) && !defined(WOLFSSL_ASN_INT_LEAD_0_ANY)
|
||||
/* kernel 5.10 crypto manager tests key(s) that fail unless leading
|
||||
* bytes are tolerated in GetASN_Integer().
|
||||
* zero bytes are tolerated in GetASN_Integer().
|
||||
*/
|
||||
#define WOLFSSL_ASN_INT_LEAD_0_ANY
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user