sgx_status_t sgx_cmac128_msg(const sgx_key_128bit_t key, const uint8_t *p_src, unsigned int src_len, sgx_mac_t *p_mac) { if(!key || !p_src || src_len == 0 || !p_mac) { return SGX_ERROR_INVALID_PARAMETER; } CMAC_CTX *cmac_ctx = NULL; size_t mac_len; if(!(cmac_ctx = CMAC_CTX_new())) { return SGX_ERROR_OUT_OF_MEMORY; } if(!CMAC_Init(cmac_ctx, key, sizeof(sgx_key_128bit_t), EVP_aes_128_cbc(), NULL)) { CMAC_CTX_free(cmac_ctx); return SGX_ERROR_UNEXPECTED; } if(!CMAC_Update(cmac_ctx, p_src, src_len)) { CMAC_CTX_free(cmac_ctx); return SGX_ERROR_UNEXPECTED; } if(!CMAC_Final(cmac_ctx, (uint8_t *)p_mac, &mac_len)) { CMAC_CTX_free(cmac_ctx); return SGX_ERROR_UNEXPECTED; } CMAC_CTX_free(cmac_ctx); assert(mac_len == sizeof(sgx_mac_t)); return SGX_SUCCESS; }
BUF_MEM * cmac(CMAC_CTX *ctx, const EVP_CIPHER *type, const BUF_MEM * key, const BUF_MEM * in, size_t maclen) { CMAC_CTX * cmac_ctx = NULL; BUF_MEM * out = NULL, * tmp = NULL; size_t cmac_len = 0; check((key && in && type), "Invalid arguments"); check((key->length >= (size_t) EVP_CIPHER_key_length(type)), "Key is too short"); if (ctx) cmac_ctx = ctx; else { cmac_ctx = CMAC_CTX_new(); } /* Initialize the CMAC context, feed in the data, and get the required * output buffer size */ if (!cmac_ctx || !CMAC_Init(cmac_ctx, key->data, EVP_CIPHER_key_length(type), type, NULL) || !CMAC_Update(cmac_ctx, in->data, in->length) || !CMAC_Final(cmac_ctx, NULL, &cmac_len)) goto err; /* get buffer in required size */ out = BUF_MEM_create(cmac_len); if (!out) goto err; /* get the actual CMAC */ if (!CMAC_Final(cmac_ctx, (unsigned char*) out->data, &out->length)) goto err; /* Truncate the CMAC if necessary */ if (cmac_len > maclen) { tmp = BUF_MEM_create_init(out->data, maclen); BUF_MEM_free(out); out = tmp; } if (!ctx) CMAC_CTX_free(cmac_ctx); return out; err: if (cmac_ctx && !ctx) { CMAC_CTX_free(cmac_ctx); } if (out) { BUF_MEM_free(out); } return NULL; }
EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, size_t len, const EVP_CIPHER *cipher) { #ifndef OPENSSL_NO_CMAC EVP_PKEY *ret = EVP_PKEY_new(); CMAC_CTX *cmctx = CMAC_CTX_new(); if (ret == NULL || cmctx == NULL || !pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1)) { /* EVPerr already called */ goto err; } if (!CMAC_Init(cmctx, priv, len, cipher, e)) { EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED); goto err; } ret->pkey.ptr = cmctx; return ret; err: EVP_PKEY_free(ret); CMAC_CTX_free(cmctx); return NULL; #else EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return NULL; #endif }
static void cmac_key_free(EVP_PKEY *pkey) { CMAC_CTX *cmctx = (CMAC_CTX *)pkey->pkey.ptr; CMAC_CTX_free(cmctx); }
static int print_cmac_gen(const EVP_CIPHER *cipher, FILE *out, unsigned char *Key, int Klen, unsigned char *Msg, int Mlen, int Tlen) { int rc, i; size_t reslen; unsigned char res[128]; CMAC_CTX *cmac_ctx = CMAC_CTX_new(); CMAC_Init(cmac_ctx, Key, Klen, cipher, 0); CMAC_Update(cmac_ctx, Msg, Mlen); if (!CMAC_Final(cmac_ctx, res, &reslen)) { fputs("Error calculating CMAC\n", stderr); rc = 0; } else if (Tlen > (int)reslen) { fputs("Parameter error, Tlen > CMAC length\n", stderr); rc = 0; } else { fputs("Mac = ", out); for (i = 0; i < Tlen; i++) fprintf(out, "%02x", res[i]); fputs("\n", out); rc = 1; } CMAC_CTX_free(cmac_ctx); return rc; }
// We are doing CBC-MAC not CMAC at this time bool AES_CMAC_Validate(COSE_MacMessage * pcose, int KeySize, int TagSize, const byte * pbAuthData, int cbAuthData, cose_errback * perr) { CMAC_CTX * pctx = NULL; const EVP_CIPHER * pcipher = NULL; byte * rgbOut = NULL; size_t cbOut; bool f = false; unsigned int i; #ifdef USE_CBOR_CONTEXT cn_cbor_context * context = &pcose->m_message.m_allocContext; #endif pctx = CMAC_CTX_new(); switch (KeySize) { case 128: pcipher = EVP_aes_128_cbc(); break; case 256: pcipher = EVP_aes_256_cbc(); break; default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break; } rgbOut = COSE_CALLOC(128/8, 1, context); CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY); CHECK_CONDITION(CMAC_Init(pctx, pcose->pbKey, pcose->cbKey, pcipher, NULL /*impl*/) == 1, COSE_ERR_CRYPTO_FAIL); CHECK_CONDITION(CMAC_Update(pctx, pbAuthData, cbAuthData), COSE_ERR_CRYPTO_FAIL); CHECK_CONDITION(CMAC_Final(pctx, rgbOut, &cbOut), COSE_ERR_CRYPTO_FAIL); cn_cbor * cn = _COSE_arrayget_int(&pcose->m_message, INDEX_MAC_TAG); CHECK_CONDITION(cn != NULL, COSE_ERR_CBOR); for (i = 0; i < (unsigned int)TagSize / 8; i++) f |= (cn->v.bytes[i] != rgbOut[i]); COSE_FREE(rgbOut, context); CMAC_CTX_cleanup(pctx); CMAC_CTX_free(pctx); return !f; errorReturn: COSE_FREE(rgbOut, context); CMAC_CTX_cleanup(pctx); CMAC_CTX_free(pctx); return false; }
/* * Calculate per-link MAC by pathname */ static int32_t calc_link_mac_v1(struct mtd_format_v1 *fmt, loc_t *loc, unsigned char *result, struct crypt_inode_info *info, struct master_cipher_info *master) { int32_t ret; unsigned char nmtd_link_key[16]; CMAC_CTX *cctx; size_t len; ret = get_nmtd_link_key(loc, master, nmtd_link_key); if (ret) { gf_log("crypt", GF_LOG_ERROR, "Can not get nmtd link key"); return -1; } cctx = CMAC_CTX_new(); if (!cctx) { gf_log("crypt", GF_LOG_ERROR, "CMAC_CTX_new failed"); return -1; } ret = CMAC_Init(cctx, nmtd_link_key, sizeof(nmtd_link_key), EVP_aes_128_cbc(), 0); if (!ret) { gf_log("crypt", GF_LOG_ERROR, "CMAC_Init failed"); CMAC_CTX_free(cctx); return -1; } ret = CMAC_Update(cctx, get_NMTD_V1(info), SIZE_OF_NMTD_V1); if (!ret) { gf_log("crypt", GF_LOG_ERROR, "CMAC_Update failed"); CMAC_CTX_free(cctx); return -1; } ret = CMAC_Final(cctx, result, &len); CMAC_CTX_free(cctx); if (!ret) { gf_log("crypt", GF_LOG_ERROR, "CMAC_Final failed"); return -1; } return 0; }
/* 7.3.45 */ int SAF_MacUpdate( void *hKeyHandle, const unsigned char *pucInData, unsigned int uiInDataLen) { int ret = SAR_UnknownErr; SAF_KEY *hkey = (SAF_KEY *)hKeyHandle; if (!hKeyHandle || !pucInData) { SAFerr(SAF_F_SAF_MACUPDATE, ERR_R_PASSED_NULL_PARAMETER); return SAR_IndataErr; } if (uiInDataLen <= 0 || uiInDataLen > INT_MAX) { SAFerr(SAF_F_SAF_MACUPDATE, SAF_R_INVALID_INPUT_LENGTH); return SAR_IndataLenErr; } if (!hkey->cmac_ctx) { const EVP_CIPHER *cipher; if (!(cipher = EVP_get_cipherbysgd(hkey->hSymmKeyObj->uiCryptoAlgID))) { SAFerr(SAF_F_SAF_MACUPDATE, SAF_R_INVALID_KEY_HANDLE); ret = SAR_IndataErr; goto end; } if (!(hkey->cmac_ctx = CMAC_CTX_new())) { SAFerr(SAF_F_SAF_MACUPDATE, ERR_R_MALLOC_FAILURE); goto end; } if (!CMAC_Init(hkey->cmac_ctx, hkey->key, hkey->keylen, cipher, hkey->hSymmKeyObj->app->engine)) { SAFerr(SAF_F_SAF_MACUPDATE, SAF_R_CMAC_FAILURE); goto end; } } if (!CMAC_Update(hkey->cmac_ctx, pucInData, uiInDataLen)) { SAFerr(SAF_F_SAF_MACUPDATE, SAF_R_CMAC_FAILURE); return SAR_UnknownErr; } ret = SAR_OK; end: if (ret != SAR_OK && hkey->cmac_ctx) { CMAC_CTX_free(hkey->cmac_ctx); hkey->cmac_ctx = NULL; } return ret; }
/* CMAC-AES256: generate hash of known digest value and compare to known precomputed correct hash */ static int FIPS_cmac_aes256_test() { 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, }; unsigned char data[] = "Sample text"; unsigned char kaval[] = { 0xec,0xc2,0xcf,0x63, 0xc7,0xce,0xfc,0xa4, 0xb0,0x86,0x37,0x5f, 0x15,0x60,0xba,0x1f, }; unsigned char *out = NULL; size_t outlen; CMAC_CTX *ctx = CMAC_CTX_new(); int r = 0; ERR_clear_error(); if (!ctx) goto end; if (!CMAC_Init(ctx,key,sizeof(key),EVP_aes_256_cbc(),NULL)) goto end; if (!CMAC_Update(ctx,data,sizeof(data)-1)) goto end; /* This should return 1. If not, there's a programming error... */ if (!CMAC_Final(ctx, out, &outlen)) goto end; out = OPENSSL_malloc(outlen); if (!CMAC_Final(ctx, out, &outlen)) goto end; #if 0 { char *hexout = OPENSSL_malloc(outlen * 2 + 1); bin2hex(out, outlen, hexout); printf("CMAC-AES256: res = %s\n", hexout); OPENSSL_free(hexout); } r = 1; #else if (!memcmp(out,kaval,outlen)) r = 1; #endif end: CMAC_CTX_free(ctx); if (out) OPENSSL_free(out); return r; }
/* CMAC-AES192: generate hash of known digest value and compare to known precomputed correct hash */ static int FIPS_cmac_aes192_test() { unsigned char key[] = { 0x8e,0x73,0xb0,0xf7, 0xda,0x0e,0x64,0x52, 0xc8,0x10,0xf3,0x2b, 0x80,0x90,0x79,0xe5, 0x62,0xf8,0xea,0xd2, 0x52,0x2c,0x6b,0x7b, }; unsigned char data[] = "Sample text"; unsigned char kaval[] = { 0xd6,0x99,0x19,0x25, 0xe5,0x1d,0x95,0x48, 0xb1,0x4a,0x0b,0xf2, 0xc6,0x3c,0x47,0x1f, }; unsigned char *out = NULL; size_t outlen; CMAC_CTX *ctx = CMAC_CTX_new(); int r = 0; ERR_clear_error(); if (!ctx) goto end; if (!CMAC_Init(ctx,key,sizeof(key),EVP_aes_192_cbc(),NULL)) goto end; if (!CMAC_Update(ctx,data,sizeof(data)-1)) goto end; /* This should return 1. If not, there's a programming error... */ if (!CMAC_Final(ctx, out, &outlen)) goto end; out = OPENSSL_malloc(outlen); if (!CMAC_Final(ctx, out, &outlen)) goto end; #if 0 { char *hexout = OPENSSL_malloc(outlen * 2 + 1); bin2hex(out, outlen, hexout); printf("CMAC-AES192: res = %s\n", hexout); OPENSSL_free(hexout); } r = 1; #else if (!memcmp(out,kaval,outlen)) r = 1; #endif end: CMAC_CTX_free(ctx); if (out) OPENSSL_free(out); return r; }
static int pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { CMAC_CTX *cmkey = CMAC_CTX_new(); CMAC_CTX *cmctx = ctx->data; if (!cmkey) return 0; if (!CMAC_CTX_copy(cmkey, cmctx)) { CMAC_CTX_free(cmkey); return 0; } EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmkey); return 1; }
/* CMAC-AES128: generate hash of known digest value and compare to known precomputed correct hash */ static int FIPS_cmac_aes128_test() { unsigned char key[16] = { 0x2b,0x7e,0x15,0x16, 0x28,0xae,0xd2,0xa6, 0xab,0xf7,0x15,0x88, 0x09,0xcf,0x4f,0x3c, }; unsigned char data[] = "Sample text"; unsigned char kaval[EVP_MAX_MD_SIZE] = { 0x16,0x83,0xfe,0xac, 0x52,0x9b,0xae,0x23, 0xd7,0xd5,0x66,0xf5, 0xd2,0x8d,0xbd,0x2a, }; unsigned char *out = NULL; size_t outlen; CMAC_CTX *ctx = CMAC_CTX_new(); int r = 0; ERR_clear_error(); if (!ctx) goto end; if (!CMAC_Init(ctx,key,sizeof(key),EVP_aes_128_cbc(),NULL)) goto end; if (!CMAC_Update(ctx,data,sizeof(data)-1)) goto end; /* This should return 1. If not, there's a programming error... */ if (!CMAC_Final(ctx, out, &outlen)) goto end; out = OPENSSL_malloc(outlen); if (!CMAC_Final(ctx, out, &outlen)) goto end; #if 0 { char *hexout = OPENSSL_malloc(outlen * 2 + 1); bin2hex(out, outlen, hexout); printf("CMAC-AES128: res = %s\n", hexout); OPENSSL_free(hexout); } r = 1; #else if (!memcmp(out,kaval,outlen)) r = 1; #endif end: CMAC_CTX_free(ctx); if (out) OPENSSL_free(out); return r; }
/* CMAC-TDEA3: generate hash of known digest value and compare to known precomputed correct hash */ static int FIPS_cmac_tdea3_test() { unsigned char key[] = { 0x8a,0xa8,0x3b,0xf8, 0xcb,0xda,0x10,0x62, 0x0b,0xc1,0xbf,0x19, 0xfb,0xb6,0xcd,0x58, 0xbc,0x31,0x3d,0x4a, 0x37,0x1c,0xa8,0xb5, }; unsigned char data[] = "Sample text"; unsigned char kaval[EVP_MAX_MD_SIZE] = { 0xb4,0x06,0x4e,0xbf, 0x59,0x89,0xba,0x68, }; unsigned char *out = NULL; size_t outlen; CMAC_CTX *ctx = CMAC_CTX_new(); int r = 0; ERR_clear_error(); if (!ctx) goto end; if (!CMAC_Init(ctx,key,sizeof(key),EVP_des_ede3_cbc(),NULL)) goto end; if (!CMAC_Update(ctx,data,sizeof(data)-1)) goto end; /* This should return 1. If not, there's a programming error... */ if (!CMAC_Final(ctx, out, &outlen)) goto end; out = OPENSSL_malloc(outlen); if (!CMAC_Final(ctx, out, &outlen)) goto end; #if 0 { char *hexout = OPENSSL_malloc(outlen * 2 + 1); bin2hex(out, outlen, hexout); printf("CMAC-TDEA3: res = %s\n", hexout); OPENSSL_free(hexout); } r = 1; #else if (!memcmp(out,kaval,outlen)) r = 1; #endif end: CMAC_CTX_free(ctx); if (out) OPENSSL_free(out); return r; }
int FIPS_selftest_cmac() { size_t n, outlen; unsigned char out[32]; const EVP_CIPHER *cipher; CMAC_CTX *ctx = CMAC_CTX_new(); const CMAC_KAT *t; int rv = 1; for (n = 0, t = vector; n < sizeof(vector) / sizeof(vector[0]); n++, t++) { cipher = FIPS_get_cipherbynid(t->nid); if (!cipher) { rv = -1; goto err; } if (!CMAC_Init(ctx, t->key, t->keysize / 8, cipher, 0)) { rv = -1; goto err; } if (!CMAC_Update(ctx, t->msg, t->msgsize / 8)) { rv = -1; goto err; } if (!CMAC_Final(ctx, out, &outlen)) { rv = -1; goto err; } CMAC_CTX_cleanup(ctx); if (outlen < t->macsize / 8 || memcmp(out, t->mac, t->macsize / 8)) { rv = 0; } } err: CMAC_CTX_free(ctx); if (rv == -1) { rv = 0; } if (!rv) FIPSerr(FIPS_F_FIPS_SELFTEST_CMAC, FIPS_R_SELFTEST_FAILED); return rv; }
static int print_cmac_ver(const EVP_CIPHER *cipher, FILE *out, unsigned char *Key, int Klen, unsigned char *Msg, int Mlen, unsigned char *Mac, int Maclen, int Tlen) { int rc; size_t reslen; unsigned char res[128]; CMAC_CTX *cmac_ctx = CMAC_CTX_new(); CMAC_Init(cmac_ctx, Key, Klen, cipher, 0); CMAC_Update(cmac_ctx, Msg, Mlen); if (!CMAC_Final(cmac_ctx, res, &reslen)) { fputs("Error calculating CMAC\n", stderr); rc = 0; } else if (Tlen > (int)reslen) { fputs("Parameter error, Tlen > CMAC length\n", stderr); rc = 0; } else if (Tlen != Maclen) { fputs("Parameter error, Tlen != resulting Mac length\n", stderr); rc = 0; } else { if (!memcmp(Mac, res, Maclen)) fputs("Result = P\n", out); else fputs("Result = F\n", out); } CMAC_CTX_free(cmac_ctx); return rc; }
static void test_cmac ( const uint8_t * key, unsigned key_length, const uint8_t * message, unsigned length, const uint8_t * expect, unsigned expected_length) { size_t size; uint8_t result[16]; ctx = CMAC_CTX_new (); CMAC_Init (ctx, key, key_length, EVP_aes_128_cbc (), NULL); CMAC_Update (ctx, message, length); CMAC_Final (ctx, result, &size); CMAC_CTX_free (ctx); if (compare_buffer (result, size, expect, expected_length) != 0) { fail ("test_cmac"); } }
/* 7.3.46 */ int SAF_MacFinal( void *hKeyHandle, unsigned char *pucOutData, unsigned int *puiOutDataLen) { int ret = SAR_UnknownErr; SAF_KEY *hkey = (SAF_KEY *)hKeyHandle; size_t outlen = *puiOutDataLen; if (!hKeyHandle || !pucOutData || !puiOutDataLen) { SAFerr(SAF_F_SAF_MACFINAL, ERR_R_PASSED_NULL_PARAMETER); return SAR_IndataErr; } if (*puiOutDataLen < EVP_MAX_MD_SIZE) { SAFerr(SAF_F_SAF_MACFINAL, SAF_R_BUFFER_TOO_SMALL); return SAR_IndataLenErr; } if (!hkey->cmac_ctx) { SAFerr(SAF_F_SAF_MACFINAL, SAF_R_OPERATION_NOT_INITIALIZED); return SAR_UnknownErr; } if (!CMAC_Final(hkey->cmac_ctx, pucOutData, &outlen)) { SAFerr(SAF_F_SAF_MACFINAL, SAF_R_MAC_FAILURE); goto end; } *puiOutDataLen = (unsigned int)outlen; ret = SAR_Ok; end: CMAC_CTX_free(hkey->cmac_ctx); hkey->cmac_ctx = NULL; return ret; }
void KA_CTX_clear_free(KA_CTX *ctx) { if (ctx) { if (ctx->cmac_ctx) /* FIXME: Segfaults if CMAC_Init has not been called */ CMAC_CTX_free(ctx->cmac_ctx); if (ctx->key) EVP_PKEY_free(ctx->key); if (ctx->shared_secret) { OPENSSL_cleanse(ctx->shared_secret->data, ctx->shared_secret->max); BUF_MEM_free(ctx->shared_secret); } if (ctx->k_mac) { OPENSSL_cleanse(ctx->k_mac->data, ctx->k_mac->max); BUF_MEM_free(ctx->k_mac); } if (ctx->k_enc) { OPENSSL_cleanse(ctx->k_enc->data, ctx->k_enc->max); BUF_MEM_free(ctx->k_enc); } free(ctx->iv); OPENSSL_free(ctx); } }
static void cmac_key_free(EVP_PKEY *pkey) { CMAC_CTX *cmctx = EVP_PKEY_get0(pkey); CMAC_CTX_free(cmctx); }
int OTP_generate(const OTP_PARAMS *params, const void *event, size_t eventlen, unsigned int *otp, const unsigned char *key, size_t keylen) { int ret = 0; time_t t = 0; unsigned char *id = NULL; size_t idlen; const EVP_MD *md; const EVP_CIPHER *cipher; EVP_MD_CTX *mdctx = NULL; CMAC_CTX *cmctx = NULL; unsigned char s[EVP_MAX_MD_SIZE]; size_t slen; uint32_t od; int i, n; OPENSSL_assert(sizeof(time_t) == 8); if (!check_params(params)) { OTPerr(OTP_F_OTP_GENERATE, OTP_R_INVALID_PARAMS); return 0; } idlen = sizeof(uint64_t) + eventlen + params->option_size; if (idlen < 16) { idlen = 16; } if (!(id = OPENSSL_malloc(idlen))) { OTPerr(OTP_F_OTP_GENERATE, ERR_R_MALLOC_FAILURE); goto end; } memset(id, 0, idlen); t = time(NULL) + params->offset; t /= params->te; memcpy(id, &t, sizeof(t)); memcpy(id + sizeof(t), event, eventlen); memcpy(id + sizeof(t) + eventlen, params->option, params->option_size); /* FIXME: try to get md and cipher, and check if cipher is ECB */ if (params->type == NID_sm3) { md = EVP_get_digestbynid(params->type); if (!(mdctx = EVP_MD_CTX_new())) { OTPerr(OTP_F_OTP_GENERATE, ERR_R_MALLOC_FAILURE); goto end; } if (!EVP_DigestInit_ex(mdctx, md, NULL)) { OTPerr(OTP_F_OTP_GENERATE, ERR_R_EVP_LIB); goto end; } if (!EVP_DigestUpdate(mdctx, key, keylen)) { OTPerr(OTP_F_OTP_GENERATE, ERR_R_EVP_LIB); goto end; } if (!EVP_DigestUpdate(mdctx, id, idlen)) { OTPerr(OTP_F_OTP_GENERATE, ERR_R_EVP_LIB); goto end; } if (!EVP_DigestFinal_ex(mdctx, s, (unsigned int *)&slen)) { OTPerr(OTP_F_OTP_GENERATE, ERR_R_EVP_LIB); goto end; } } else if (params->type == NID_sms4_ecb) { cipher = EVP_get_cipherbynid(params->type); if (!(cmctx = CMAC_CTX_new())) { OTPerr(OTP_F_OTP_GENERATE, ERR_R_MALLOC_FAILURE); goto end; } if (!CMAC_Init(cmctx, key, keylen, cipher, NULL)) { OTPerr(OTP_F_OTP_GENERATE, OTP_R_CMAC_FAILURE); goto end; } if (!CMAC_Update(cmctx, id, idlen)) { OTPerr(OTP_F_OTP_GENERATE, OTP_R_CMAC_FAILURE); goto end; } if (!CMAC_Final(cmctx, s, &slen)) { OTPerr(OTP_F_OTP_GENERATE, OTP_R_CMAC_FAILURE); goto end; } } else { goto end; } OPENSSL_assert(slen % 4 == 0); od = 0; n = (int)slen; for (i = 0; i < n/4; i++) { od += GETU32(&s[i * 4]); } *otp = od % pow_table[params->otp_digits]; ret = 1; end: OPENSSL_free(id); EVP_MD_CTX_free(mdctx); CMAC_CTX_free(cmctx); return ret; }
int FIPS_selftest_cmac() { size_t n, outlen; unsigned char out[32]; const EVP_CIPHER *cipher; CMAC_CTX *ctx = CMAC_CTX_new(); const CMAC_KAT *t; int subid = -1, rv = 1; for(n=0,t=vector; n<sizeof(vector)/sizeof(vector[0]); n++,t++) { cipher = FIPS_get_cipherbynid(t->nid); if (!cipher) { rv = -1; goto err; } subid = M_EVP_CIPHER_nid(cipher); if (!fips_post_started(FIPS_TEST_CMAC, subid, 0)) continue; if (!CMAC_Init(ctx, t->key, t->keysize/8, cipher, 0)) { rv = -1; goto err; } if (!CMAC_Update(ctx, t->msg, t->msgsize/8)) { rv = -1; goto err; } if (!fips_post_corrupt(FIPS_TEST_CMAC, subid, NULL)) { if (!CMAC_Update(ctx, t->msg, 1)) { rv = -1; goto err; } } if (!CMAC_Final(ctx, out, &outlen)) { rv = -1; goto err; } CMAC_CTX_cleanup(ctx); if(outlen < t->macsize/8 || memcmp(out,t->mac,t->macsize/8)) { fips_post_failed(FIPS_TEST_CMAC, subid, NULL); rv = 0; } else if (!fips_post_success(FIPS_TEST_CMAC, subid, NULL)) { rv = 0; goto err; } } err: CMAC_CTX_free(ctx); if (rv == -1) { fips_post_failed(FIPS_TEST_CMAC, subid, NULL); rv = 0; } if (!rv) FIPSerr(FIPS_F_FIPS_SELFTEST_CMAC,FIPS_R_SELFTEST_FAILED); return rv; }
/*! @brief Create integrity cmac t for a given message. @param[in] stream_cipher Structure containing various variables to setup encoding @param[out] out For EIA2 the output string is 32 bits long */ int nas_stream_encrypt_eia2 ( nas_stream_cipher_t * stream_cipher, uint8_t out[4]) { uint8_t *m = NULL; uint32_t local_count; size_t size = 4; uint8_t data[16]; CMAC_CTX *cmac_ctx = NULL; const EVP_CIPHER *cipher = EVP_aes_128_cbc (); uint32_t zero_bit = 0; uint32_t m_length; int ret; DevAssert (stream_cipher != NULL); DevAssert (stream_cipher->key != NULL); DevAssert (stream_cipher->key_length > 0); DevAssert (out != NULL); memset (data, 0, 16); zero_bit = stream_cipher->blength & 0x7; m_length = stream_cipher->blength >> 3; if (zero_bit > 0) m_length += 1; local_count = hton_int32 (stream_cipher->count); m = calloc (m_length + 8, sizeof (uint8_t)); memcpy (&m[0], &local_count, 4); m[4] = ((stream_cipher->bearer & 0x1F) << 3) | ((stream_cipher->direction & 0x01) << 2); memcpy (&m[8], stream_cipher->message, m_length); #if SECU_DEBUG { int i; printf ("Byte length: %u, Zero bits: %u\nm: ", m_length + 8, zero_bit); for (i = 0; i < m_length + 8; i++) printf ("%02x", m[i]); printf ("\nKey:"); for (i = 0; i < stream_cipher->key_length; i++) printf ("%02x", stream_cipher->key[i]); printf ("\nMessage:"); for (i = 0; i < m_length; i++) printf ("%02x", stream_cipher->message[i]); printf ("\n"); } #endif cmac_ctx = CMAC_CTX_new (); ret = CMAC_Init (cmac_ctx, stream_cipher->key, stream_cipher->key_length, cipher, NULL); ret = CMAC_Update (cmac_ctx, m, m_length + 8); CMAC_Final (cmac_ctx, data, &size); CMAC_CTX_free (cmac_ctx); #if SECU_DEBUG { int i; printf ("out: "); for (i = 0; i < size; i++) printf ("%02x", data[i]); printf ("\n"); } #endif memcpy (out, data, 4); free (m); return 0; }
static void pkey_cmac_cleanup(EVP_PKEY_CTX *ctx) { CMAC_CTX_free(ctx->data); }