簡體   English   中英

來自Linux內核的CCM-AES

[英]CCM-AES from Linux Kernel

我需要與Solaris加密機器SUN_CKM_AES_CCM兼容。 在Linux中,我相信我應該設置一個AEAD請求以獲得“ccm(aes)”機制。 Linux Crypto的文檔看起來確實很差,最好的例子似乎是tcrypt.c測試和內核源代碼。

在Solaris中,我對512字節塊進行了測試加密,具有16字節hmac和12字節iv。 這需要保持不變,希望結果是相同的。

但是,我認為應該起作用,不會;

   struct crypto_aead *tfm = NULL;
   struct aead_request *req;
   unsigned char key[16] = {
    0x5c, 0x95, 0x64, 0x42, 0x00, 0x82, 0x1c, 0x9e,
    0xd4, 0xac, 0x01, 0x83, 0xc4, 0x9c, 0x14, 0x97
   };
  unsigned int ivsize;
  int ret;
  struct scatterlist plaintext[1];
  struct scatterlist ciphertext[1];
  struct scatterlist hmactext[1];
  unsigned char *plaindata = NULL;
  unsigned char *cipherdata = NULL;
  unsigned char *hmacdata = NULL;
  unsigned char *ivp = NULL;
  int i;
  unsigned char d;
  struct tcrypt_result result;

  tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
  init_completion(&result.completion);
  req = aead_request_alloc(tfm, GFP_KERNEL);
  aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
                          cipher_work_done, &result);

  crypto_aead_clear_flags(tfm, ~0);

  ret = crypto_aead_setkey(tfm, key, sizeof(key));

  ret = crypto_aead_setauthsize(tfm, 16); // authsize is hmac?

  ivsize = crypto_aead_ivsize(tfm);
  if (ivsize != 12) {
    printk("ivsize is not 12 %d - this needs to be fixed\n", ivsize);
  }

  plaindata  = kmalloc(512, GFP_KERNEL);
  cipherdata = kmalloc(512, GFP_KERNEL);
  hmacdata   = kmalloc(16, GFP_KERNEL);
  ivp        = kmalloc(ivsize, GFP_KERNEL);

  if (!plaindata || !cipherdata || !hmacdata || !ivp) goto out;

  // put 00 01 02 03 ... in the input buffer...
  for (i = 0, d = 0; i < 512; i++, d++)
    plaindata[i] = d;

  memset(cipherdata, 0, 512);
  memset(hmacdata, 0, 16);
  memset(ivp, 0, ivsize);

  // Put a8 a9 aa .... in iv
  for (i = 0,d=0xa8; i < 12; i++, d++)
    ivp[i] = d;

  sg_init_one(&plaintext[0],  plaindata,  512);
  sg_init_one(&ciphertext[0], cipherdata, 512);
  sg_init_one(&hmactext[0],   hmacdata,   16);

  aead_request_set_crypt(req, plaintext, ciphertext, 512, ivp);

  aead_request_set_assoc(req, hmactext, 16);

  ret = crypto_aead_encrypt(req);

  printk("cipher call returns %d \n", ret);

我們得到的是ivsize是16(並且我認為沒有辦法將其設置為12),並且加密失敗了“-22”或EINVAL。 代碼中有很多錯誤檢查,在這里刪除,確認所有先前的呼叫返回成功。

據我所知,我非常接近tcrypt.c來源。 但是,我想知道強制ivsize = 16是否意味着無論如何我都不能使用提供的算法。 除此之外,看到加密調用成功以及加密數據輸出中的內容會很高興。

代碼放入內核模塊,並在_init()時運行。 最初我使用blkcipher“aes”,它起作用,但不是ccm-aes變體。 這讓我改變使用aead,我無法工作。

好的,這就是我所學到的。

1)讓我們調用應用程序的iv nonce 讓我們稱之為內部加密iv iv 事實證明,Solaris代碼使用的是nonce-len=12 ,但CCM-AES算法仍然使用iv-len=16

從Solaris內核源代碼中, iv由以下內容組成:

iv[0] = 1..7, based on ivlen 16 - noncelen 12 = 2.
iv[1] = the nonce data (12 bytes).
iv[14] = 0
iv[15] = 1

因此,在Linux上我想用ivlen 16“ccm(aes)”,並正確地從nonce准備iv

2)當調用crypto_aead_encrypt() ,忽略先前調用aead_request_set_assoc() ,並將HMAC放在密碼緩沖區的末尾。 就我而言,在密文[512]中,為16個字節。 所以輸入需要長度為+16。

使用分散列表,如果設置正確,HMAC“在末尾”可以是不同的地方。

3)當調用crypto_aead_decrypt() ,cryptolen應為+16(cipherinputlen + maclen)。 從輸入緩沖區的末尾讀取MAC,即密文[512]為16字節。 它也可以是使用scatterlist的單獨緩沖區。

4) crypto_aead_setauthsize()檢查len給出的是否正確,然后對它做任何事情。 不要以為這實際上設定了尺寸!

5)必須設置aead_request_set_assoc() ,即使它只是一個零的緩沖區。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM