EVACインターフェイスを使用してCMACを動作させることができました。先に失敗した鍵生成部分も機能します。ここにコードがあります。ご覧のとおり、ここに掲載されている例はHow to calculate AES CMAC using OpenSSL?で、OpenSSLのCMAC_Init/Update/Finalインターフェイスを使用し、さまざまなNIST値を試してEVPインターフェイスがCMACで動作するかどうかを試しました。ここにコードスニペットがあります。キー生成も今でも機能します。私が見落としたことがあれば教えてください。私はEVPを使用している間に発言をする。以下の注意事項のセクションもご覧ください。
/*
* 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;
}
注:コードに見られるように
、重要なことはEVP_DigestSignInitを使用する場合にOpenSSLで述べたように、メッセージエンベロープ構造(EVP_MD)のダイジェストがNULLとして解釈されるべきではないことに注意することですウィキ(私がテストされたOpenSSL 1.0.2eのための少なくとも)は:NULLが渡された場合は
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.
、私はダイジェストがNULLであることをエラーが発生します。 この構造体は基本的に無視されるので、渡されたものはCMAC生成に影響を与えないようです。ここにあるOpenSSLの人が明らかにできることを願っています。ありがとう!!
["Signing"](https://wiki.openssl.org/index.php/EVP_Signing_and_Verifying#Signing_2)セクションの最後には、CMACが_1.1.0_ OpenSSLバージョンでのみサポートされていることが記載されています。 CMACはOpenSSLの(未だリリースされていない)バージョン1.1.0でのみサポートされていることに注意してください。ただし、EVP APIを使用しない場合でも、CMACを使用できるはずです。可能な例については、[here](http://rubenlaguna.com/wp/2015/02/05/compute-aes-cmac-using-openssl-slash-libcrypto/)を参照してください。 – Castaglia