Libav
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 32
30 #define MAX_BLOCKLEN 64
31 
32 struct AVHMAC {
33  void *hash;
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 #define DEFINE_SHA(bits) \
43 static av_cold void sha ## bits ##_init(void *ctx) \
44 { \
45  av_sha_init(ctx, bits); \
46 }
47 
48 DEFINE_SHA(160)
49 DEFINE_SHA(224)
50 DEFINE_SHA(256)
51 
53 {
54  AVHMAC *c = av_mallocz(sizeof(*c));
55  if (!c)
56  return NULL;
57  switch (type) {
58  case AV_HMAC_MD5:
59  c->blocklen = 64;
60  c->hashlen = 16;
61  c->init = av_md5_init;
62  c->update = av_md5_update;
63  c->final = av_md5_final;
64  c->hash = av_md5_alloc();
65  break;
66  case AV_HMAC_SHA1:
67  c->blocklen = 64;
68  c->hashlen = 20;
69  c->init = sha160_init;
70  c->update = av_sha_update;
71  c->final = av_sha_final;
72  c->hash = av_sha_alloc();
73  break;
74  case AV_HMAC_SHA224:
75  c->blocklen = 64;
76  c->hashlen = 28;
77  c->init = sha224_init;
78  c->update = av_sha_update;
79  c->final = av_sha_final;
80  c->hash = av_sha_alloc();
81  break;
82  case AV_HMAC_SHA256:
83  c->blocklen = 64;
84  c->hashlen = 32;
85  c->init = sha256_init;
86  c->update = av_sha_update;
87  c->final = av_sha_final;
88  c->hash = av_sha_alloc();
89  break;
90  default:
91  av_free(c);
92  return NULL;
93  }
94  if (!c->hash) {
95  av_free(c);
96  return NULL;
97  }
98  return c;
99 }
100 
102 {
103  if (!c)
104  return;
105  av_free(c->hash);
106  av_free(c);
107 }
108 
109 void av_hmac_init(AVHMAC *c, const uint8_t *key, unsigned int keylen)
110 {
111  int i;
113  if (keylen > c->blocklen) {
114  c->init(c->hash);
115  c->update(c->hash, key, keylen);
116  c->final(c->hash, c->key);
117  c->keylen = c->hashlen;
118  } else {
119  memcpy(c->key, key, keylen);
120  c->keylen = keylen;
121  }
122  c->init(c->hash);
123  for (i = 0; i < c->keylen; i++)
124  block[i] = c->key[i] ^ 0x36;
125  for (i = c->keylen; i < c->blocklen; i++)
126  block[i] = 0x36;
127  c->update(c->hash, block, c->blocklen);
128 }
129 
130 void av_hmac_update(AVHMAC *c, const uint8_t *data, unsigned int len)
131 {
132  c->update(c->hash, data, len);
133 }
134 
135 int av_hmac_final(AVHMAC *c, uint8_t *out, unsigned int outlen)
136 {
138  int i;
139  if (outlen < c->hashlen)
140  return AVERROR(EINVAL);
141  c->final(c->hash, out);
142  c->init(c->hash);
143  for (i = 0; i < c->keylen; i++)
144  block[i] = c->key[i] ^ 0x5C;
145  for (i = c->keylen; i < c->blocklen; i++)
146  block[i] = 0x5C;
147  c->update(c->hash, block, c->blocklen);
148  c->update(c->hash, out, c->hashlen);
149  c->final(c->hash, out);
150  return c->hashlen;
151 }
152 
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)
156 {
157  av_hmac_init(c, key, keylen);
158  av_hmac_update(c, data, len);
159  return av_hmac_final(c, out, outlen);
160 }
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha.c:320
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:153
void av_sha_update(AVSHA *ctx, const uint8_t *data, unsigned int len)
Update hash value.
Definition: sha.c:293
AVHMAC * av_hmac_alloc(enum AVHMACType type)
Allocate an AVHMAC context.
Definition: hmac.c:52
memory handling functions
AVHMACType
Definition: hmac.h:32
Macro definitions for various function/variable attributes.
void * hash
Definition: hmac.c:33
static int16_t block[64]
Definition: dct.c:97
struct AVMD5 * av_md5_alloc(void)
Definition: md5.c:46
uint8_t
void(* final)(void *, uint8_t *)
Definition: hmac.c:35
const char data[16]
Definition: mxf.c:70
void av_hmac_update(AVHMAC *c, const uint8_t *data, unsigned int len)
Hash data with the HMAC.
Definition: hmac.c:130
void av_md5_update(AVMD5 *ctx, const uint8_t *src, const int len)
Definition: md5.c:149
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:190
void(* init)(void *)
Definition: hmac.c:37
#define AVERROR(e)
Definition: error.h:43
int hashlen
Definition: hmac.c:34
int blocklen
Definition: hmac.c:34
Definition: hmac.c:32
void av_hmac_init(AVHMAC *c, const uint8_t *key, unsigned int keylen)
Initialize an AVHMAC context with an authentication key.
Definition: hmac.c:109
uint8_t key[MAX_BLOCKLEN]
Definition: hmac.c:38
NULL
Definition: eval.c:55
static void(WINAPI *cond_broadcast)(pthread_cond_t *cond)
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition: sha.c:43
void av_md5_init(AVMD5 *ctx)
Definition: md5.c:139
#define MAX_BLOCKLEN
Definition: hmac.c:30
void av_md5_final(AVMD5 *ctx, uint8_t *dst)
Definition: md5.c:165
int av_hmac_final(AVHMAC *c, uint8_t *out, unsigned int outlen)
Finish hashing and output the HMAC digest.
Definition: hmac.c:135
int keylen
Definition: hmac.c:39
void av_hmac_free(AVHMAC *c)
Free an AVHMAC context.
Definition: hmac.c:101
void(* update)(void *, const uint8_t *, int len)
Definition: hmac.c:36
int len
FILE * out
Definition: movenc.c:54
#define DEFINE_SHA(bits)
Definition: hmac.c:42
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:211
for(j=16;j >0;--j)