2016-01-25 4 views
7

विफल रहता है मैं ओएमएसएसएसएस के साथ सीएमएसी की गणना के लिए कुंजी उत्पन्न करने की कोशिश कर रहा हूं।OpenSSL EVP_DigestSign के साथ सीएमएसी कुंजी पीढ़ी *

हालांकि, ये नीचे कॉपी किए गए त्रुटि संदेश में विफल होने लगते हैं। क्या कोई बता सकता है कि समस्या कहां है? क्या किसी ने EVP_DigestSign* कॉल के साथ सीएमएसी किया है?

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"); 

यहाँ त्रुटि:

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: 
pmeth_lib.c में

और लाइन 390 पर:

यहाँ कोड है जो https://wiki.openssl.org/index.php/EVP_Key_and_Parameter_Generation में उदाहरण से निर्माण किया गया है का हिस्सा है

EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); 

मैं ओपनएसएसएल 1.0.1e का उपयोग कर रहा हूं।

भी देखें How to calculate AES CMAC using OpenSSL's CMAC_xxx functions?

+0

["साइनिंग"] (https://wiki.openssl.org/index.php/EVP_Signing_and_Verifying#Signing_2) अनुभाग के अंत में, यह उल्लेख करता है कि सीएमएसी केवल _1.1.0_ ओपनएसएसएल संस्करण में समर्थित है: "ध्यान दें कि सीएमएसी केवल ओपनएसएसएल के संस्करण 1.1.0 में समर्थित है (जैसा कि अभी तक रिलीज़ नहीं है)। हालांकि, यदि आप ईवीपी एपीआई का उपयोग नहीं करते हैं, तो भी आपको सीएमएसी का उपयोग करने में सक्षम होना चाहिए; एक संभावित उदाहरण के लिए [यहां] देखें (http://rubenlaguna.com/wp/2015/02/05/compute-aes-cmac-using-openssl-slash-libcrypto/)। – Castaglia

उत्तर

1

यह वर्तमान में असंभव है, क्योंकि यह समर्थित नहीं है।

केवल एक चीज जिसे आप आजमा सकते हैं, नवीनतम ओपनएसएसएल का उपयोग करना और एक ही चीज़ का प्रयास करना है, लेकिन मुझे संदेह है कि यह काम करेगा। ईवीपी के बिना प्रयास करें।

2

मैं ईवीपी इंटरफेस का उपयोग कर सीएमएसी काम करने में कामयाब रहा। महत्वपूर्ण पीढ़ी का हिस्सा जो पहले विफल रहा था, भी काम करता है। कोड यहाँ है। जैसा कि आप देख सकते हैं, मैंने यहां पोस्ट किया गया उदाहरण लिया है: How to calculate AES CMAC using OpenSSL? जो ओपनएसएसएल के सीएमएसी_इनिट/अपडेट/फाइनल इंटरफेस का उपयोग करता है और यह जांचने के लिए विभिन्न एनआईएसटी मानों का प्रयास करता है कि ईवीपी इंटरफेस सीएमएसी के लिए काम करता है या नहीं: यहां कोड स्निपेट है। मुख्य पीढ़ी अब भी काम करती है। अगर मुझे कुछ भी नजरअंदाज कर दिया गया है तो कृपया मुझे बताएं। ईवीपी का उपयोग करते समय मेरे पास एक टिप्पणी है। कृपया नीचे टिप्पणी अनुभाग भी देखें।

/* 
* 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; 
} 

REMARK:

के रूप में कोड में देखा, क्या महत्वपूर्ण है ध्यान दें कि जब EVP_DigestSignInit का उपयोग कर, संदेश को पचाने लिफाफा संरचना (EVP_MD) से OpenSSL में उल्लेख शून्य के रूप में नहीं लिया जाना चाहिए है विकी (OpenSSL 1.0.2e के लिए कम से कम है जो मैं कहाँ का परीक्षण):

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.

शून्य से पारित कर दिया गया है, तो मैं एक त्रुटि है कि डाइजेस्ट शून्य है मिलता है। ऐसा लगता है कि पारित होने से सीएमएसी पीढ़ी को प्रभावित नहीं होता है क्योंकि इस संरचना को मूल रूप से अनदेखा किया जाता है। मुझे उम्मीद है कि यहां ओपनएसएसएल के लोग स्पष्ट कर सकते हैं। धन्यवाद!!

संबंधित मुद्दे