Linux kernel 如何在linux内核2.6中使用CryptoAPI

Linux kernel 如何在linux内核2.6中使用CryptoAPI,linux-kernel,kernel,kernel-module,cryptoapi,Linux Kernel,Kernel,Kernel Module,Cryptoapi,我已经寻找了一段时间,但是没有找到足够的文档/示例来说明如何使用linux附带的CryptoAPI创建系统调用/在内核中 如果有人知道一个好的源代码,请告诉我,我想知道如何只在内核空间中执行SHA1/MD5和Blowfish/AES。最好从内核源代码中的Documentation/crytpo开始。dm crypt是许多可能使用内核加密API的组件之一,您可以参考它了解使用情况。内核中有几个地方使用加密模块:eCryptfs文件系统(linux/fs/eCryptfs/)和802.11无线堆栈(

我已经寻找了一段时间,但是没有找到足够的文档/示例来说明如何使用linux附带的CryptoAPI创建系统调用/在内核中


如果有人知道一个好的源代码,请告诉我,我想知道如何只在内核空间中执行SHA1/MD5和Blowfish/AES。

最好从内核源代码中的Documentation/crytpo开始。dm crypt是许多可能使用内核加密API的组件之一,您可以参考它了解使用情况。

内核中有几个地方使用加密模块:eCryptfs文件系统(linux/fs/eCryptfs/)和802.11无线堆栈(linux/drivers/staging/rtl8187se/ieee80211/)。这两种方法都使用AES,但您可能能够将在那里找到的结果推断为MD5

如何仅在内核空间中执行SHA1/MD5和Blowfish/AES

使用两元素散点列表散列数据的示例:

struct crypto_hash *tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC); if (tfm == NULL) fail; char *output_buf = kmalloc(crypto_hash_digestsize(tfm), GFP_KERNEL); if (output_buf == NULL) fail; struct scatterlist sg[2]; struct hash_desc desc = {.tfm = tfm}; ret = crypto_hash_init(&desc); if (ret != 0) fail; sg_init_table(sg, ARRAY_SIZE(sg)); sg_set_buf(&sg[0], "Hello", 5); sg_set_buf(&sg[1], " World", 6); ret = crypto_hash_digest(&desc, sg, 11, output_buf); if (ret != 0) fail; struct crypto_hash*tfm=crypto_alloc_hash(“sha1”,0,crypto_ALG_ASYNC); if(tfm==NULL) 失败; char*output\u buf=kmalloc(加密哈希大小(tfm),GFP\u内核); 如果(输出_buf==NULL) 失败; 结构散射列表sg[2]; 结构hash_desc desc={.tfm=tfm}; ret=加密散列初始化(&desc); 如果(ret!=0) 失败; sg_init_表(sg,数组大小(sg)); sg_set_buf(&sg[0],“Hello”,5); sg_set_buf(&sg[1],“世界”,6); ret=加密哈希摘要(&desc,sg,11,输出); 如果(ret!=0)
失败 另一个很好的例子是security/seclvl.c中的2.6.18内核源代码

注意:如果需要,您可以更改加密请求睡眠

static int
plaintext_to_sha1(unsigned char *hash, const char *plaintext, unsigned int len)
{
  struct crypto_tfm *tfm;
  struct scatterlist sg;
  if (len > PAGE_SIZE) {
    seclvl_printk(0, KERN_ERR, "Plaintext password too large (%d "
            "characters).  Largest possible is %lu "
            "bytes.\n", len, PAGE_SIZE);
    return -EINVAL;
  }
  tfm = crypto_alloc_tfm("sha1", CRYPTO_TFM_REQ_MAY_SLEEP);
  if (tfm == NULL) {
    seclvl_printk(0, KERN_ERR,
            "Failed to load transform for SHA1\n");
    return -EINVAL;
  }
  sg_init_one(&sg, (u8 *)plaintext, len);
  crypto_digest_init(tfm);
  crypto_digest_update(tfm, &sg, 1);
  crypto_digest_final(tfm, hash);
  crypto_free_tfm(tfm);
  return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#定义SHA1_长度20
静态整数初始化sha1初始化(void)
{
结构散点表;
结构加密散列*tfm;
结构哈希描述;
无符号字符输出[SHA1_长度];
无符号字符buf[10];
int i;
printk(内核信息“sha1:%s\n”,函数);
memset(buf'A',10);
memset(输出,0x00,SHA1_长度);
tfm=crypto_alloc_hash(“sha1”,0,crypto_ALG_ASYNC);
desc.tfm=tfm;
desc.flags=0;
sg_init_one(和sg,buf,10);
加密散列初始化(&desc);
加密哈希更新(&desc,&sg,10);
加密\u散列\u最终(&desc,输出);
对于(i=0;i<20;i++){
printk(内核错误“%d-%d\n”,输出[i],i);
}
无加密散列(tfm);
返回0;
}
静态无效\uuuu出口sha1\u出口(无效)
{
printk(内核信息“sha1:%s\n”,函数);
}
模块_init(sha1_init);
模块出口(sha1出口);
模块许可证(“双MIT/GPL”);
模块作者(“我”);
一个关键注意事项:

切勿将
crypto\u alloc\u hash
函数的返回值与NULL进行比较,以检测故障

步骤:

为此,请始终使用
IS\u ERR
功能。与
NULL相比
不会捕获错误,因此以后会出现分段错误


如果IS_ERR返回失败,则可能在内核映像(或作为模块)中编译了缺少的加密算法。确保已选择适当的加密算法。表单
make menuconfig

加密开发linux

它是一个内核模块,通过
/dev/crypto
向用户空间公开内核加密API

SHA计算示例:

正如其他人提到的,内核似乎没有向用户空间本身公开加密API,这是一个遗憾,因为内核已经可以在内部使用本机硬件加速的加密函数

Crypto操作cryptodev支持:


加密操作Linux x86支持:

如何编译它??我的意思是依赖libs是什么?这是一个内核模块示例,因此不依赖于库,而是依赖于其他内核模块。为您计算这些依赖项,modprobe将按正确的顺序加载所有内容。
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/crypto.h>
#include <linux/err.h>
#include <linux/scatterlist.h>

#define SHA1_LENGTH     20

static int __init sha1_init(void)
{
    struct scatterlist sg;
    struct crypto_hash *tfm;
    struct hash_desc desc;
    unsigned char output[SHA1_LENGTH];
    unsigned char buf[10];
    int i;

    printk(KERN_INFO "sha1: %s\n", __FUNCTION__);

    memset(buf, 'A', 10);
    memset(output, 0x00, SHA1_LENGTH);

    tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC);

    desc.tfm = tfm;
    desc.flags = 0;

    sg_init_one(&sg, buf, 10);
    crypto_hash_init(&desc);

    crypto_hash_update(&desc, &sg, 10);
    crypto_hash_final(&desc, output);

    for (i = 0; i < 20; i++) {
        printk(KERN_ERR "%d-%d\n", output[i], i);
    }

    crypto_free_hash(tfm);

    return 0;
}

static void __exit sha1_exit(void)
{
    printk(KERN_INFO "sha1: %s\n", __FUNCTION__);
}

module_init(sha1_init);
module_exit(sha1_exit);

MODULE_LICENSE("Dual MIT/GPL");
MODULE_AUTHOR("Me");