how to use CryptoAPI in the linux kernel 2.6
Asked Answered
W

7

13

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.

Weese answered 6/10, 2010 at 1:58 Comment(0)
H
6

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.

Headrick answered 6/10, 2010 at 20:38 Comment(0)
A
11
#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");
Alcahest answered 14/3, 2013 at 9:16 Comment(2)
how do u compile it?? I mean whatare the dependent libs?Summitry
This is a kernel module example and as such, does not depend on libraries, but rather on other kernel modules. depmod calculates these dependencies for you, and modprobe loades everything in the right order.Balbur
H
6

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.

Headrick answered 6/10, 2010 at 20:38 Comment(0)
U
6

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;
}
Ursuline answered 18/7, 2011 at 23:45 Comment(0)
B
2

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

Brasca answered 24/4, 2015 at 8:13 Comment(0)
P
1

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.

Puentes answered 6/10, 2010 at 16:52 Comment(0)
D
1

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;
Dogtrot answered 21/11, 2010 at 13:31 Comment(0)
E
1

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.

Experientialism answered 26/8, 2014 at 7:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.