1/* 2 * cchmac_init.c 3 * corecrypto 4 * 5 * Created by Michael Brouwer on 12/7/10. 6 * Copyright 2010,2011 Apple Inc. All rights reserved. 7 * 8 */ 9 10#include <corecrypto/cchmac.h> 11#include <corecrypto/ccn.h> 12#include <pexpert/pexpert.h> 13 14/* The HMAC_<DIG> transform looks like: 15 <DIG> (K XOR opad || <DIG> (K XOR ipad || text)) 16 Where K is a n byte key 17 ipad is the byte 0x36 repeated 64 times. 18 opad is the byte 0x5c repeated 64 times. 19 text is the data being protected. 20 */ 21void cchmac_init(const struct ccdigest_info *di, cchmac_ctx_t hc, 22 unsigned long key_len, const void *key_data) { 23 const unsigned char *key = key_data; 24 25 /* Set cchmac_data(di, hc) to key ^ opad. */ 26 unsigned long byte = 0; 27 if (key_len <= di->block_size) { 28 for (;byte < key_len; ++byte) { 29 cchmac_data(di, hc)[byte] = key[byte] ^ 0x5c; 30 } 31 } else { 32 /* Key is longer than di->block size, reset it to key=digest(key) */ 33 ccdigest_init(di, cchmac_digest_ctx(di, hc)); 34 ccdigest_update(di, cchmac_digest_ctx(di, hc), key_len, key); 35 ccdigest_final(di, cchmac_digest_ctx(di, hc), cchmac_data(di, hc)); 36 key_len = di->output_size; 37 for (;byte < key_len; ++byte) { 38 cchmac_data(di, hc)[byte] ^= 0x5c; 39 } 40 } 41 /* Fill remainder of cchmac_data(di, hc) with opad. */ 42 if (key_len < di->block_size) { 43 CC_MEMSET(cchmac_data(di, hc) + key_len, 0x5c, di->block_size - key_len); 44 } 45 46 /* Set cchmac_ostate32(di, hc) to the state of the first round of the 47 outer digest. */ 48 ccdigest_copy_state(di, cchmac_ostate32(di, hc), di->initial_state); 49 di->compress(cchmac_ostate(di, hc), 1, cchmac_data(di, hc)); 50 51 /* Set cchmac_data(di, hc) to key ^ ipad. */ 52 for (byte = 0; byte < di->block_size; ++byte) { 53 cchmac_data(di, hc)[byte] ^= (0x5c ^ 0x36); 54 } 55 ccdigest_copy_state(di, cchmac_istate32(di, hc), di->initial_state); 56 di->compress(cchmac_istate(di, hc), 1, cchmac_data(di, hc)); 57 cchmac_num(di, hc) = 0; 58 cchmac_nbits(di, hc) = di->block_size * 8; 59} 60