#include <corecrypto/cchmac.h>
#include <corecrypto/ccn.h>
#include <corecrypto/cc_priv.h>
void cchmac_init(const struct ccdigest_info *di, cchmac_ctx_t hc,
size_t key_len, const void *key_data) {
const unsigned char *key = key_data;
size_t byte = 0;
if (key_len <= di->block_size) {
for (;byte < key_len; ++byte) {
cchmac_data(di, hc)[byte] = key[byte] ^ 0x5c;
}
} else {
ccdigest_init(di, cchmac_digest_ctx(di, hc));
ccdigest_update(di, cchmac_digest_ctx(di, hc), key_len, key);
ccdigest_final(di, cchmac_digest_ctx(di, hc), cchmac_data(di, hc));
key_len = di->output_size;
for (;byte < key_len; ++byte) {
cchmac_data(di, hc)[byte] ^= 0x5c;
}
}
if (key_len < di->block_size) {
CC_MEMSET(cchmac_data(di, hc) + key_len, 0x5c, di->block_size - key_len);
}
ccdigest_copy_state(di, cchmac_ostate32(di, hc), di->initial_state);
di->compress(cchmac_ostate(di, hc), 1, cchmac_data(di, hc));
for (byte = 0; byte < di->block_size; ++byte) {
cchmac_data(di, hc)[byte] ^= (0x5c ^ 0x36);
}
ccdigest_copy_state(di, cchmac_istate32(di, hc), di->initial_state);
di->compress(cchmac_istate(di, hc), 1, cchmac_data(di, hc));
cchmac_num(di, hc) = 0;
cchmac_nbits(di, hc) = di->block_size * 8;
}