1 /* MIT (BSD) license - see LICENSE file for details */
2 #include <ccan/crypto/hmac_sha256/hmac_sha256.h>
5 #define IPAD 0x3636363636363636ULL
6 #define OPAD 0x5C5C5C5C5C5C5C5CULL
8 #define BLOCK_U64S (64 / sizeof(uint64_t))
10 static inline void xor_block(uint64_t block[BLOCK_U64S], uint64_t pad)
14 for (i = 0; i < BLOCK_U64S; i++)
19 void hmac_sha256(struct hmac_sha256 *hmac,
20 const void *k, size_t ksize,
21 const void *d, size_t dsize)
23 struct sha256_ctx shactx;
24 uint64_t block[BLOCK_U64S];
25 struct sha256 hash, hashed_key;
27 /* (keys longer than B bytes are first hashed using H) */
28 if (ksize > sizeof(block)) {
29 sha256(&hashed_key, k, ksize);
31 ksize = sizeof(hashed_key);
36 * (1) append zeros to the end of K to create a B byte string
37 * (e.g., if K is of length 20 bytes and B=64, then K will be
38 * appended with 44 zero bytes 0x00)
40 memcpy(block, k, ksize);
41 memset((char *)block + ksize, 0, sizeof(block) - ksize);
44 * (2) XOR (bitwise exclusive-OR) the B byte string computed
45 * in step (1) with ipad
47 xor_block(block, IPAD);
50 * (3) append the stream of data 'text' to the B byte string resulting
52 * (4) apply H to the stream generated in step (3)
55 sha256_update(&shactx, block, sizeof(block));
56 sha256_update(&shactx, d, dsize);
57 sha256_done(&shactx, &hash);
60 * (5) XOR (bitwise exclusive-OR) the B byte string computed in
63 xor_block(block, IPAD^OPAD);
66 * (6) append the H result from step (4) to the B byte string
67 * resulting from step (5)
68 * (7) apply H to the stream generated in step (6) and output
72 sha256_update(&shactx, block, sizeof(block));
73 sha256_update(&shactx, &hash, sizeof(hash));
74 sha256_done(&shactx, &hmac->sha);
77 /* Direct mapping from MD5 example in RFC2104 */
78 void hmac_sha256(struct hmac_sha256 *hmac,
79 const void *key, size_t key_len,
80 const void *text, size_t text_len)
82 struct sha256_ctx context;
83 unsigned char k_ipad[65]; /* inner padding -
86 unsigned char k_opad[65]; /* outer padding -
88 *//* start out by storing key in pads */
92 /* if key is longer than 64 bytes reset it to key=MD5(key) */
95 struct sha256_ctx tctx;
98 sha256_update(&tctx, key, key_len);
99 sha256_done(&tctx, tk);
104 bzero( k_ipad, sizeof k_ipad);
105 bzero( k_opad, sizeof k_opad);
106 bcopy( key, k_ipad, key_len);
107 bcopy( key, k_opad, key_len);
109 /* XOR key with ipad and opad values */
110 for (i=0; i<64; i++) {
117 sha256_init(&context); /* init context for 1st
119 sha256_update(&context, k_ipad, 64); /* start with inner pad */
120 sha256_update(&context, text, text_len); /* then text of datagram */
121 sha256_done(&context, &hmac->sha); /* finish up 1st pass */
125 sha256_init(&context); /* init context for 2nd
127 sha256_update(&context, k_opad, 64); /* start with outer pad */
128 sha256_update(&context, &hmac->sha, 32); /* then results of 1st
130 sha256_done(&context, &hmac->sha); /* finish up 2nd pass */