3 * implementation of HMAC as described in RFC2104
10 * hmac = hash ( k^opad , hash( k^ipad , msg))
20 typedef sha256_ctx_t hmac_sha256_ctx_t;
22 void hmac_sha256_init(hmac_sha256_ctx_t *s, void* key, uint16_t kl){
23 uint8_t buffer[SHA256_BLOCK_BITS/8];
26 if (kl > SHA256_BLOCK_BITS){
27 sha256((void*)buffer, key, kl);
29 memcpy(buffer, key, kl/8 + (kl & 0x7)?1:0);
32 for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
37 sha256_nextBlock(s, buffer);
38 #if defined SECURE_WIPE_BUFFER
39 memset(buffer, 0, SHA256_BLOCK_BITS/8);
43 void hmac_sha256_final(hmac_sha256_ctx_t *s, void* key, uint16_t kl){
44 uint8_t buffer[SHA256_BLOCK_BITS/8];
48 if (kl > SHA256_BLOCK_BITS){
49 sha256((void*)buffer, key, kl);
51 memcpy(buffer, key, kl/8 + (kl & 0x7)?1:0);
54 for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
59 sha256_nextBlock(&a, buffer); /* hash key ^ opad */
60 sha256_ctx2hash((void*)buffer, s); /* copy hash(key ^ ipad, msg) to buffer */
61 sha256_lastBlock(s, buffer, SHA256_HASH_BITS);
62 #if defined SECURE_WIPE_BUFFER
63 memset(buffer, 0, SHA256_BLOCK_BITS/8);
69 void hmac_sha256_nextBlock()
70 void hmac_sha256_lastBlock()
75 * message length in bits!
77 void hmac_sha256(void* dest, void* key, uint16_t kl, void* msg, uint64_t ml){ /* a one-shot*/
80 uint8_t buffer[SHA256_BLOCK_BITS/8];
82 memset(buffer, 0, SHA256_BLOCK_BITS/8);
84 /* if key is larger than a block we have to hash it*/
85 if (kl > SHA256_BLOCK_BITS){
86 sha256((void*)buffer, key, kl);
88 memcpy(buffer, key, kl/8 + (kl & 0x7)?1:0);
91 for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
95 sha256_nextBlock(&s, buffer);
96 while (ml >= SHA256_BLOCK_BITS){
97 sha256_nextBlock(&s, msg);
98 msg = (uint8_t*)msg + SHA256_BLOCK_BITS/8;
99 ml -= SHA256_BLOCK_BITS;
101 sha256_lastBlock(&s, msg, ml);
102 /* since buffer still contains key xor ipad we can do ... */
103 for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
104 buffer[i] ^= IPAD ^ OPAD;
106 sha256_ctx2hash(dest, &s); /* save inner hash temporary to dest */
108 sha256_nextBlock(&s, buffer);
109 sha256_lastBlock(&s, dest, SHA256_HASH_BITS);
110 sha256_ctx2hash(dest, &s);