]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/corecrypto/cchmac/src/cchmac_init.c
8d426e8c824959aee203117e8e1fddfbd0a26f4c
5 * Created on 12/07/2010
7 * Copyright (c) 2010,2011,2015 Apple Inc. All rights reserved.
11 #include <corecrypto/cchmac.h>
12 #include <corecrypto/ccn.h>
13 #include <corecrypto/cc_priv.h>
15 /* The HMAC_<DIG> transform looks like:
16 <DIG> (K XOR opad || <DIG> (K XOR ipad || text))
17 Where K is a n byte key
18 ipad is the byte 0x36 repeated 64 times.
19 opad is the byte 0x5c repeated 64 times.
20 text is the data being protected.
22 void cchmac_init(const struct ccdigest_info
*di
, cchmac_ctx_t hc
,
23 unsigned long key_len
, const void *key_data
) {
24 const unsigned char *key
= key_data
;
26 /* Set cchmac_data(di, hc) to key ^ opad. */
27 unsigned long byte
= 0;
28 if (key_len
<= di
->block_size
) {
29 for (;byte
< key_len
; ++byte
) {
30 cchmac_data(di
, hc
)[byte
] = key
[byte
] ^ 0x5c;
33 /* Key is longer than di->block size, reset it to key=digest(key) */
34 ccdigest_init(di
, cchmac_digest_ctx(di
, hc
));
35 ccdigest_update(di
, cchmac_digest_ctx(di
, hc
), key_len
, key
);
36 ccdigest_final(di
, cchmac_digest_ctx(di
, hc
), cchmac_data(di
, hc
));
37 key_len
= di
->output_size
;
38 for (;byte
< key_len
; ++byte
) {
39 cchmac_data(di
, hc
)[byte
] ^= 0x5c;
42 /* Fill remainder of cchmac_data(di, hc) with opad. */
43 if (key_len
< di
->block_size
) {
44 CC_MEMSET(cchmac_data(di
, hc
) + key_len
, 0x5c, di
->block_size
- key_len
);
47 /* Set cchmac_ostate32(di, hc) to the state of the first round of the
49 ccdigest_copy_state(di
, cchmac_ostate32(di
, hc
), di
->initial_state
);
50 di
->compress(cchmac_ostate(di
, hc
), 1, cchmac_data(di
, hc
));
52 /* Set cchmac_data(di, hc) to key ^ ipad. */
53 for (byte
= 0; byte
< di
->block_size
; ++byte
) {
54 cchmac_data(di
, hc
)[byte
] ^= (0x5c ^ 0x36);
56 ccdigest_copy_state(di
, cchmac_istate32(di
, hc
), di
->initial_state
);
57 di
->compress(cchmac_istate(di
, hc
), 1, cchmac_data(di
, hc
));
58 cchmac_num(di
, hc
) = 0;
59 cchmac_nbits(di
, hc
) = di
->block_size
* 8;