2016-06-29 12 views
1

GCM暗号化を使用した暗号化のAEADサンプルコードを実装しようとしています。モジュールを挿入するには、キーGCM-AEADは、Linux kernel-3.10を実行するubuntuシステムをサポートしています。

static int init_aead(void) 
    { 
     printk("Starting encryption\n"); 
     struct crypto_aead *tfm = NULL; 
     struct aead_request *req; 
     struct tcrypt_result tresult; 

     struct scatterlist plaintext[1] ; 
     struct scatterlist ciphertext[1]; 
     struct scatterlist gmactext[1]; 
     unsigned char *plaindata = NULL; 
     unsigned char *cipherdata = NULL; 
     unsigned char *gmacdata = NULL; 

     const u8 *key = kmalloc(16, GFP_KERNEL); 

     char *algo = "rfc4106(gcm(aes))"; 
     unsigned char *ivp = NULL; 
     int ret, i, d; 
     unsigned int iv_len; 
     unsigned int keylen = 16; 

     /* Allocating a cipher handle for AEAD */ 
     tfm = crypto_alloc_aead(algo, 0, 0); 
     init_completion(&tresult.completion); 
     if(IS_ERR(tfm)) { 
        pr_err("alg: aead: Failed to load transform for %s: %ld\n", algo, 
          PTR_ERR(tfm)); 
       return PTR_ERR(tfm); 
     } 

     /* Allocating request data structure to be used with AEAD data structure */ 
     req = aead_request_alloc(tfm, GFP_KERNEL); 
     if(IS_ERR(req)) { 
      pr_err("Couldn't allocate request handle for %s:\n", algo); 
      return PTR_ERR(req); 
     } 

     /* Allocting a callback function to be used , when the request completes */ 
     aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, aead_work_done,&tresult); 

     crypto_aead_clear_flags(tfm, ~0); 

     /* Set key */ 
     get_random_bytes((void*)key, keylen); 

    if((ret = crypto_aead_setkey(tfm, key, 16) != 0)) { 
      pr_err("Return value for setkey is %d\n", ret); 
      pr_info("key could not be set\n"); 
       ret = -EAGAIN; 
      return ret; 
     } 

     /* Set authentication tag length */ 
      if(crypto_aead_setauthsize(tfm, 16)) { 
      pr_info("Tag size could not be authenticated\n"); 
       ret = -EAGAIN; 
      return ret; 
     } 

     /* Set IV size */ 
     iv_len = crypto_aead_ivsize(tfm); 
     if (!(iv_len)){ 
      pr_info("IV size could not be authenticated\n"); 
        ret = -EAGAIN; 
        return ret; 
      } 


     plaindata = kmalloc(16, GFP_KERNEL); 
     cipherdata = kmalloc(16, GFP_KERNEL); 
     gmacdata = kmalloc(16, GFP_KERNEL); 
     ivp  = kmalloc(iv_len, GFP_KERNEL); 

     if(!plaindata || !cipherdata || !gmacdata || !ivp) { 
      printk("Memory not availaible\n"); 
      ret = -ENOMEM; 
      return ret; 
     } 
     for (i = 0, d = 0; i < 16; i++, d++) 
      plaindata[i] = d; 

     memset(cipherdata, 0, 16); 
     memset(gmacdata, 0, 16); 

     for (i = 0,d=0xa8; i < 16; i++, d++) 
      ivp[i] = d; 

     sg_init_one(&plaintext[0], plaindata, 16); 
     sg_init_one(&ciphertext[0], cipherdata, 16); 
     sg_init_one(&gmactext[0], gmacdata, 128); 
     aead_request_set_crypt(req, plaintext, ciphertext, 16, ivp); 
     aead_request_set_assoc(req, gmactext, 16); 

     ret = crypto_aead_encrypt(req); 

     if (ret) 
      printk("cipher call returns %d \n", ret); 
     else 
      printk("Failure \n"); 
     return 0; 
    } 

    module_init(init_aead); 
    module_exit(exit_aead); 
    MODULE_LICENSE("GPL"); 
    MODULE_DESCRIPTION("My code for aead encryption test"); 
    } 

を設定しながら、しかし、私はいつもはsetkeyため

開始暗号
戻り値が-22
キーは設定できませんでし出力私は、次の取得の無効な引数エラーを取得します

AEAD仕様によれば、aeadはaes-128を暗号化に使用するため、ブロックサイズは128ビットにする必要があります。

しかし、私のシステムが示しAEAD

name   : rfc4106(gcm(aes)) 
driver  : rfc4106-gcm-aesni 
module  : aesni_intel 
priority  : 400 
refcnt  : 1 
selftest  : passed 
type   : nivaead 
async  : yes 
blocksize : 1 
ivsize  : 8 
maxauthsize : 16 
geniv  : seqiv 

のための唯一の1つのバイトのブロックサイズのサポートは無効な引数エラーがブロックサイズのbecuaseスローされません。もしそうなら、私はそれを機能させるために何をしなければならないでしょうか?

答えて

0

AESのブロックサイズは、常に128ビットです。 GCMのブロックサイズは別の問題です。 GCM(ガロア・カウンタ・モード)は、名前が示すように、CTR(カウンタ)動作モードの上に構築され、時にはSIC(セグメント化整数カウンタ)動作モードとも呼ばれます。これにより、AESがストリーム暗号に変換されます。ストリーム暗号は定義上、1バイトのブロックサイズを持ちます(より正確には1ビットですが、通常はビットレベルの操作はAPIではサポートされません)。

ブロックサイズは、呼び出しで表示されるキーサイズとほとんど関係がありません。引数には、ビット(通常、キーの長さが定義されている)ではなくバイトが必要なようです。

IVのサイズは12バイト(デフォルト)です。それ以外の場合は、GCM実装によって追加の計算が必要になる場合があります(存在する場合)。

+0

上記のコメントが問題の解決に役立つかどうか確認できますか? –

+0

あなたの助けを頼りにしてください。私はもう一つ疑いがある。 blocksize:1は、入力ブロックサイズの長さまたは出力ブロックサイズを指定しますか? 。最新のメインラインカーネルのcrypto_aead_setkey定義による。 "" AES暗号ハンドルに16バイトのキーを提供する場合、AES-128が実行されます。 "" [http://lxr.free-electrons.com/source/crypto/aead .c#L52]。ブロックサイズが入力データサイズ、すなわち1バイトであり、16バイトのキーを提供する場合、それは機能するか?もしそうでなければ、私は - 固有のエラーerorを得ている理由は何ですか? – addy

+0

ブロックサイズとキーサイズはお互いに直接関係していません。入力と出力のブロックサイズは常に同じです。実装によっては、時間内に処理されるバイト数が異なります。残念ながら私は30分を食べて、私のカヤックを準備するために左に持っています:) –

関連する問題