Kernel Module Snippets - Part 5 - Encryption

Kernel Module Snippets - Part 5 - Encryption

Intro

Key to transporting anything over the internet these days, is encryption. For a tunnel, this involved encrypting the whole packet that would be your payload. We don’t want anyone along the path to be able to intercept packets and see what the unencapsulated traffic would look like. Especially in the case of LAN to LAN tunneled traffic.

``

``

``

For legacy compatibility, I needed to stick with salsa20 encryption. The example below shows how to set up the encryption function.

The Code

#include <linux/module.h>

#include <crypto/skcipher.h>

#include <linux/scatterlist.h>

struct my_crypto_vars {

char *iv;

size_t ivsize;

char key[16];

size_t keysize;

struct crypto_skcipher *tfm;

struct scatterlist sg;

struct skcipher_request *req;

};

int my_crypt_encrypt(struct my_crypto_vars *mgc, u8 *data, size_t datasize, int decrypt) {

int err = 0;

char plaintext[1500] = {0};

char ciphertext[1500] = {0};

// init encrypt

memcpy(plaintext, data, datasize);

sg_init_one(&mgc->sg, plaintext, datasize);

skcipher_request_set_crypt(mgc->req, &mgc->sg, &mgc->sg, datasize, mgc->iv);

//actual encrypt

err = crypto_skcipher_encrypt(mgc->req);

if (err) {

pr_err(“could not encrypt data\n”);

goto out;

}

sg_copy_to_buffer(&mgc->sg, 1, ciphertext, datasize);

//actual decrypt

memset(plaintext, 0, 1500);

sg_init_one(&mgc->sg, ciphertext, datasize);

err = crypto_skcipher_decrypt(mgc->req);

if (err) {

pr_err(“could not decrypt data\n”);

goto out;

}

sg_copy_to_buffer(&mgc->sg, 1, plaintext, datasize);

print_hex_dump(KERN_DEBUG, “decr text: “, DUMP_PREFIX_NONE, 16, 1, plaintext, datasize, true);

goto out;

out:

return err;

}

int my_crypt_init(struct my_crypto_vars *mgc) {

int err = 0;

/* Check the existence of the cipher in the kernel (it might be a

* module and it isn’t loaded. */

if (!crypto_has_skcipher(“salsa20”, 0, 0)) {

pr_err(“skcipher not found\n”);

err = -EINVAL;

goto out;

}

/* Allocate synchronous cipher handler.

*

* For generic implementation you can provide either the generic name

* “salsa20” or the driver (specific) name “salsa20-generic”, since

* the generic has higher priority compared to the x86_64 instruction

* implementation “salsa20-asm”.

*

* Also, cypher type will be left 0 since there isn’t any other type

* other than the default one for this cypher and the mask also will

* be 0 since I don’t want to use the asynchronous interface variant.

*/

mgc->tfm = crypto_alloc_skcipher(“salsa20”, 0, 0);

if (IS_ERR(mgc->tfm)) {

pr_err(“impossible to allocate skcipher\n”);

return PTR_ERR(mgc->tfm);

}

memset(mgc->key, 0, 16);

mgc->keysize = 16;

memcpy(mgc->key,“12345678901234567890123456”, 16);

print_hex_dump(KERN_DEBUG, “key: “, DUMP_PREFIX_NONE, 16, 1, mgc->key, mgc->keysize, false);

/* Default function to set the key for the symetric key cipher */

crypto_skcipher_setkey(mgc->tfm, mgc->key, mgc->keysize);

if (err) {

pr_err(“fail setting key for transformation: %d\n”, err);

goto error0;

}

mgc->ivsize = crypto_skcipher_ivsize(mgc->tfm);

mgc->iv = kmalloc(mgc->ivsize, GFP_KERNEL);

if (!mgc->iv) {

pr_err(“could not allocate iv vector\n”);

err = -ENOMEM;

goto error0;

}

print_hex_dump(KERN_DEBUG, “iv: “, DUMP_PREFIX_NONE, 16, 1, mgc->iv, mgc->ivsize, false);

mgc->req = skcipher_request_alloc(mgc->tfm, GFP_KERNEL);

if (!mgc->req) {

pr_err(“impossible to allocate skcipher request\n”);

err = -ENOMEM;

goto error0;

}

goto out;

error1:

skcipher_request_free(mgc->req);

error0:

crypto_free_skcipher(mgc->tfm);

if (mgc->iv)

kfree(mgc->iv);

out:

return err;

}

void my_crypt_deinit(struct my_crypto_vars *mgc) {

skcipher_request_free(mgc->req);

crypto_free_skcipher(mgc->tfm);

if (mgc->iv)

kfree(mgc->iv);

}

MODULE_AUTHOR(“Rob Hartzenberg rob@craftypenguins.ca");

MODULE_LICENSE(“GPL”);

MODULE_DESCRIPTION(“Salsa20 Encryption”);

Categories: Development, Training

By Rob Hartzenberg

October 1, 2020

Rob Hartzenberg
Author: Rob Hartzenberg

Key to transporting anything over the internet these days, is encryption. For a tunnel, this involved encrypting the whole packet that would be your payload

PREVIOUS

Kernel Module Snippets – Part 4 – UDP in the kernel

NEXT

Kernel Module Snippets – Part 3 – UDP in the kernel