2010-10-06 5 views
9

Ich suche seit einiger Zeit, aber habe nicht annähernd genügend Dokumentation/Beispiele gefunden, wie man die CryptoAPI benutzt, die mit linux bei der Erstellung von syscalls/im Kernel Land kommt.Wie benutze ich CryptoAPI im Linux Kernel 2.6

Wenn jemand eine gute Quelle kennt, lass es mich wissen, ich würde gerne wissen, wie man SHA1/MD5 und Blowfish/AES nur innerhalb des Kernels macht.

Antwort

6

Es gibt ein paar Stellen im Kernel, die das Crypto-Modul verwenden: das eCryptfs-Dateisystem (linux/fs/ecryptfs /) und den 802.11-WLAN-Stack (linux/drivers/staging/rtl8187se/ieee80211 /). Beide verwenden AES, aber Sie können möglicherweise das, was Sie dort finden, zu MD5 extrapolieren.

+1

ecryptfs war der Weg zu gehen, dank – Conor

1

Der beste Startpunkt ist Dokumentation/crytpo in den Kernel-Quellen. dm-crypt ist eine der vielen Komponenten, die wahrscheinlich die Kernel-Crypto-API verwenden. Sie können sich darauf beziehen, um eine Vorstellung von der Verwendung zu erhalten.

2

wie SHA1/MD5 und Blowfish/AES nur innerhalb des Kernel-Space zu tun.

Beispiel Hashing-Daten unter Verwendung eines Zweielement 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;
6

Ein weiteres gutes Beispiel von der Quelle 2.6.18-Kernel ist in Sicherheit/seclvl.c

Hinweis: Sie können sich ändern CRYPTO_TFM_REQ_MAY_SLEEP benötigt, wenn

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; 
} 
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"); 
+0

wie u es kompilieren ?? Ich meine, was sind die abhängigen libs? – user907810

+0

Dies ist ein Kernelmodul-Beispiel und hängt als solches nicht von Bibliotheken ab, sondern von anderen Kernel-Modulen. [depmod] (http://linux.about.com/library/cmd/blcmdl8_depmod.htm) berechnet diese Abhängigkeiten für Sie, und modprobe läd alles in der richtigen Reihenfolge auf. – Przemek

1

Eine kritische Anmerkung:

Vergleichen Sie nie den Rückgabewert von crypto_alloc_hash Funktion mit NULL für die Erkennung des Fehlers.

Schritte:

immer IS_ERR Funktion für diesen Zweck verwenden. Vergleichen mit NULL erfasst den Fehler nicht, daher erhalten Sie später Segmentationsfehler.

Wenn IS_ERR fehlschlägt, haben Sie möglicherweise einen fehlenden Kryptoalgorithmus in Ihrem Kernel-Image (oder als ein Modul) kompiliert. Stellen Sie sicher, dass Sie den entsprechenden Crypto Algo ausgewählt haben. Formular make menuconfig.

2

cryptodev-Linux

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

Es ist ein Kernel-Modul, das die Kernel Krypto-API Userspace durch /dev/crypto aussetzt.

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

Wie andere erwähnt haben, der Kernel scheint nicht zu den Krypto-API entlarven sich an den Userspace, was schade ist, da der Kernel bereits nativer Hardware beschleunigt intern Krypto-Funktionen verwenden.

Crypto-Operationen cryptodev unterstützt: https://github.com/nmav/cryptodev-linux/blob/383922cabeea7dca354415e8c590f8e932f4d7a8/crypto/cryptodev.h

Crypto-Operationen Linux x86 unterstützt: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/x86/crypto?id=refs/tags/v4.0