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;
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 
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 
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 {
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?";
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 */
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha.c:320
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:205
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:131
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:46
int av_sha_init(AVSHA *ctx, int bits)
Initialize SHA-1 or SHA-2 hashing.
Definition: sha.c:252
memory handling functions
AVHMACType
Definition: hmac.h:32
void * hash
Definition: hmac.c:32
struct AVMD5 * av_md5_alloc(void)
Definition: md5.c:47
uint8_t
void(* final)(void *, uint8_t *)
Definition: hmac.c:34
void av_hmac_update(AVHMAC *c, const uint8_t *data, unsigned int len)
Hash data with the HMAC.
Definition: hmac.c:108
void av_md5_update(AVMD5 *ctx, const uint8_t *src, const int len)
Definition: md5.c:142
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
void(* init)(void *)
Definition: hmac.c:36
Spectrum Plot time data
int hashlen
Definition: hmac.c:33
int blocklen
Definition: hmac.c:33
FFmpeg Automated Testing Environment ************************************Table of Contents *****************FFmpeg Automated Testing Environment Introduction Using FATE from your FFmpeg source directory Submitting the results to the FFmpeg result aggregation server FATE makefile targets and variables Makefile targets Makefile variables Examples Introduction **************FATE is an extended regression suite on the client side and a means for results aggregation and presentation on the server side The first part of this document explains how you can use FATE from your FFmpeg source directory to test your ffmpeg binary The second part describes how you can run FATE to submit the results to FFmpeg s FATE server In any way you can have a look at the publicly viewable FATE results by visiting this as it can be seen if some test on some platform broke with their recent contribution This usually happens on the platforms the developers could not test on The second part of this document describes how you can run FATE to submit your results to FFmpeg s FATE server If you want to submit your results be sure to check that your combination of OS and compiler is not already listed on the above mentioned website In the third part you can find a comprehensive listing of FATE makefile targets and variables Using FATE from your FFmpeg source directory **********************************************If you want to run FATE on your machine you need to have the samples in place You can get the samples via the build target fate rsync Use this command from the top level source this will cause FATE to fail NOTE To use a custom wrapper to run the test
Definition: fate.txt:34
Definition: hmac.c:31
void av_hmac_init(AVHMAC *c, const uint8_t *key, unsigned int keylen)
Initialize an AVHMAC context with an authentication key.
Definition: hmac.c:87
uint8_t key[MAX_BLOCKLEN]
Definition: hmac.c:37
NULL
Definition: eval.c:55
static void sha1_init(void *ctx)
Definition: hmac.c:41
typedef void(RENAME(mix_any_func_type))
#define MAX_HASHLEN
Definition: hmac.c:28
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition: sha.c:43
void av_md5_init(AVMD5 *ctx)
Definition: md5.c:132
void * buf
Definition: avisynth_c.h:594
#define MAX_BLOCKLEN
Definition: hmac.c:29
synthesis window for stochastic i
void av_md5_final(AVMD5 *ctx, uint8_t *dst)
Definition: md5.c:158
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
#define type
int av_hmac_final(AVHMAC *c, uint8_t *out, unsigned int outlen)
Finish hashing and output the HMAC digest.
Definition: hmac.c:113
int keylen
Definition: hmac.c:38
static double c[64]
void av_hmac_free(AVHMAC *c)
Free an AVHMAC context.
Definition: hmac.c:79
void(* update)(void *, const uint8_t *, int len)
Definition: hmac.c:35
int len
printf("static const uint8_t my_array[100] = {\n")
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=av_sample_fmt_is_planar(in_fmt);out_planar=av_sample_fmt_is_planar(out_fmt);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> out
int main(int argc, char **argv)
Definition: main.c:22
for(j=16;j >0;--j)