как использовать CryptoAPI в ядре Linux 2.6 - PullRequest
10 голосов
/ 06 октября 2010

Я искал некоторое время, но не нашел нигде рядом достаточной документации / примеров того, как использовать CryptoAPI, поставляемый с linux, при создании syscalls / в стране ядра.

Если кто-то знает охороший источник, пожалуйста, дайте мне знать, я хотел бы знать, как сделать SHA1 / MD5 и Blowfish / AES только в пространстве ядра.

Ответы [ 7 ]

11 голосов
/ 14 марта 2013
#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");
6 голосов
/ 19 июля 2011

Другой хороший пример взят из исходного кода ядра 2.6.18 в security / seclvl.c

Примечание. При необходимости вы можете изменить 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;
}
6 голосов
/ 07 октября 2010

В ядре есть несколько мест, где используется криптомодуль: файловая система eCryptfs (linux / fs / ecryptfs /) и беспроводной стек 802.11 (linux / drivers / staging / rtl8187se / ieee80211 /).Оба они используют AES, но вы можете экстраполировать то, что вы там найдете, на MD5.

2 голосов

Cryptodev-линукс

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

Это модуль ядра, который предоставляет крипто-API ядра для пространства пользователя через /dev/crypto.

Пример расчета 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

1 голос
/ 26 августа 2014

Одно критическое замечание:

Никогда не сравнивайте возвращаемое значение функции crypto_alloc_hash со значением NULL для выявления неисправности.

Шаги:

Всегда используйте для этой цели функцию IS_ERR.Сравнение с NULL не фиксирует ошибку, следовательно, позже вы получите ошибки сегментации.

Если IS_ERR возвращает ошибку, возможно, у вас отсутствует криптоалгоритм, скомпилированный в образ вашего ядра (или как модуль)Убедитесь, что вы выбрали соответствующий криптографический алгоритм.форма make menuconfig.

1 голос
/ 21 ноября 2010

как сделать 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;
1 голос
/ 06 октября 2010

Лучше всего начать с документации / crytpo в исходных кодах ядра. dm-crypt - один из многих компонентов, который, вероятно, использует API-интерфейс ядра crypto, и вы можете обратиться к нему, чтобы получить представление об использовании.

...