I tried to write Linux kernel module with cryptoapi. I found some examples like this: https://codedream.me/2014/04/cryptoapi-linux-kernel/
This example is working for me. Then I made some changes. Now my system crashes, when I try to load module. Can you help me with this?
/* Common headers */ #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/err.h> /* crypto headers */ #include <linux/crypto.h> #include <linux/err.h> #include <linux/scatterlist.h> #define AES_BLOCK_SIZE (16) #define AES_IV_SIZE (16) #define AES_KEY_SIZE (64) /* because we are using XTS mode */ typedef enum { ENCRYPT, DECRYPT } cipher_mode; static int crypt_data(u8 *key, u32 key_len, u8 *iv, u32 iv_len, u8 *dst, u32 dst_len, u8 *src, u8 src_len, cipher_mode mode) { struct crypto_blkcipher *blk; struct blkcipher_desc desc; struct scatterlist sg[2]; /* CRYPTO_ALG_TYPE_BLKCIPHER_MASK, CRYPTO_ALG_TYPE_BLKCIPHER */ blk = crypto_alloc_blkcipher("xts(aes)", 0, 0); if (IS_ERR(blk)) { printk(KERN_ALERT "Failed to initialize AES-XTS moden"); return -1; } else { printk(KERN_ALERT "Initialized cipher: %sn", crypto_blkcipher_name(blk)); printk(KERN_ALERT "with IV size: %dn", crypto_blkcipher_ivsize(blk)); printk(KERN_ALERT "block size: %dn", crypto_blkcipher_blocksize(blk)); } if (crypto_blkcipher_setkey(blk, key, key_len)) { printk(KERN_ALERT "Failed to set key.n"); goto err; } crypto_blkcipher_set_iv(blk, iv, iv_len); sg_init_one(&sg[0],src,src_len); sg_init_one(&sg[1],dst,dst_len); /* do encryption */ desc.tfm = blk; desc.flags = 0; if (mode == ENCRYPT) { if (crypto_blkcipher_encrypt(&desc, &sg[1], &sg[0], src_len)) printk(KERN_ALERT "Failed to encrypt.n"); } else { if (crypto_blkcipher_decrypt(&desc, &sg[1], &sg[0], src_len)) printk(KERN_ALERT "Failed to encrypt.n"); } crypto_free_blkcipher(blk); return 0; err: crypto_free_blkcipher(blk); return -1; } static int aes_crypt_init(void) { int len = 5000; u8 key[AES_KEY_SIZE]; u8 iv[AES_IV_SIZE]; u8 src[len]; u8 enc[len]; u8 dec[len]; int err = 0; printk(KERN_ALERT "AES crypto module start initialyzing.n"); err = crypt_data(key, AES_KEY_SIZE, iv, AES_IV_SIZE, enc, len, src, len, ENCRYPT); return err; } static void aes_crypt_exit(void) { printk(KERN_ALERT "AES crypto module exiting.n"); } module_init(aes_crypt_init); module_exit(aes_crypt_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Dmitry Falko"); MODULE_DESCRIPTION("Testing module crypto api for AES-XTS mode");
When variable len = 1000
, module is loaded normal. But if I change it on len = 5000
, I get system crash when I load module.
My system is: Linux ubuntu-virtual-machine 3.13.0-65-generic #105-Ubuntu SMP Mon Sep 21 18:50:58 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
Advertisement
Answer
You’re probably running out of stack space. Stack in kernel threads is extremely limited; allocating 15 KB (5000 x 3) of data on the stack is not going to work.
Use kmalloc()
and kfree()
to allocate large buffers.