Libav
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavutil
hmac.c
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2012 Martin Storsjo
3
*
4
* This file is part of Libav.
5
*
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.
10
*
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.
15
*
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
19
*/
20
21
#include <string.h>
22
23
#include "
attributes.h
"
24
#include "
hmac.h
"
25
#include "
md5.h
"
26
#include "
sha.h
"
27
#include "
mem.h
"
28
29
#define MAX_HASHLEN 20
30
#define MAX_BLOCKLEN 64
31
32
struct
AVHMAC
{
33
void
*
hash
;
34
int
blocklen
,
hashlen
;
35
void
(*
final
)(
void
*,
uint8_t
*);
36
void
(*
update
)(
void
*,
const
uint8_t
*,
int
len
);
37
void
(*
init
)(
void
*);
38
uint8_t
key
[
MAX_BLOCKLEN
];
39
int
keylen
;
40
};
41
42
static
av_cold
void
sha1_init
(
void
*ctx)
43
{
44
av_sha_init
(ctx, 160);
45
}
46
47
AVHMAC
*
av_hmac_alloc
(
enum
AVHMACType
type)
48
{
49
AVHMAC
*c =
av_mallocz
(
sizeof
(*c));
50
if
(!c)
51
return
NULL
;
52
switch
(type) {
53
case
AV_HMAC_MD5
:
54
c->
blocklen
= 64;
55
c->
hashlen
= 16;
56
c->
init
=
av_md5_init
;
57
c->
update
=
av_md5_update
;
58
c->
final
=
av_md5_final
;
59
c->
hash
=
av_md5_alloc
();
60
break
;
61
case
AV_HMAC_SHA1
:
62
c->
blocklen
= 64;
63
c->
hashlen
= 20;
64
c->
init
=
sha1_init
;
65
c->
update
=
av_sha_update
;
66
c->
final
=
av_sha_final
;
67
c->
hash
=
av_sha_alloc
();
68
break
;
69
default
:
70
av_free
(c);
71
return
NULL
;
72
}
73
if
(!c->
hash
) {
74
av_free
(c);
75
return
NULL
;
76
}
77
return
c;
78
}
79
80
void
av_hmac_free
(
AVHMAC
*c)
81
{
82
if
(!c)
83
return
;
84
av_free
(c->
hash
);
85
av_free
(c);
86
}
87
88
void
av_hmac_init
(
AVHMAC
*c,
const
uint8_t
*key,
unsigned
int
keylen)
89
{
90
int
i;
91
uint8_t
block
[
MAX_BLOCKLEN
];
92
if
(keylen > c->
blocklen
) {
93
c->
init
(c->
hash
);
94
c->
update
(c->
hash
, key, keylen);
95
c->
final
(c->
hash
, c->
key
);
96
c->
keylen
= c->
hashlen
;
97
}
else
{
98
memcpy(c->
key
, key, keylen);
99
c->
keylen
= keylen;
100
}
101
c->
init
(c->
hash
);
102
for
(i = 0; i < c->
keylen
; i++)
103
block[i] = c->
key
[i] ^ 0x36;
104
for
(i = c->
keylen
; i < c->blocklen; i++)
105
block[i] = 0x36;
106
c->
update
(c->
hash
, block, c->
blocklen
);
107
}
108
109
void
av_hmac_update
(
AVHMAC
*c,
const
uint8_t
*
data
,
unsigned
int
len
)
110
{
111
c->
update
(c->
hash
, data, len);
112
}
113
114
int
av_hmac_final
(
AVHMAC
*c,
uint8_t
*
out
,
unsigned
int
outlen)
115
{
116
uint8_t
block
[
MAX_BLOCKLEN
];
117
int
i;
118
if
(outlen < c->hashlen)
119
return
AVERROR
(EINVAL);
120
c->
final
(c->
hash
, out);
121
c->
init
(c->
hash
);
122
for
(i = 0; i < c->
keylen
; i++)
123
block[i] = c->
key
[i] ^ 0x5C;
124
for
(i = c->
keylen
; i < c->blocklen; i++)
125
block[i] = 0x5C;
126
c->
update
(c->
hash
, block, c->
blocklen
);
127
c->
update
(c->
hash
, out, c->
hashlen
);
128
c->
final
(c->
hash
, out);
129
return
c->
hashlen
;
130
}
131
132
int
av_hmac_calc
(
AVHMAC
*c,
const
uint8_t
*
data
,
unsigned
int
len
,
133
const
uint8_t
*key,
unsigned
int
keylen,
134
uint8_t
*
out
,
unsigned
int
outlen)
135
{
136
av_hmac_init
(c, key, keylen);
137
av_hmac_update
(c, data, len);
138
return
av_hmac_final
(c, out, outlen);
139
}
140
141
#ifdef TEST
142
#include <stdio.h>
143
144
static
void
test
(
AVHMAC
*hmac,
const
uint8_t
*key,
int
keylen,
145
const
uint8_t
*
data
,
int
datalen)
146
{
147
uint8_t
buf[
MAX_HASHLEN
];
148
int
out
, i;
149
// Some of the test vectors are strings, where sizeof() includes the
150
// trailing null byte - remove that.
151
if
(!key[keylen - 1])
152
keylen--;
153
if
(!data[datalen - 1])
154
datalen--;
155
out =
av_hmac_calc
(hmac, data, datalen, key, keylen, buf,
sizeof
(buf));
156
for
(i = 0; i <
out
; i++)
157
printf(
"%02x"
, buf[i]);
158
printf(
"\n"
);
159
}
160
161
int
main
(
void
)
162
{
163
uint8_t
key1[16], key3[16], data3[50], key4[63], key5[64], key6[65];
164
const
uint8_t
key2[] =
"Jefe"
;
165
const
uint8_t
data1[] =
"Hi There"
;
166
const
uint8_t
data2[] =
"what do ya want for nothing?"
;
167
AVHMAC
*hmac =
av_hmac_alloc
(
AV_HMAC_MD5
);
168
if
(!hmac)
169
return
1;
170
memset(key1, 0x0b,
sizeof
(key1));
171
memset(key3, 0xaa,
sizeof
(key3));
172
memset(key4, 0x44,
sizeof
(key4));
173
memset(key5, 0x55,
sizeof
(key5));
174
memset(key6, 0x66,
sizeof
(key6));
175
memset(data3, 0xdd,
sizeof
(data3));
176
// RFC 2104 test vectors
177
test
(hmac, key1,
sizeof
(key1), data1,
sizeof
(data1));
178
test
(hmac, key2,
sizeof
(key2), data2,
sizeof
(data2));
179
test
(hmac, key3,
sizeof
(key3), data3,
sizeof
(data3));
180
// Additional tests, to test cases where the key is too long
181
test
(hmac, key4,
sizeof
(key4), data1,
sizeof
(data1));
182
test
(hmac, key5,
sizeof
(key5), data2,
sizeof
(data2));
183
test
(hmac, key6,
sizeof
(key6), data3,
sizeof
(data3));
184
av_hmac_free
(hmac);
185
return
0;
186
}
187
#endif
/* TEST */
Generated on Tue Mar 1 2016 21:14:52 for Libav by
1.8.4