FFmpeg
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
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 Sat May 25 2013 04:01:20 for FFmpeg by
1.8.2