免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 28049 | 回复: 18
打印 上一主题 下一主题

Linux内核的加密函数框架 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-23 17:39 |只看该作者 |倒序浏览
Linux内核支持很多加密算法,包括对称加密算法,如AES;摘要算法,如sha1,md5;压缩算法,如deflate。不过内核好像不支持非对称加密算法。这些算法作为加密函数框架的最底层,提供加密和解密的实际操作。这些函数可以在内核crypto文件夹下,相应的文件中找到。不过内核模块不能直接调用这些函数,因为它们并没有export。内核提供一个统一的框架,来管理这些算法。加密算法通过crypto_register_alg()和crypto_unregister_alg()注册。内核将加密算法分为三类,1)cipher,2)compress,3)digest。加密函数框架中有相应的API封装,提供给模块调用。
对于使用这些加密函数,首先通过crypto_alloc_tfm()来分配一个加密函数对象的实例。初始化这些实例,然后就可以通过框架提供的API对数据进行加密和解密。完成以后,必须通过crypto_free_tfm()撤销实例。

下面是几个代码,或许能够够对内核的加密框架有更直观的了解:

1)digest算法(sha1)
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <linux/gfp.h>
#include <linux/err.h>
#include <linux/syscalls.h>
#include <linux/slab.h>

struct crypto_tfm *tfm;
struct scatterlist sg[1];
char * code1 = "2ew34123132513451345";
char * code2 = "234123132513451345";

char *do_digest(char * code) {
    char *result;
    int code_len = strlen(code);
   
        tfm = crypto_alloc_tfm("sha1",0);
        if(IS_ERR(tfm))
                return 0;
        sg_init_one(sg,code,code_len);

        crypto_digest_init(tfm);
        crypto_digest_update(tfm,sg,1);
    result = (char *)kmalloc(sizeof(char)*50,GFP_KERNEL);

    if(result == NULL) {
        crypto_free_tfm(tfm);
        return 0;
    }
    memset(result,0,sizeof(char)*50);
    crypto_digest_final(tfm,result);
        crypto_free_tfm(tfm);
    return result;
}

static int __init test_init(void)
{
    char *result1,*result2;
    result1 = do_digest(code1);
    if(!result1)
        goto failed2;
    result2 = do_digest(code2);
    if(!result2)
        goto failed1;
   
    if(memcmp(result1,result2,50) != 0)
        printk("<1>code1 != code2\n");
    else
        printk("<1>code1 == code2\n");
    kfree(result2);

failed1:
    kfree(result1);
failed2:
    return 0;
}

static void __exit test_exit(void)
{

}

module_init(test_init);
module_exit(test_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("richardhesidu@chinaunix");



2)compress算法(deflate)
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <linux/gfp.h>
#include <linux/err.h>
#include <linux/syscalls.h>
#include <linux/slab.h>

struct crypto_tfm *tfm;
char * code = "Hello everyone, I'm richardhesidu from chinaunix.net !";


static inline  void hexdump(unsigned char *buf,unsigned int len) {
    while(len--)
        printk("0x%02x,",*buf++);
    printk("\n");
}

static int __init test_init(void) {
    int ret,result_len,temp_len;
    char result[512];
    char temp[512];

    printk("<1>%s\n",code);   
   
    /* Allocate transform for deflate */
            
    tfm = crypto_alloc_tfm("deflate",0);
        if(IS_ERR(tfm)) {
        printk("<1>failed to load transform for deflate !\n");
                return 0;
    }

    memset(result,0,sizeof(result));

    temp_len = 512;
    ret = crypto_comp_compress(tfm,code,strlen(code),temp,&temp_len);
    if(ret) {
        printk("<1>failed to compress !\n");
        return 0;
    }
      
    hexdump(temp,strlen(temp));
   
    memset(result,0,sizeof(result));

    result_len = 512;
    ret = crypto_comp_decompress(tfm,temp,strlen(temp),result,&result_len);
    if(ret) {
                printk("<1>failed to decompress !\n");
                return 0;
        }

    printk("<1>%s\n",result);

    if(memcmp(code,result,strlen(code)) != 0)
        printk("<1>decompressed was not successful\n");
    else
        printk("<1>decompressed was successful\n");

           crypto_free_tfm(tfm);
    return 0;
}

static void __exit test_exit(void)
{

}

module_init(test_init);
module_exit(test_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("richardhesidu@chinaunix");


3)cipher算法(aes)
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <linux/gfp.h>
#include <linux/err.h>
#include <linux/syscalls.h>
#include <linux/slab.h>
#include <linux/highmem.h>

struct crypto_tfm *tfm;
#if 1
char *code = "Hello everyone,I'm Richardhesidu"
        "Hello everyone,I'm Richardhesidu"
            "Hello everyone,I'm Richardhesidu";

char *key = "00112233445566778899aabbccddeeff";
#endif

#if 0
char code[] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,
        0xbb,0xcc,0xdd,0xee,0xff};
char key[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,
        0x0b,0x0c,0x0d,0x0e,0x0f};
#endif

static inline  void hexdump(unsigned char *buf,unsigned int len) {
    while(len--)
        printk("%02x",*buf++);
    printk("\n");
}

static int __init test_init(void) {
    int ret,templen,keylen,codelen;
    struct scatterlist sg[1];
    char *result;
    char *temp;

    keylen = 16;
    codelen = strlen(code)/2;
#if 0
    printk("<1>%s, codelen=%d\n",code,strlen(code));
    printk("<1>%s, keylen=%d\n",key,strlen(key));   
#endif   
    /* Allocate transform for AES ECB mode */
            
    tfm = crypto_alloc_tfm("aes",CRYPTO_TFM_MODE_ECB);
        if(IS_ERR(tfm)) {
        printk("<1>failed to load transform for aes ECB mode !\n");
                return 0;
    }

    ret = crypto_cipher_setkey(tfm,key,keylen);
    if(ret) {
        printk("<1>failed to setkey \n");
        goto failed1;
    }
   
    sg_init_one(sg,code,codelen);
        
    /* start encrypt */
   
    ret = crypto_cipher_encrypt(tfm,sg,sg,codelen);
    if(ret) {
        printk("<1>encrypt failed \n");
        goto failed1;
    }
   
    temp = kmap(sg[0].page) + sg[0].offset;

    hexdump(temp,sg[0].length);
   
          /* start dencrypt */
    templen = strlen(temp)/2;
    sg_init_one(sg,temp,templen);
    ret = crypto_cipher_decrypt(tfm,sg,sg,templen);
        if(ret) {
                printk("<1>dencrypt failed \n");
                goto failed1;
        }

        result = kmap(sg[0].page) + sg[0].offset;
    printk("<1>%s\n",result);
//        hexdump(result,sg[0].length);


#if 0
    if(memcmp(code,result,strlen(code)) != 0)
        printk("<1>dencrpt was not successful\n");
    else
        printk("<1>dencrypt was successful\n");
#endif
failed1:
           crypto_free_tfm(tfm);
    return 0;
}

static void __exit test_exit(void)
{

}

module_init(test_init);
module_exit(test_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("richardhesidu@chinaunix");


[ 本帖最后由 richardhesidu 于 2009-4-24 10:56 编辑 ]

评分

参与人数 1可用积分 +15 收起 理由
Godbach + 15 我很赞同

查看全部评分

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
2 [报告]
发表于 2009-04-23 19:28 |只看该作者
多谢richardhesidu 兄分享

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
3 [报告]
发表于 2009-04-23 21:18 |只看该作者

论坛徽章:
0
4 [报告]
发表于 2009-04-23 23:58 |只看该作者
这加密算法不用在内核里吧

论坛徽章:
0
5 [报告]
发表于 2009-04-24 10:28 |只看该作者
不错,学习了。

论坛徽章:
0
6 [报告]
发表于 2009-04-24 10:31 |只看该作者
原帖由 emmoblin 于 2009-4-23 23:58 发表
这加密算法不用在内核里吧

驱动做数据加密可能用到.

论坛徽章:
0
7 [报告]
发表于 2009-04-24 10:42 |只看该作者
路過,看看

论坛徽章:
0
8 [报告]
发表于 2009-04-25 19:32 |只看该作者
原帖由 epegasus 于 2009-4-24 10:31 发表

驱动做数据加密可能用到.


IPSec 会用到。

论坛徽章:
0
9 [报告]
发表于 2009-08-14 09:50 |只看该作者

内核加密文件

你好,我现在需要做的是在内核对一个文件操作,不知有没有办法可以得到文件的长度的?因为只有这个才可以读出整个文件的内
容,再用上面的digest做摘要啊!

论坛徽章:
24
15-16赛季CBA联赛之北京
日期:2018-08-17 18:43:33技术图书徽章
日期:2018-08-22 12:53:57技术图书徽章
日期:2018-08-22 12:54:20技术图书徽章
日期:2018-08-22 12:54:3015-16赛季CBA联赛之福建
日期:2018-10-19 16:58:1619周年集字徽章-庆
日期:2019-08-27 13:28:5619周年集字徽章-19
日期:2019-08-27 13:31:2619周年集字徽章-19
日期:2019-08-27 13:31:2615-16赛季CBA联赛之同曦
日期:2019-09-05 12:03:2819周年集字徽章-周
日期:2019-09-06 18:54:5415-16赛季CBA联赛之上海
日期:2018-07-25 11:55:2615-16赛季CBA联赛之青岛
日期:2018-07-10 14:13:18
10 [报告]
发表于 2009-08-18 14:47 |只看该作者
请问这些代码编译时要带哪些参数.
比如 crypto的动态支持?
还需要安装 openssl吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP