• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
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 "hash.h"
24 
25 #include "adler32.h"
26 #include "crc.h"
27 #include "md5.h"
28 #include "murmur3.h"
29 #include "ripemd.h"
30 #include "sha.h"
31 #include "sha512.h"
32 
33 #include "avstring.h"
34 #include "base64.h"
35 #include "error.h"
36 #include "intreadwrite.h"
37 #include "mem.h"
38 
39 enum hashtype {
40     MD5,
41     MURMUR3,
42     RIPEMD128,
43     RIPEMD160,
44     RIPEMD256,
45     RIPEMD320,
46     SHA160,
47     SHA224,
48     SHA256,
49     SHA512_224,
50     SHA512_256,
51     SHA384,
52     SHA512,
53     CRC32,
54     ADLER32,
55     NUM_HASHES
56 };
57 
58 typedef struct AVHashContext {
59     void *ctx;
60     enum hashtype type;
61     const AVCRC *crctab;
62     uint32_t crc;
63 } AVHashContext;
64 
65 static const struct {
66     const char *name;
67     int size;
68 } hashdesc[] = {
69     [MD5]     = {"MD5",     16},
70     [MURMUR3] = {"murmur3", 16},
71     [RIPEMD128] = {"RIPEMD128", 16},
72     [RIPEMD160] = {"RIPEMD160", 20},
73     [RIPEMD256] = {"RIPEMD256", 32},
74     [RIPEMD320] = {"RIPEMD320", 40},
75     [SHA160]  = {"SHA160",  20},
76     [SHA224]  = {"SHA224",  28},
77     [SHA256]  = {"SHA256",  32},
78     [SHA512_224]  = {"SHA512/224",  28},
79     [SHA512_256]  = {"SHA512/256",  32},
80     [SHA384]  = {"SHA384",  48},
81     [SHA512]  = {"SHA512",  64},
82     [CRC32]   = {"CRC32",    4},
83     [ADLER32] = {"adler32",  4},
84 };
85 
av_hash_names(int i)86 const char *av_hash_names(int i)
87 {
88     if (i < 0 || i >= NUM_HASHES) return NULL;
89     return hashdesc[i].name;
90 }
91 
av_hash_get_name(const AVHashContext * ctx)92 const char *av_hash_get_name(const AVHashContext *ctx)
93 {
94     return hashdesc[ctx->type].name;
95 }
96 
av_hash_get_size(const AVHashContext * ctx)97 int av_hash_get_size(const AVHashContext *ctx)
98 {
99     return hashdesc[ctx->type].size;
100 }
101 
av_hash_alloc(AVHashContext ** ctx,const char * name)102 int av_hash_alloc(AVHashContext **ctx, const char *name)
103 {
104     AVHashContext *res;
105     int i;
106     *ctx = NULL;
107     for (i = 0; i < NUM_HASHES; i++)
108         if (av_strcasecmp(name, hashdesc[i].name) == 0)
109             break;
110     if (i >= NUM_HASHES) return AVERROR(EINVAL);
111     res = av_mallocz(sizeof(*res));
112     if (!res) return AVERROR(ENOMEM);
113     res->type = i;
114     switch (i) {
115     case MD5:     res->ctx = av_md5_alloc(); break;
116     case MURMUR3: res->ctx = av_murmur3_alloc(); break;
117     case RIPEMD128:
118     case RIPEMD160:
119     case RIPEMD256:
120     case RIPEMD320: res->ctx = av_ripemd_alloc(); break;
121     case SHA160:
122     case SHA224:
123     case SHA256:  res->ctx = av_sha_alloc(); break;
124     case SHA512_224:
125     case SHA512_256:
126     case SHA384:
127     case SHA512:  res->ctx = av_sha512_alloc(); break;
128     case CRC32:   res->crctab = av_crc_get_table(AV_CRC_32_IEEE_LE); break;
129     case ADLER32: break;
130     }
131     if (i != ADLER32 && i != CRC32 && !res->ctx) {
132         av_free(res);
133         return AVERROR(ENOMEM);
134     }
135     *ctx = res;
136     return 0;
137 }
138 
av_hash_init(AVHashContext * ctx)139 void av_hash_init(AVHashContext *ctx)
140 {
141     switch (ctx->type) {
142     case MD5:     av_md5_init(ctx->ctx); break;
143     case MURMUR3: av_murmur3_init(ctx->ctx); break;
144     case RIPEMD128: av_ripemd_init(ctx->ctx, 128); break;
145     case RIPEMD160: av_ripemd_init(ctx->ctx, 160); break;
146     case RIPEMD256: av_ripemd_init(ctx->ctx, 256); break;
147     case RIPEMD320: av_ripemd_init(ctx->ctx, 320); break;
148     case SHA160:  av_sha_init(ctx->ctx, 160); break;
149     case SHA224:  av_sha_init(ctx->ctx, 224); break;
150     case SHA256:  av_sha_init(ctx->ctx, 256); break;
151     case SHA512_224:  av_sha512_init(ctx->ctx, 224); break;
152     case SHA512_256:  av_sha512_init(ctx->ctx, 256); break;
153     case SHA384:  av_sha512_init(ctx->ctx, 384); break;
154     case SHA512:  av_sha512_init(ctx->ctx, 512); break;
155     case CRC32:   ctx->crc = UINT32_MAX; break;
156     case ADLER32: ctx->crc = 1; break;
157     }
158 }
159 
av_hash_update(AVHashContext * ctx,const uint8_t * src,size_t len)160 void av_hash_update(AVHashContext *ctx, const uint8_t *src, size_t len)
161 {
162     switch (ctx->type) {
163     case MD5:     av_md5_update(ctx->ctx, src, len); break;
164     case MURMUR3: av_murmur3_update(ctx->ctx, src, len); break;
165     case RIPEMD128:
166     case RIPEMD160:
167     case RIPEMD256:
168     case RIPEMD320: av_ripemd_update(ctx->ctx, src, len); break;
169     case SHA160:
170     case SHA224:
171     case SHA256:  av_sha_update(ctx->ctx, src, len); break;
172     case SHA512_224:
173     case SHA512_256:
174     case SHA384:
175     case SHA512:  av_sha512_update(ctx->ctx, src, len); break;
176     case CRC32:   ctx->crc = av_crc(ctx->crctab, ctx->crc, src, len); break;
177     case ADLER32: ctx->crc = av_adler32_update(ctx->crc, src, len); break;
178     }
179 }
180 
av_hash_final(AVHashContext * ctx,uint8_t * dst)181 void av_hash_final(AVHashContext *ctx, uint8_t *dst)
182 {
183     switch (ctx->type) {
184     case MD5:     av_md5_final(ctx->ctx, dst); break;
185     case MURMUR3: av_murmur3_final(ctx->ctx, dst); break;
186     case RIPEMD128:
187     case RIPEMD160:
188     case RIPEMD256:
189     case RIPEMD320: av_ripemd_final(ctx->ctx, dst); break;
190     case SHA160:
191     case SHA224:
192     case SHA256:  av_sha_final(ctx->ctx, dst); break;
193     case SHA512_224:
194     case SHA512_256:
195     case SHA384:
196     case SHA512:  av_sha512_final(ctx->ctx, dst); break;
197     case CRC32:   AV_WB32(dst, ctx->crc ^ UINT32_MAX); break;
198     case ADLER32: AV_WB32(dst, ctx->crc); break;
199     }
200 }
201 
av_hash_final_bin(struct AVHashContext * ctx,uint8_t * dst,int size)202 void av_hash_final_bin(struct AVHashContext *ctx, uint8_t *dst, int size)
203 {
204     uint8_t buf[AV_HASH_MAX_SIZE];
205     unsigned rsize = av_hash_get_size(ctx);
206 
207     av_hash_final(ctx, buf);
208     memcpy(dst, buf, FFMIN(size, rsize));
209     if (size > rsize)
210         memset(dst + rsize, 0, size - rsize);
211 }
212 
av_hash_final_hex(struct AVHashContext * ctx,uint8_t * dst,int size)213 void av_hash_final_hex(struct AVHashContext *ctx, uint8_t *dst, int size)
214 {
215     uint8_t buf[AV_HASH_MAX_SIZE];
216     unsigned rsize = av_hash_get_size(ctx), i;
217 
218     av_hash_final(ctx, buf);
219     for (i = 0; i < FFMIN(rsize, size / 2); i++)
220         snprintf(dst + i * 2, size - i * 2, "%02x", buf[i]);
221 }
222 
av_hash_final_b64(struct AVHashContext * ctx,uint8_t * dst,int size)223 void av_hash_final_b64(struct AVHashContext *ctx, uint8_t *dst, int size)
224 {
225     uint8_t buf[AV_HASH_MAX_SIZE], b64[AV_BASE64_SIZE(AV_HASH_MAX_SIZE)];
226     unsigned rsize = av_hash_get_size(ctx), osize;
227 
228     av_hash_final(ctx, buf);
229     av_base64_encode(b64, sizeof(b64), buf, rsize);
230     osize = AV_BASE64_SIZE(rsize);
231     memcpy(dst, b64, FFMIN(osize, size));
232     if (size < osize)
233         dst[size - 1] = 0;
234 }
235 
av_hash_freep(AVHashContext ** ctx)236 void av_hash_freep(AVHashContext **ctx)
237 {
238     if (*ctx)
239         av_freep(&(*ctx)->ctx);
240     av_freep(ctx);
241 }
242