static int cmac_test_generic(DrewLoader *ldr, const char *name, const struct test *testdata, size_t ntests, size_t outputsz) { int result = 0; drew_mac_t c; uint8_t buf[BUFFER_SIZE]; drew_param_t param; drew_block_t block; int id; if ((id = drew_loader_lookup_by_name(ldr, name, 0, -1)) < 0) return id; drew_loader_get_functbl(ldr, id, (const void **)&block.functbl); block.functbl->init(&block, 0, ldr, NULL); param.name = "cipher"; param.next = NULL; param.param.value = █ for (size_t i = 0; i < ntests; i++) { const struct test *t = testdata + i; int retval; memset(buf, 0, sizeof(buf)); result <<= 1; if ((retval = cmac_init(&c, 0, ldr, ¶m))) return retval; cmac_setkey(&c, t->key, t->keysz); for (size_t j = 0; j < t->datarep; j++) for (size_t k = 0; k < t->datasz; k += 9) cmac_update(&c, t->data+k, MIN(9, t->datasz-k)); cmac_final(&c, buf, 0); result |= !!memcmp(buf, t->output, outputsz); cmac_fini(&c, 0); } block.functbl->fini(&block, 0); return result; }
/*FUNCTION********************************************************************** * * Function Name : LTC_DRV_hash_update * Description : Add data to current CMAC. * * This can be called repeatedly with an arbitrary amount of data to be * hashed. * * ctx Input CMAC context * input Input data * inputSize Size of input data in bytes. * *END**************************************************************************/ ltc_status_t LTC_DRV_hash_update(ltc_drv_hash_ctx *ctx, const uint8_t *input, uint32_t inputSize) { bool update_state; ltc_hal_mode_t mode_reg; /* read and write LTC mode register */ uint32_t instance; ltc_status_t status; if ((NULL == ctx) || (NULL == input)) { return kStatus_LTC_InvalidInput; } if ((ctx->algo != kLtcXcbcMac) && (ctx->algo != kLtcCMAC)) { return kStatus_LTC_InvalidInput; } instance = ctx->instance; if(!ltc_drv_check_instance(instance)) { return kStatus_LTC_InvalidInput; } update_state = ctx->state == kLtcHashUpdate; ltc_drv_lock(instance); if (ctx->state == kLtcHashInit) { /* set LTC mode register to INITIALIZE job */ cmac_init(ctx); ctx->state = kLtcHashUpdate; update_state = true; mode_reg = LTC_HAL_ReadMode(g_ltcBase[instance]); LTC_HAL_SetDataSize(g_ltcBase[instance], 0); ltc_drv_wait(instance); } else if (update_state) { /* restore LTC context from context struct */ cmac_restore_context(ctx); } if (update_state) { /* set LTC mode register to UPDATE job */ cmac_prepare_context_switch(instance); mode_reg = 0u; LTC_HAL_ClearWritten(g_ltcBase[instance],kLTCClear_DataSize); LTC_HAL_ModeSetAlgorithm(&mode_reg, kLTCAlgorithm_AES); LTC_HAL_ModeSetAlgorithmState(&mode_reg, kLTCMode_AS_Update); LTC_HAL_ModeSetSymmetricAlg(&mode_reg, (ltc_hal_mode_symmetric_alg_t)ctx->algo); /* Write the mode register to the hardware. */ LTC_HAL_WriteMode(g_ltcBase[instance], mode_reg); cmac_process_input_data(ctx, input, inputSize, mode_reg); /* save LTC context to context struct */ cmac_save_context(ctx); } status = ltc_drv_return_status(instance); ltc_drv_clear_all(instance, false); ltc_drv_unlock(instance); return status; }
int cmack_init(drew_kdf_t *ctx, int flags, DrewLoader *ldr, const drew_param_t *param) { return cmac_init(MAC(ctx), flags, ldr, param); }
int gen_vectors(char *in_file_name, char *out_file_name) { uint64_t vec_no; int err = 0; std::fstream in_file, out_file; std::string line; cmac_ctx ctx[1]; test_def v; /* open template input file */ in_file.open(in_file_name, std::ios_base::in); if(!in_file) goto exit3; /* open test vector output file */ out_file.open(out_file_name, std::ios_base::out | std::ios_base::trunc); if(!out_file) goto exit2; while(!in_file.eof()) { do /* look for start line 'MODE XXX' */ { std::getline(in_file, line); } while (!in_file.eof() && strncmp((char*)line.c_str(), "MODE", 4) != 0); if (in_file.eof()) break; if (strncmp(line.c_str() + 5, "CMAC", 3)) continue; /* output mode header 'MDE XXX' */ out_file << std::endl << "MDE " << line.c_str() + 5; /* output date and time */ time_t secs; struct tm now; char buf[32]; time(&secs); localtime_s(&now, &secs); asctime_s(buf, 32, &now); out_file << std::endl << "REM Produced by GENTEST on " << buf; /* output line designator summary */ out_file << rem; while(!in_file.eof()) { if(!input_test_def(in_file, v, &vec_no)) break; do { size_t key_len, msg_len; unsigned char * const key = v["KEY"].get_value(&key_len); unsigned char * const msg = v["MSG"].get_value(&msg_len); unsigned char tag[AES_BLOCK_SIZE]; cmac_init( key, key_len, ctx); cmac_data( msg, msg_len, ctx); cmac_end(tag, ctx); v["TAG"].set_binary(tag, AES_BLOCK_SIZE); v.vector_out(out_file, vec_no); ++vec_no; } while(v.next()); } } out_file << std::endl << "END" << std::endl; exit1: out_file.close(); exit2: in_file.close(); exit3: return err; }