2016-12-11 4 views
0

Я работаю над модулем ядра, который использует асимметричный шифр ядра crypto api, kernel version 4.8.0. Я генерирую асимметричные пары ключей с помощью openssl, преобразовываю их в формат DER (который, как я знал, был подмножеством BER), и код в мой модуль. Частный ключ работает очень хорошо, но открытый ключ всегда терпит неудачу в crypto_akcipher_set_pub_key, даже если я попробую другие пары ключей. dmesg просто печатает:crypto_akcipher_set_pub_key в ядре асимметричный крипто всегда возвращает ошибку

[16891.604718] next_op: pc=0/10 dp=0/161 C=0 J=0 
[16891.604721] - match? 30 30 00 
[16891.604724] - TAG: 30 158 CONS 
[16891.604726] next_op: pc=2/10 dp=3/161 C=1 J=0 
[16891.604727] - match? 30 02 32 
[16891.604729] 
       ASN1: Unexpected tag [m=2 d=4 ot=02 t=30 l=158] 
[16891.604730] set key error! -74,,,,,0 

Вот мои вопросы:

A) Означает ли dmesg открытый ключ не так? Как сгенерировать пары ключей, совместимые с ядром?

B) Я не могу найти полезные пары ключей rsa для несимметричного шифрования ядра, даже в Linux/crypto/testmgr.h или libkcapi/test/test.sh, вы можете мне помочь?

Спасибо!

Вот мой модуль:

#include <linux/module.h> 
#include <linux/kernel.h> 
#include <linux/crypto.h> 
#include <linux/scatterlist.h> 
#include <linux/gfp.h> 
#include <linux/err.h> 
#include <linux/syscalls.h> 
#include <linux/slab.h> 
#include <crypto/skcipher.h> 
#include <crypto/akcipher.h> 
#include <linux/random.h> 
#include <linux/delay.h> 
#include <linux/highmem.h> 
const char *priv_key = 
    "\x30\x82\x02\x5d\x02\x01\x00\x02\x81\x81\x00\xd0" 
    "\xb4\x5a\xc1\x9e\x2e\x4d\xae\xbd\x51\x39\xcc\x4b" 
    "\x12\xf5\x76\x30\xcf\x39\x97\xf1\xd3\x0d\xaa\x37" 
    "\x70\x2d\x2f\x01\xc9\x69\x09\xe3\x4e\xd5\x90\x68" 
    "\xfe\xbf\x7c\x8b\x86\xdf\xf3\x14\xb3\x96\xcf\x1b" 
    "\x39\xe3\xe6\x8a\x77\x6d\xe4\x89\xef\xdb\xba\x4a" 
    "\x40\x6d\xa9\xec\x21\x62\x00\xa4\xc3\x45\xcc\xdd" 
    "\x56\xb2\x77\x59\x46\x17\x27\x0e\x2c\xfe\x85\x53" 
    "\x72\x26\x9b\xdc\x24\x83\xd1\x67\xa7\x4c\x88\x70" 
    "\x78\x3f\x1c\x60\xd4\x95\x14\x57\xfc\xdb\x15\xaa" 
    "\xab\x31\x32\xb2\x44\x72\xdd\xb0\x0b\x13\x62\x03" 
    "\x50\x1d\xd4\x6a\xf6\xb2\x23\x02\x03\x01\x00\x01" 
    "\x02\x81\x80\x7b\x83\x10\xe6\xde\xf7\x26\x30\x10" 
    "\x88\x3e\x7d\x61\xbc\xa1\x99\xc5\xbf\x0d\xa5\x97" 
    "\x8e\xc0\xda\x88\x9e\x91\x8e\xed\x2e\xc6\x43\xfc" 
    "\xcb\x0d\xe6\xbd\xcc\x6d\x84\x86\x8a\x56\x84\xe4" 
    "\x2e\x78\x44\xaf\x27\x2e\x71\xa4\x66\x93\x99\x99" 
    "\xec\x62\x8c\x38\x1f\x33\x06\x37\xc1\x9d\x17\x6b" 
    "\xad\xfb\x8e\x44\xd3\x11\xcb\x74\xa4\x01\x78\xb0" 
    "\x9c\x64\xd3\x0d\x63\x99\x65\xe3\xca\xae\x11\xb2" 
    "\xc4\x00\x36\xc2\xfc\x4b\x7b\x6f\x9e\x84\xb6\x97" 
    "\x00\x56\x5b\x09\xa1\x28\xf5\x28\x8d\xc7\x93\x45" 
    "\xba\xc0\x6b\xa9\x2d\xeb\x02\xcd\xde\x1e\x29\x02" 
    "\x41\x00\xf6\x0e\x41\xbc\xfa\x40\x82\xba\xa0\x6a" 
    "\xa5\x75\x5c\xcd\xfe\xa8\x11\xa6\xef\xbc\xad\x5f" 
    "\x86\x40\xb4\x5a\x65\xc1\x7b\x5e\x89\xc2\x60\x38" 
    "\x0e\x8b\x7d\x7d\x99\x30\x01\xf1\xea\x1e\x3e\x46" 
    "\xf4\xd2\xd9\x80\xaf\x3a\x4b\x2f\xbb\x91\xbb\xb7" 
    "\x22\x2d\x6a\x0f\x4e\x6f\x02\x41\x00\xd9\x23\xa7" 
    "\x98\x0c\x58\xe1\x5d\xa7\x15\x05\xc6\xd9\x7b\xc5" 
    "\x7b\xd3\x01\x8b\x1e\xf1\x2e\x99\xc5\xac\x41\xf1" 
    "\x92\x88\xd9\x8e\x50\x86\xf9\x2f\x66\x42\xeb\xf9" 
    "\x80\x78\xfa\xc7\xea\x63\x35\x7e\x6f\xc5\x35\x36" 
    "\x6b\xa1\x8a\xa3\x49\x97\xbc\xa6\x9b\x5c\x6e\xf1" 
    "\x8d\x02\x40\x44\x70\xa0\xbe\x64\xc9\x4e\xd3\x84" 
    "\x4d\x45\xaa\x88\x5e\xcf\xe7\x85\xc9\x6e\x43\x87" 
    "\xe1\xdb\x20\xe2\x49\x86\xa6\x33\x9f\x8f\x27\xde" 
    "\xc5\x98\xde\x19\xd0\xb6\xac\x50\xce\x2e\x35\xad" 
    "\x52\xe5\x44\x44\xb5\x73\x87\xfe\x63\xcf\x83\x70" 
    "\xb8\x36\xac\x75\x24\xbe\xc7\x02\x41\x00\x87\xd2" 
    "\x97\xa8\xb2\x40\x7e\x67\xf8\x75\x5b\xf1\xb0\x64" 
    "\x8d\x79\x10\xd9\xec\x4d\xe4\x8b\x43\xc0\xb4\x29" 
    "\x63\x94\x47\x69\xde\x6d\x5c\xa0\x4e\x17\xe7\x50" 
    "\x77\xf6\xf6\xb5\xd7\x8b\x33\x97\x68\x89\x3d\x90" 
    "\x35\x84\x49\xbd\xd0\xb9\xdd\xe2\x31\x4d\x09\x1a" 
    "\x94\x99\x02\x41\x00\xc9\x12\xec\x64\xe9\x01\x27" 
    "\x10\x6c\xad\xc5\x83\x8a\x26\x39\xe0\x05\xde\xde" 
    "\xf9\x1a\x5d\xf6\xcb\xe8\xd2\x9b\x40\xd5\x11\xc8" 
    "\x9a\x6d\x29\xb6\x15\x36\x9a\xee\x45\xe2\x51\x14" 
    "\xa8\x2d\xab\x57\x86\x80\x87\x0a\x02\xaf\xfa\xda" 
    "\x5e\x7d\xfb\x84\xd1\x3a\xe0\xed\x57"; 
const int priv_key_len = 609; 

const char *pub_key = 
    "\x30\x81\x9e\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7" 
    "\x0d\x01\x01\x01\x05\x00\x03\x81\x8c\x00\x30\x81" 
    "\x88\x02\x81\x80\x6d\x4d\xaf\xf5\x32\x98\xfa\x33" 
    "\xf2\x4a\xb0\x50\x27\x6f\x50\x0b\x28\xca\x5f\x6e" 
    "\xde\xec\x7b\xae\xeb\xd1\x89\xdf\xcf\x8d\x12\x6c" 
    "\x0d\xf2\x32\x65\xb7\x04\xf2\xb8\x76\x67\xe9\x28" 
    "\xc3\x12\x6b\x4a\x52\x09\xd6\x61\x9b\x21\x25\x04" 
    "\xe0\x9a\xec\xbc\x25\x3f\xfc\x6f\x1a\x98\xa8\x02" 
    "\xa8\x2e\x89\x91\x20\xcf\xf0\xd1\x9d\x09\x35\xac" 
    "\x95\xe2\xe4\x8e\x5b\x7c\x34\x93\x39\x4f\x33\xbd" 
    "\x6e\xe7\xc5\xbb\x2a\x28\x32\x13\x62\x39\x37\x87" 
    "\x40\xe7\x59\xf8\x94\xad\xc4\x2e\xaf\x23\xf4\x98" 
    "\xcd\x90\x27\x96\x41\xc6\x4a\xcd\x6d\x56\xfd\x5b" 
    "\x02\x03\x01\x00\x01"; 
const int pub_key_len = 161; 

const char *msg = "\x54\x85\x9b\x34\x2c\x49\xea\x2a"; 
const int msg_len = 8; 

char *crypted = NULL; 
int crypted_len = 0; 

struct tcrypt_result { 
    struct completion completion; 
    int err; 
}; 

struct akcipher_testvec { 
    unsigned char *key; 
    unsigned char *msg; 
    unsigned int key_size; 
    unsigned int msg_size; 
}; 

static inline void hexdump(unsigned char *buf,unsigned int len) { 
    while(len--) 
     printk("%02x",*buf++); 
    printk("\n"); 
} 

static void tcrypt_complete(struct crypto_async_request *req, int err) 
{ 
    struct tcrypt_result *res = req->data; 

    if (err == -EINPROGRESS) 
     return; 

    res->err = err; 
    complete(&res->completion); 
} 

static int wait_async_op(struct tcrypt_result *tr, int ret) 
{ 
    if (ret == -EINPROGRESS || ret == -EBUSY) { 
     wait_for_completion(&tr->completion); 
     reinit_completion(&tr->completion); 
     ret = tr->err; 
    } 
    return ret; 
} 

static int uf_akcrypto(struct crypto_akcipher *tfm, 
         void *data, int datalen, int phase) 
{ 
    void *xbuf = NULL; 
    struct akcipher_request *req; 
    void *outbuf = NULL; 
    struct tcrypt_result result; 
    unsigned int out_len_max = 0; 
    struct scatterlist src, dst; 

    int err = -ENOMEM; 
    xbuf = kmalloc(PAGE_SIZE, GFP_KERNEL); 
    if (!xbuf) 
     return err; 

    req = akcipher_request_alloc(tfm, GFP_KERNEL); 
    if (!req) 
     goto free_xbuf; 

    init_completion(&result.completion); 


    if (!phase) //test 
     err = crypto_akcipher_set_pub_key(tfm, pub_key, pub_key_len); 
    else 
     err = crypto_akcipher_set_priv_key(tfm, priv_key, priv_key_len); 

// err = crypto_akcipher_set_priv_key(tfm, priv_key, priv_key_len); 
    if (err){ 
     printk("set key error! %d,,,,,%d\n", err,phase); 
     goto free_req; 
    } 

    err = -ENOMEM; 
    out_len_max = crypto_akcipher_maxsize(tfm); 
    outbuf = kzalloc(out_len_max, GFP_KERNEL); 
    if (!outbuf) 
     goto free_req; 

    if (WARN_ON(datalen > PAGE_SIZE)) 
     goto free_all; 

    memcpy(xbuf, data, datalen); 
    sg_init_one(&src, xbuf, datalen); 
    sg_init_one(&dst, outbuf, out_len_max); 
    akcipher_request_set_crypt(req, &src, &dst, datalen, out_len_max); 
    akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 
           tcrypt_complete, &result); 

    if (phase){ 
     err = wait_async_op(&result, crypto_akcipher_encrypt(req)); 
     if (err) { 
      pr_err("alg: akcipher: encrypt test failed. err %d\n", err); 
      goto free_all; 
     } 
     memcpy(crypted,outbuf,out_len_max); 
     crypted_len = out_len_max; 
     hexdump(crypted, out_len_max); 
    }else{ 
     err = wait_async_op(&result, crypto_akcipher_decrypt(req)); 
     if (err) { 
      pr_err("alg: akcipher: decrypt test failed. err %d\n", err); 
      goto free_all; 
     } 
     hexdump(outbuf, out_len_max); 
    } 

free_all: 
    kfree(outbuf); 
free_req: 
    akcipher_request_free(req); 
free_xbuf: 
    kfree(xbuf); 
    return err; 
} 


static int userfaultfd_akcrypto(void *data, int datalen, int phase) 
{ 
    struct crypto_akcipher *tfm; 
    int err = 0; 

    tfm = crypto_alloc_akcipher("rsa", CRYPTO_ALG_INTERNAL, 0); 
    if (IS_ERR(tfm)) { 
      pr_err("alg: akcipher: Failed to load tfm for rsa: %ld\n", PTR_ERR(tfm)); 
      return PTR_ERR(tfm); 
    } 
    err = uf_akcrypto(tfm,data,datalen,phase); 

    crypto_free_akcipher(tfm); 
    return err; 
} 

static int __init test_init(void) 
{ 
    crypted = kmalloc(PAGE_SIZE, GFP_KERNEL); 
    if (!crypted){ 
     printk("crypted kmalloc error\n"); 
     return -1; 
    } 

    userfaultfd_akcrypto(msg,msg_len,1); 
    userfaultfd_akcrypto(crypted,crypted_len,0); 
    kfree(crypted); 
} 

static void __exit test_exit(void) 
{ 

} 

module_init(test_init); 
module_exit(test_exit); 

MODULE_LICENSE("GPL"); 

ответ

0

Я понял это сам.

Факт - это генерация открытого ключа с помощью openssl, но она содержит больше информации в его голове, которая не требуется ядром крипто api. С дополнительными данными ядро ​​ctypto api не может правильно разобрать структуру открытого ключа, поэтому «ASN1: Неожиданный тег».

Посмотрите на ядро-совместимый открытый ключ here, он содержит только следующие элементы:

{ 
    total size 
    integer size and value 
    integer size and value 
} 

Следующая команда покажет вам структуру открытого ключа в дер формиата генерируют OpenSSL:

openssl asn1parse -in public_key.der -inform DER 

выходы, подобные этим:

0:d=0 hl=3 l= 159 cons: SEQUENCE   
3:d=1 hl=2 l= 13 cons: SEQUENCE   
5:d=2 hl=2 l= 9 prim: OBJECT   :rsaEncryption 
16:d=2 hl=2 l= 0 prim: NULL    
18:d=1 hl=3 l= 141 prim: BIT STRING 

Реальные данные находятся в BIT STRING. И его смещение равно 18. Таким образом, от смещения 18 до конца - данные, которые вы хотели.

Вы можете прочитать BIT STRING внутреннюю структуру, введя команду:

openssl asn1parse -in public_key.der -inform DER -strparse 18 

выходы как:

0:d=0 hl=3 l= 137 cons: SEQUENCE   
3:d=1 hl=3 l= 129 prim: INTEGER   :D0B45AC19E2E4DA .... 
135:d=1 hl=2 l= 3 prim: INTEGER   :010001 

так же, как и той же структуры, как открытого ключа ядра-совместимый.