Skip to content
Advertisement

System crash with Linux CryptoApi Module

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.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement