1 /*
2 * Copyright (C) 2012 Martin Storsjo
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <string.h>
22
29
30 #define MAX_HASHLEN 64
31 #define MAX_BLOCKLEN 128
32
41 };
42
43 #define DEFINE_SHA(bits) \
44 static av_cold void sha ## bits ##_init(void *ctx) \
45 { \
46 av_sha_init(ctx, bits); \
47 }
48
49 #define DEFINE_SHA512(bits) \
50 static av_cold void sha ## bits ##_init(void *ctx) \
51 { \
52 av_sha512_init(ctx, bits); \
53 }
54
60
62 {
64 if (!c)
65 return NULL;
66 switch (type) {
74 break;
78 c->
init = sha160_init;
82 break;
86 c->
init = sha224_init;
90 break;
94 c->
init = sha256_init;
98 break;
102 c->
init = sha384_init;
106 break;
110 c->
init = sha512_init;
114 break;
115 default:
117 return NULL;
118 }
121 return NULL;
122 }
124 }
125
127 {
128 if (!c)
129 return;
132 }
133
135 {
136 int i;
143 } else {
144 memcpy(c->
key, key, keylen);
146 }
148 for (i = 0; i < c->
keylen; i++)
149 block[i] = c->
key[i] ^ 0x36;
150 for (i = c->
keylen; i < c->blocklen; i++)
151 block[i] = 0x36;
153 }
154
156 {
158 }
159
161 {
163 int i;
164 if (outlen < c->hashlen)
168 for (i = 0; i < c->
keylen; i++)
169 block[i] = c->
key[i] ^ 0x5C;
170 for (i = c->
keylen; i < c->blocklen; i++)
171 block[i] = 0x5C;
176 }
177
179 const uint8_t *key,
unsigned int keylen,
181 {
185 }
186
187 #ifdef TEST
188 #include <stdio.h>
189
192 {
195 // Some of the test vectors are strings, where sizeof() includes the
196 // trailing null byte - remove that.
197 if (!key[keylen - 1])
198 keylen--;
199 if (!data[datalen - 1])
200 datalen--;
201 out =
av_hmac_calc(hmac, data, datalen, key, keylen, buf,
sizeof(buf));
202 for (i = 0; i <
out; i++)
203 printf("%02x", buf[i]);
204 printf("\n");
205 }
206
208 {
209 uint8_t key1[20], key3[131], data3[50];
211 static const uint8_t key2[] =
"Jefe";
212 static const uint8_t data1[] =
"Hi There";
213 static const uint8_t data2[] =
"what do ya want for nothing?";
214 static const uint8_t data4[] =
"Test Using Larger Than Block-Size Key - Hash Key First";
215 static const uint8_t data5[] =
"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data";
216 static const uint8_t data6[] =
"This is a test using a larger than block-size key and a larger "
217 "than block-size data. The key needs to be hashed before being used"
218 " by the HMAC algorithm.";
220 if (!hmac)
221 return 1;
222 memset(key1, 0x0b, sizeof(key1));
223 memset(key3, 0xaa, sizeof(key3));
224 memset(data3, 0xdd, sizeof(data3));
225 // RFC 2202 test vectors
226 test(hmac, key1, 16, data1,
sizeof(data1));
227 test(hmac, key2,
sizeof(key2), data2,
sizeof(data2));
228 test(hmac, key3, 16, data3,
sizeof(data3));
229 test(hmac, key3, 80, data4,
sizeof(data4));
230 test(hmac, key3, 80, data5,
sizeof(data5));
232
233 /* SHA-1 */
235 if (!hmac)
236 return 1;
237 // RFC 2202 test vectors
238 test(hmac, key1,
sizeof(key1), data1,
sizeof(data1));
239 test(hmac, key2,
sizeof(key2), data2,
sizeof(data2));
240 test(hmac, key3, 20, data3,
sizeof(data3));
241 test(hmac, key3, 80, data4,
sizeof(data4));
242 test(hmac, key3, 80, data5,
sizeof(data5));
244
245 /* SHA-2 */
248 // RFC 4231 test vectors
249 test(hmac, key1,
sizeof(key1), data1,
sizeof(data1));
250 test(hmac, key2,
sizeof(key2), data2,
sizeof(data2));
251 test(hmac, key3, 20, data3,
sizeof(data3));
252 test(hmac, key3,
sizeof(key3), data4,
sizeof(data4));
253 test(hmac, key3,
sizeof(key3), data6,
sizeof(data6));
255 i++;
256 }
257 return 0;
258 }
259 #endif /* TEST */