如何在linux内核2.6中使用CryptoAPI

发布于 2024-09-26 17:50:24 字数 141 浏览 0 评论 0原文

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

如果有人知道好的来源请告诉我,我想知道如何仅在内核空间内执行 SHA1 / MD5 和 Blowfish / AES。

I have been looking for some time but have not found anywhere near sufficient documentation / examples on how to use the CryptoAPI that comes with linux in the creation of syscalls / in kernel land.

If anyone knows of a good source please let me know, I would like to know how to do SHA1 / MD5 and Blowfish / AES within the kernel space only.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

倒数 2024-10-03 17:50:24
#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");
#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");
梦回梦里 2024-10-03 17:50:24

内核中有几个地方使用了加密模块:eCryptfs 文件系统 (linux/fs/ecryptfs/) 和 802.11 无线堆栈 (linux/drivers/staging/rtl8187se/ieee80211/)。这两者都使用 AES,但您也许可以将其中发现的内容推断为 MD5。

There are a couple of places in the kernel which use the crypto module: the eCryptfs file system (linux/fs/ecryptfs/) and the 802.11 wireless stack (linux/drivers/staging/rtl8187se/ieee80211/). Both of these use AES, but you may be able to extrapolate what you find there to MD5.

青衫负雪 2024-10-03 17:50:24

另一个很好的例子来自 security/seclvl.c 中的 2.6.18 内核源代码

注意:如果需要,您可以更改 CRYPTO_TFM_REQ_MAY_SLEEP

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;
}

Another good example is from the 2.6.18 kernel source in security/seclvl.c

Note: You can change CRYPTO_TFM_REQ_MAY_SLEEP if needed

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;
}
说好的呢 2024-10-03 17:50:24

Cryptodev-linux

https://github.com/cryptodev-linux/ cryptodev-linux

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

SHA计算示例: https://github.com/ cryptodev-linux/cryptodev-linux/blob/da730106c2558c8e0c8e1b1b1812d32ef9574ab7/examples/sha.c

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

cryptodev 支持的加密操作: https://github.com/nmav /cryptodev-linux/blob/383922cabeea7dca354415e8c590f8e932f4d7a8/crypto/cryptodev.h

Linux x86 支持的加密操作: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux。 git/tree/arch/x86/crypto?id=refs/tags/v4.0

Cryptodev-linux

https://github.com/cryptodev-linux/cryptodev-linux

It is a kernel module that exposes the kernel crypto API to userspace through /dev/crypto .

SHA calculation example: https://github.com/cryptodev-linux/cryptodev-linux/blob/da730106c2558c8e0c8e1b1b1812d32ef9574ab7/examples/sha.c

As others have mentioned, the kernel does not seem to expose the crypto API to userspace itself, which is a shame since the kernel can already use native hardware accelerated crypto functions internally.

Crypto operations cryptodev supports: https://github.com/nmav/cryptodev-linux/blob/383922cabeea7dca354415e8c590f8e932f4d7a8/crypto/cryptodev.h

Crypto operations Linux x86 supports: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/x86/crypto?id=refs/tags/v4.0

如何视而不见 2024-10-03 17:50:24

最好的起点是内核源代码中的 Documentation/crytpo。 dm-crypt 是可能使用内核加密 API 的众多组件之一,您可以参考它来了解用法。

The best place to start is Documentation/crytpo in the kernel sources. dm-crypt is one of the many components that probably uses the kernel crypto API and you can refer to it to get an idea about usage.

梦醒时光 2024-10-03 17:50:24

如何仅在内核空间内执行 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;

how to do SHA1 / MD5 and Blowfish / AES within the kernel space only.

Example of hashing data using a two-element scatterlist:

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;
临走之时 2024-10-03 17:50:24

一个关键注意事项:

切勿将crypto_alloc_hash 函数的返回值与 NULL 进行比较来检测失败。

步骤:

始终使用 IS_ERR 函数来实现此目的。与 NULL 相比不会捕获错误,因此稍后会出现分段错误。

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

One critical note:

Never compare the return value of crypto_alloc_hash function to NULL for detecting the failure.

Steps:

Always use IS_ERR function for this purpose. Comparing to NULL does not capture the error, hence you get segmentation faults later on.

If IS_ERR returns fail, you possibly have a missing crypto algorithm compiled into your kernel image (or as a module). Make sure you have selected the appropriate crypto algo. form make menuconfig.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文