2016-01-25 24 views
7

CMAC, OpenSSL ile hesaplamak için anahtar oluşturmaya çalışıyorum. Ancak, bunlar aşağıda kopyalanan hata iletisiyle başarısız gibi görünüyor. Birisi sorunun nerede olduğuna işaret edebilir mi? EVP_DigestSign* numaralı aramalarla CMAC'ı kim yaptı? Burada hataCMAC Anahtar oluşturma OpenSSL ile EVP_DigestSign * başarısız olur

BIO *out = NULL; 
out = BIO_new(BIO_s_file()); 

if (out == NULL) 
     return -1; 
BIO_set_fp(out, stdout, BIO_NOCLOSE); 

EVP_MD_CTX* rctx = NULL; 
EVP_PKEY *pkey = NULL; 
EVP_PKEY_CTX *kctx = NULL; 

rctx = EVP_MD_CTX_create(); 
if(rctx == NULL) { 
    printf("EVP_MD_CTX_create failed\n"); 
} 
if(!EVP_PKEY_keygen_init(kctx)){ 
    printf("EVP_PKEY_keygen_init failed\n"); 
} 

if (EVP_PKEY_CTX_ctrl(kctx, -1, EVP_PKEY_OP_KEYGEN,EVP_PKEY_CTRL_CIPHER,0, (void *)EVP_aes_256_ecb()) <= 0) 
    printf("EVP_PKEY_CTX_ctrl 1 failed\n"); 

if (EVP_PKEY_CTX_ctrl(kctx, -1, EVP_PKEY_OP_KEYGEN,EVP_PKEY_CTRL_SET_MAC_KEY,/*key length*/32, "") <= 0) 
    printf("Set the key data failed 1\n"); 

: pmeth_lib.c içinde

EVP_PKEY_CTX_ctrl failed 
3073898120:error:06093096:lib(6):func(147):reason(150):pmeth_gn.c:122: 
3073898120:error:06089093:lib(6):func(137):reason(147):pmeth_lib.c:390: 

ve hat 390:

Burada

https://wiki.openssl.org/index.php/EVP_Key_and_Parameter_Generation örneğin inşa edilmiş kod parçasıdır

EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); 

OpenSSL 1.0.1e kullanıyorum.

o desteklenmeyen çünkü ayrıca How to calculate AES CMAC using OpenSSL's CMAC_xxx functions?

+0

["İmza"] (https://wiki.openssl.org/index.php/EVP_Signing_and_Verifying#Signing_2) bölümünün sonunda, CMAC'ın yalnızca _1.1.0_ OpenSSL sürümünde desteklendiğinden bahseder: "CMAC'ın yalnızca (henüz yayımlanmamış) OpenSSL sürüm 1.1.0 sürümünde desteklendiğini unutmayın." Ancak, EVP API'sini kullanmıyorsanız, CMAC'yi kullanabilmeniz gerekir; olası bir örnek için bakınız [burada] (http://rubenlaguna.com/wp/2015/02/05/compute-aes-cmac-using-openssl-slash-libcrypto/). – Castaglia

cevap

1

Halen imkansız bakın.

Sadece deneyebileceğiniz en son OpenSSL'yi kullanmak ve aynı şeyi denemek ama işe yarayacağından şüpheliyim. EVP olmadan deneyin.

2

CMP'yi EVP arabirimlerini kullanarak çalışmayı başardım. Daha önce başarısız olan anahtar üretimi bölümü de işe yarıyor. İşte kod. Gördüğünüz gibi, burada yayınlanan örneği aldım: OpenSSL CMAC_Init/Update/Final arabirimlerini kullanan ve çeşitli NIST değerlerini deneyen CMP_Init/Update/Final arabirimlerini kullanarak CMP için EVP arabirimlerinin çalışıp çalışmadığını kontrol ettim: İşte kod snippet'i. Anahtar üretimi şimdi de çalışıyor. Gözardı ettiğim bir şey varsa lütfen bana bildirin. EVP kullanırken bir notum var. Lütfen aşağıdaki açıklama bölümüne de bakınız.

/* 
* CMACSiging.c 
*/ 

#include <stdio.h> 
#include <openssl/cmac.h> 
#include <openssl/err.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <openssl/evp.h> 
#include <string.h> 

typedef signed char  int8_t; 
typedef signed short  int16_t; 
typedef signed int  int32_t; 
typedef unsigned char  uint8_t; 
typedef unsigned short uint16_t; 
typedef unsigned int  uint32_t; 

void printBytes(unsigned char *buf, size_t len) { 
    int i; 
    for(i=0; i<len; i++) { 
     printf("%02x", buf[i]); 
    } 
    printf("\n"); 
} 
EVP_PKEY *generate_key(int type) 
{ 
    EVP_PKEY_CTX *pctx = NULL, *kctx = NULL; 
    EVP_PKEY *params = NULL, *key = NULL; 

    unsigned char k[] = {0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4}; 
    /* Create context for the key generation */ 
    if(!(kctx = EVP_PKEY_CTX_new_id(type, NULL))) goto err; 

    /* Generate the key */ 

    if(!EVP_PKEY_keygen_init(kctx)) goto err; 

    if(type == EVP_PKEY_CMAC) 
    { 
     if (EVP_PKEY_CTX_ctrl(kctx, -1, EVP_PKEY_OP_KEYGEN, 
      EVP_PKEY_CTRL_CIPHER, 
      0, (void *)EVP_aes_256_cbc()) <= 0) 
      goto err; 

     if (EVP_PKEY_CTX_ctrl(kctx, -1, EVP_PKEY_OP_KEYGEN, 
      EVP_PKEY_CTRL_SET_MAC_KEY, sizeof(k), k) <= 0) 
      goto err; 
    } 

    if (!EVP_PKEY_keygen(kctx, &key)) goto err; 

    goto end; 
err: 

end: 

    if(pctx) EVP_PKEY_CTX_free(pctx); 
    if(params) EVP_PKEY_free(params); 
    if(kctx) EVP_PKEY_CTX_free(kctx); 

    return key; 
} 

void trial(uint8_t *msg, uint8_t mlen, uint8_t *key, uint8_t keylen, uint8_t **sig, uint8_t *slen) 
{ 
//16 byte msg with 32 byte key with aes 256 cbc based CMAC 
    if(!msg || !mlen || !key) { 
     //handleError 
    } 

    if(*sig) 
     OPENSSL_free(*sig); 

    *sig = NULL; 
    *slen = 0; 

    EVP_MD_CTX* ctx = NULL; 
    EVP_PKEY *pkey = NULL; 
    const EVP_MD* md = NULL; 
    OpenSSL_add_all_digests(); 

    do 
    { 
     ctx = EVP_MD_CTX_create(); 
     if(ctx == NULL) { 
      printf("EVP_MD_CTX_create failed\n"); 
      break; // failed 
     } 
     if(!(md = EVP_get_digestbyname("SHA256"))) 
       printf("EVP_get_digestbyname failed\n"); 

     printf("Over to EVP calls \n"); 
     if(!(pkey = generate_key(EVP_PKEY_CMAC))) printf("Error 5 \n"); 
     int rc ; 
     rc = EVP_DigestSignInit(ctx, NULL, md, NULL, pkey); 
     if(rc != 1) { 
      printf("EVP_DigestSignInit failed\n"); 
      ERR_print_errors_fp(stdout); 
      break; 
     } 

     rc = EVP_DigestSignUpdate(ctx, msg, mlen); 
     if(rc != 1) { 
      printf("EVP_DigestSignUpdate failed\n"); 
      ERR_print_errors_fp(stdout); 
      break; 
     } 

     size_t req = 0; 
     rc = EVP_DigestSignFinal(ctx, NULL, &req); 

     if(rc != 1) { 
      printf("EVP_DigestSignFinal failed\n"); 
      ERR_print_errors_fp(stdout); 
      break; 
     } 

     if(!(req > 0)) { 
      printf("EVP_DigestSignFinal failed (2)\n"); 
      break; 
     } 

     *sig = OPENSSL_malloc(req); 
     if(*sig == NULL) { 
      printf("OPENSSL_malloc failed, error \n"); 
      break; 
     } 

     *slen = req; 
     rc = EVP_DigestSignFinal(ctx, *sig, slen); 
     if(rc != 1) { 
      printf("EVP_DigestSignFinal failed (3)\n"); 
      ERR_print_errors_fp(stdout); 
      break; 
     } 

    } while(0); 

    if(ctx) { 
     EVP_MD_CTX_destroy(ctx); 
     ctx = NULL; 
    } 
} 

int main(int argc, char *argv[]) 
{ 
    // https://tools.ietf.org/html/rfc4493 

    // K, M and T from 
    // http://csrc.nist.gov/publications/nistpubs/800-38B/Updated_CMAC_Examples.pdf 
    // D.1 AES-128 

    // K: 2b7e1516 28aed2a6 abf71588 09cf4f3c 

    unsigned char key[] = {0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4}; 

    // M: 6bc1bee2 2e409f96 e93d7e11 7393172a Mlen: 128 
    unsigned char message[] = { 0x6b,0xc1,0xbe,0xe2, 
      0x2e,0x40,0x9f,0x96, 
      0xe9,0x3d,0x7e,0x11, 
      0x73,0x93,0x17,0x2a }; 

    unsigned char mact[16] = {0}; 
    size_t mactlen; 

    CMAC_CTX *ctx = CMAC_CTX_new(); 
    CMAC_Init(ctx, key, 32, EVP_aes_256_cbc(), NULL); 
    printf("message length = %lu bytes (%lu bits)\n",sizeof(message), sizeof(message)*8); 

    CMAC_Update(ctx, message, sizeof(message)); 
    CMAC_Final(ctx, mact, &mactlen); 

    printBytes(mact, mactlen); 
    //expected result T = 070a16b4 6b4d4144 f79bdd9d d04a287c 

    CMAC_CTX_free(ctx); 


    uint8_t key_len = sizeof(key); 
    uint8_t mlen = sizeof(message); 
    uint8_t *dgst = NULL; 
    size_t dlen; 
    trial(message, mlen, key, key_len, &dgst, &dlen); 
    printf("length of sig = %d\n", dlen); 
    printf("CMAC returned from trial is: "); 
    int i; 
    for(i = 0; i < dlen; i++) 
     printf("%02x", dgst[i]); 
    printf("\n"); 

    return 0; 
} 

AÇIKLAMA: kodunda görüldüğü gibi

, önemli olan OpenSSL'deki belirtildiği gibi NULL olarak alınmamalıdır EVP_DigestSignInit kullanırken, mesaj zarf yapısı (EVP_MD) sindirmek dikkat etmektir Wiki (I test OpenSSL 1.0.2e yönelik en az): NULL geçirilir

Note: There is no difference in the API between signing using an asymmetric algorithm, and generating a MAC code. In the case of CMAC no message digest function is required (NULL can be passed). Signing using the EVP_Sign* functions is very similar to the above example, except there is no support for MAC codes. Note that CMAC is only supported in the (as yet unreleased) version 1.1.0 of OpenSSL.

, I dijesti NULL bir hata olsun. Geçilenin, bu yapı temel olarak yok sayıldığı için CMAC neslini etkilemediği anlaşılıyor. Umarım OpenSSL adamları burada açıklığa kavuşabilir. Teşekkürler!!

İlgili konular