rpm 5.2.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

digest.c
Go to the documentation of this file.
1
5 #include "system.h"
6
7 #include "rpmio_internal.h"
8
9 #include <rpmbc.h>
10
11 #include "crc.h"
12 #include "md2.h"
13 #include "md4.h"
14 #include "sha224.h"
15 #include "rmd128.h"
16 #include "rmd160.h"
17 #include "rmd256.h"
18 #include "rmd320.h"
19 #include "salsa10.h"
20 #include "salsa20.h"
21 #include "tiger.h"
22
23 #include "debug.h"
24
25 #ifdef SHA_DEBUG
26 #define DPRINTF(_a) fprintf _a
27 #else
28 #define DPRINTF(_a)
29 #endif
30
31 /* Include Bob Jenkins lookup3 hash */
32 #define _JLU3_jlu32l
33 #include "lookup3.c"
34
35 /*@access DIGEST_CTX@*/
36
40 struct DIGEST_CTX_s {
41 /*@observer@*/
42 const char * name;
43 size_t paramsize;
44 size_t datasize;
45 size_t digestsize;
46 int (*Reset) (void * param)
47 /*@modifies param @*/;
48 int (*Update) (void * param, const byte * data, size_t size)
49 /*@modifies param @*/;
50 int (*Digest) (void * param, /*@out@*/ byte * digest)
51 /*@modifies param, digest @*/;
52 pgpHashAlgo hashalgo;
53 rpmDigestFlags flags;
54 /*@observer@*/ /*@null@*/
55 const char * asn1;
56 void * param;
57 };
58
59 pgpHashAlgo rpmDigestAlgo(DIGEST_CTX ctx)
60 {
61 return (ctx != NULL ? ctx->hashalgo : PGPHASHALGO_NONE);
62 }
63
64 const char * rpmDigestName(DIGEST_CTX ctx)
65 {
66 return (ctx != NULL ? ctx->name : "UNKNOWN");
67 }
68
69 const char * rpmDigestASN1(DIGEST_CTX ctx)
70 {
71 return (ctx != NULL ? ctx->asn1 : NULL);
72 }
73
74
75 DIGEST_CTX
76 rpmDigestDup(DIGEST_CTX octx)
77 {
78 DIGEST_CTX nctx;
79 nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
80 nctx->param = memcpy(xcalloc(1, nctx->paramsize), octx->param, nctx->paramsize);
81 return nctx;
82 }
83
84 DIGEST_CTX
85 rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
86 {
87 DIGEST_CTX ctx = xcalloc(1, sizeof(*ctx));
88 int xx;
89
90 ctx->hashalgo = hashalgo;
91 ctx->flags = flags;
92
93 switch (hashalgo) {
94 case PGPHASHALGO_MD5:
95 ctx->name = "MD5";
96 ctx->digestsize = 128/8;
97 ctx->datasize = 64;
98 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
99 ctx->paramsize = sizeof(md5Param);
100 /*@=sizeoftype@*/
101 ctx->param = xcalloc(1, ctx->paramsize);
102 /*@-type@*/
103 ctx->Reset = (int (*)(void *)) md5Reset;
104 ctx->Update = (int (*)(void *, const byte *, size_t)) md5Update;
105 ctx->Digest = (int (*)(void *, byte *)) md5Digest;
106 /*@=type@*/
107 ctx->asn1 = "3020300c06082a864886f70d020505000410";
108 break;
109 case PGPHASHALGO_SHA1:
110 ctx->name = "SHA1";
111 ctx->digestsize = 160/8;
112 ctx->datasize = 64;
113 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
114 ctx->paramsize = sizeof(sha1Param);
115 /*@=sizeoftype@*/
116 ctx->param = xcalloc(1, ctx->paramsize);
117 /*@-type@*/
118 ctx->Reset = (int (*)(void *)) sha1Reset;
119 ctx->Update = (int (*)(void *, const byte *, size_t)) sha1Update;
120 ctx->Digest = (int (*)(void *, byte *)) sha1Digest;
121 /*@=type@*/
122 ctx->asn1 = "3021300906052b0e03021a05000414";
123 break;
124 case PGPHASHALGO_RIPEMD128:
125 ctx->name = "RIPEMD128";
126 ctx->digestsize = 128/8;
127 ctx->datasize = 64;
128 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
129 ctx->paramsize = sizeof(rmd128Param);
130 /*@=sizeoftype@*/
131 ctx->param = xcalloc(1, ctx->paramsize);
132 /*@-type@*/
133 ctx->Reset = (int (*)(void *)) rmd128Reset;
134 ctx->Update = (int (*)(void *, const byte *, size_t)) rmd128Update;
135 ctx->Digest = (int (*)(void *, byte *)) rmd128Digest;
136 /*@=type@*/
137 break;
138 case PGPHASHALGO_RIPEMD160:
139 ctx->name = "RIPEMD160";
140 ctx->digestsize = 160/8;
141 ctx->datasize = 64;
142 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
143 ctx->paramsize = sizeof(rmd160Param);
144 /*@=sizeoftype@*/
145 ctx->param = xcalloc(1, ctx->paramsize);
146 /*@-type@*/
147 ctx->Reset = (int (*)(void *)) rmd160Reset;
148 ctx->Update = (int (*)(void *, const byte *, size_t)) rmd160Update;
149 ctx->Digest = (int (*)(void *, byte *)) rmd160Digest;
150 /*@=type@*/
151 ctx->asn1 = "3021300906052b2403020105000414";
152 break;
153 case PGPHASHALGO_RIPEMD256:
154 ctx->name = "RIPEMD256";
155 ctx->digestsize = 256/8;
156 ctx->datasize = 64;
157 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
158 ctx->paramsize = sizeof(rmd256Param);
159 /*@=sizeoftype@*/
160 ctx->param = xcalloc(1, ctx->paramsize);
161 /*@-type@*/
162 ctx->Reset = (int (*)(void *)) rmd256Reset;
163 ctx->Update = (int (*)(void *, const byte *, size_t)) rmd256Update;
164 ctx->Digest = (int (*)(void *, byte *)) rmd256Digest;
165 /*@=type@*/
166 break;
167 case PGPHASHALGO_RIPEMD320:
168 ctx->name = "RIPEMD320";
169 ctx->digestsize = 320/8;
170 ctx->datasize = 64;
171 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
172 ctx->paramsize = sizeof(rmd320Param);
173 /*@=sizeoftype@*/
174 ctx->param = xcalloc(1, ctx->paramsize);
175 /*@-type@*/
176 ctx->Reset = (int (*)(void *)) rmd320Reset;
177 ctx->Update = (int (*)(void *, const byte *, size_t)) rmd320Update;
178 ctx->Digest = (int (*)(void *, byte *)) rmd320Digest;
179 /*@=type@*/
180 break;
181 case PGPHASHALGO_SALSA10:
182 ctx->name = "SALSA10";
183 ctx->digestsize = 512/8;
184 ctx->datasize = 64;
185 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
186 ctx->paramsize = sizeof(salsa10Param);
187 /*@=sizeoftype@*/
188 ctx->param = xcalloc(1, ctx->paramsize);
189 /*@-type@*/
190 ctx->Reset = (int (*)(void *)) salsa10Reset;
191 ctx->Update = (int (*)(void *, const byte *, size_t)) salsa10Update;
192 ctx->Digest = (int (*)(void *, byte *)) salsa10Digest;
193 /*@=type@*/
194 break;
195 case PGPHASHALGO_SALSA20:
196 ctx->name = "SALSA20";
197 ctx->digestsize = 512/8;
198 ctx->datasize = 64;
199 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
200 ctx->paramsize = sizeof(salsa20Param);
201 /*@=sizeoftype@*/
202 ctx->param = xcalloc(1, ctx->paramsize);
203 /*@-type@*/
204 ctx->Reset = (int (*)(void *)) salsa20Reset;
205 ctx->Update = (int (*)(void *, const byte *, size_t)) salsa20Update;
206 ctx->Digest = (int (*)(void *, byte *)) salsa20Digest;
207 /*@=type@*/
208 break;
209 case PGPHASHALGO_TIGER192:
210 ctx->name = "TIGER192";
211 ctx->digestsize = 192/8;
212 ctx->datasize = 64;
213 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
214 ctx->paramsize = sizeof(tigerParam);
215 /*@=sizeoftype@*/
216 ctx->param = xcalloc(1, ctx->paramsize);
217 /*@-type@*/
218 ctx->Reset = (int (*)(void *)) tigerReset;
219 ctx->Update = (int (*)(void *, const byte *, size_t)) tigerUpdate;
220 ctx->Digest = (int (*)(void *, byte *)) tigerDigest;
221 /*@=type@*/
222 ctx->asn1 = "3029300d06092b06010401da470c0205000418";
223 break;
224 case PGPHASHALGO_MD2:
225 ctx->name = "MD2";
226 ctx->digestsize = 128/8;
227 ctx->datasize = 16;
228 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
229 ctx->paramsize = sizeof(md2Param);
230 /*@=sizeoftype@*/
231 ctx->param = xcalloc(1, ctx->paramsize);
232 /*@-type@*/
233 ctx->Reset = (int (*)(void *)) md2Reset;
234 ctx->Update = (int (*)(void *, const byte *, size_t)) md2Update;
235 ctx->Digest = (int (*)(void *, byte *)) md2Digest;
236 /*@=type@*/
237 ctx->asn1 = "3020300c06082a864886f70d020205000410";
238 break;
239 case PGPHASHALGO_MD4:
240 ctx->name = "MD4";
241 ctx->digestsize = 128/8;
242 ctx->datasize = 64;
243 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
244 ctx->paramsize = sizeof(md4Param);
245 /*@=sizeoftype@*/
246 ctx->param = xcalloc(1, ctx->paramsize);
247 /*@-type@*/
248 ctx->Reset = (int (*)(void *)) md4Reset;
249 ctx->Update = (int (*)(void *, const byte *, size_t)) md4Update;
250 ctx->Digest = (int (*)(void *, byte *)) md4Digest;
251 /*@=type@*/
252 break;
253 case PGPHASHALGO_CRC32:
254 ctx->name = "CRC32";
255 ctx->digestsize = 32/8;
256 ctx->datasize = 8;
257 { sum32Param * mp = xcalloc(1, sizeof(*mp));
258 /*@-type @*/
259 mp->update = (rpmuint32_t (*)(rpmuint32_t, const byte *, size_t)) __crc32;
260 mp->combine = (rpmuint32_t (*)(rpmuint32_t, rpmuint32_t, size_t)) __crc32_combine;
261 /*@=type @*/
262 ctx->paramsize = sizeof(*mp);
263 ctx->param = mp;
264 }
265 /*@-type@*/
266 ctx->Reset = (int (*)(void *)) sum32Reset;
267 ctx->Update = (int (*)(void *, const byte *, size_t)) sum32Update;
268 ctx->Digest = (int (*)(void *, byte *)) sum32Digest;
269 /*@=type@*/
270 break;
271 case PGPHASHALGO_ADLER32:
272 ctx->name = "ADLER32";
273 ctx->digestsize = 32/8;
274 ctx->datasize = 8;
275 { sum32Param * mp = xcalloc(1, sizeof(*mp));
276 /*@-type @*/
277 mp->update = (rpmuint32_t (*)(rpmuint32_t, const byte *, size_t)) __adler32;
278 mp->combine = (rpmuint32_t (*)(rpmuint32_t, rpmuint32_t, size_t)) __adler32_combine;
279 /*@=type @*/
280 ctx->paramsize = sizeof(*mp);
281 ctx->param = mp;
282 }
283 /*@-type@*/
284 ctx->Reset = (int (*)(void *)) sum32Reset;
285 ctx->Update = (int (*)(void *, const byte *, size_t)) sum32Update;
286 ctx->Digest = (int (*)(void *, byte *)) sum32Digest;
287 /*@=type@*/
288 break;
289 case PGPHASHALGO_JLU32:
290 ctx->name = "JLU32";
291 ctx->digestsize = 32/8;
292 ctx->datasize = 8;
293 { sum32Param * mp = xcalloc(1, sizeof(*mp));
294 /*@-type @*/
295 mp->update = (rpmuint32_t (*)(rpmuint32_t, const byte *, size_t)) jlu32l;
296 /*@=type @*/
297 ctx->paramsize = sizeof(*mp);
298 ctx->param = mp;
299 }
300 /*@-type@*/
301 ctx->Reset = (int (*)(void *)) sum32Reset;
302 ctx->Update = (int (*)(void *, const byte *, size_t)) sum32Update;
303 ctx->Digest = (int (*)(void *, byte *)) sum32Digest;
304 /*@=type@*/
305 break;
306 case PGPHASHALGO_CRC64:
307 ctx->name = "CRC64";
308 ctx->digestsize = 64/8;
309 ctx->datasize = 8;
310 { sum64Param * mp = xcalloc(1, sizeof(*mp));
311 /*@-type@*/
312 mp->update = (rpmuint64_t (*)(rpmuint64_t, const byte *, size_t)) __crc64;
313 mp->combine = (rpmuint64_t (*)(rpmuint64_t, rpmuint64_t, size_t)) __crc64_combine;
314 /*@=type@*/
315 ctx->paramsize = sizeof(*mp);
316 ctx->param = mp;
317 }
318 /*@-type@*/
319 ctx->Reset = (int (*)(void *)) sum64Reset;
320 ctx->Update = (int (*)(void *, const byte *, size_t)) sum64Update;
321 ctx->Digest = (int (*)(void *, byte *)) sum64Digest;
322 /*@=type@*/
323 break;
324 #if defined(HAVE_BEECRYPT_API_H)
325 case PGPHASHALGO_SHA224:
326 ctx->name = "SHA224";
327 ctx->digestsize = 224/8;
328 ctx->datasize = 64;
329 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
330 ctx->paramsize = sizeof(sha224Param);
331 /*@=sizeoftype@*/
332 ctx->param = xcalloc(1, ctx->paramsize);
333 /*@-type@*/
334 ctx->Reset = (int (*)(void *)) sha224Reset;
335 ctx->Update = (int (*)(void *, const byte *, size_t)) sha224Update;
336 ctx->Digest = (int (*)(void *, byte *)) sha224Digest;
337 /*@=type@*/
338 ctx->asn1 = "302d300d06096086480165030402040500041C";
339 break;
340 case PGPHASHALGO_SHA256:
341 ctx->name = "SHA256";
342 ctx->digestsize = 256/8;
343 ctx->datasize = 64;
344 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
345 ctx->paramsize = sizeof(sha256Param);
346 /*@=sizeoftype@*/
347 ctx->param = xcalloc(1, ctx->paramsize);
348 /*@-type@*/
349 ctx->Reset = (int (*)(void *)) sha256Reset;
350 ctx->Update = (int (*)(void *, const byte *, size_t)) sha256Update;
351 ctx->Digest = (int (*)(void *, byte *)) sha256Digest;
352 /*@=type@*/
353 ctx->asn1 = "3031300d060960864801650304020105000420";
354 break;
355 case PGPHASHALGO_SHA384:
356 ctx->name = "SHA384";
357 ctx->digestsize = 384/8;
358 ctx->datasize = 128;
359 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
360 ctx->paramsize = sizeof(sha384Param);
361 /*@=sizeoftype@*/
362 ctx->param = xcalloc(1, ctx->paramsize);
363 /*@-type@*/
364 ctx->Reset = (int (*)(void *)) sha384Reset;
365 ctx->Update = (int (*)(void *, const byte *, size_t)) sha384Update;
366 ctx->Digest = (int (*)(void *, byte *)) sha384Digest;
367 /*@=type@*/
368 ctx->asn1 = "3041300d060960864801650304020205000430";
369 break;
370 case PGPHASHALGO_SHA512:
371 ctx->name = "SHA512";
372 ctx->digestsize = 512/8;
373 ctx->datasize = 128;
374 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
375 ctx->paramsize = sizeof(sha512Param);
376 /*@=sizeoftype@*/
377 ctx->param = xcalloc(1, ctx->paramsize);
378 /*@-type@*/
379 ctx->Reset = (int (*)(void *)) sha512Reset;
380 ctx->Update = (int (*)(void *, const byte *, size_t)) sha512Update;
381 ctx->Digest = (int (*)(void *, byte *)) sha512Digest;
382 /*@=type@*/
383 ctx->asn1 = "3051300d060960864801650304020305000440";
384 break;
385 #endif
386 case PGPHASHALGO_HAVAL_5_160:
387 default:
388 free(ctx);
389 return NULL;
390 /*@notreached@*/ break;
391 }
392
393 xx = (*ctx->Reset) (ctx->param);
394
395 DPRINTF((stderr, "*** Init(%x) ctx %p param %p\n", flags, ctx, ctx->param));
396 return ctx;
397 }
398
399 /*@-mustmod@*/ /* LCL: ctx->param may be modified, but ctx is abstract @*/
400 int
401 rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
402 {
403 if (ctx == NULL)
404 return -1;
405
406 DPRINTF((stderr, "*** Update(%p,%p,%d) param %p \"%s\"\n", ctx, data, len, ctx->param, ((char *)data)));
407 return (*ctx->Update) (ctx->param, data, len);
408 }
409 /*@=mustmod@*/
410
411 int
412 rpmDigestFinal(DIGEST_CTX ctx, void * datap, size_t *lenp, int asAscii)
413 {
414 byte * digest;
415 char * t;
416
417 if (ctx == NULL)
418 return -1;
419 digest = xmalloc(ctx->digestsize);
420
421 DPRINTF((stderr, "*** Final(%p,%p,%p,%d) param %p digest %p\n", ctx, datap, lenp, asAscii, ctx->param, digest));
422 /*@-noeffectuncon@*/ /* FIX: check rc */
423 (void) (*ctx->Digest) (ctx->param, digest);
424 /*@=noeffectuncon@*/
425
426 /* Return final digest. */
427 if (!asAscii) {
428 if (lenp) *lenp = ctx->digestsize;
429 if (datap) {
430 *(byte **)datap = digest;
431 digest = NULL;
432 }
433 } else {
434 if (lenp) *lenp = (2*ctx->digestsize) + 1;
435 if (datap) {
436 const byte * s = (const byte *) digest;
437 static const char hex[] = "0123456789abcdef";
438 size_t i;
439
440 *(char **)datap = t = xmalloc((2*ctx->digestsize) + 1);
441 for (i = 0 ; i < ctx->digestsize; i++) {
442 *t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ];
443 *t++ = hex[ (unsigned)((*s++ ) & 0x0f) ];
444 }
445 *t = '\0';
446 }
447 }
448 if (digest) {
449 memset(digest, 0, ctx->digestsize); /* In case it's sensitive */
450 free(digest);
451 }
452 memset(ctx->param, 0, ctx->paramsize); /* In case it's sensitive */
453 free(ctx->param);
454 memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
455 free(ctx);
456 return 0;
457 }