]> git.cryptolib.org Git - avr-crypto-lib.git/blob - hmac-sha256.c
4e23f8e5de18d62d81be3b5f66d7b85ef3683c13
[avr-crypto-lib.git] / hmac-sha256.c
1 /**
2  * 
3  * implementation of HMAC as described in RFC2104
4  * Author:      Daniel Otte
5  * 
6  * License:     GPL
7  **/
8
9 /* 
10  * hmac = hash ( k^opad , hash( k^ipad  , msg))
11  */
12
13 #include <stdint.h>
14 #include <string.h>
15 #include "config.h"
16 #include "sha256.h"
17
18 #define IPAD 0x36
19 #define OPAD 0x5C
20
21 typedef sha256_ctx_t hmac_sha256_ctx_t;
22
23 #ifndef HMAC_SHORTONLY
24
25 void hmac_sha256_init(hmac_sha256_ctx_t *s, void* key, uint16_t kl){
26         uint8_t buffer[SHA256_BLOCK_BITS/8];
27         uint8_t i;
28         
29         memset(buffer, 0, SHA256_BLOCK_BITS/8);
30         if (kl > SHA256_BLOCK_BITS){
31                 sha256((void*)buffer, key, kl);
32         } else {
33                 memcpy(buffer, key, (kl+7)/8);
34         }
35         
36         for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
37                 buffer[i] ^= IPAD;
38         }
39         
40         sha256_init(s);
41         sha256_nextBlock(s, buffer);
42 #if defined SECURE_WIPE_BUFFER
43         memset(buffer, 0, SHA256_BLOCK_BITS/8);
44 #endif
45 }
46
47 void hmac_sha256_final(hmac_sha256_ctx_t *s, void* key, uint16_t kl){
48         uint8_t buffer[SHA256_BLOCK_BITS/8];
49         uint8_t i;
50         sha256_ctx_t a;
51         
52         memset(buffer, 0, SHA256_BLOCK_BITS/8);
53         if (kl > SHA256_BLOCK_BITS){
54                 sha256((void*)buffer, key, kl);
55         } else {
56                 memcpy(buffer, key, (kl+7)/8);
57         }
58         
59         for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
60                 buffer[i] ^= OPAD;
61         }
62         
63         sha256_init(&a);
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);
70         memset(a.h, 0, 8*4);
71 #endif  
72 }
73
74 #endif
75
76 /*
77 void hmac_sha256_nextBlock()
78 void hmac_sha256_lastBlock()
79 */
80
81 /*
82  * keylength in bits!
83  * message length in bits!
84  */
85 void hmac_sha256(void* dest, void* key, uint16_t kl, void* msg, uint64_t ml){ /* a one-shot*/
86         sha256_ctx_t s;
87         uint8_t i;
88         uint8_t buffer[SHA256_BLOCK_BITS/8];
89         
90         memset(buffer, 0, SHA256_BLOCK_BITS/8);
91         
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);
95         } else {
96                 memcpy(buffer, key, (kl+7)/8);
97         }
98         
99         for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
100                 buffer[i] ^= IPAD;
101         }
102         sha256_init(&s);
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;
108         }
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;
113         }
114         sha256_ctx2hash(dest, &s); /* save inner hash temporary to dest */
115         sha256_init(&s);
116         sha256_nextBlock(&s, buffer);
117         sha256_lastBlock(&s, dest, SHA256_HASH_BITS);
118         sha256_ctx2hash(dest, &s);
119 }