3 * implementation of HMAC as described in RFC2104
10 * hmac = hash ( k^opad , hash( k^ipad , msg))
21 typedef sha256_ctx_t hmac_sha256_ctx_t;
23 #ifndef HMAC_SHORTONLY
25 void hmac_sha256_init(hmac_sha256_ctx_t *s, void* key, uint16_t kl){
26 uint8_t buffer[SHA256_BLOCK_BITS/8];
29 memset(buffer, 0, SHA256_BLOCK_BITS/8);
30 if (kl > SHA256_BLOCK_BITS){
31 sha256((void*)buffer, key, kl);
33 memcpy(buffer, key, (kl+7)/8);
36 for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
41 sha256_nextBlock(s, buffer);
42 #if defined SECURE_WIPE_BUFFER
43 memset(buffer, 0, SHA256_BLOCK_BITS/8);
47 void hmac_sha256_final(hmac_sha256_ctx_t *s, void* key, uint16_t kl){
48 uint8_t buffer[SHA256_BLOCK_BITS/8];
52 memset(buffer, 0, SHA256_BLOCK_BITS/8);
53 if (kl > SHA256_BLOCK_BITS){
54 sha256((void*)buffer, key, kl);
56 memcpy(buffer, key, (kl+7)/8);
59 for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
64 sha256_nextBlock(&a, buffer); /* hash key ^ opad */
65 sha256_ctx2hash((void*)buffer, s); /* copy hash(key ^ ipad, msg) to buffer */
66 sha256_lastBlock(&a, buffer, SHA256_HASH_BITS);
67 memcpy(s, &a, sizeof(sha256_ctx_t));
68 #if defined SECURE_WIPE_BUFFER
69 memset(buffer, 0, SHA256_BLOCK_BITS/8);
77 void hmac_sha256_nextBlock()
78 void hmac_sha256_lastBlock()
83 * message length in bits!
85 void hmac_sha256(void* dest, void* key, uint16_t kl, void* msg, uint64_t ml){ /* a one-shot*/
88 uint8_t buffer[SHA256_BLOCK_BITS/8];
90 memset(buffer, 0, SHA256_BLOCK_BITS/8);
92 /* if key is larger than a block we have to hash it*/
93 if (kl > SHA256_BLOCK_BITS){
94 sha256((void*)buffer, key, kl);
96 memcpy(buffer, key, (kl+7)/8);
99 for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
103 sha256_nextBlock(&s, buffer);
104 while (ml >= SHA256_BLOCK_BITS){
105 sha256_nextBlock(&s, msg);
106 msg = (uint8_t*)msg + SHA256_BLOCK_BITS/8;
107 ml -= SHA256_BLOCK_BITS;
109 sha256_lastBlock(&s, msg, ml);
110 /* since buffer still contains key xor ipad we can do ... */
111 for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
112 buffer[i] ^= IPAD ^ OPAD;
114 sha256_ctx2hash(dest, &s); /* save inner hash temporary to dest */
116 sha256_nextBlock(&s, buffer);
117 sha256_lastBlock(&s, dest, SHA256_HASH_BITS);
118 sha256_ctx2hash(dest, &s);