2010-10-06 16 views
9

He estado buscando algo de tiempo pero no he encontrado en ningún lado documentación suficiente/ejemplos sobre cómo usar el CryptoAPI que viene con Linux en la creación de syscalls/en kernel land.cómo usar CryptoAPI en el núcleo de Linux 2.6

Si alguien sabe de una buena fuente, por favor avíseme, me gustaría saber cómo hacer SHA1/MD5 y Blowfish/AES dentro del espacio del kernel solamente.

Respuesta

6

Hay un par de lugares en el núcleo que usan el módulo de cifrado: el sistema de archivos eCryptfs (linux/fs/ecryptfs /) y la pila inalámbrica 802.11 (linux/drivers/staging/rtl8187se/ieee80211 /). Ambos usan AES, pero es posible que pueda extrapolar lo que encuentre allí a MD5.

+1

ecryptfs era el camino a seguir, gracias – Conor

1

El mejor lugar para comenzar es Documentation/crytpo en las fuentes del kernel. dm-crypt es uno de los muchos componentes que probablemente usa kernel crypto API y puedes consultarlo para tener una idea sobre el uso.

2

cómo hacer SHA1/MD5 y Blowfish/AES dentro del espacio del núcleo solamente.

Ejemplo de datos de hash utilizando un scatterlist de dos elementos:

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

Otro buen ejemplo es el de la fuente del kernel 2.6.18 en la seguridad/seclvl.c

Nota: se puede cambiar CRYPTO_TFM_REQ_MAY_SLEEP si es necesario

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

u ¿cómo compilarlo ?? Quiero decir, ¿qué son las libs dependientes? – user907810

+0

Este es un ejemplo de módulo kernel y, como tal, no depende de las bibliotecas, sino de otros módulos kernel. [depmod] (http://linux.about.com/library/cmd/blcmdl8_depmod.htm) calcula estas dependencias por usted, y modprobe loaade todo en el orden correcto. – Przemek

1

Una nota crítica:

Nunca compare el valor de retorno de la función crypto_alloc_hash a NULL para detectar el error.

Pasos:

utilizan siempre IS_ERR función para este propósito. Si se compara con NULL, no se captura el error, por lo que luego se obtienen fallas de segmentación.

Si IS_ERR devuelve un error, posiblemente tenga un algoritmo de cifrado faltante compilado en la imagen de su kernel (o como un módulo). Asegúrese de haber seleccionado el algoritmo apropiado. formulario make menuconfig.

2

Cryptodev-Linux

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

Se trata de un módulo del kernel que expone la API de criptografía kernel al espacio de usuario a través /dev/crypto.

SHA ejemplo de cálculo: https://github.com/cryptodev-linux/cryptodev-linux/blob/da730106c2558c8e0c8e1b1b1812d32ef9574ab7/examples/sha.c

Como otros han mencionado, no parece que el kernel para exponer la API de criptografía al espacio de usuario en sí, que es una lástima ya que el núcleo ya se pueden utilizar las funciones de cifrado de hardware nativo acelerados internamente.

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

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

Cuestiones relacionadas