rpm  4.5
digest.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 
7 #include <zlib.h>
8 
9 #include "rpmio_internal.h"
10 
11 #include "md2.h"
12 #include "md4.h"
13 #include "sha224.h"
14 #include "rmd128.h"
15 #include "rmd160.h"
16 #include "rmd256.h"
17 #include "rmd320.h"
18 #include "salsa10.h"
19 #include "salsa20.h"
20 #include "tiger.h"
21 
22 #include "debug.h"
23 
24 #ifdef SHA_DEBUG
25 #define DPRINTF(_a) fprintf _a
26 #else
27 #define DPRINTF(_a)
28 #endif
29 
30 #if !defined(ZLIB_H) || defined(__LCLINT__)
31 
33 /*@-shadow@*/
34 static uint32_t crc32(uint32_t crc, const byte * data, size_t size)
35  /*@*/
36 {
37  static uint32_t polynomial = 0xedb88320; /* reflected 0x04c11db7 */
38  static uint32_t xorout = 0xffffffff;
39  static uint32_t table[256];
40 
41  crc ^= xorout;
42 
43  if (data == NULL) {
44  /* generate the table of CRC remainders for all possible bytes */
45  uint32_t c;
46  uint32_t i, j;
47  for (i = 0; i < 256; i++) {
48  c = i;
49  for (j = 0; j < 8; j++) {
50  if (c & 1)
51  c = polynomial ^ (c >> 1);
52  else
53  c = (c >> 1);
54  }
55  table[i] = c;
56  }
57  } else
58  while (size) {
59  crc = table[(crc ^ *data) & 0xff] ^ (crc >> 8);
60  size--;
61  data++;
62  }
63 
64  crc ^= xorout;
65 
66  return crc;
67 
68 }
69 /*@=shadow@*/
70 #endif
71 
72 /* Include Bob Jenkins lookup3 hash */
73 #define _JLU3_jlu32l
74 #include "lookup3.c"
75 
78 typedef struct {
79  uint32_t crc;
80  uint32_t (*update) (uint32_t crc, const byte * data, size_t size);
81  uint32_t (*combine) (uint32_t crc1, uint32_t crc2, size_t len2);
82 } sum32Param;
83 
86 static int sum32Reset(register sum32Param* mp)
87  /*@modifies *mp @*/
88 {
89  if (mp->update)
90  mp->crc = (*mp->update) (0, NULL, 0);
91  return 0;
92 }
93 
96 static int sum32Update(sum32Param* mp, const byte* data, size_t size)
97  /*@modifies *mp @*/
98 {
99  if (mp->update)
100  mp->crc = (*mp->update) (mp->crc, data, size);
101  return 0;
102 }
103 
106 static int sum32Digest(sum32Param* mp, byte* data)
107  /*@modifies *mp, data @*/
108 {
109  uint32_t c = mp->crc;
110 
111  data[ 0] = (byte)(c >> 24);
112  data[ 1] = (byte)(c >> 16);
113  data[ 2] = (byte)(c >> 8);
114  data[ 3] = (byte)(c );
115 
116  (void) sum32Reset(mp);
117 
118  return 0;
119 }
120 
121 /*
122  * ECMA-182 polynomial, see
123  * http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-182.pdf
124  */
127 static uint64_t crc64(uint64_t crc, const byte * data, size_t size)
128  /*@*/
129 {
130  static uint64_t polynomial =
131  0xc96c5795d7870f42ULL; /* reflected 0x42f0e1eba9ea3693ULL */
132  static uint64_t xorout = 0xffffffffffffffffULL;
133  static uint64_t table[256];
134 
135  crc ^= xorout;
136 
137  if (data == NULL) {
138  /* generate the table of CRC remainders for all possible bytes */
139  uint64_t c;
140  uint32_t i, j;
141  for (i = 0; i < 256; i++) {
142  c = i;
143  for (j = 0; j < 8; j++) {
144  if (c & 1)
145  c = polynomial ^ (c >> 1);
146  else
147  c = (c >> 1);
148  }
149  table[i] = c;
150  }
151  } else
152  while (size) {
153  crc = table[(crc ^ *data) & 0xff] ^ (crc >> 8);
154  size--;
155  data++;
156  }
157 
158  crc ^= xorout;
159 
160  return crc;
161 
162 }
163 
164 /*
165  * Swiped from zlib, using uint64_t rather than unsigned long computation.
166  * Use at your own risk, uint64_t problems with compilers may exist.
167  */
168 #define GF2_DIM 64
169 
172 static uint64_t gf2_matrix_times(uint64_t *mat, uint64_t vec)
173  /*@*/
174 {
175  uint64_t sum;
176 
177  sum = 0;
178  while (vec) {
179  if (vec & 1)
180  sum ^= *mat;
181  vec >>= 1;
182  mat++;
183  }
184  return sum;
185 }
186 
189 static void gf2_matrix_square(/*@out@*/ uint64_t *square, uint64_t *mat)
190  /*@modifies square @*/
191 {
192  int n;
193 
194  for (n = 0; n < GF2_DIM; n++)
195  square[n] = gf2_matrix_times(mat, mat[n]);
196 }
197 
200 static uint64_t crc64_combine(uint64_t crc1, uint64_t crc2, size_t len2)
201  /*@*/
202 {
203  int n;
204  uint64_t row;
205  uint64_t even[GF2_DIM]; /* even-power-of-two zeros operator */
206  uint64_t odd[GF2_DIM]; /* odd-power-of-two zeros operator */
207 
208  /* degenerate case */
209  if (len2 == 0)
210  return crc1;
211 
212  /* put operator for one zero bit in odd */
213  odd[0] = 0xc96c5795d7870f42ULL; /* reflected 0x42f0e1eba9ea3693ULL */
214  row = 1;
215  for (n = 1; n < GF2_DIM; n++) {
216  odd[n] = row;
217  row <<= 1;
218  }
219 
220  /* put operator for two zero bits in even */
221  gf2_matrix_square(even, odd);
222 
223  /* put operator for four zero bits in odd */
224  gf2_matrix_square(odd, even);
225 
226  /* apply len2 zeros to crc1 (first square will put the operator for one
227  zero byte, eight zero bits, in even) */
228  do {
229  /* apply zeros operator for this bit of len2 */
230  gf2_matrix_square(even, odd);
231  if (len2 & 1)
232  crc1 = gf2_matrix_times(even, crc1);
233  len2 >>= 1;
234 
235  /* if no more bits set, then done */
236  if (len2 == 0)
237  break;
238 
239  /* another iteration of the loop with odd and even swapped */
240  gf2_matrix_square(odd, even);
241  if (len2 & 1)
242  crc1 = gf2_matrix_times(odd, crc1);
243  len2 >>= 1;
244 
245  /* if no more bits set, then done */
246  } while (len2 != 0);
247 
248  /* return combined crc */
249  crc1 ^= crc2;
250  return crc1;
251 }
252 
255 typedef struct {
256  uint64_t crc;
257  uint64_t (*update) (uint64_t crc, const byte * data, size_t size);
258  uint64_t (*combine) (uint64_t crc1, uint64_t crc2, size_t len2);
259 } sum64Param;
260 
263 static int sum64Reset(register sum64Param* mp)
264  /*@modifies *mp @*/
265 {
266  if (mp->update)
267  mp->crc = (*mp->update) (0, NULL, 0);
268  return 0;
269 }
270 
273 static int sum64Update(sum64Param* mp, const byte* data, size_t size)
274  /*@modifies *mp @*/
275 {
276  if (mp->update)
277  mp->crc = (*mp->update) (mp->crc, data, size);
278  return 0;
279 }
280 
283 static int sum64Digest(sum64Param* mp, byte* data)
284  /*@modifies *mp, data @*/
285 {
286  uint64_t c = mp->crc;
287 
288  data[ 0] = (byte)(c >> 56);
289  data[ 1] = (byte)(c >> 48);
290  data[ 2] = (byte)(c >> 40);
291  data[ 3] = (byte)(c >> 32);
292  data[ 4] = (byte)(c >> 24);
293  data[ 5] = (byte)(c >> 16);
294  data[ 6] = (byte)(c >> 8);
295  data[ 7] = (byte)(c );
296 
297  (void) sum64Reset(mp);
298 
299  return 0;
300 }
301 
302 /*@access DIGEST_CTX@*/
303 
307 struct DIGEST_CTX_s {
308 /*@observer@*/
309  const char * name;
310  size_t paramsize;
311  size_t datasize;
312  size_t digestsize;
313  int (*Reset) (void * param)
314  /*@modifies param @*/;
315  int (*Update) (void * param, const byte * data, size_t size)
316  /*@modifies param @*/;
317  int (*Digest) (void * param, /*@out@*/ byte * digest)
318  /*@modifies param, digest @*/;
320  void * param;
321 };
322 
323 /*@-boundsread@*/
326 {
327  DIGEST_CTX nctx;
328  nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
329  nctx->param = memcpy(xcalloc(1, nctx->paramsize), octx->param, nctx->paramsize);
330  return nctx;
331 }
332 /*@=boundsread@*/
333 
336 {
337  DIGEST_CTX ctx = xcalloc(1, sizeof(*ctx));
338  int xx;
339 
340  ctx->flags = flags;
341 
342  switch (hashalgo) {
343  case PGPHASHALGO_MD5:
344  ctx->name = "MD5";
345  ctx->digestsize = 128/8;
346  ctx->datasize = 64;
347 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
348  ctx->paramsize = sizeof(md5Param);
349 /*@=sizeoftype@*/
350  ctx->param = xcalloc(1, ctx->paramsize);
351 /*@-type@*/
352  ctx->Reset = (void *) md5Reset;
353  ctx->Update = (void *) md5Update;
354  ctx->Digest = (void *) md5Digest;
355 /*@=type@*/
356  break;
357  case PGPHASHALGO_SHA1:
358  ctx->name = "SHA-1";
359  ctx->digestsize = 160/8;
360  ctx->datasize = 64;
361 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
362  ctx->paramsize = sizeof(sha1Param);
363 /*@=sizeoftype@*/
364  ctx->param = xcalloc(1, ctx->paramsize);
365 /*@-type@*/
366  ctx->Reset = (void *) sha1Reset;
367  ctx->Update = (void *) sha1Update;
368  ctx->Digest = (void *) sha1Digest;
369 /*@=type@*/
370  break;
372  ctx->name = "RIPEMD-128";
373  ctx->digestsize = 128/8;
374  ctx->datasize = 64;
375 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
376  ctx->paramsize = sizeof(rmd128Param);
377 /*@=sizeoftype@*/
378  ctx->param = xcalloc(1, ctx->paramsize);
379 /*@-type@*/
380  ctx->Reset = (void *) rmd128Reset;
381  ctx->Update = (void *) rmd128Update;
382  ctx->Digest = (void *) rmd128Digest;
383 /*@=type@*/
384  break;
386  ctx->name = "RIPEMD-160";
387  ctx->digestsize = 160/8;
388  ctx->datasize = 64;
389 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
390  ctx->paramsize = sizeof(rmd160Param);
391 /*@=sizeoftype@*/
392  ctx->param = xcalloc(1, ctx->paramsize);
393 /*@-type@*/
394  ctx->Reset = (void *) rmd160Reset;
395  ctx->Update = (void *) rmd160Update;
396  ctx->Digest = (void *) rmd160Digest;
397 /*@=type@*/
398  break;
400  ctx->name = "RIPEMD-256";
401  ctx->digestsize = 256/8;
402  ctx->datasize = 64;
403 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
404  ctx->paramsize = sizeof(rmd256Param);
405 /*@=sizeoftype@*/
406  ctx->param = xcalloc(1, ctx->paramsize);
407 /*@-type@*/
408  ctx->Reset = (void *) rmd256Reset;
409  ctx->Update = (void *) rmd256Update;
410  ctx->Digest = (void *) rmd256Digest;
411 /*@=type@*/
412  break;
414  ctx->name = "RIPEMD-320";
415  ctx->digestsize = 320/8;
416  ctx->datasize = 64;
417 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
418  ctx->paramsize = sizeof(rmd320Param);
419 /*@=sizeoftype@*/
420  ctx->param = xcalloc(1, ctx->paramsize);
421 /*@-type@*/
422  ctx->Reset = (void *) rmd320Reset;
423  ctx->Update = (void *) rmd320Update;
424  ctx->Digest = (void *) rmd320Digest;
425 /*@=type@*/
426  break;
427  case PGPHASHALGO_SALSA10:
428  ctx->name = "SALSA-10";
429  ctx->digestsize = 512/8;
430  ctx->datasize = 64;
431 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
432  ctx->paramsize = sizeof(salsa10Param);
433 /*@=sizeoftype@*/
434  ctx->param = xcalloc(1, ctx->paramsize);
435 /*@-type@*/
436  ctx->Reset = (void *) salsa10Reset;
437  ctx->Update = (void *) salsa10Update;
438  ctx->Digest = (void *) salsa10Digest;
439 /*@=type@*/
440  break;
441  case PGPHASHALGO_SALSA20:
442  ctx->name = "SALSA-20";
443  ctx->digestsize = 512/8;
444  ctx->datasize = 64;
445 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
446  ctx->paramsize = sizeof(salsa20Param);
447 /*@=sizeoftype@*/
448  ctx->param = xcalloc(1, ctx->paramsize);
449 /*@-type@*/
450  ctx->Reset = (void *) salsa20Reset;
451  ctx->Update = (void *) salsa20Update;
452  ctx->Digest = (void *) salsa20Digest;
453 /*@=type@*/
454  break;
456  ctx->name = "TIGER-192";
457  ctx->digestsize = 192/8;
458  ctx->datasize = 64;
459 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
460  ctx->paramsize = sizeof(tigerParam);
461 /*@=sizeoftype@*/
462  ctx->param = xcalloc(1, ctx->paramsize);
463 /*@-type@*/
464  ctx->Reset = (void *) tigerReset;
465  ctx->Update = (void *) tigerUpdate;
466  ctx->Digest = (void *) tigerDigest;
467 /*@=type@*/
468  break;
469  case PGPHASHALGO_MD2:
470  ctx->name = "MD2";
471  ctx->digestsize = 128/8;
472  ctx->datasize = 16;
473 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
474  ctx->paramsize = sizeof(md2Param);
475 /*@=sizeoftype@*/
476  ctx->param = xcalloc(1, ctx->paramsize);
477 /*@-type@*/
478  ctx->Reset = (void *) md2Reset;
479  ctx->Update = (void *) md2Update;
480  ctx->Digest = (void *) md2Digest;
481 /*@=type@*/
482  break;
483  case PGPHASHALGO_MD4:
484  ctx->name = "MD4";
485  ctx->digestsize = 128/8;
486  ctx->datasize = 64;
487 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
488  ctx->paramsize = sizeof(md4Param);
489 /*@=sizeoftype@*/
490  ctx->param = xcalloc(1, ctx->paramsize);
491 /*@-type@*/
492  ctx->Reset = (void *) md4Reset;
493  ctx->Update = (void *) md4Update;
494  ctx->Digest = (void *) md4Digest;
495 /*@=type@*/
496  break;
497  case PGPHASHALGO_CRC32:
498  ctx->name = "CRC-32";
499  ctx->digestsize = 32/8;
500  ctx->datasize = 8;
501  { sum32Param * mp = xcalloc(1, sizeof(*mp));
502 /*@-type @*/
503  mp->update = (void *) crc32;
504 #if defined(ZLIB_H)
505  mp->combine = (void *) crc32_combine;
506 #endif
507 /*@=type @*/
508  ctx->paramsize = sizeof(*mp);
509  ctx->param = mp;
510  }
511 /*@-type@*/
512  ctx->Reset = (void *) sum32Reset;
513  ctx->Update = (void *) sum32Update;
514  ctx->Digest = (void *) sum32Digest;
515 /*@=type@*/
516  break;
517  case PGPHASHALGO_ADLER32:
518  ctx->name = "ADLER-32";
519  ctx->digestsize = 32/8;
520  ctx->datasize = 8;
521  { sum32Param * mp = xcalloc(1, sizeof(*mp));
522 /*@-type @*/
523 #if defined(ZLIB_H)
524  mp->update = (void *) adler32;
525  mp->combine = (void *) adler32_combine;
526 #endif
527 /*@=type @*/
528  ctx->paramsize = sizeof(*mp);
529  ctx->param = mp;
530  }
531 /*@-type@*/
532  ctx->Reset = (void *) sum32Reset;
533  ctx->Update = (void *) sum32Update;
534  ctx->Digest = (void *) sum32Digest;
535 /*@=type@*/
536  break;
537  case PGPHASHALGO_JLU32:
538  ctx->name = "JLU-32";
539  ctx->digestsize = 32/8;
540  ctx->datasize = 8;
541  { sum32Param * mp = xcalloc(1, sizeof(*mp));
542 /*@-type @*/
543  mp->update = (void *) jlu32l;
544 /*@=type @*/
545  ctx->paramsize = sizeof(*mp);
546  ctx->param = mp;
547  }
548 /*@-type@*/
549  ctx->Reset = (void *) sum32Reset;
550  ctx->Update = (void *) sum32Update;
551  ctx->Digest = (void *) sum32Digest;
552 /*@=type@*/
553  break;
554  case PGPHASHALGO_CRC64:
555  ctx->name = "CRC-64";
556  ctx->digestsize = 64/8;
557  ctx->datasize = 8;
558  { sum64Param * mp = xcalloc(1, sizeof(*mp));
559 /*@-type@*/
560  mp->update = (void *) crc64;
561  mp->combine = (void *) crc64_combine;
562 /*@=type@*/
563  ctx->paramsize = sizeof(*mp);
564  ctx->param = mp;
565  }
566 /*@-type@*/
567  ctx->Reset = (void *) sum64Reset;
568  ctx->Update = (void *) sum64Update;
569  ctx->Digest = (void *) sum64Digest;
570 /*@=type@*/
571  break;
572 #if HAVE_BEECRYPT_API_H
573  case PGPHASHALGO_SHA224:
574  ctx->name = "SHA-224";
575  ctx->digestsize = 224/8;
576  ctx->datasize = 64;
577 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
578  ctx->paramsize = sizeof(sha224Param);
579 /*@=sizeoftype@*/
580  ctx->param = xcalloc(1, ctx->paramsize);
581 /*@-type@*/
582  ctx->Reset = (void *) sha224Reset;
583  ctx->Update = (void *) sha224Update;
584  ctx->Digest = (void *) sha224Digest;
585 /*@=type@*/
586  break;
587  case PGPHASHALGO_SHA256:
588  ctx->name = "SHA-256";
589  ctx->digestsize = 256/8;
590  ctx->datasize = 64;
591 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
592  ctx->paramsize = sizeof(sha256Param);
593 /*@=sizeoftype@*/
594  ctx->param = xcalloc(1, ctx->paramsize);
595 /*@-type@*/
596  ctx->Reset = (void *) sha256Reset;
597  ctx->Update = (void *) sha256Update;
598  ctx->Digest = (void *) sha256Digest;
599 /*@=type@*/
600  break;
601  case PGPHASHALGO_SHA384:
602  ctx->name = "SHA-384";
603  ctx->digestsize = 384/8;
604  ctx->datasize = 128;
605 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
606  ctx->paramsize = sizeof(sha384Param);
607 /*@=sizeoftype@*/
608  ctx->param = xcalloc(1, ctx->paramsize);
609 /*@-type@*/
610  ctx->Reset = (void *) sha384Reset;
611  ctx->Update = (void *) sha384Update;
612  ctx->Digest = (void *) sha384Digest;
613 /*@=type@*/
614  break;
615  case PGPHASHALGO_SHA512:
616  ctx->name = "SHA-512";
617  ctx->digestsize = 512/8;
618  ctx->datasize = 128;
619 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
620  ctx->paramsize = sizeof(sha512Param);
621 /*@=sizeoftype@*/
622  ctx->param = xcalloc(1, ctx->paramsize);
623 /*@-type@*/
624  ctx->Reset = (void *) sha512Reset;
625  ctx->Update = (void *) sha512Update;
626  ctx->Digest = (void *) sha512Digest;
627 /*@=type@*/
628  break;
629 #endif
631  default:
632  free(ctx);
633  return NULL;
634  /*@notreached@*/ break;
635  }
636 
637 /*@-boundsread@*/
638  xx = (*ctx->Reset) (ctx->param);
639 /*@=boundsread@*/
640 
641 DPRINTF((stderr, "*** Init(%x) ctx %p param %p\n", flags, ctx, ctx->param));
642  return ctx;
643 }
644 
645 /*@-mustmod@*/ /* LCL: ctx->param may be modified, but ctx is abstract @*/
646 int
647 rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
648 {
649  if (ctx == NULL)
650  return -1;
651 
652 DPRINTF((stderr, "*** Update(%p,%p,%d) param %p \"%s\"\n", ctx, data, len, ctx->param, ((char *)data)));
653 /*@-boundsread@*/
654  return (*ctx->Update) (ctx->param, data, len);
655 /*@=boundsread@*/
656 }
657 /*@=mustmod@*/
658 
659 /*@-boundswrite@*/
660 int
661 rpmDigestFinal(DIGEST_CTX ctx, void * datap, size_t *lenp, int asAscii)
662 {
663  byte * digest;
664  char * t;
665  int i;
666 
667  if (ctx == NULL)
668  return -1;
669  digest = xmalloc(ctx->digestsize);
670 
671 DPRINTF((stderr, "*** Final(%p,%p,%p,%d) param %p digest %p\n", ctx, datap, lenp, asAscii, ctx->param, digest));
672 /*@-noeffectuncon@*/ /* FIX: check rc */
673  (void) (*ctx->Digest) (ctx->param, digest);
674 /*@=noeffectuncon@*/
675 
676  /* Return final digest. */
677 /*@-branchstate@*/
678  if (!asAscii) {
679  if (lenp) *lenp = ctx->digestsize;
680  if (datap) {
681  *(byte **)datap = digest;
682  digest = NULL;
683  }
684  } else {
685  if (lenp) *lenp = (2*ctx->digestsize) + 1;
686  if (datap) {
687  const byte * s = (const byte *) digest;
688  static const char hex[] = "0123456789abcdef";
689 
690  *(char **)datap = t = xmalloc((2*ctx->digestsize) + 1);
691  for (i = 0 ; i < ctx->digestsize; i++) {
692  *t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ];
693  *t++ = hex[ (unsigned)((*s++ ) & 0x0f) ];
694  }
695  *t = '\0';
696  }
697  }
698 /*@=branchstate@*/
699  if (digest) {
700  memset(digest, 0, ctx->digestsize); /* In case it's sensitive */
701  free(digest);
702  }
703  memset(ctx->param, 0, ctx->paramsize); /* In case it's sensitive */
704  free(ctx->param);
705  memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
706  free(ctx);
707  return 0;
708 }
709 /*@=boundswrite@*/
710 
712 
716 struct poptOption rpmDigestPoptTable[] = {
717  { "md2", '\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_MD2,
718  NULL, NULL },
719  { "md4", '\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_MD4,
720  NULL, NULL },
721  { "md5", '\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_MD5,
722  NULL, NULL },
723  { "sha1",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SHA1,
724  NULL, NULL },
725  { "sha224",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SHA224,
726  NULL, NULL },
727  { "sha256",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SHA256,
728  NULL, NULL },
729  { "sha384",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SHA384,
730  NULL, NULL },
731  { "sha512",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SHA512,
732  NULL, NULL },
733  { "salsa10",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SALSA10,
734  NULL, NULL },
735  { "salsa20",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SALSA20,
736  NULL, NULL },
737  { "rmd128",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_RIPEMD128,
738  NULL, NULL },
739  { "rmd160",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_RIPEMD160,
740  NULL, NULL },
741  { "rmd256",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_RIPEMD256,
742  NULL, NULL },
743  { "rmd320",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_RIPEMD320,
744  NULL, NULL },
745  { "tiger",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_TIGER192,
746  NULL, NULL },
747  { "crc32",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_CRC32,
748  NULL, NULL },
749  { "crc64",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_CRC64,
750  NULL, NULL },
751  { "adler32",'\0', POPT_ARG_VAL,&rpmDigestHashAlgo, PGPHASHALGO_ADLER32,
752  NULL, NULL },
753  { "jlu32",'\0', POPT_ARG_VAL,&rpmDigestHashAlgo, PGPHASHALGO_JLU32,
754  NULL, NULL },
755  { "nodigest",'\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &rpmDigestHashAlgo, PGPHASHALGO_NONE,
756  N_("no hash algorithm"), NULL },
757  { "alldigests",'\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &rpmDigestHashAlgo, 256,
758  N_("all hash algorithm(s)"), NULL },
759  POPT_TABLEEND
760 };