2 * Copyright (C) 2012 Martin Storsjo
4 * This file is part of Libav.
6 * Libav 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.
11 * Libav 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.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with Libav; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "attributes.h"
29 #define MAX_HASHLEN 32
30 #define MAX_BLOCKLEN 64
34 int blocklen
, hashlen
;
35 void (*final
)(void*, uint8_t*);
36 void (*update
)(void*, const uint8_t*, int len
);
38 uint8_t key
[MAX_BLOCKLEN
];
42 #define DEFINE_SHA(bits) \
43 static av_cold void sha ## bits ##_init(void *ctx) \
45 av_sha_init(ctx, bits); \
52 AVHMAC
*av_hmac_alloc(enum AVHMACType type
)
54 AVHMAC
*c
= av_mallocz(sizeof(*c
));
61 c
->init
= av_md5_init
;
62 c
->update
= av_md5_update
;
63 c
->final
= av_md5_final
;
64 c
->hash
= av_md5_alloc();
69 c
->init
= sha160_init
;
70 c
->update
= av_sha_update
;
71 c
->final
= av_sha_final
;
72 c
->hash
= av_sha_alloc();
77 c
->init
= sha224_init
;
78 c
->update
= av_sha_update
;
79 c
->final
= av_sha_final
;
80 c
->hash
= av_sha_alloc();
85 c
->init
= sha256_init
;
86 c
->update
= av_sha_update
;
87 c
->final
= av_sha_final
;
88 c
->hash
= av_sha_alloc();
101 void av_hmac_free(AVHMAC
*c
)
109 void av_hmac_init(AVHMAC
*c
, const uint8_t *key
, unsigned int keylen
)
112 uint8_t block
[MAX_BLOCKLEN
];
113 if (keylen
> c
->blocklen
) {
115 c
->update(c
->hash
, key
, keylen
);
116 c
->final(c
->hash
, c
->key
);
117 c
->keylen
= c
->hashlen
;
119 memcpy(c
->key
, key
, keylen
);
123 for (i
= 0; i
< c
->keylen
; i
++)
124 block
[i
] = c
->key
[i
] ^ 0x36;
125 for (i
= c
->keylen
; i
< c
->blocklen
; i
++)
127 c
->update(c
->hash
, block
, c
->blocklen
);
130 void av_hmac_update(AVHMAC
*c
, const uint8_t *data
, unsigned int len
)
132 c
->update(c
->hash
, data
, len
);
135 int av_hmac_final(AVHMAC
*c
, uint8_t *out
, unsigned int outlen
)
137 uint8_t block
[MAX_BLOCKLEN
];
139 if (outlen
< c
->hashlen
)
140 return AVERROR(EINVAL
);
141 c
->final(c
->hash
, out
);
143 for (i
= 0; i
< c
->keylen
; i
++)
144 block
[i
] = c
->key
[i
] ^ 0x5C;
145 for (i
= c
->keylen
; i
< c
->blocklen
; i
++)
147 c
->update(c
->hash
, block
, c
->blocklen
);
148 c
->update(c
->hash
, out
, c
->hashlen
);
149 c
->final(c
->hash
, out
);
153 int av_hmac_calc(AVHMAC
*c
, const uint8_t *data
, unsigned int len
,
154 const uint8_t *key
, unsigned int keylen
,
155 uint8_t *out
, unsigned int outlen
)
157 av_hmac_init(c
, key
, keylen
);
158 av_hmac_update(c
, data
, len
);
159 return av_hmac_final(c
, out
, outlen
);
165 static void test(AVHMAC
*hmac
, const uint8_t *key
, int keylen
,
166 const uint8_t *data
, int datalen
)
168 uint8_t buf
[MAX_HASHLEN
];
170 // Some of the test vectors are strings, where sizeof() includes the
171 // trailing null byte - remove that.
172 if (!key
[keylen
- 1])
174 if (!data
[datalen
- 1])
176 out
= av_hmac_calc(hmac
, data
, datalen
, key
, keylen
, buf
, sizeof(buf
));
177 for (i
= 0; i
< out
; i
++)
178 printf("%02x", buf
[i
]);
184 uint8_t key1
[16], key3
[16], data3
[50], key4
[63], key5
[64], key6
[65];
185 const uint8_t key2
[] = "Jefe";
186 const uint8_t data1
[] = "Hi There";
187 const uint8_t data2
[] = "what do ya want for nothing?";
188 AVHMAC
*hmac
= av_hmac_alloc(AV_HMAC_MD5
);
191 memset(key1
, 0x0b, sizeof(key1
));
192 memset(key3
, 0xaa, sizeof(key3
));
193 memset(key4
, 0x44, sizeof(key4
));
194 memset(key5
, 0x55, sizeof(key5
));
195 memset(key6
, 0x66, sizeof(key6
));
196 memset(data3
, 0xdd, sizeof(data3
));
197 // RFC 2104 test vectors
198 test(hmac
, key1
, sizeof(key1
), data1
, sizeof(data1
));
199 test(hmac
, key2
, sizeof(key2
), data2
, sizeof(data2
));
200 test(hmac
, key3
, sizeof(key3
), data3
, sizeof(data3
));
201 // Additional tests, to test cases where the key is too long
202 test(hmac
, key4
, sizeof(key4
), data1
, sizeof(data1
));
203 test(hmac
, key5
, sizeof(key5
), data2
, sizeof(data2
));
204 test(hmac
, key6
, sizeof(key6
), data3
, sizeof(data3
));