]> git.cryptolib.org Git - avr-crypto-lib.git/blob - hmac-sha256.c
new, derived from old avr/crypto + cast5
[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 "sha256.h"
16
17 #define IPAD 0x36
18 #define OPAD 0x5C
19
20 typedef sha256_ctx_t hmac_sha256_ctx_t;
21
22 void hmac_sha256_init(hmac_sha256_ctx_t *s, void* key, uint16_t kl){
23         uint8_t buffer[SHA256_BLOCK_BITS/8];
24         uint8_t i;
25         
26         if (kl > SHA256_BLOCK_BITS){
27                 sha256((void*)buffer, key, kl);
28         } else {
29                 memcpy(buffer, key, kl/8 + (kl & 0x7)?1:0);
30         }
31         
32         for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
33                 buffer[i] ^= IPAD;
34         }
35         
36         sha256_init(s);
37         sha256_nextBlock(s, buffer);
38 #if defined SECURE_WIPE_BUFFER
39         memset(buffer, 0, SHA256_BLOCK_BITS/8);
40 #endif
41 }
42
43 void hmac_sha256_final(hmac_sha256_ctx_t *s, void* key, uint16_t kl){
44         uint8_t buffer[SHA256_BLOCK_BITS/8];
45         uint8_t i;
46         sha256_ctx_t a;
47         
48         if (kl > SHA256_BLOCK_BITS){
49                 sha256((void*)buffer, key, kl);
50         } else {
51                 memcpy(buffer, key, kl/8 + (kl & 0x7)?1:0);
52         }
53         
54         for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
55                 buffer[i] ^= OPAD;
56         }
57         
58         sha256_init(&a);
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);
64         memset(a.h, 0, 8*4);
65 #endif  
66 }
67
68 /*
69 void hmac_sha256_nextBlock()
70 void hmac_sha256_lastBlock()
71 */
72
73 /*
74  * keylength in bits!
75  * message length in bits!
76  */
77 void hmac_sha256(void* dest, void* key, uint16_t kl, void* msg, uint64_t ml){ /* a one-shot*/
78         sha256_ctx_t s;
79         uint8_t i;
80         uint8_t buffer[SHA256_BLOCK_BITS/8];
81         
82         /* if key is larger than a block we have to hash it*/
83         if (kl > SHA256_BLOCK_BITS){
84                 sha256((void*)buffer, key, kl);
85         } else {
86                 memcpy(buffer, key, kl/8 + (kl & 0x7)?1:0);
87         }
88         
89         for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
90                 buffer[i] ^= IPAD;
91         }
92         sha256_init(&s);
93         sha256_nextBlock(&s, buffer);
94         while (ml >= SHA256_BLOCK_BITS){
95                 sha256_nextBlock(&s, msg);
96                 msg += SHA256_BLOCK_BITS/8;
97                 ml -=  SHA256_BLOCK_BITS;
98         }
99         sha256_lastBlock(&s, msg, ml);
100         /* since buffer still contains key xor ipad we can do ... */
101         for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
102                 buffer[i] ^= IPAD ^ OPAD;
103         }
104         sha265_ctx2hash(dest, &s); /* save inner hash temporary to dest */
105         sha256_init(&s);
106         sha256_nextBlock(&s, buffer);
107         sha256_lastBlock(&s, dest, SHA256_HASH_BITS);
108         sha265_ctx2hash(dest, &s);
109 }