Skip to content

Commit b3944a7

Browse files
committed
linuxkm/lkcapi_sha_glue.c:
* implement interception of _get_random_bytes() and get_random_bytes_user() (implicitly intercepts /dev/random and /dev/urandom): * get_crypto_default_rng() * get_default_drbg_ctx() * wc__get_random_bytes() * wc_get_random_bytes_user() * wc_extract_crng_user() * wc_mix_pool_bytes() * wc_crng_reseed() * wc_get_random_bytes_by_kprobe() * wc_get_random_bytes_user_kretprobe_enter() * wc_get_random_bytes_user_kretprobe_exit() * add LINUXKM_DRBG_GET_RANDOM_BYTES sections to wc_linuxkm_drbg_startup() and wc_linuxkm_drbg_cleanup() * add linuxkm/patches/*/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-*.patch, initially for versions: * 5.10.17 * 5.10.236 * 5.15 * 5.17 * 6.1.73 * 6.12 * 6.15 * remove "*.patch" from .gitignore. * add linuxkm/patches/regen-patches.sh. * in wc_linuxkm_drbg_ctx_clear(), check lock count before freeing. * in get_drbg() and put_drbg(), use migrate_disable(), not DISABLE_VECTOR_REGISTERS(). * in wc_linuxkm_drbg_generate(), explicitly DISABLE_VECTOR_REGISTERS() for the crypto_default_rng. * in wc_linuxkm_drbg_generate(), add DRBG reinitialization code to handle RNG_FAILURE_E. This handles the situation where a DRBG was instantiated in a vector-ops-allowed context, caching a vectorized SHA256 ethod, but later used in a no-vector-ops-allowed context. * in wc_linuxkm_drbg_seed(), add DISABLE_VECTOR_REGISTERS() wrapper around wc_RNG_DRBG_Reseed() for crypto_default_rng. linuxkm/x86_vector_register_glue.c: * add crash recovery logic to wc_linuxkm_fpu_state_assoc_unlikely() * in wc_linuxkm_fpu_state_assoc(), when wc_linuxkm_fpu_states is null, don't call wc_linuxkm_fpu_state_assoc_unlikely() if !assume_fpu_began. * in can_save_vector_registers_x86(), save_vector_registers_x86(), and restore_vector_registers_x86(), check for hard interrupt context first, to return early failure if current->pid is unusable. * in save_vector_registers_x86(), tweak logic around WC_FPU_INHIBITED_FLAG, adding local_bh_disable()...local_bh_enable() to provide for safe recursion. wolfcrypt/src/random.c: optimization: in Hash_df(), for WOLFSSL_LINUXKM, don't put digest[WC_SHA256_DIGEST_SIZE] in the heap, keep it on the stack. wolfssl/wolfcrypt/types.h: add WOLFSSL_NO_ASM no-op definitions for DISABLE_VECTOR_REGISTERS() and REENABLE_VECTOR_REGISTERS(). configure.ac: * move --enable-linuxkm and --enable-linuxkm-defaults initial detection early, so that HMAC_COPY_DEFAULT picks it up. * add ENABLED_ENTROPY_MEMUSE_DEFAULT, and enable it by default when ENABLED_LINUXKM_DEFAULTS. * update linuxkm-lkcapi-register help message. linuxkm/linuxkm_wc_port.h: * add my_kallsyms_lookup_name(). * add preempt_count, _raw_spin_lock_irqsave, _raw_spin_trylock, _raw_spin_unlock_irqrestore, and _cond_resched, to wolfssl_linuxkm_pie_redirect_table, and add spin_unlock_irqrestore() macro to mask native inline. * move linuxkm mutex wrappers from wolfcrypt/src/wc_port.c to linuxkm_wc_port.h, make them inlines, and add new default spinlock-based implementation, with old method now gated on WOLFSSL_LINUXKM_USE_MUTEXES. * change malloc() and realloc() wrappers from GFP_KERNEL to GFP_ATOMIC. linuxkm/lkcapi_glue.c: make misc.h/misc.c inclusion unconditional, and trim now-redundant inclusions out of lkcapi_dh_glue.c and lkcapi_ecdh_glue.c.
1 parent b25d484 commit b3944a7

21 files changed

Lines changed: 3635 additions & 172 deletions

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ ctaocrypt/src/src/
33
*.lo
44
*.la
55
*.o
6-
*.patch
76
*.deps
87
*.d
98
*.libs
@@ -246,6 +245,9 @@ linuxkm/libwolfssl.mod.c
246245
linuxkm/libwolfssl.lds
247246
linuxkm/module_exports.c
248247
linuxkm/linuxkm/get_thread_size
248+
linuxkm/linuxkm
249+
linuxkm/src
250+
linuxkm/patches/src
249251
*.nds
250252

251253
# autotools generated

.wolfssl_known_macro_extras

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ CONFIG_IDF_TARGET_ESP32S3
112112
CONFIG_IDF_TARGET_ESP8266
113113
CONFIG_IDF_TARGET_ESP8684
114114
CONFIG_KASAN
115+
CONFIG_KPROBES
115116
CONFIG_MAIN_TASK_STACK_SIZE
116117
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
117118
CONFIG_MBEDTLS_PSA_CRYPTO_C
@@ -538,6 +539,7 @@ USE_ALT_MPRIME
538539
USE_ANY_ADDR
539540
USE_CERT_BUFFERS_25519
540541
USE_CERT_BUFFERS_3072
542+
USE_CONTESTMUTEX
541543
USE_ECDSA_KEYSZ_HASH_ALGO
542544
USE_FULL_ASSERT
543545
USE_HAL_DRIVER
@@ -716,6 +718,8 @@ WOLFSSL_KYBER_NO_DECAPSULATE
716718
WOLFSSL_KYBER_NO_ENCAPSULATE
717719
WOLFSSL_KYBER_NO_MAKE_KEY
718720
WOLFSSL_LIB
721+
WOLFSSL_LINUXKM_USE_GET_RANDOM_KPROBES
722+
WOLFSSL_LINUXKM_USE_MUTEXES
719723
WOLFSSL_LMS_CACHE_BITS
720724
WOLFSSL_LMS_FULL_HASH
721725
WOLFSSL_LMS_LARGE_CACHES

configure.ac

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,22 @@ then
119119
AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_EXPERIMENTAL_SETTINGS"
120120
fi
121121

122+
123+
# Linux Kernel Module options (more options later)
124+
125+
AC_ARG_ENABLE([linuxkm],
126+
[AS_HELP_STRING([--enable-linuxkm],[Enable Linux Kernel Module (default: disabled)])],
127+
[ENABLED_LINUXKM=$enableval],
128+
[ENABLED_LINUXKM=no]
129+
)
130+
131+
AC_ARG_ENABLE([linuxkm-defaults],
132+
[AS_HELP_STRING([--enable-linuxkm-defaults],[Enable feature defaults for Linux Kernel Module (default: disabled)])],
133+
[ENABLED_LINUXKM_DEFAULTS=$enableval],
134+
[ENABLED_LINUXKM_DEFAULTS=$ENABLED_LINUXKM]
135+
)
136+
137+
122138
AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h stddef.h time.h sys/ioctl.h sys/socket.h sys/time.h errno.h sys/un.h ctype.h])
123139
AC_CHECK_LIB([network],[socket])
124140
AC_C_BIGENDIAN
@@ -658,18 +674,7 @@ AC_ARG_ENABLE([benchmark],
658674
)
659675

660676

661-
# Linux Kernel Module
662-
AC_ARG_ENABLE([linuxkm],
663-
[AS_HELP_STRING([--enable-linuxkm],[Enable Linux Kernel Module (default: disabled)])],
664-
[ENABLED_LINUXKM=$enableval],
665-
[ENABLED_LINUXKM=no]
666-
)
667-
668-
AC_ARG_ENABLE([linuxkm-defaults],
669-
[AS_HELP_STRING([--enable-linuxkm-defaults],[Enable feature defaults for Linux Kernel Module (default: disabled)])],
670-
[ENABLED_LINUXKM_DEFAULTS=$enableval],
671-
[ENABLED_LINUXKM_DEFAULTS=$ENABLED_LINUXKM]
672-
)
677+
# Remainder of Linux kernel module options, continued from earlier:
673678

674679
AC_ARG_ENABLE([linuxkm-pie],
675680
[AS_HELP_STRING([--enable-linuxkm-pie],[Enable relocatable object build of Linux kernel module (default: disabled)])],
@@ -5649,10 +5654,18 @@ AC_ARG_ENABLE([pwdbased],
56495654

56505655
# MemUse Entropy
56515656
# wolfEntropy Software Jitter SP800-90B certifiable entropy source
5657+
5658+
if test "$ENABLED_LINUXKM_DEFAULTS" = "yes"
5659+
then
5660+
ENABLED_ENTROPY_MEMUSE_DEFAULT=yes
5661+
else
5662+
ENABLED_ENTROPY_MEMUSE_DEFAULT=no
5663+
fi
5664+
56525665
AC_ARG_ENABLE([wolfEntropy],
56535666
[AS_HELP_STRING([--enable-wolfEntropy],[Enable memuse entropy support (default: disabled)])],
56545667
[ ENABLED_ENTROPY_MEMUSE=$enableval ],
5655-
[ ENABLED_ENTROPY_MEMUSE=no ]
5668+
[ ENABLED_ENTROPY_MEMUSE=$ENABLED_ENTROPY_MEMUSE_DEFAULT ]
56565669
)
56575670
AC_ARG_ENABLE([entropy-memuse],
56585671
[AS_HELP_STRING([--enable-entropy-memuse],[Enable memuse entropy support (default: disabled)])],
@@ -9538,7 +9551,11 @@ if test -n "$MPI_MAX_KEY_BITS" -o -n "$WITH_MAX_ECC_BITS"; then
95389551
fi
95399552
95409553
AC_ARG_ENABLE([linuxkm-lkcapi-register],
9541-
[AS_HELP_STRING([--enable-linuxkm-lkcapi-register],[Register wolfCrypt implementations with the Linux Kernel Crypto API backplane. Possible values are "none", "all", "cbc(aes)", "cfb(aes)", "gcm(aes)", and "xts(aes)", or a comma-separate combination. (default: none)])],
9554+
[AS_HELP_STRING([--enable-linuxkm-lkcapi-register],[Register wolfCrypt implementations with the Linux Kernel Crypto API backplane.
9555+
Possible values are "none" or a comma-separated combination of "all", "all-kconfig", "sysfs-nodes-only", "cbc(aes)", "cfb(aes)",
9556+
"gcm(aes)", "rfc4106(gcm(aes))", "xts(aes)", "ctr(aes)", "ofb(aes)", "ecb(aes)", "sha1", "sha2", "sha3", "hmac(sha1)", "hmac(sha2)",
9557+
"hmac(sha3)", "stdrng", "stdrng-default", "ecdsa", "ecdh", "rsa", "dh", and negations of the foregoing algorithms by prefixing "-".
9558+
(default: none)])],
95429559
[ENABLED_LINUXKM_LKCAPI_REGISTER=$enableval],
95439560
[ENABLED_LINUXKM_LKCAPI_REGISTER=no]
95449561
)

linuxkm/linuxkm_wc_port.h

Lines changed: 138 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,9 @@
301301
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)
302302
#include <crypto/internal/sig.h>
303303
#endif /* linux ver >= 6.13 */
304+
#ifdef WOLFSSL_LINUXKM_USE_GET_RANDOM_KPROBES
305+
#include <linux/kprobes.h>
306+
#endif
304307

305308
/* the LKCAPI assumes that expanded encrypt and decrypt keys will stay
306309
* loaded simultaneously, and the Linux in-tree implementations have two
@@ -712,6 +715,12 @@
712715
#endif
713716
#endif
714717

718+
typeof(preempt_count) *preempt_count;
719+
typeof(_raw_spin_lock_irqsave) *_raw_spin_lock_irqsave;
720+
typeof(_raw_spin_trylock) *_raw_spin_trylock;
721+
typeof(_raw_spin_unlock_irqrestore) *_raw_spin_unlock_irqrestore;
722+
typeof(_cond_resched) *_cond_resched;
723+
715724
const void *_last_slot;
716725
};
717726

@@ -874,6 +883,18 @@
874883
#define dump_stack (wolfssl_linuxkm_get_pie_redirect_table()->dump_stack)
875884
#endif
876885

886+
#undef preempt_count /* just in case -- not a macro on x86. */
887+
#define preempt_count (wolfssl_linuxkm_get_pie_redirect_table()->preempt_count)
888+
#define _raw_spin_lock_irqsave (wolfssl_linuxkm_get_pie_redirect_table()->_raw_spin_lock_irqsave)
889+
#define _raw_spin_trylock (wolfssl_linuxkm_get_pie_redirect_table()->_raw_spin_trylock)
890+
#define _raw_spin_unlock_irqrestore (wolfssl_linuxkm_get_pie_redirect_table()->_raw_spin_unlock_irqrestore)
891+
#define _cond_resched (wolfssl_linuxkm_get_pie_redirect_table()->_cond_resched)
892+
893+
/* this is defined in linux/spinlock.h as an inline that calls the unshimmed
894+
* raw_spin_unlock_irqrestore(). use a macro here to supersede it.
895+
*/
896+
#define spin_unlock_irqrestore(lock, flags) raw_spin_unlock_irqrestore(&((lock)->rlock), flags)
897+
877898
#endif /* __PIE__ */
878899

879900
#endif /* USE_WOLFSSL_LINUXKM_PIE_REDIRECT_TABLE */
@@ -932,9 +953,120 @@
932953
* above, with the bevy of warnings suppressed, and the below include will
933954
* be a redundant no-op.
934955
*/
935-
#include <linux/mutex.h>
936-
typedef struct mutex wolfSSL_Mutex;
937-
#define WOLFSSL_MUTEX_INITIALIZER(lockname) __MUTEX_INITIALIZER(lockname)
956+
957+
/* Copied from wc_port.h: For FIPS keep the function names the same */
958+
#ifdef HAVE_FIPS
959+
#define wc_InitMutex InitMutex
960+
#define wc_FreeMutex FreeMutex
961+
#define wc_LockMutex LockMutex
962+
#define wc_UnLockMutex UnLockMutex
963+
#endif /* HAVE_FIPS */
964+
965+
#ifdef WOLFSSL_LINUXKM_USE_MUTEXES
966+
#ifdef LINUXKM_LKCAPI_REGISTER
967+
/* must use spin locks when registering implementations with the
968+
* kernel, because mutexes are forbidden when calling with nonzero
969+
* irq_count().
970+
*/
971+
#error WOLFSSL_LINUXKM_USE_MUTEXES is incompatible with LINUXKM_LKCAPI_REGISTER.
972+
#endif
973+
974+
#include <linux/mutex.h>
975+
typedef struct mutex wolfSSL_Mutex;
976+
#define WOLFSSL_MUTEX_INITIALIZER(lockname) __MUTEX_INITIALIZER(lockname)
977+
978+
/* Linux kernel mutex routines are voids, alas. */
979+
980+
static inline int wc_InitMutex(wolfSSL_Mutex* m)
981+
{
982+
mutex_init(m);
983+
return 0;
984+
}
985+
986+
static inline int wc_FreeMutex(wolfSSL_Mutex* m)
987+
{
988+
mutex_destroy(m);
989+
return 0;
990+
}
991+
992+
static inline int wc_LockMutex(wolfSSL_Mutex* m)
993+
{
994+
if (in_nmi() || in_hardirq() || in_softirq())
995+
return BAD_STATE_E;
996+
mutex_lock(m);
997+
return 0;
998+
}
999+
1000+
static inline int wc_UnLockMutex(wolfSSL_Mutex* m)
1001+
{
1002+
mutex_unlock(m);
1003+
return 0;
1004+
}
1005+
#else
1006+
typedef struct {
1007+
spinlock_t lock;
1008+
unsigned long irq_flags;
1009+
} wolfSSL_Mutex;
1010+
#define WOLFSSL_MUTEX_INITIALIZER(lockname) { .lock =__SPIN_LOCK_UNLOCKED(lockname), .irq_flags = 0 }
1011+
1012+
static __always_inline int wc_InitMutex(wolfSSL_Mutex* m)
1013+
{
1014+
m->lock = __SPIN_LOCK_UNLOCKED(m);
1015+
m->irq_flags = 0;
1016+
1017+
return 0;
1018+
}
1019+
1020+
static __always_inline int wc_FreeMutex(wolfSSL_Mutex* m)
1021+
{
1022+
(void)m;
1023+
return 0;
1024+
}
1025+
1026+
static __always_inline int wc_LockMutex(wolfSSL_Mutex* m)
1027+
{
1028+
unsigned long irq_flags;
1029+
/* first, try the cheap way. */
1030+
if (spin_trylock_irqsave(&m->lock, irq_flags)) {
1031+
m->irq_flags = irq_flags;
1032+
return 0;
1033+
}
1034+
if (irq_count() != 0) {
1035+
/* Note, this catches calls while SAVE_VECTOR_REGISTERS()ed as
1036+
* required, because in_softirq() is always true while saved,
1037+
* even for WC_FPU_INHIBITED_FLAG contexts.
1038+
*/
1039+
spin_lock_irqsave(&m->lock, irq_flags);
1040+
m->irq_flags = irq_flags;
1041+
return 0;
1042+
}
1043+
else {
1044+
for (;;) {
1045+
if (spin_trylock_irqsave(&m->lock, irq_flags)) {
1046+
m->irq_flags = irq_flags;
1047+
return 0;
1048+
}
1049+
cond_resched();
1050+
}
1051+
}
1052+
__builtin_unreachable();
1053+
}
1054+
1055+
static __always_inline int wc_UnLockMutex(wolfSSL_Mutex* m)
1056+
{
1057+
spin_unlock_irqrestore(&m->lock, m->irq_flags);
1058+
return 0;
1059+
}
1060+
1061+
#endif
1062+
1063+
/* Undo copied defines from wc_port.h, to avoid redefinition warnings. */
1064+
#ifdef HAVE_FIPS
1065+
#undef wc_InitMutex
1066+
#undef wc_FreeMutex
1067+
#undef wc_LockMutex
1068+
#undef wc_UnLockMutex
1069+
#endif /* HAVE_FIPS */
9381070

9391071
/* prevent gcc's mm_malloc.h from being included, since it unconditionally
9401072
* includes stdlib.h, which is kernel-incompatible.
@@ -953,14 +1085,14 @@
9531085
_alloc_sz; \
9541086
})
9551087
#ifdef HAVE_KVMALLOC
956-
#define malloc(size) kvmalloc_node(WC_LINUXKM_ROUND_UP_P_OF_2(size), GFP_KERNEL, NUMA_NO_NODE)
1088+
#define malloc(size) kvmalloc_node(WC_LINUXKM_ROUND_UP_P_OF_2(size), GFP_ATOMIC, NUMA_NO_NODE)
9571089
#define free(ptr) kvfree(ptr)
9581090
void *lkm_realloc(void *ptr, size_t newsize);
9591091
#define realloc(ptr, newsize) lkm_realloc(ptr, WC_LINUXKM_ROUND_UP_P_OF_2(newsize))
9601092
#else
961-
#define malloc(size) kmalloc(WC_LINUXKM_ROUND_UP_P_OF_2(size), GFP_KERNEL)
1093+
#define malloc(size) kmalloc(WC_LINUXKM_ROUND_UP_P_OF_2(size), GFP_ATOMIC)
9621094
#define free(ptr) kfree(ptr)
963-
#define realloc(ptr, newsize) krealloc(ptr, WC_LINUXKM_ROUND_UP_P_OF_2(newsize), GFP_KERNEL)
1095+
#define realloc(ptr, newsize) krealloc(ptr, WC_LINUXKM_ROUND_UP_P_OF_2(newsize), GFP_ATOMIC)
9641096
#endif
9651097

9661098
#ifndef static_assert

linuxkm/lkcapi_dh_glue.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,6 @@
8282
#include <wolfssl/wolfcrypt/dh.h>
8383
#include <crypto/dh.h>
8484

85-
/* need misc.c for ForceZero(). */
86-
#ifdef NO_INLINE
87-
#include <wolfssl/wolfcrypt/misc.h>
88-
#else
89-
#define WOLFSSL_MISC_INCLUDED
90-
#include <wolfcrypt/src/misc.c>
91-
#endif
92-
9385
#define WOLFKM_DH_NAME ("dh")
9486
#define WOLFKM_DH_DRIVER ("dh" WOLFKM_DRIVER_FIPS \
9587
"-wolfcrypt")

linuxkm/lkcapi_ecdh_glue.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,6 @@
5858
#include <wolfssl/wolfcrypt/ecc.h>
5959
#include <crypto/ecdh.h>
6060

61-
/* need misc.c for ForceZero(). */
62-
#ifdef NO_INLINE
63-
#include <wolfssl/wolfcrypt/misc.h>
64-
#else
65-
#define WOLFSSL_MISC_INCLUDED
66-
#include <wolfcrypt/src/misc.c>
67-
#endif
68-
6961
#define WOLFKM_ECDH_DRIVER ("ecdh-wolfcrypt")
7062

7163
#define WOLFKM_ECDH_P192_NAME ("ecdh-nist-p192")

linuxkm/lkcapi_glue.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,12 @@
4343
#include <linux/fips.h>
4444
#endif
4545

46-
#if defined(HAVE_FIPS) && FIPS_VERSION3_LT(6,0,0)
47-
/* need misc.c for ForceZero(). */
48-
#ifdef NO_INLINE
49-
#include <wolfssl/wolfcrypt/misc.h>
50-
#else
51-
#define WOLFSSL_MISC_INCLUDED
52-
#include <wolfcrypt/src/misc.c>
53-
#endif
46+
/* need misc.c for ForceZero(). */
47+
#ifdef NO_INLINE
48+
#include <wolfssl/wolfcrypt/misc.h>
49+
#else
50+
#define WOLFSSL_MISC_INCLUDED
51+
#include <wolfcrypt/src/misc.c>
5452
#endif
5553

5654
#ifndef WOLFSSL_LINUXKM_LKCAPI_PRIORITY

0 commit comments

Comments
 (0)