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