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
15 changes: 15 additions & 0 deletions kernel/bsdkm/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# example module name and sources
KMOD=bsd_example
SRCS=bsd_example.c

# path to wolfssl dir
WOLFSSL_DIR=../../../wolfssl/

# suppress wolfcrypt/src/misc.c drops const qualifier
CFLAGS+= -Wno-cast-qual
CFLAGS+= -Wno-error=cast-qual
CFLAGS+= -I/usr/include
CFLAGS+=-I${WOLFSSL_DIR} -DWOLFSSL_USE_OPTIONS_H -DWOLFSSL_CUSTOM_CONFIG

# point to live kernel kmod dot mk
.include "/usr/src/sys/conf/kmod.mk"
118 changes: 118 additions & 0 deletions kernel/bsdkm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# FreeBSD wolfcrypt kernel module example

## About


Tested on FreeBSD 14.2:
```sh
uname -rsm
FreeBSD 14.2-RELEASE amd64
```

## Build libwolfssl.ko

```sh
cd ~/
git clone https://github.com/philljj/wolfssl.git
cd ~/wolfssl && git co bsdkm
./autogen.sh
./configure --enable-bsdkm --enable-cryptonly --enable-crypttests --enable-all-crypto --disable-asm && make
file bsdkm/libwolfssl.ko
```

Load the kernel module:
```sh
sudo kldload bsdkm/libwolfssl.ko
```

In dmesg output you should see something like:
```sh
dmesg | tail -n10
PKCS7enveloped test passed!
PKCS7authenveloped test passed!
mp test passed!
prime test passed!
logging test passed!
mutex test passed!
crypto callback test passed!
Test complete
wolfCrypt self-test passed.
info: wolfkmod init good
```

and kldstat:
```sh
kldstat
Id Refs Address Size Name
1 20 0xffffffff80200000 1f3c6c0 kernel
2 1 0xffffffff82818000 3220 intpm.ko
3 1 0xffffffff8281c000 2178 smbus.ko
4 1 0xffffffff8281f000 430c virtio_console.ko
5 1 0xffffffff82824000 3360 uhid.ko
6 1 0xffffffff82828000 3360 wmt.ko
17 1 0xffffffff8282c000 154520 libwolfssl.ko
```

wolfssl will also appear in vmstat entries:
```sh
vmstat -m | grep wolf
wolfssl 0 0 1275500 16,32,64,128,256,384,512,1024,2048,4096,8192,16384
```

## Build this example

From this example dir:
```sh
make && file bsd_example.ko
```

Load it:
```sh
sudo kldload ./bsd_example.ko
```

dmesg should show:
```sh
dmesg | tail -n5
Test complete
wolfCrypt self-test passed.
info: wolfkmod init good
info: bsdkm_example: running wc_aes_test()
info: bsdkm_example: wc_aes_test good
```

and kldstat:
```sh
kldstat
Id Refs Address Size Name
1 22 0xffffffff80200000 1f3c6c0 kernel
2 1 0xffffffff82818000 3220 intpm.ko
3 1 0xffffffff8281c000 2178 smbus.ko
4 1 0xffffffff8281f000 430c virtio_console.ko
5 1 0xffffffff82824000 3360 uhid.ko
6 1 0xffffffff82828000 3360 wmt.ko
17 2 0xffffffff8282c000 154520 libwolfssl.ko
18 1 0xffffffff82981000 2188 bsd_example.ko
```

Notice `libwolfssl.ko` reference count has incremented.

Unload in the opposite order as loading:
```sh
sudo kldunload bsd_example.ko
sudo kldunload libwolfssl.ko
kldstat
Id Refs Address Size Name
1 18 0xffffffff80200000 1f3c6c0 kernel
2 1 0xffffffff82818000 3220 intpm.ko
3 1 0xffffffff8281c000 2178 smbus.ko
4 1 0xffffffff8281f000 430c virtio_console.ko
5 1 0xffffffff82824000 3360 uhid.ko
6 1 0xffffffff82828000 3360 wmt.ko
```
wolfssl should now have disappeared from the vmstat listing:

```sh
# returns nothing
vmstat -m | grep wolf
```
125 changes: 125 additions & 0 deletions kernel/bsdkm/bsd_example.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/* freebsd system includes */
#include <sys/param.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/libkern.h>
#include <sys/malloc.h>
#include <sys/systm.h>

/* wolfssl includes */
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/aes.h>
#include <wolfssl/wolfcrypt/error-crypt.h>

MALLOC_DEFINE(M_BSD_EXAMPLE, "bsd_example", "example kernel memory");

static int wc_aes_test(void);
const char * ko_name = "bsdkm_example";

static int
example_loader(struct module * m, int what, void * arg)
{
int ret = 0;
switch (what) {
case MOD_LOAD:
printf("info: %s: running wc_aes_test()\n", ko_name);
ret = wc_aes_test();
if (ret != 0) {
return ECANCELED;
}
break;
case MOD_UNLOAD:
printf("info: %s: unload\n", ko_name);
break;
default:
printf("info: %s: not implemented: %d\n", ko_name, what);
return EOPNOTSUPP;
}

return 0;
}

static int wc_aes_test(void)
{
int ret = 0;
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
Aes *aes = NULL;
#else
Aes aes[1];
#endif

/* "Now is the time for all " w/o trailing 0 */
const byte msg[] = {
0x6e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,
0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20,
0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20
};
const byte verify[] =
{
0x95,0x94,0x92,0x57,0x5f,0x42,0x81,0x53,
0x2c,0xcc,0x9d,0x46,0x77,0xa2,0x33,0xcb
};
/* padded to 16-bytes */
const byte key[] = "0123456789abcdef ";
/* padded to 16-bytes */
const byte iv[] = "1234567890abcdef ";
byte cipher[WC_AES_BLOCK_SIZE * 4];

#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
if ((aes = (Aes *)malloc(sizeof(*aes), M_BSD_EXAMPLE, M_WAITOK | M_ZERO)) == NULL) {
printf("error: %s: xts aes alloc failed\n", ko_name);
return MEMORY_E;
}
#endif

ret = wc_AesInit(aes, NULL, INVALID_DEVID);
if (ret) {
printf("error: %s: wc_AesXtsInit returned: %d\n", ko_name, ret);
goto wc_aes_test_end;
}

ret = wc_AesSetKey(aes, key, WC_AES_BLOCK_SIZE, iv, AES_ENCRYPTION);
if (ret) {
printf("error: %s: wc_AesSetKey returned: %d\n", ko_name, ret);
goto wc_aes_test_end;
}

memset(cipher, 0, sizeof(cipher));
ret = wc_AesCbcEncrypt(aes, cipher, msg, WC_AES_BLOCK_SIZE);
if (ret) {
printf("error: %s: wc_AesCbcEncrypt returned: %d\n", ko_name, ret);
goto wc_aes_test_end;
}

if (XMEMCMP(cipher, verify, WC_AES_BLOCK_SIZE)) {
printf("error: %s: wc_AesCbcDecrypt failed cipher-verify compare\n",
ko_name);
ret = -1;
goto wc_aes_test_end;
}

if (ret == 0) {
printf("info: %s: wc_aes_test good\n", ko_name);
}

wc_aes_test_end:
wc_AesFree(aes);
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
if (aes) {
free(aes, M_BSD_EXAMPLE);
aes = NULL;
}
#endif

return ret;
}

static moduledata_t hellomod = {
"bsdkm_example", /* name */
example_loader, /* loader */
NULL /* extra data */
};

DECLARE_MODULE(bsdkm_example, hellomod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
MODULE_DEPEND(bsdkm_example, libwolfssl, 1, 1, 1);