2015-11-06 8 views
1

Я попытался написать модуль ядра Linux с криптоапи. Я нашел несколько таких примеров: https://codedream.me/2014/04/cryptoapi-linux-kernel/Системный сбой с Linux CryptoApi Module

Этот пример работает для меня. Затем я внес некоторые изменения. Теперь моя система падает, когда я пытаюсь загрузить модуль. ты можешь помочь мне с этим?

/* 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 mode\n"); 
     return -1; 
    } else { 
     printk(KERN_ALERT "Initialized cipher: %s\n", crypto_blkcipher_name(blk)); 
     printk(KERN_ALERT "with IV size: %d\n", crypto_blkcipher_ivsize(blk)); 
     printk(KERN_ALERT "block size: %d\n", 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"); 

При изменении len = 1000, модуль загружается нормально. Но если я изменю его на len = 5000, я получаю системный сбой при загрузке модуля.

Моя система: 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

ответ

2

Вы, вероятно, бежать из стека. Стек в ядрах - extreme limited; выделение 15 КБ (5000 х 3) данных в стеке не сработает.

Используйте kmalloc() и kfree() для выделения больших буферов.

+0

спасибо, он решает проблему. – Ragnar