FFmpeg
Loading...
Searching...
No Matches
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 <stddef.h>
22#include <stdint.h>
23#include <string.h>
24
25#include "attributes.h"
26#include "error.h"
27#include "hmac.h"
28#include "md5.h"
29#include "sha.h"
30#include "sha512.h"
31#include "mem.h"
32
33#define MAX_HASHLEN 64
34#define MAX_BLOCKLEN 128
35
36typedef void (*hmac_final)(void *ctx, uint8_t *dst);
37typedef void (*hmac_update)(void *ctx, const uint8_t *src, size_t len);
38typedef void (*hmac_init)(void *ctx);
39
49
50#define DEFINE_ALGO_BITS_INIT(prefix, bits) \
51static av_cold void prefix##bits##_init(void *ctx) \
52{ \
53 av_##prefix##_init(ctx, bits); \
54}
55
56#define DEFINE_ALGO_INIT(prefix) \
57static av_cold void prefix##_init(void *ctx) \
58{ \
59 av_##prefix##_init(ctx); \
60}
61
62#define DEFINE_ALGO(prefix) \
63static void prefix##_update(void *ctx, const uint8_t *src, size_t len) \
64{ \
65 av_##prefix##_update(ctx, src, len); \
66} \
67static void prefix##_final(void *ctx, uint8_t *dst) \
68{ \
69 av_##prefix##_final(ctx, dst); \
70}
71
76DEFINE_ALGO_BITS_INIT(sha512, 384)
77DEFINE_ALGO_BITS_INIT(sha512, 512)
79DEFINE_ALGO(sha)
80DEFINE_ALGO(sha512)
81
83{
84 AVHMAC *c = av_mallocz(sizeof(*c));
85 if (!c)
86 return NULL;
87 switch (type) {
88 case AV_HMAC_MD5:
89 c->blocklen = 64;
90 c->hashlen = 16;
91 c->init = md5_init;
92 c->update = md5_update;
93 c->final = md5_final;
94 c->hash = av_md5_alloc();
95 break;
96 case AV_HMAC_SHA1:
97 c->blocklen = 64;
98 c->hashlen = 20;
99 c->init = sha160_init;
100 c->update = sha_update;
101 c->final = sha_final;
102 c->hash = av_sha_alloc();
103 break;
104 case AV_HMAC_SHA224:
105 c->blocklen = 64;
106 c->hashlen = 28;
107 c->init = sha224_init;
108 c->update = sha_update;
109 c->final = sha_final;
110 c->hash = av_sha_alloc();
111 break;
112 case AV_HMAC_SHA256:
113 c->blocklen = 64;
114 c->hashlen = 32;
115 c->init = sha256_init;
116 c->update = sha_update;
117 c->final = sha_final;
118 c->hash = av_sha_alloc();
119 break;
120 case AV_HMAC_SHA384:
121 c->blocklen = 128;
122 c->hashlen = 48;
123 c->init = sha512384_init;
124 c->update = sha512_update;
125 c->final = sha512_final;
126 c->hash = av_sha512_alloc();
127 break;
128 case AV_HMAC_SHA512:
129 c->blocklen = 128;
130 c->hashlen = 64;
131 c->init = sha512512_init;
132 c->update = sha512_update;
133 c->final = sha512_final;
134 c->hash = av_sha512_alloc();
135 break;
136 default:
137 av_free(c);
138 return NULL;
139 }
140 if (!c->hash) {
141 av_free(c);
142 return NULL;
143 }
144 return c;
145}
146
148{
149 if (!c)
150 return;
151 av_freep(&c->hash);
152 av_free(c);
153}
154
155void av_hmac_init(AVHMAC *c, const uint8_t *key, unsigned int keylen)
156{
157 int i;
158 uint8_t block[MAX_BLOCKLEN];
159 if (keylen > c->blocklen) {
160 c->init(c->hash);
161 c->update(c->hash, key, keylen);
162 c->final(c->hash, c->key);
163 c->keylen = c->hashlen;
164 } else {
165 memcpy(c->key, key, keylen);
166 c->keylen = keylen;
167 }
168 c->init(c->hash);
169 for (i = 0; i < c->keylen; i++)
170 block[i] = c->key[i] ^ 0x36;
171 for (i = c->keylen; i < c->blocklen; i++)
172 block[i] = 0x36;
173 c->update(c->hash, block, c->blocklen);
174}
175
176void av_hmac_update(AVHMAC *c, const uint8_t *data, unsigned int len)
177{
178 c->update(c->hash, data, len);
179}
180
181int av_hmac_final(AVHMAC *c, uint8_t *out, unsigned int outlen)
182{
183 uint8_t block[MAX_BLOCKLEN];
184 int i;
185 if (outlen < c->hashlen)
186 return AVERROR(EINVAL);
187 c->final(c->hash, out);
188 c->init(c->hash);
189 for (i = 0; i < c->keylen; i++)
190 block[i] = c->key[i] ^ 0x5C;
191 for (i = c->keylen; i < c->blocklen; i++)
192 block[i] = 0x5C;
193 c->update(c->hash, block, c->blocklen);
194 c->update(c->hash, out, c->hashlen);
195 c->final(c->hash, out);
196 return c->hashlen;
197}
198
199int av_hmac_calc(AVHMAC *c, const uint8_t *data, unsigned int len,
200 const uint8_t *key, unsigned int keylen,
201 uint8_t *out, unsigned int outlen)
202{
203 av_hmac_init(c, key, keylen);
205 return av_hmac_final(c, out, outlen);
206}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
static FILE * out
static struct AVMD5 * md5
static AVFormatContext * ctx
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define NULL
Definition coverity.c:32
static int16_t block[64]
Definition dct.c:125
error code definitions
const char * key
#define AVERROR(e)
Definition error.h:45
int av_hmac_final(AVHMAC *c, uint8_t *out, unsigned int outlen)
Finish hashing and output the HMAC digest.
Definition hmac.c:181
int av_hmac_calc(AVHMAC *c, const uint8_t *data, unsigned int len, const uint8_t *key, unsigned int keylen, uint8_t *out, unsigned int outlen)
Hash an array of data with a key.
Definition hmac.c:199
AVHMAC * av_hmac_alloc(enum AVHMACType type)
Allocate an AVHMAC context.
Definition hmac.c:82
void av_hmac_update(AVHMAC *c, const uint8_t *data, unsigned int len)
Hash data with the HMAC.
Definition hmac.c:176
void av_hmac_free(AVHMAC *c)
Free an AVHMAC context.
Definition hmac.c:147
void av_hmac_init(AVHMAC *c, const uint8_t *key, unsigned int keylen)
Initialize an AVHMAC context with an authentication key.
Definition hmac.c:155
AVHMACType
Definition hmac.h:32
@ AV_HMAC_MD5
Definition hmac.h:33
@ AV_HMAC_SHA384
Definition hmac.h:37
@ AV_HMAC_SHA224
Definition hmac.h:35
@ AV_HMAC_SHA256
Definition hmac.h:36
@ AV_HMAC_SHA1
Definition hmac.h:34
@ AV_HMAC_SHA512
Definition hmac.h:38
struct AVMD5 * av_md5_alloc(void)
Allocate an AVMD5 context.
Definition md5.c:50
struct AVSHA512 * av_sha512_alloc(void)
Allocate an AVSHA512 context.
Definition sha512.c:44
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition sha.c:46
#define DEFINE_ALGO_INIT(prefix)
Definition hmac.c:56
#define DEFINE_ALGO(prefix)
Definition hmac.c:62
void(* hmac_init)(void *ctx)
Definition hmac.c:38
void(* hmac_update)(void *ctx, const uint8_t *src, size_t len)
Definition hmac.c:37
void(* hmac_final)(void *ctx, uint8_t *dst)
Definition hmac.c:36
#define DEFINE_ALGO_BITS_INIT(prefix, bits)
Definition hmac.c:50
#define MAX_BLOCKLEN
Definition hmac.c:34
cl_device_type type
Macro definitions for various function/variable attributes.
Public header for MD5 hash function implementation.
Memory handling functions.
const char data[16]
Definition mxf.c:149
Public header for SHA-512 implementation.
Public header for SHA-1 & SHA-256 hash function implementations.
Definition hmac.c:40
hmac_update update
Definition hmac.c:44
int keylen
Definition hmac.c:47
int blocklen
Definition hmac.c:42
uint8_t key[MAX_BLOCKLEN]
Definition hmac.c:46
void * hash
Definition hmac.c:41
hmac_init init
Definition hmac.c:45
int hashlen
Definition hmac.c:42
#define av_free(p)
#define av_mallocz(s)
#define av_freep(p)
#define src
Definition vp8dsp.c:248
int len
static double c[64]