]> begriffs open source - freertos/blob - FreeRTOS-Plus/CyaSSL/ctaocrypt/src/hmac.c
Prepare for V7.2.0 release.
[freertos] / FreeRTOS-Plus / CyaSSL / ctaocrypt / src / hmac.c
1 /* hmac.c
2  *
3  * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
4  *
5  * This file is part of CyaSSL.
6  *
7  * CyaSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * CyaSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24 #endif
25
26 #ifndef NO_HMAC
27
28 #include <cyassl/ctaocrypt/hmac.h>
29 #include <cyassl/ctaocrypt/error.h>
30
31
32 static int InitHmac(Hmac* hmac, int type)
33 {
34     hmac->innerHashKeyed = 0;
35     hmac->macType = (byte)type;
36
37     if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384))
38         return BAD_FUNC_ARG;
39
40     if (type == MD5)
41         InitMd5(&hmac->hash.md5);
42     else if (type == SHA)
43         InitSha(&hmac->hash.sha);
44 #ifndef NO_SHA256
45     else if (type == SHA256)
46         InitSha256(&hmac->hash.sha256);
47 #endif
48 #ifdef CYASSL_SHA384
49     else if (type == SHA384)
50         InitSha384(&hmac->hash.sha384);
51 #endif
52
53     return 0;
54 }
55
56
57 void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
58 {
59     byte*  ip = (byte*) hmac->ipad;
60     byte*  op = (byte*) hmac->opad;
61     word32 i, hmac_block_size = MD5_BLOCK_SIZE;
62
63     InitHmac(hmac, type);
64
65     if (hmac->macType == MD5) {
66         if (length <= MD5_BLOCK_SIZE) {
67             XMEMCPY(ip, key, length);
68         }
69         else {
70             Md5Update(&hmac->hash.md5, key, length);
71             Md5Final(&hmac->hash.md5, ip);
72             length = MD5_DIGEST_SIZE;
73         }
74     }
75     else if (hmac->macType == SHA) {
76                 hmac_block_size = SHA_BLOCK_SIZE;
77         if (length <= SHA_BLOCK_SIZE) {
78             XMEMCPY(ip, key, length);
79         }
80         else {
81             ShaUpdate(&hmac->hash.sha, key, length);
82             ShaFinal(&hmac->hash.sha, ip);
83             length = SHA_DIGEST_SIZE;
84         }
85     }
86 #ifndef NO_SHA256
87     else if (hmac->macType == SHA256) {
88                 hmac_block_size = SHA256_BLOCK_SIZE;
89         if (length <= SHA256_BLOCK_SIZE) {
90             XMEMCPY(ip, key, length);
91         }
92         else {
93             Sha256Update(&hmac->hash.sha256, key, length);
94             Sha256Final(&hmac->hash.sha256, ip);
95             length = SHA256_DIGEST_SIZE;
96         }
97     }
98 #endif
99 #ifdef CYASSL_SHA384
100     else if (hmac->macType == SHA384) {
101         hmac_block_size = SHA384_BLOCK_SIZE;
102         if (length <= SHA384_BLOCK_SIZE) {
103             XMEMCPY(ip, key, length);
104         }
105         else {
106             Sha384Update(&hmac->hash.sha384, key, length);
107             Sha384Final(&hmac->hash.sha384, ip);
108             length = SHA384_DIGEST_SIZE;
109         }
110     }
111 #endif
112     XMEMSET(ip + length, 0, hmac_block_size - length);
113
114     for(i = 0; i < hmac_block_size; i++) {
115         op[i] = ip[i] ^ OPAD;
116         ip[i] ^= IPAD;
117     }
118 }
119
120
121 static void HmacKeyInnerHash(Hmac* hmac)
122 {
123     if (hmac->macType == MD5)
124         Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, MD5_BLOCK_SIZE);
125     else if (hmac->macType == SHA)
126         ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, SHA_BLOCK_SIZE);
127 #ifndef NO_SHA256
128     else if (hmac->macType == SHA256)
129         Sha256Update(&hmac->hash.sha256, (byte*) hmac->ipad, SHA256_BLOCK_SIZE);
130 #endif
131 #ifdef CYASSL_SHA384
132     else if (hmac->macType == SHA384)
133         Sha384Update(&hmac->hash.sha384, (byte*) hmac->ipad, SHA384_BLOCK_SIZE);
134 #endif
135
136     hmac->innerHashKeyed = 1;
137 }
138
139
140 void HmacUpdate(Hmac* hmac, const byte* msg, word32 length)
141 {
142     if (!hmac->innerHashKeyed)
143         HmacKeyInnerHash(hmac);
144
145     if (hmac->macType == MD5)
146         Md5Update(&hmac->hash.md5, msg, length);
147     else if (hmac->macType == SHA)
148         ShaUpdate(&hmac->hash.sha, msg, length);
149 #ifndef NO_SHA256
150     else if (hmac->macType == SHA256)
151         Sha256Update(&hmac->hash.sha256, msg, length);
152 #endif
153 #ifdef CYASSL_SHA384
154     else if (hmac->macType == SHA384)
155         Sha384Update(&hmac->hash.sha384, msg, length);
156 #endif
157
158 }
159
160
161 void HmacFinal(Hmac* hmac, byte* hash)
162 {
163     if (!hmac->innerHashKeyed)
164         HmacKeyInnerHash(hmac);
165
166     if (hmac->macType == MD5) {
167         Md5Final(&hmac->hash.md5, (byte*) hmac->innerHash);
168
169         Md5Update(&hmac->hash.md5, (byte*) hmac->opad, MD5_BLOCK_SIZE);
170         Md5Update(&hmac->hash.md5, (byte*) hmac->innerHash, MD5_DIGEST_SIZE);
171
172         Md5Final(&hmac->hash.md5, hash);
173     }
174     else if (hmac->macType == SHA) {
175         ShaFinal(&hmac->hash.sha, (byte*) hmac->innerHash);
176
177         ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, SHA_BLOCK_SIZE);
178         ShaUpdate(&hmac->hash.sha, (byte*) hmac->innerHash, SHA_DIGEST_SIZE);
179
180         ShaFinal(&hmac->hash.sha, hash);
181     }
182 #ifndef NO_SHA256
183     else if (hmac->macType == SHA256) {
184         Sha256Final(&hmac->hash.sha256, (byte*) hmac->innerHash);
185
186         Sha256Update(&hmac->hash.sha256, (byte*) hmac->opad, SHA256_BLOCK_SIZE);
187         Sha256Update(&hmac->hash.sha256, (byte*) hmac->innerHash,
188                      SHA256_DIGEST_SIZE);
189
190         Sha256Final(&hmac->hash.sha256, hash);
191     }
192 #endif
193 #ifdef CYASSL_SHA384
194     else if (hmac->macType == SHA384) {
195         Sha384Final(&hmac->hash.sha384, (byte*) hmac->innerHash);
196
197         Sha384Update(&hmac->hash.sha384, (byte*) hmac->opad, SHA384_BLOCK_SIZE);
198         Sha384Update(&hmac->hash.sha384, (byte*) hmac->innerHash,
199                      SHA384_DIGEST_SIZE);
200
201         Sha384Final(&hmac->hash.sha384, hash);
202     }
203 #endif
204
205     hmac->innerHashKeyed = 0;
206 }
207
208
209 #endif /* NO_HMAC */
210