Line | Branch | Exec | Source |
---|---|---|---|
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 <assert.h> | ||
22 | #include <stddef.h> | ||
23 | #include <stdint.h> | ||
24 | #include <stdio.h> | ||
25 | #include <string.h> | ||
26 | #include "hash.h" | ||
27 | |||
28 | #include "adler32.h" | ||
29 | #include "crc.h" | ||
30 | #include "md5.h" | ||
31 | #include "murmur3.h" | ||
32 | #include "ripemd.h" | ||
33 | #include "sha.h" | ||
34 | #include "sha512.h" | ||
35 | |||
36 | #include "avstring.h" | ||
37 | #include "base64.h" | ||
38 | #include "error.h" | ||
39 | #include "intreadwrite.h" | ||
40 | #include "mem.h" | ||
41 | |||
42 | // ENTRY(HASH_TYPE, HASH_NAME, HASH_SIZE) | ||
43 | #define HASHES(ENTRY) \ | ||
44 | ENTRY(MD5, "MD5", 16) \ | ||
45 | ENTRY(MURMUR3, "murmur3", 16) \ | ||
46 | ENTRY(RIPEMD128, "RIPEMD128", 16) \ | ||
47 | ENTRY(RIPEMD160, "RIPEMD160", 20) \ | ||
48 | ENTRY(RIPEMD256, "RIPEMD256", 32) \ | ||
49 | ENTRY(RIPEMD320, "RIPEMD320", 40) \ | ||
50 | ENTRY(SHA160, "SHA160", 20) \ | ||
51 | ENTRY(SHA224, "SHA224", 28) \ | ||
52 | ENTRY(SHA256, "SHA256", 32) \ | ||
53 | ENTRY(SHA512_224, "SHA512/224", 28) \ | ||
54 | ENTRY(SHA512_256, "SHA512/256", 32) \ | ||
55 | ENTRY(SHA384, "SHA384", 48) \ | ||
56 | ENTRY(SHA512, "SHA512", 64) \ | ||
57 | ENTRY(CRC32, "CRC32", 4) \ | ||
58 | ENTRY(ADLER32, "adler32", 4) \ | ||
59 | |||
60 | enum hashtype { | ||
61 | #define HASH_TYPE(TYPE, NAME, SIZE) TYPE, | ||
62 | HASHES(HASH_TYPE) | ||
63 | NUM_HASHES | ||
64 | }; | ||
65 | |||
66 | typedef struct AVHashContext { | ||
67 | void *ctx; | ||
68 | enum hashtype type; | ||
69 | const AVCRC *crctab; | ||
70 | uint32_t crc; | ||
71 | } AVHashContext; | ||
72 | |||
73 | #define HASH_MAX_SIZE(TYPE, NAME, SIZE) \ | ||
74 | HASH_MAX_SIZE_BEFORE_ ## TYPE, \ | ||
75 | HASH_MAX_SIZE_UNTIL_ ## TYPE ## _MINUS_ONE = FFMAX(SIZE, HASH_MAX_SIZE_BEFORE_ ## TYPE) - 1, | ||
76 | enum { | ||
77 | HASHES(HASH_MAX_SIZE) | ||
78 | MAX_HASH_SIZE | ||
79 | }; | ||
80 | static_assert(AV_HASH_MAX_SIZE >= MAX_HASH_SIZE, "AV_HASH_MAX_SIZE needs to be updated!"); | ||
81 | |||
82 | #define HASH_MAX_NAME_SIZE(TYPE, NAME, SIZE) \ | ||
83 | HASH_MAX_NAME_SIZE_BEFORE_ ## TYPE, \ | ||
84 | HASH_MAX_NAME_SIZE_UNTIL_ ## TYPE ## _MINUS_ONE = FFMAX(sizeof(NAME), HASH_MAX_NAME_SIZE_BEFORE_ ## TYPE) - 1, | ||
85 | enum { | ||
86 | HASHES(HASH_MAX_NAME_SIZE) | ||
87 | MAX_HASH_NAME_SIZE | ||
88 | }; | ||
89 | |||
90 | static const struct { | ||
91 | const char name[MAX_HASH_NAME_SIZE]; | ||
92 | int size; | ||
93 | } hashdesc[] = { | ||
94 | #define HASH_DESC(TYPE, NAME, SIZE) [TYPE] = { NAME, SIZE }, | ||
95 | HASHES(HASH_DESC) | ||
96 | }; | ||
97 | |||
98 | 31 | const char *av_hash_names(int i) | |
99 | { | ||
100 |
3/4✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 30 times.
|
31 | if (i < 0 || i >= NUM_HASHES) return NULL; |
101 | 30 | return hashdesc[i].name; | |
102 | } | ||
103 | |||
104 | 2378 | const char *av_hash_get_name(const AVHashContext *ctx) | |
105 | { | ||
106 | 2378 | return hashdesc[ctx->type].name; | |
107 | } | ||
108 | |||
109 | 9569 | int av_hash_get_size(const AVHashContext *ctx) | |
110 | { | ||
111 | 9569 | return hashdesc[ctx->type].size; | |
112 | } | ||
113 | |||
114 | 654 | int av_hash_alloc(AVHashContext **ctx, const char *name) | |
115 | { | ||
116 | AVHashContext *res; | ||
117 | int i; | ||
118 | 654 | *ctx = NULL; | |
119 |
1/2✓ Branch 0 taken 920 times.
✗ Branch 1 not taken.
|
920 | for (i = 0; i < NUM_HASHES; i++) |
120 |
2/2✓ Branch 1 taken 654 times.
✓ Branch 2 taken 266 times.
|
920 | if (av_strcasecmp(name, hashdesc[i].name) == 0) |
121 | 654 | break; | |
122 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 654 times.
|
654 | if (i >= NUM_HASHES) return AVERROR(EINVAL); |
123 | 654 | res = av_mallocz(sizeof(*res)); | |
124 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 654 times.
|
654 | if (!res) return AVERROR(ENOMEM); |
125 | 654 | res->type = i; | |
126 |
7/8✓ Branch 0 taken 627 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
|
654 | switch (i) { |
127 | 627 | case MD5: res->ctx = av_md5_alloc(); break; | |
128 | 1 | case MURMUR3: res->ctx = av_murmur3_alloc(); break; | |
129 | 4 | case RIPEMD128: | |
130 | case RIPEMD160: | ||
131 | case RIPEMD256: | ||
132 | 4 | case RIPEMD320: res->ctx = av_ripemd_alloc(); break; | |
133 | 5 | case SHA160: | |
134 | case SHA224: | ||
135 | 5 | case SHA256: res->ctx = av_sha_alloc(); break; | |
136 | 4 | case SHA512_224: | |
137 | case SHA512_256: | ||
138 | case SHA384: | ||
139 | 4 | case SHA512: res->ctx = av_sha512_alloc(); break; | |
140 | 10 | case CRC32: res->crctab = av_crc_get_table(AV_CRC_32_IEEE_LE); break; | |
141 | 3 | case ADLER32: break; | |
142 | } | ||
143 |
5/6✓ Branch 0 taken 651 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 641 times.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 641 times.
|
654 | if (i != ADLER32 && i != CRC32 && !res->ctx) { |
144 | ✗ | av_free(res); | |
145 | ✗ | return AVERROR(ENOMEM); | |
146 | } | ||
147 | 654 | *ctx = res; | |
148 | 654 | return 0; | |
149 | } | ||
150 | |||
151 | 8854 | void av_hash_init(AVHashContext *ctx) | |
152 | { | ||
153 |
15/16✓ Branch 0 taken 6805 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 5 times.
✓ Branch 9 taken 3 times.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 3 times.
✓ Branch 12 taken 3 times.
✓ Branch 13 taken 2006 times.
✓ Branch 14 taken 5 times.
✗ Branch 15 not taken.
|
8854 | switch (ctx->type) { |
154 | 6805 | case MD5: av_md5_init(ctx->ctx); break; | |
155 | 3 | case MURMUR3: av_murmur3_init(ctx->ctx); break; | |
156 | 3 | case RIPEMD128: av_ripemd_init(ctx->ctx, 128); break; | |
157 | 3 | case RIPEMD160: av_ripemd_init(ctx->ctx, 160); break; | |
158 | 3 | case RIPEMD256: av_ripemd_init(ctx->ctx, 256); break; | |
159 | 3 | case RIPEMD320: av_ripemd_init(ctx->ctx, 320); break; | |
160 | 3 | case SHA160: av_sha_init(ctx->ctx, 160); break; | |
161 | 3 | case SHA224: av_sha_init(ctx->ctx, 224); break; | |
162 | 5 | case SHA256: av_sha_init(ctx->ctx, 256); break; | |
163 | 3 | case SHA512_224: av_sha512_init(ctx->ctx, 224); break; | |
164 | 3 | case SHA512_256: av_sha512_init(ctx->ctx, 256); break; | |
165 | 3 | case SHA384: av_sha512_init(ctx->ctx, 384); break; | |
166 | 3 | case SHA512: av_sha512_init(ctx->ctx, 512); break; | |
167 | 2006 | case CRC32: ctx->crc = UINT32_MAX; break; | |
168 | 5 | case ADLER32: ctx->crc = 1; break; | |
169 | } | ||
170 | 8854 | } | |
171 | |||
172 | 181870 | void av_hash_update(AVHashContext *ctx, const uint8_t *src, size_t len) | |
173 | { | ||
174 |
7/8✓ Branch 0 taken 179305 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 527 times.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 2006 times.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
|
181870 | switch (ctx->type) { |
175 | 179305 | case MD5: av_md5_update(ctx->ctx, src, len); break; | |
176 | 3 | case MURMUR3: av_murmur3_update(ctx->ctx, src, len); break; | |
177 | 12 | case RIPEMD128: | |
178 | case RIPEMD160: | ||
179 | case RIPEMD256: | ||
180 | 12 | case RIPEMD320: av_ripemd_update(ctx->ctx, src, len); break; | |
181 | 527 | case SHA160: | |
182 | case SHA224: | ||
183 | 527 | case SHA256: av_sha_update(ctx->ctx, src, len); break; | |
184 | 12 | case SHA512_224: | |
185 | case SHA512_256: | ||
186 | case SHA384: | ||
187 | 12 | case SHA512: av_sha512_update(ctx->ctx, src, len); break; | |
188 | 2006 | case CRC32: ctx->crc = av_crc(ctx->crctab, ctx->crc, src, len); break; | |
189 | 5 | case ADLER32: ctx->crc = av_adler32_update(ctx->crc, src, len); break; | |
190 | } | ||
191 | 181870 | } | |
192 | |||
193 | 8854 | void av_hash_final(AVHashContext *ctx, uint8_t *dst) | |
194 | { | ||
195 |
7/8✓ Branch 0 taken 6805 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 11 times.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 2006 times.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
|
8854 | switch (ctx->type) { |
196 | 6805 | case MD5: av_md5_final(ctx->ctx, dst); break; | |
197 | 3 | case MURMUR3: av_murmur3_final(ctx->ctx, dst); break; | |
198 | 12 | case RIPEMD128: | |
199 | case RIPEMD160: | ||
200 | case RIPEMD256: | ||
201 | 12 | case RIPEMD320: av_ripemd_final(ctx->ctx, dst); break; | |
202 | 11 | case SHA160: | |
203 | case SHA224: | ||
204 | 11 | case SHA256: av_sha_final(ctx->ctx, dst); break; | |
205 | 12 | case SHA512_224: | |
206 | case SHA512_256: | ||
207 | case SHA384: | ||
208 | 12 | case SHA512: av_sha512_final(ctx->ctx, dst); break; | |
209 | 2006 | case CRC32: AV_WB32(dst, ctx->crc ^ UINT32_MAX); break; | |
210 | 5 | case ADLER32: AV_WB32(dst, ctx->crc); break; | |
211 | } | ||
212 | 8854 | } | |
213 | |||
214 | 15 | void av_hash_final_bin(struct AVHashContext *ctx, uint8_t *dst, int size) | |
215 | { | ||
216 | uint8_t buf[AV_HASH_MAX_SIZE]; | ||
217 | 15 | unsigned rsize = av_hash_get_size(ctx); | |
218 | |||
219 | 15 | av_hash_final(ctx, buf); | |
220 | 15 | memcpy(dst, buf, FFMIN(size, rsize)); | |
221 |
1/2✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
|
15 | if (size > rsize) |
222 | 15 | memset(dst + rsize, 0, size - rsize); | |
223 | 15 | } | |
224 | |||
225 | 8824 | void av_hash_final_hex(struct AVHashContext *ctx, uint8_t *dst, int size) | |
226 | { | ||
227 | uint8_t buf[AV_HASH_MAX_SIZE]; | ||
228 | 8824 | unsigned rsize = av_hash_get_size(ctx), i; | |
229 | |||
230 | 8824 | av_hash_final(ctx, buf); | |
231 |
2/2✓ Branch 0 taken 117316 times.
✓ Branch 1 taken 8824 times.
|
126140 | for (i = 0; i < FFMIN(rsize, size / 2); i++) |
232 | 117316 | snprintf(dst + i * 2, size - i * 2, "%02x", buf[i]); | |
233 | 8824 | } | |
234 | |||
235 | 15 | void av_hash_final_b64(struct AVHashContext *ctx, uint8_t *dst, int size) | |
236 | { | ||
237 | uint8_t buf[AV_HASH_MAX_SIZE], b64[AV_BASE64_SIZE(AV_HASH_MAX_SIZE)]; | ||
238 | 15 | unsigned rsize = av_hash_get_size(ctx), osize; | |
239 | |||
240 | 15 | av_hash_final(ctx, buf); | |
241 | 15 | av_base64_encode(b64, sizeof(b64), buf, rsize); | |
242 | 15 | osize = AV_BASE64_SIZE(rsize); | |
243 | 15 | memcpy(dst, b64, FFMIN(osize, size)); | |
244 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
|
15 | if (size < osize) |
245 | ✗ | dst[size - 1] = 0; | |
246 | 15 | } | |
247 | |||
248 | 796 | void av_hash_freep(AVHashContext **ctx) | |
249 | { | ||
250 |
2/2✓ Branch 0 taken 654 times.
✓ Branch 1 taken 142 times.
|
796 | if (*ctx) |
251 | 654 | av_freep(&(*ctx)->ctx); | |
252 | 796 | av_freep(ctx); | |
253 | 796 | } | |
254 |