]> git.sesse.net Git - ffmpeg/blob - libavutil/hash.c
d626c31181923b888592644bbe4160685da4c826
[ffmpeg] / libavutil / hash.c
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
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
92 const char *av_hash_get_name(const AVHashContext *ctx)
93 {
94     return hashdesc[ctx->type].name;
95 }
96
97 int av_hash_get_size(const AVHashContext *ctx)
98 {
99     return hashdesc[ctx->type].size;
100 }
101
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
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
160 #if FF_API_CRYPTO_SIZE_T
161 void av_hash_update(AVHashContext *ctx, const uint8_t *src, int len)
162 #else
163 void av_hash_update(AVHashContext *ctx, const uint8_t *src, size_t len)
164 #endif
165 {
166     switch (ctx->type) {
167     case MD5:     av_md5_update(ctx->ctx, src, len); break;
168     case MURMUR3: av_murmur3_update(ctx->ctx, src, len); break;
169     case RIPEMD128:
170     case RIPEMD160:
171     case RIPEMD256:
172     case RIPEMD320: av_ripemd_update(ctx->ctx, src, len); break;
173     case SHA160:
174     case SHA224:
175     case SHA256:  av_sha_update(ctx->ctx, src, len); break;
176     case SHA512_224:
177     case SHA512_256:
178     case SHA384:
179     case SHA512:  av_sha512_update(ctx->ctx, src, len); break;
180     case CRC32:   ctx->crc = av_crc(ctx->crctab, ctx->crc, src, len); break;
181     case ADLER32: ctx->crc = av_adler32_update(ctx->crc, src, len); break;
182     }
183 }
184
185 void av_hash_final(AVHashContext *ctx, uint8_t *dst)
186 {
187     switch (ctx->type) {
188     case MD5:     av_md5_final(ctx->ctx, dst); break;
189     case MURMUR3: av_murmur3_final(ctx->ctx, dst); break;
190     case RIPEMD128:
191     case RIPEMD160:
192     case RIPEMD256:
193     case RIPEMD320: av_ripemd_final(ctx->ctx, dst); break;
194     case SHA160:
195     case SHA224:
196     case SHA256:  av_sha_final(ctx->ctx, dst); break;
197     case SHA512_224:
198     case SHA512_256:
199     case SHA384:
200     case SHA512:  av_sha512_final(ctx->ctx, dst); break;
201     case CRC32:   AV_WB32(dst, ctx->crc ^ UINT32_MAX); break;
202     case ADLER32: AV_WB32(dst, ctx->crc); break;
203     }
204 }
205
206 void av_hash_final_bin(struct AVHashContext *ctx, uint8_t *dst, int size)
207 {
208     uint8_t buf[AV_HASH_MAX_SIZE];
209     unsigned rsize = av_hash_get_size(ctx);
210
211     av_hash_final(ctx, buf);
212     memcpy(dst, buf, FFMIN(size, rsize));
213     if (size > rsize)
214         memset(dst + rsize, 0, size - rsize);
215 }
216
217 void av_hash_final_hex(struct AVHashContext *ctx, uint8_t *dst, int size)
218 {
219     uint8_t buf[AV_HASH_MAX_SIZE];
220     unsigned rsize = av_hash_get_size(ctx), i;
221
222     av_hash_final(ctx, buf);
223     for (i = 0; i < FFMIN(rsize, size / 2); i++)
224         snprintf(dst + i * 2, size - i * 2, "%02x", buf[i]);
225 }
226
227 void av_hash_final_b64(struct AVHashContext *ctx, uint8_t *dst, int size)
228 {
229     uint8_t buf[AV_HASH_MAX_SIZE], b64[AV_BASE64_SIZE(AV_HASH_MAX_SIZE)];
230     unsigned rsize = av_hash_get_size(ctx), osize;
231
232     av_hash_final(ctx, buf);
233     av_base64_encode(b64, sizeof(b64), buf, rsize);
234     osize = AV_BASE64_SIZE(rsize);
235     memcpy(dst, b64, FFMIN(osize, size));
236     if (size < osize)
237         dst[size - 1] = 0;
238 }
239
240 void av_hash_freep(AVHashContext **ctx)
241 {
242     if (*ctx)
243         av_freep(&(*ctx)->ctx);
244     av_freep(ctx);
245 }