blob: b0db2970db8a883803d40fb6f2650602b612c7c5
1 | /* |
2 | * Copyright (C) 2007 Michael Niedermayer <michaelni@gmx.at> |
3 | * Copyright (C) 2013 James Almer |
4 | * |
5 | * This file is part of FFmpeg. |
6 | * |
7 | * FFmpeg is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU Lesser General Public |
9 | * License as published by the Free Software Foundation; either |
10 | * version 2.1 of the License, or (at your option) any later version. |
11 | * |
12 | * FFmpeg is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | * Lesser General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU Lesser General Public |
18 | * License along with FFmpeg; if not, write to the Free Software |
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | */ |
21 | |
22 | #include <string.h> |
23 | |
24 | #include "attributes.h" |
25 | #include "avutil.h" |
26 | #include "bswap.h" |
27 | #include "intreadwrite.h" |
28 | #include "ripemd.h" |
29 | #include "mem.h" |
30 | |
31 | /** hash context */ |
32 | typedef struct AVRIPEMD { |
33 | uint8_t digest_len; ///< digest length in 32-bit words |
34 | uint64_t count; ///< number of bytes in buffer |
35 | uint8_t buffer[64]; ///< 512-bit buffer of input values used in hash updating |
36 | uint32_t state[10]; ///< current hash value |
37 | /** function used to update hash for 512-bit input block */ |
38 | void (*transform)(uint32_t *state, const uint8_t buffer[64]); |
39 | } AVRIPEMD; |
40 | |
41 | const int av_ripemd_size = sizeof(AVRIPEMD); |
42 | |
43 | struct AVRIPEMD *av_ripemd_alloc(void) |
44 | { |
45 | return av_mallocz(sizeof(struct AVRIPEMD)); |
46 | } |
47 | |
48 | static const uint32_t KA[4] = { |
49 | 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e |
50 | }; |
51 | |
52 | static const uint32_t KB[4] = { |
53 | 0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9 |
54 | }; |
55 | |
56 | static const int ROTA[80] = { |
57 | 11, 14, 15, 12, 5, 8, 7 , 9, 11, 13, 14, 15, 6, 7, 9, 8, |
58 | 7 , 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, |
59 | 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, |
60 | 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, |
61 | 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 |
62 | }; |
63 | |
64 | static const int ROTB[80] = { |
65 | 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, |
66 | 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, |
67 | 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, |
68 | 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, |
69 | 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 |
70 | }; |
71 | |
72 | static const int WA[80] = { |
73 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, |
74 | 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, |
75 | 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, |
76 | 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, |
77 | 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 |
78 | }; |
79 | |
80 | static const int WB[80] = { |
81 | 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, |
82 | 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, |
83 | 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, |
84 | 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, |
85 | 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 |
86 | }; |
87 | |
88 | #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) |
89 | |
90 | #define ROUND128_0_TO_15(a,b,c,d,e,f,g,h) \ |
91 | a = rol(a + (( b ^ c ^ d) + block[WA[n]]), ROTA[n]); \ |
92 | e = rol(e + ((((f ^ g) & h) ^ g) + block[WB[n]] + KB[0]), ROTB[n]); \ |
93 | n++ |
94 | |
95 | #define ROUND128_16_TO_31(a,b,c,d,e,f,g,h) \ |
96 | a = rol(a + ((((c ^ d) & b) ^ d) + block[WA[n]] + KA[0]), ROTA[n]); \ |
97 | e = rol(e + (((~g | f) ^ h) + block[WB[n]] + KB[1]), ROTB[n]); \ |
98 | n++ |
99 | |
100 | #define ROUND128_32_TO_47(a,b,c,d,e,f,g,h) \ |
101 | a = rol(a + (((~c | b) ^ d) + block[WA[n]] + KA[1]), ROTA[n]); \ |
102 | e = rol(e + ((((g ^ h) & f) ^ h) + block[WB[n]] + KB[2]), ROTB[n]); \ |
103 | n++ |
104 | |
105 | #define ROUND128_48_TO_63(a,b,c,d,e,f,g,h) \ |
106 | a = rol(a + ((((b ^ c) & d) ^ c) + block[WA[n]] + KA[2]), ROTA[n]); \ |
107 | e = rol(e + (( f ^ g ^ h) + block[WB[n]]), ROTB[n]); \ |
108 | n++ |
109 | |
110 | #define R128_0 \ |
111 | ROUND128_0_TO_15(a,b,c,d,e,f,g,h); \ |
112 | ROUND128_0_TO_15(d,a,b,c,h,e,f,g); \ |
113 | ROUND128_0_TO_15(c,d,a,b,g,h,e,f); \ |
114 | ROUND128_0_TO_15(b,c,d,a,f,g,h,e) |
115 | |
116 | #define R128_16 \ |
117 | ROUND128_16_TO_31(a,b,c,d,e,f,g,h); \ |
118 | ROUND128_16_TO_31(d,a,b,c,h,e,f,g); \ |
119 | ROUND128_16_TO_31(c,d,a,b,g,h,e,f); \ |
120 | ROUND128_16_TO_31(b,c,d,a,f,g,h,e) |
121 | |
122 | #define R128_32 \ |
123 | ROUND128_32_TO_47(a,b,c,d,e,f,g,h); \ |
124 | ROUND128_32_TO_47(d,a,b,c,h,e,f,g); \ |
125 | ROUND128_32_TO_47(c,d,a,b,g,h,e,f); \ |
126 | ROUND128_32_TO_47(b,c,d,a,f,g,h,e) |
127 | |
128 | #define R128_48 \ |
129 | ROUND128_48_TO_63(a,b,c,d,e,f,g,h); \ |
130 | ROUND128_48_TO_63(d,a,b,c,h,e,f,g); \ |
131 | ROUND128_48_TO_63(c,d,a,b,g,h,e,f); \ |
132 | ROUND128_48_TO_63(b,c,d,a,f,g,h,e) |
133 | |
134 | static void ripemd128_transform(uint32_t *state, const uint8_t buffer[64]) |
135 | { |
136 | uint32_t a, b, c, d, e, f, g, h, av_unused t; |
137 | uint32_t block[16]; |
138 | int n; |
139 | |
140 | a = e = state[0]; |
141 | b = f = state[1]; |
142 | c = g = state[2]; |
143 | d = h = state[3]; |
144 | |
145 | for (n = 0; n < 16; n++) |
146 | block[n] = AV_RL32(buffer + 4 * n); |
147 | n = 0; |
148 | |
149 | #if CONFIG_SMALL |
150 | for (; n < 16;) { |
151 | ROUND128_0_TO_15(a,b,c,d,e,f,g,h); |
152 | t = d; d = c; c = b; b = a; a = t; |
153 | t = h; h = g; g = f; f = e; e = t; |
154 | } |
155 | |
156 | for (; n < 32;) { |
157 | ROUND128_16_TO_31(a,b,c,d,e,f,g,h); |
158 | t = d; d = c; c = b; b = a; a = t; |
159 | t = h; h = g; g = f; f = e; e = t; |
160 | } |
161 | |
162 | for (; n < 48;) { |
163 | ROUND128_32_TO_47(a,b,c,d,e,f,g,h); |
164 | t = d; d = c; c = b; b = a; a = t; |
165 | t = h; h = g; g = f; f = e; e = t; |
166 | } |
167 | |
168 | for (; n < 64;) { |
169 | ROUND128_48_TO_63(a,b,c,d,e,f,g,h); |
170 | t = d; d = c; c = b; b = a; a = t; |
171 | t = h; h = g; g = f; f = e; e = t; |
172 | } |
173 | #else |
174 | |
175 | R128_0; R128_0; R128_0; R128_0; |
176 | |
177 | R128_16; R128_16; R128_16; R128_16; |
178 | |
179 | R128_32; R128_32; R128_32; R128_32; |
180 | |
181 | R128_48; R128_48; R128_48; R128_48; |
182 | #endif |
183 | |
184 | h += c + state[1]; |
185 | state[1] = state[2] + d + e; |
186 | state[2] = state[3] + a + f; |
187 | state[3] = state[0] + b + g; |
188 | state[0] = h; |
189 | } |
190 | |
191 | static void ripemd256_transform(uint32_t *state, const uint8_t buffer[64]) |
192 | { |
193 | uint32_t a, b, c, d, e, f, g, h, av_unused t; |
194 | uint32_t block[16]; |
195 | int n; |
196 | |
197 | a = state[0]; b = state[1]; c = state[2]; d = state[3]; |
198 | e = state[4]; f = state[5]; g = state[6]; h = state[7]; |
199 | |
200 | for (n = 0; n < 16; n++) |
201 | block[n] = AV_RL32(buffer + 4 * n); |
202 | n = 0; |
203 | |
204 | #if CONFIG_SMALL |
205 | for (; n < 16;) { |
206 | ROUND128_0_TO_15(a,b,c,d,e,f,g,h); |
207 | t = d; d = c; c = b; b = a; a = t; |
208 | t = h; h = g; g = f; f = e; e = t; |
209 | } |
210 | FFSWAP(uint32_t, a, e); |
211 | |
212 | for (; n < 32;) { |
213 | ROUND128_16_TO_31(a,b,c,d,e,f,g,h); |
214 | t = d; d = c; c = b; b = a; a = t; |
215 | t = h; h = g; g = f; f = e; e = t; |
216 | } |
217 | FFSWAP(uint32_t, b, f); |
218 | |
219 | for (; n < 48;) { |
220 | ROUND128_32_TO_47(a,b,c,d,e,f,g,h); |
221 | t = d; d = c; c = b; b = a; a = t; |
222 | t = h; h = g; g = f; f = e; e = t; |
223 | } |
224 | FFSWAP(uint32_t, c, g); |
225 | |
226 | for (; n < 64;) { |
227 | ROUND128_48_TO_63(a,b,c,d,e,f,g,h); |
228 | t = d; d = c; c = b; b = a; a = t; |
229 | t = h; h = g; g = f; f = e; e = t; |
230 | } |
231 | FFSWAP(uint32_t, d, h); |
232 | #else |
233 | |
234 | R128_0; R128_0; R128_0; R128_0; |
235 | FFSWAP(uint32_t, a, e); |
236 | |
237 | R128_16; R128_16; R128_16; R128_16; |
238 | FFSWAP(uint32_t, b, f); |
239 | |
240 | R128_32; R128_32; R128_32; R128_32; |
241 | FFSWAP(uint32_t, c, g); |
242 | |
243 | R128_48; R128_48; R128_48; R128_48; |
244 | FFSWAP(uint32_t, d, h); |
245 | #endif |
246 | |
247 | state[0] += a; state[1] += b; state[2] += c; state[3] += d; |
248 | state[4] += e; state[5] += f; state[6] += g; state[7] += h; |
249 | } |
250 | |
251 | #define ROTATE(x,y) \ |
252 | x = rol(x, 10); \ |
253 | y = rol(y, 10); \ |
254 | n++ |
255 | |
256 | #define ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j) \ |
257 | a = rol(a + (( b ^ c ^ d) + block[WA[n]]), ROTA[n]) + e; \ |
258 | f = rol(f + (((~i | h) ^ g) + block[WB[n]] + KB[0]), ROTB[n]) + j; \ |
259 | ROTATE(c,h) |
260 | |
261 | #define ROUND160_16_TO_31(a,b,c,d,e,f,g,h,i,j) \ |
262 | a = rol(a + ((((c ^ d) & b) ^ d) + block[WA[n]] + KA[0]), ROTA[n]) + e; \ |
263 | f = rol(f + ((((g ^ h) & i) ^ h) + block[WB[n]] + KB[1]), ROTB[n]) + j; \ |
264 | ROTATE(c,h) |
265 | |
266 | #define ROUND160_32_TO_47(a,b,c,d,e,f,g,h,i,j) \ |
267 | a = rol(a + (((~c | b) ^ d) + block[WA[n]] + KA[1]), ROTA[n]) + e; \ |
268 | f = rol(f + (((~h | g) ^ i) + block[WB[n]] + KB[2]), ROTB[n]) + j; \ |
269 | ROTATE(c,h) |
270 | |
271 | #define ROUND160_48_TO_63(a,b,c,d,e,f,g,h,i,j) \ |
272 | a = rol(a + ((((b ^ c) & d) ^ c) + block[WA[n]] + KA[2]), ROTA[n]) + e; \ |
273 | f = rol(f + ((((h ^ i) & g) ^ i) + block[WB[n]] + KB[3]), ROTB[n]) + j; \ |
274 | ROTATE(c,h) |
275 | |
276 | #define ROUND160_64_TO_79(a,b,c,d,e,f,g,h,i,j) \ |
277 | a = rol(a + (((~d | c) ^ b) + block[WA[n]] + KA[3]), ROTA[n]) + e; \ |
278 | f = rol(f + (( g ^ h ^ i) + block[WB[n]]), ROTB[n]) + j; \ |
279 | ROTATE(c,h) |
280 | |
281 | #define R160_0 \ |
282 | ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j); \ |
283 | ROUND160_0_TO_15(e,a,b,c,d,j,f,g,h,i); \ |
284 | ROUND160_0_TO_15(d,e,a,b,c,i,j,f,g,h); \ |
285 | ROUND160_0_TO_15(c,d,e,a,b,h,i,j,f,g); \ |
286 | ROUND160_0_TO_15(b,c,d,e,a,g,h,i,j,f) |
287 | |
288 | #define R160_16 \ |
289 | ROUND160_16_TO_31(e,a,b,c,d,j,f,g,h,i); \ |
290 | ROUND160_16_TO_31(d,e,a,b,c,i,j,f,g,h); \ |
291 | ROUND160_16_TO_31(c,d,e,a,b,h,i,j,f,g); \ |
292 | ROUND160_16_TO_31(b,c,d,e,a,g,h,i,j,f); \ |
293 | ROUND160_16_TO_31(a,b,c,d,e,f,g,h,i,j) |
294 | |
295 | #define R160_32 \ |
296 | ROUND160_32_TO_47(d,e,a,b,c,i,j,f,g,h); \ |
297 | ROUND160_32_TO_47(c,d,e,a,b,h,i,j,f,g); \ |
298 | ROUND160_32_TO_47(b,c,d,e,a,g,h,i,j,f); \ |
299 | ROUND160_32_TO_47(a,b,c,d,e,f,g,h,i,j); \ |
300 | ROUND160_32_TO_47(e,a,b,c,d,j,f,g,h,i) |
301 | |
302 | #define R160_48 \ |
303 | ROUND160_48_TO_63(c,d,e,a,b,h,i,j,f,g); \ |
304 | ROUND160_48_TO_63(b,c,d,e,a,g,h,i,j,f); \ |
305 | ROUND160_48_TO_63(a,b,c,d,e,f,g,h,i,j); \ |
306 | ROUND160_48_TO_63(e,a,b,c,d,j,f,g,h,i); \ |
307 | ROUND160_48_TO_63(d,e,a,b,c,i,j,f,g,h) |
308 | |
309 | #define R160_64 \ |
310 | ROUND160_64_TO_79(b,c,d,e,a,g,h,i,j,f); \ |
311 | ROUND160_64_TO_79(a,b,c,d,e,f,g,h,i,j); \ |
312 | ROUND160_64_TO_79(e,a,b,c,d,j,f,g,h,i); \ |
313 | ROUND160_64_TO_79(d,e,a,b,c,i,j,f,g,h); \ |
314 | ROUND160_64_TO_79(c,d,e,a,b,h,i,j,f,g) |
315 | |
316 | static void ripemd160_transform(uint32_t *state, const uint8_t buffer[64]) |
317 | { |
318 | uint32_t a, b, c, d, e, f, g, h, i, j, av_unused t; |
319 | uint32_t block[16]; |
320 | int n; |
321 | |
322 | a = f = state[0]; |
323 | b = g = state[1]; |
324 | c = h = state[2]; |
325 | d = i = state[3]; |
326 | e = j = state[4]; |
327 | |
328 | for (n = 0; n < 16; n++) |
329 | block[n] = AV_RL32(buffer + 4 * n); |
330 | n = 0; |
331 | |
332 | #if CONFIG_SMALL |
333 | for (; n < 16;) { |
334 | ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j); |
335 | t = e; e = d; d = c; c = b; b = a; a = t; |
336 | t = j; j = i; i = h; h = g; g = f; f = t; |
337 | } |
338 | |
339 | for (; n < 32;) { |
340 | ROUND160_16_TO_31(a,b,c,d,e,f,g,h,i,j); |
341 | t = e; e = d; d = c; c = b; b = a; a = t; |
342 | t = j; j = i; i = h; h = g; g = f; f = t; |
343 | } |
344 | |
345 | for (; n < 48;) { |
346 | ROUND160_32_TO_47(a,b,c,d,e,f,g,h,i,j); |
347 | t = e; e = d; d = c; c = b; b = a; a = t; |
348 | t = j; j = i; i = h; h = g; g = f; f = t; |
349 | } |
350 | |
351 | for (; n < 64;) { |
352 | ROUND160_48_TO_63(a,b,c,d,e,f,g,h,i,j); |
353 | t = e; e = d; d = c; c = b; b = a; a = t; |
354 | t = j; j = i; i = h; h = g; g = f; f = t; |
355 | } |
356 | |
357 | for (; n < 80;) { |
358 | ROUND160_64_TO_79(a,b,c,d,e,f,g,h,i,j); |
359 | t = e; e = d; d = c; c = b; b = a; a = t; |
360 | t = j; j = i; i = h; h = g; g = f; f = t; |
361 | } |
362 | #else |
363 | |
364 | R160_0; R160_0; R160_0; |
365 | ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j); |
366 | |
367 | R160_16; R160_16; R160_16; |
368 | ROUND160_16_TO_31(e,a,b,c,d,j,f,g,h,i); |
369 | |
370 | R160_32; R160_32; R160_32; |
371 | ROUND160_32_TO_47(d,e,a,b,c,i,j,f,g,h); |
372 | |
373 | R160_48; R160_48; R160_48; |
374 | ROUND160_48_TO_63(c,d,e,a,b,h,i,j,f,g); |
375 | |
376 | R160_64; R160_64; R160_64; |
377 | ROUND160_64_TO_79(b,c,d,e,a,g,h,i,j,f); |
378 | #endif |
379 | |
380 | i += c + state[1]; |
381 | state[1] = state[2] + d + j; |
382 | state[2] = state[3] + e + f; |
383 | state[3] = state[4] + a + g; |
384 | state[4] = state[0] + b + h; |
385 | state[0] = i; |
386 | } |
387 | |
388 | static void ripemd320_transform(uint32_t *state, const uint8_t buffer[64]) |
389 | { |
390 | uint32_t a, b, c, d, e, f, g, h, i, j, av_unused t; |
391 | uint32_t block[16]; |
392 | int n; |
393 | |
394 | a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; |
395 | f = state[5]; g = state[6]; h = state[7]; i = state[8]; j = state[9]; |
396 | |
397 | for (n = 0; n < 16; n++) |
398 | block[n] = AV_RL32(buffer + 4 * n); |
399 | n = 0; |
400 | |
401 | #if CONFIG_SMALL |
402 | for (; n < 16;) { |
403 | ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j); |
404 | t = e; e = d; d = c; c = b; b = a; a = t; |
405 | t = j; j = i; i = h; h = g; g = f; f = t; |
406 | } |
407 | FFSWAP(uint32_t, b, g); |
408 | |
409 | for (; n < 32;) { |
410 | ROUND160_16_TO_31(a,b,c,d,e,f,g,h,i,j); |
411 | t = e; e = d; d = c; c = b; b = a; a = t; |
412 | t = j; j = i; i = h; h = g; g = f; f = t; |
413 | } |
414 | FFSWAP(uint32_t, d, i); |
415 | |
416 | for (; n < 48;) { |
417 | ROUND160_32_TO_47(a,b,c,d,e,f,g,h,i,j); |
418 | t = e; e = d; d = c; c = b; b = a; a = t; |
419 | t = j; j = i; i = h; h = g; g = f; f = t; |
420 | } |
421 | FFSWAP(uint32_t, a, f); |
422 | |
423 | for (; n < 64;) { |
424 | ROUND160_48_TO_63(a,b,c,d,e,f,g,h,i,j); |
425 | t = e; e = d; d = c; c = b; b = a; a = t; |
426 | t = j; j = i; i = h; h = g; g = f; f = t; |
427 | } |
428 | FFSWAP(uint32_t, c, h); |
429 | |
430 | for (; n < 80;) { |
431 | ROUND160_64_TO_79(a,b,c,d,e,f,g,h,i,j); |
432 | t = e; e = d; d = c; c = b; b = a; a = t; |
433 | t = j; j = i; i = h; h = g; g = f; f = t; |
434 | } |
435 | FFSWAP(uint32_t, e, j); |
436 | #else |
437 | |
438 | R160_0; R160_0; R160_0; |
439 | ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j); |
440 | FFSWAP(uint32_t, a, f); |
441 | |
442 | R160_16; R160_16; R160_16; |
443 | ROUND160_16_TO_31(e,a,b,c,d,j,f,g,h,i); |
444 | FFSWAP(uint32_t, b, g); |
445 | |
446 | R160_32; R160_32; R160_32; |
447 | ROUND160_32_TO_47(d,e,a,b,c,i,j,f,g,h); |
448 | FFSWAP(uint32_t, c, h); |
449 | |
450 | R160_48; R160_48; R160_48; |
451 | ROUND160_48_TO_63(c,d,e,a,b,h,i,j,f,g); |
452 | FFSWAP(uint32_t, d, i); |
453 | |
454 | R160_64; R160_64; R160_64; |
455 | ROUND160_64_TO_79(b,c,d,e,a,g,h,i,j,f); |
456 | FFSWAP(uint32_t, e, j); |
457 | #endif |
458 | |
459 | state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; |
460 | state[5] += f; state[6] += g; state[7] += h; state[8] += i; state[9] += j; |
461 | } |
462 | |
463 | av_cold int av_ripemd_init(AVRIPEMD *ctx, int bits) |
464 | { |
465 | ctx->digest_len = bits >> 5; |
466 | switch (bits) { |
467 | case 128: // RIPEMD-128 |
468 | ctx->state[0] = 0x67452301; |
469 | ctx->state[1] = 0xEFCDAB89; |
470 | ctx->state[2] = 0x98BADCFE; |
471 | ctx->state[3] = 0x10325476; |
472 | ctx->transform = ripemd128_transform; |
473 | break; |
474 | case 160: // RIPEMD-160 |
475 | ctx->state[0] = 0x67452301; |
476 | ctx->state[1] = 0xEFCDAB89; |
477 | ctx->state[2] = 0x98BADCFE; |
478 | ctx->state[3] = 0x10325476; |
479 | ctx->state[4] = 0xC3D2E1F0; |
480 | ctx->transform = ripemd160_transform; |
481 | break; |
482 | case 256: // RIPEMD-256 |
483 | ctx->state[0] = 0x67452301; |
484 | ctx->state[1] = 0xEFCDAB89; |
485 | ctx->state[2] = 0x98BADCFE; |
486 | ctx->state[3] = 0x10325476; |
487 | ctx->state[4] = 0x76543210; |
488 | ctx->state[5] = 0xFEDCBA98; |
489 | ctx->state[6] = 0x89ABCDEF; |
490 | ctx->state[7] = 0x01234567; |
491 | ctx->transform = ripemd256_transform; |
492 | break; |
493 | case 320: // RIPEMD-320 |
494 | ctx->state[0] = 0x67452301; |
495 | ctx->state[1] = 0xEFCDAB89; |
496 | ctx->state[2] = 0x98BADCFE; |
497 | ctx->state[3] = 0x10325476; |
498 | ctx->state[4] = 0xC3D2E1F0; |
499 | ctx->state[5] = 0x76543210; |
500 | ctx->state[6] = 0xFEDCBA98; |
501 | ctx->state[7] = 0x89ABCDEF; |
502 | ctx->state[8] = 0x01234567; |
503 | ctx->state[9] = 0x3C2D1E0F; |
504 | ctx->transform = ripemd320_transform; |
505 | break; |
506 | default: |
507 | return AVERROR(EINVAL); |
508 | } |
509 | ctx->count = 0; |
510 | return 0; |
511 | } |
512 | |
513 | void av_ripemd_update(AVRIPEMD* ctx, const uint8_t* data, unsigned int len) |
514 | { |
515 | unsigned int i, j; |
516 | |
517 | j = ctx->count & 63; |
518 | ctx->count += len; |
519 | #if CONFIG_SMALL |
520 | for (i = 0; i < len; i++) { |
521 | ctx->buffer[j++] = data[i]; |
522 | if (64 == j) { |
523 | ctx->transform(ctx->state, ctx->buffer); |
524 | j = 0; |
525 | } |
526 | } |
527 | #else |
528 | if ((j + len) > 63) { |
529 | memcpy(&ctx->buffer[j], data, (i = 64 - j)); |
530 | ctx->transform(ctx->state, ctx->buffer); |
531 | for (; i + 63 < len; i += 64) |
532 | ctx->transform(ctx->state, &data[i]); |
533 | j = 0; |
534 | } else |
535 | i = 0; |
536 | memcpy(&ctx->buffer[j], &data[i], len - i); |
537 | #endif |
538 | } |
539 | |
540 | void av_ripemd_final(AVRIPEMD* ctx, uint8_t *digest) |
541 | { |
542 | int i; |
543 | uint64_t finalcount = av_le2ne64(ctx->count << 3); |
544 | |
545 | av_ripemd_update(ctx, "\200", 1); |
546 | while ((ctx->count & 63) != 56) |
547 | av_ripemd_update(ctx, "", 1); |
548 | av_ripemd_update(ctx, (uint8_t *)&finalcount, 8); /* Should cause a transform() */ |
549 | for (i = 0; i < ctx->digest_len; i++) |
550 | AV_WL32(digest + i*4, ctx->state[i]); |
551 | } |
552 |