rpm  5.2.1
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 @*/;
54 /*@observer@*/ /*@null@*/
55  const char * asn1;
56  void * param;
57 };
58 
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 
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 
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;
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;
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;
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;
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;
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;
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;
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;
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
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 }