Hi,

Some time ago there was a question about support for the WHIRLPOOL hash in
GnuPG. I thought it wouldn't be to difficult since libgcrypt already implements
WHIRLPOOL.

Attached is a patch against the current svn (r5101). If it gets mangled by the
mailing list it is also available as download[1].

[1]: http://schot.a-eskwadraat.nl/files/gpg-r5101-whirlpool.diff

Regards,
-- 
Jeroen Schot
Index: include/cipher.h
===================================================================
--- include/cipher.h	(revision 5101)
+++ include/cipher.h	(working copy)
@@ -74,6 +74,7 @@
 /* SHA224 is only available in libgcrypt 1.4.0; thus we
    can't use the GCRY macro here.  */
 #define DIGEST_ALGO_SHA224    /* 11 */ 11 /* GCRY_MD_SHA224 */
+#define DIGEST_ALGO_WHIRLPOOL /* 100 */ 100 /* Experimental, does not match libgcrypt */
 
 #define COMPRESS_ALGO_NONE 0
 #define COMPRESS_ALGO_ZIP  1
Index: g10/sign.c
===================================================================
--- g10/sign.c	(revision 5101)
+++ g10/sign.c	(working copy)
@@ -253,7 +253,7 @@
 	digest_algo = gcry_md_get_algo (md);
 
     print_digest_algo_note( digest_algo );
-    dp = gcry_md_read ( md, digest_algo );
+    dp = gcry_md_read ( md, map_md_openpgp_to_gcry (digest_algo));
     sig->digest_algo = digest_algo;
     sig->digest_start[0] = dp[0];
     sig->digest_start[1] = dp[1];
@@ -267,8 +267,10 @@
         snbuf = serialno_and_fpr_from_sk (sk->protect.iv,
                                           sk->protect.ivlen, sk);
         rc = agent_scd_pksign (snbuf, digest_algo,
-                               gcry_md_read (md, digest_algo),
-                               gcry_md_get_algo_dlen (digest_algo),
+                               gcry_md_read (md,
+							     map_md_openpgp_to_gcry (digest_algo)),
+                               gcry_md_get_algo_dlen (
+							     map_md_openpgp_to_gcry (digest_algo)),
                                &rbuf, &rbuflen);
         xfree (snbuf);
         if (!rc)
@@ -319,7 +321,7 @@
 	    char *ustr = get_user_id_string_native (sig->keyid);
 	    log_info(_("%s/%s signature from: \"%s\"\n"),
 		     gcry_pk_algo_name (sk->pubkey_algo),
-		     gcry_md_algo_name (sig->digest_algo),
+		     openpgp_md_algo_name (sig->digest_algo),
 		     ustr );
 	    xfree(ustr);
 	}
@@ -833,7 +835,7 @@
 				      NULL)!=opt.def_digest_algo)
 	  log_info(_("WARNING: forcing digest algorithm %s (%d)"
 		     " violates recipient preferences\n"),
-		   gcry_md_algo_name (opt.def_digest_algo),
+		   openpgp_md_algo_name (opt.def_digest_algo),
 		   opt.def_digest_algo );
 	  }
 	else
@@ -894,7 +896,7 @@
 
     for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
 	PKT_secret_key *sk = sk_rover->sk;
-	gcry_md_enable (mfx.md, hash_for(sk));
+	gcry_md_enable (mfx.md, map_md_openpgp_to_gcry (hash_for(sk)));
     }
 
     if( !multifile )
@@ -1137,7 +1139,7 @@
 	    int i = hash_for(sk);
 
 	    if( !hashs_seen[ i & 0xff ] ) {
-		s = gcry_md_algo_name ( i );
+		s = openpgp_md_algo_name ( i );
 		if( s ) {
 		    hashs_seen[ i & 0xff ] = 1;
 		    if( any )
@@ -1160,7 +1162,7 @@
       BUG ();
     for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
 	PKT_secret_key *sk = sk_rover->sk;
-	gcry_md_enable (textmd, hash_for(sk));
+	gcry_md_enable (textmd, map_md_openpgp_to_gcry (hash_for(sk)));
     }
     if ( DBG_HASHING )
       gcry_md_start_debug ( textmd, "clearsign" );
@@ -1289,7 +1291,7 @@
 
     for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) {
 	PKT_secret_key *sk = sk_rover->sk;
-	gcry_md_enable (mfx.md, hash_for (sk));
+	gcry_md_enable (mfx.md, map_md_openpgp_to_gcry (hash_for (sk)));
     }
 
     iobuf_push_filter (inp, md_filter, &mfx);
@@ -1425,7 +1427,7 @@
 	  digest_algo = DIGEST_ALGO_SHA1;
       }
 
-    if ( gcry_md_open (&md, digest_algo, 0 ) )
+    if ( gcry_md_open (&md, map_md_openpgp_to_gcry (digest_algo), 0 ) )
       BUG ();
 
     /* Hash the public key certificate. */
@@ -1509,7 +1511,7 @@
 	|| (orig_sig->sig_class == 0x18 && !subpk))
       return G10ERR_GENERAL;
 
-    if ( gcry_md_open (&md, orig_sig->digest_algo, 0 ) )
+    if ( gcry_md_open (&md, map_md_openpgp_to_gcry (orig_sig->digest_algo), 0 ) )
       BUG ();
 
     /* Hash the public key certificate and the user id. */
Index: g10/mainproc.c
===================================================================
--- g10/mainproc.c	(revision 5101)
+++ g10/mainproc.c	(working copy)
@@ -628,8 +628,8 @@
   	    /* For the onepass signature case */
 	    if( n->pkt->pkt.onepass_sig->digest_algo )
 	      {
-		gcry_md_enable (c->mfx.md,
-                                n->pkt->pkt.onepass_sig->digest_algo);
+		gcry_md_enable (c->mfx.md, map_md_openpgp_to_gcry (
+                                   n->pkt->pkt.onepass_sig->digest_algo));
 		if( !any && n->pkt->pkt.onepass_sig->digest_algo
 		    == DIGEST_ALGO_MD5 )
 		  only_md5 = 1;
@@ -655,7 +655,7 @@
              * documents */
             clearsig = (*data == 0x01);
             for( data++, datalen--; datalen; datalen--, data++ )
-	        gcry_md_enable (c->mfx.md, *data);
+	        gcry_md_enable (c->mfx.md, map_md_openpgp_to_gcry (*data));
             any = 1;
             break;  /* Stop here as one-pass signature packets are not
                        expected.  */
@@ -663,7 +663,8 @@
 	else if(n->pkt->pkttype==PKT_SIGNATURE)
 	  {
 	    /* For the SIG+LITERAL case that PGP used to use. */
-	    gcry_md_enable ( c->mfx.md, n->pkt->pkt.signature->digest_algo );
+	    gcry_md_enable ( c->mfx.md, map_md_openpgp_to_gcry (
+                                    n->pkt->pkt.signature->digest_algo ));
 	    any=1;
 	  }
       }
@@ -1941,7 +1942,7 @@
 	  log_info(_("%s signature, digest algorithm %s\n"),
 		   sig->sig_class==0x00?_("binary"):
 		   sig->sig_class==0x01?_("textmode"):_("unknown"),
-		   gcry_md_algo_name (sig->digest_algo));
+		   openpgp_md_algo_name (sig->digest_algo));
 
 	if( rc )
 	    g10_errors_seen = 1;
@@ -2014,8 +2015,8 @@
                one-pass packet? */
 	    for ( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); )
               {
-		gcry_md_enable (c->mfx.md,
-                                n1->pkt->pkt.signature->digest_algo);
+		gcry_md_enable (c->mfx.md, map_md_openpgp_to_gcry (
+                                   n1->pkt->pkt.signature->digest_algo));
               }
 
             if (n1 && n1->pkt->pkt.onepass_sig->sig_class == 0x01)
@@ -2100,7 +2101,8 @@
 	else if( !c->have_data ) {
 	    /* detached signature */
 	    free_md_filter_context( &c->mfx );
-            if (gcry_md_open (&c->mfx.md, sig->digest_algo, 0))
+            if (gcry_md_open (&c->mfx.md, map_md_openpgp_to_gcry (
+				                          sig->digest_algo), 0))
               BUG ();
 
 	    if( !opt.pgp2_workarounds )
Index: g10/cipher.c
===================================================================
--- g10/cipher.c	(revision 5101)
+++ g10/cipher.c	(working copy)
@@ -147,7 +147,7 @@
 	    gcry_md_putc (cfx->mdc_hash, temp[1]);
 
 	    gcry_md_final (cfx->mdc_hash);
-	    hash = gcry_md_read (cfx->mdc_hash, 0);
+	    hash = gcry_md_read (map_md_openpgp_to_gcry (cfx->mdc_hash), 0);
 	    memcpy(temp+2, hash, 20);
 	    gcry_cipher_encrypt (cfx->cipher_hd, temp, 22, NULL, 0);
 	    gcry_md_close (cfx->mdc_hash); cfx->mdc_hash = NULL;
Index: g10/armor.c
===================================================================
--- g10/armor.c	(revision 5101)
+++ g10/armor.c	(working copy)
@@ -296,6 +296,8 @@
 	    found |= 32;
 	else if( !strncmp( s, "SHA512", s2-s ) )
 	    found |= 64;
+	else if( !strncmp( s, "WHIRLPOOL", s2-s ) )
+	    found |= 128;
 	else
 	    return 0;
 	for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
@@ -1007,7 +1009,7 @@
 		/* the buffer is at least 15+n*15 bytes long, so it
 		 * is easy to construct the packets */
 
-		hashes &= 1|2|4|8|16|32|64;
+		hashes &= 1|2|4|8|16|32|64|128;
 		if( !hashes ) {
 		    hashes |= 4;  /* default to MD 5 */
 		    /* This is non-ideal since PGP 5-8 have the same
@@ -1037,6 +1039,8 @@
                     buf[n++] = DIGEST_ALGO_SHA384;
                 if( hashes & 64 )
                     buf[n++] = DIGEST_ALGO_SHA512;
+                if( hashes & 128 )
+                    buf[n++] = DIGEST_ALGO_WHIRLPOOL;
                 buf[1] = n - 2;
 
 		/* ...followed by an invented plaintext packet.
Index: g10/sig-check.c
===================================================================
--- g10/sig-check.c	(revision 5101)
+++ g10/sig-check.c	(working copy)
@@ -70,7 +70,7 @@
       ; /* We don't have this digest. */
     else if ((rc=openpgp_pk_test_algo(sig->pubkey_algo)))
       ; /* We don't have this pubkey algo. */
-    else if (!gcry_md_is_enabled (digest,sig->digest_algo))
+    else if (!gcry_md_is_enabled (digest,map_md_openpgp_to_gcry (sig->digest_algo)))
       {
 	/* Sanity check that the md has a context for the hash that the
 	   sig is expecting.  This can happen if a onepass sig header does
@@ -268,7 +268,7 @@
 
     /* Make sure the digest algo is enabled (in case of a detached
        signature).  */
-    gcry_md_enable (digest, sig->digest_algo);
+    gcry_md_enable (digest, map_md_openpgp_to_gcry (sig->digest_algo));
 
     /* Complete the digest. */
     if( sig->version >= 4 )
@@ -437,7 +437,7 @@
 	    {
               gcry_md_hd_t md;
     
-              if (gcry_md_open (&md, sig->digest_algo, 0))
+              if (gcry_md_open (&md, map_md_openpgp_to_gcry (sig->digest_algo), 0))
                 BUG ();
               hash_public_key(md,pk);
               rc=signature_check(sig,md);
@@ -474,7 +474,7 @@
   if(!opt.no_sig_cache && backsig->flags.checked)
     return backsig->flags.valid? 0 : gpg_error (GPG_ERR_BAD_SIGNATURE);
 
-  rc = gcry_md_open (&md, backsig->digest_algo,0);
+  rc = gcry_md_open (&md, map_md_openpgp_to_gcry (backsig->digest_algo),0);
   if (!rc)
     {
       hash_public_key(md,main_pk);
@@ -564,7 +564,7 @@
 	  rc=check_revocation_keys(pk,sig);
 	else
 	  {
-	    if (gcry_md_open (&md, algo, 0 ))
+	    if (gcry_md_open (&md, map_md_openpgp_to_gcry (algo), 0 ))
               BUG ();
 	    hash_public_key( md, pk );
 	    rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
@@ -576,7 +576,7 @@
 	KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
 
 	if( snode ) {
-            if (gcry_md_open (&md, algo, 0))
+            if (gcry_md_open (&md, map_md_openpgp_to_gcry (algo), 0))
               BUG ();
 	    hash_public_key( md, pk );
 	    hash_public_key( md, snode->pkt->pkt.public_key );
@@ -603,7 +603,7 @@
 		if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
 		    *is_selfsig = 1;
 	    }
-	    if (gcry_md_open (&md, algo, 0))
+	    if (gcry_md_open (&md, map_md_openpgp_to_gcry (algo), 0))
               BUG ();
 	    hash_public_key( md, pk );
 	    hash_public_key( md, snode->pkt->pkt.public_key );
@@ -620,7 +620,7 @@
 	  }
     }
     else if( sig->sig_class == 0x1f ) { /* direct key signature */
-        if (gcry_md_open (&md, algo, 0 ))
+        if (gcry_md_open (&md, map_md_openpgp_to_gcry (algo), 0 ))
           BUG ();
 	hash_public_key( md, pk );
 	rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
@@ -634,7 +634,7 @@
 	    u32 keyid[2];
 
 	    keyid_from_pk( pk, keyid );
-	    if (gcry_md_open (&md, algo, 0 ))
+	    if (gcry_md_open (&md, map_md_openpgp_to_gcry (algo), 0 ))
               BUG ();
 	    hash_public_key( md, pk );
 	    hash_uid_node( unode, md, sig );
Index: g10/seskey.c
===================================================================
--- g10/seskey.c	(revision 5101)
+++ g10/seskey.c	(working copy)
@@ -179,7 +179,7 @@
     memset( frame+n, 0xff, i ); n += i;
     frame[n++] = 0;
     memcpy( frame+n, asn, asnlen ); n += asnlen;
-    memcpy( frame+n, gcry_md_read (md, algo), len ); n += len;
+    memcpy( frame+n, gcry_md_read (md, map_md_openpgp_to_gcry (algo)), len ); n += len;
     assert( n == nframe );
 
     if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe ))
@@ -247,7 +247,7 @@
 
       /* Check if we're too short.  Too long is safe as we'll
 	 automatically left-truncate. */
-      if (gcry_md_get_algo_dlen (hash_algo) < qbytes)
+      if (gcry_md_get_algo_dlen (map_md_openpgp_to_gcry (hash_algo)) < qbytes)
 	{
 	  log_error (_("DSA key %s requires a %u bit or larger hash\n"),
                      pk?keystr_from_pk(pk):keystr_from_sk(sk),
@@ -256,7 +256,7 @@
 	}
 
       if (gcry_mpi_scan (&frame, GCRYMPI_FMT_USG,
-                         gcry_md_read (md, hash_algo), qbytes, &qbytes))
+                         gcry_md_read (md, map_md_openpgp_to_gcry (hash_algo)), qbytes, &qbytes))
         BUG();
     }
   else
@@ -265,14 +265,14 @@
       byte *asn;
       size_t asnlen;
 
-      rc = gcry_md_algo_info (hash_algo, GCRYCTL_GET_ASNOID, NULL, &asnlen);
+      rc = gcry_md_algo_info (map_md_openpgp_to_gcry (hash_algo), GCRYCTL_GET_ASNOID, NULL, &asnlen);
       if (rc)
         log_fatal ("can't get OID of digest algorithm %d: %s\n",
                    hash_algo, gpg_strerror (rc));
       asn = xmalloc (asnlen);
-      if ( gcry_md_algo_info (hash_algo, GCRYCTL_GET_ASNOID, asn, &asnlen) )
+      if (gcry_md_algo_info (map_md_openpgp_to_gcry (hash_algo), GCRYCTL_GET_ASNOID, asn, &asnlen))
         BUG();
-      frame = do_encode_md (md, hash_algo, gcry_md_get_algo_dlen (hash_algo),
+      frame = do_encode_md (md, hash_algo, gcry_md_get_algo_dlen (map_md_openpgp_to_gcry (hash_algo)),
                             gcry_mpi_get_nbits (pk?pk->pkey[0]:sk->skey[0]),
                             asn, asnlen);
       xfree (asn);
Index: g10/passphrase.c
===================================================================
--- g10/passphrase.c	(revision 5101)
+++ g10/passphrase.c	(working copy)
@@ -65,7 +65,7 @@
   if ( !(dek->keylen > 0 && dek->keylen <= DIM(dek->key)) )
     BUG();
 
-  if (gcry_md_open (&md, s2k->hash_algo, 1))
+  if (gcry_md_open (&md, map_md_openpgp_to_gcry (s2k->hash_algo), 1))
     BUG ();
   for (pass=0; used < dek->keylen ; pass++ ) 
     {
Index: g10/import.c
===================================================================
--- g10/import.c	(revision 5101)
+++ g10/import.c	(working copy)
@@ -617,9 +617,9 @@
 		  if(openpgp_md_test_algo(prefs->value))
 		    {
 		      const char *algo =
-                        (gcry_md_test_algo (prefs->value)
+                        (openpgp_md_test_algo (prefs->value)
                          ? num 
-                         : gcry_md_algo_name (prefs->value));
+                         : openpgp_md_algo_name (prefs->value));
 		      if(!problem)
 			check_prefs_warning(pk);
 		      log_info(_("         \"%s\": preference for digest"
Index: g10/gpg.c
===================================================================
--- g10/gpg.c	(revision 5101)
+++ g10/gpg.c	(working copy)
@@ -858,7 +858,7 @@
       case 36:
 	if( !digests )
 	    digests = build_list(_("Hash: "), 'H', 
-                                 gcry_md_algo_name,
+                                 openpgp_md_algo_name,
                                  openpgp_md_test_algo );
 	p = digests;
 	break;
@@ -1523,7 +1523,7 @@
           || !ascii_strcasecmp(name,"hashname"))
 	{
 	  printf ("cfg:digestname:");
-	  print_algo_names (openpgp_md_test_algo, gcry_md_algo_name);
+	  print_algo_names (openpgp_md_test_algo, openpgp_md_algo_name);
 	  printf("\n");
 	  any=1;
 	}
@@ -3262,13 +3262,13 @@
 	else if(opt.def_digest_algo
 		&& !algo_available(PREFTYPE_HASH,opt.def_digest_algo,NULL))
 	  {
-	    badalg = gcry_md_algo_name (opt.def_digest_algo);
+	    badalg = openpgp_md_algo_name (opt.def_digest_algo);
 	    badtype = PREFTYPE_HASH;
 	  }
 	else if(opt.cert_digest_algo
 		&& !algo_available(PREFTYPE_HASH,opt.cert_digest_algo,NULL))
 	  {
-	    badalg = gcry_md_algo_name (opt.cert_digest_algo);
+	    badalg = openpgp_md_algo_name (opt.cert_digest_algo);
 	    badtype = PREFTYPE_HASH;
 	  }
 	else if(opt.compress_algo!=-1
@@ -3849,7 +3849,7 @@
 	    wrong_args("--print-md algo [files]");
 	{
 	    int all_algos = (**argv=='*' && !(*argv)[1]);
-	    int algo = all_algos? 0 : gcry_md_map_name (*argv);
+	    int algo = all_algos? 0 : map_md_gcry_to_openpgp (gcry_md_map_name (*argv));
 
 	    if( !algo && !all_algos )
 		log_error(_("invalid hash algorithm `%s'\n"), *argv );
@@ -4058,15 +4058,19 @@
 
   if(algo==DIGEST_ALGO_RMD160)
     indent+=printf("RMD160 = ");
-  else if(algo>0)
-    indent+=printf("%6s = ", gcry_md_algo_name (algo));
   else
-    algo=abs(algo);
-
+    {
+	if(algo==DIGEST_ALGO_WHIRLPOOL)
+      indent+=printf("WHRLPL = ");
+    else if(algo>0)
+      indent+=printf("%6s = ", openpgp_md_algo_name (algo));
+    else
+      algo=abs(algo);
+    }
   count=indent;
 
-  p = gcry_md_read (md, algo);
-  n = gcry_md_get_algo_dlen (algo);
+  p = gcry_md_read (md, map_md_openpgp_to_gcry (algo));
+  n = gcry_md_get_algo_dlen (map_md_openpgp_to_gcry (algo));
 
   count += printf ("%02X",*p++);
 
@@ -4137,8 +4141,8 @@
     }
     putchar(':');
     printf("%d:", algo );
-    p = gcry_md_read (md, algo);
-    n = gcry_md_get_algo_dlen (algo);
+    p = gcry_md_read (md, map_md_openpgp_to_gcry (algo));
+    n = gcry_md_get_algo_dlen (map_md_openpgp_to_gcry (algo));
     for(i=0; i < n ; i++, p++ ) 
         printf("%02X", *p );
     putchar(':');
@@ -4175,7 +4179,7 @@
 
     gcry_md_open (&md, 0, 0);
     if( algo )
-        gcry_md_enable (md, algo);
+        gcry_md_enable (md, map_md_openpgp_to_gcry (algo));
     else {
 	gcry_md_enable (md, GCRY_MD_MD5);
 	gcry_md_enable (md, GCRY_MD_SHA1);
@@ -4188,6 +4192,8 @@
           gcry_md_enable (md, GCRY_MD_SHA384);
         if (!openpgp_md_test_algo (GCRY_MD_SHA512))
           gcry_md_enable (md, GCRY_MD_SHA512);
+        if (!openpgp_md_test_algo (DIGEST_ALGO_WHIRLPOOL))
+          gcry_md_enable (md, GCRY_MD_WHIRLPOOL);
     }
 
     while( (n=fread( buf, 1, DIM(buf), fp )) )
@@ -4212,6 +4218,8 @@
                     print_hashline ( md, GCRY_MD_SHA384, fname );
                 if (!gcry_md_test_algo (GCRY_MD_SHA512))
                     print_hashline ( md, GCRY_MD_SHA512, fname );
+                if (!gcry_md_test_algo (GCRY_MD_WHIRLPOOL))
+                    print_hashline ( md, DIGEST_ALGO_WHIRLPOOL, fname );
             }
         }
         else {
@@ -4230,6 +4238,8 @@
                     print_hex( md, GCRY_MD_SHA384, fname );
                 if (!gcry_md_test_algo (GCRY_MD_SHA512))
                     print_hex( md, GCRY_MD_SHA512, fname );
+                if (!gcry_md_test_algo (GCRY_MD_WHIRLPOOL))
+                    print_hex( md, DIGEST_ALGO_WHIRLPOOL, fname );
             }
         }
     }
Index: g10/keyedit.c
===================================================================
--- g10/keyedit.c	(revision 5101)
+++ g10/keyedit.c	(working copy)
@@ -2373,9 +2373,9 @@
                     tty_printf (", ");
                 any = 1;
                 /* We don't want to display strings for experimental algos */
-                if (!gcry_md_test_algo (prefs[i].value)
+                if (!openpgp_md_test_algo (prefs[i].value)
                     && prefs[i].value < 100 )
-                    tty_printf ("%s", gcry_md_algo_name (prefs[i].value) );
+                    tty_printf ("%s", openpgp_md_algo_name (prefs[i].value) );
                 else
                     tty_printf ("[%d]", prefs[i].value);
                 if (prefs[i].value == DIGEST_ALGO_SHA1 )
Index: g10/seckey-cert.c
===================================================================
--- g10/seckey-cert.c	(revision 5101)
+++ g10/seckey-cert.c	(working copy)
@@ -67,7 +67,7 @@
               }
 	    return G10ERR_CIPHER_ALGO;
 	}
-	if(gcry_md_test_algo (sk->protect.s2k.hash_algo))
+	if(openpgp_md_test_algo (sk->protect.s2k.hash_algo))
 	  {
 	    log_info(_("protection digest %d is not supported\n"),
 		     sk->protect.s2k.hash_algo);
Index: g10/main.h
===================================================================
--- g10/main.h	(revision 5101)
+++ g10/main.h	(working copy)
@@ -83,12 +83,15 @@
 u32 buffer_to_u32( const byte *buffer );
 const byte *get_session_marker( size_t *rlen );
 int map_cipher_openpgp_to_gcry (int algo);
+int map_md_openpgp_to_gcry (int algo);
+int map_md_gcry_to_openpgp (int algo);
 #define openpgp_cipher_open(_a,_b,_c,_d) gcry_cipher_open((_a),map_cipher_openpgp_to_gcry((_b)),(_c),(_d))
 #define openpgp_cipher_get_algo_keylen(_a) gcry_cipher_get_algo_keylen(map_cipher_openpgp_to_gcry((_a)))
 #define openpgp_cipher_get_algo_blklen(_a) gcry_cipher_get_algo_blklen(map_cipher_openpgp_to_gcry((_a)))
 int openpgp_cipher_blocklen (int algo);
 int openpgp_cipher_test_algo( int algo );
 const char *openpgp_cipher_algo_name (int algo);
+const char *openpgp_md_algo_name (int algo);
 int openpgp_pk_test_algo( int algo );
 int openpgp_pk_test_algo2 ( int algo, unsigned int use );
 int openpgp_pk_algo_usage ( int algo );
Index: g10/misc.c
===================================================================
--- g10/misc.c	(revision 5101)
+++ g10/misc.c	(working copy)
@@ -328,7 +328,7 @@
 	{
 	  warn=1;
 	  log_info (_("WARNING: using experimental digest algorithm %s\n"),
-                    gcry_md_algo_name (algo));
+                    openpgp_md_algo_name (algo));
 	}
     }
   else if(algo==DIGEST_ALGO_MD5)
@@ -365,6 +365,29 @@
     }
 }
 
+/* Map OpenPGP digest numbers to those used by Libgcrypt.  We need to do
+   this for digests we implemented in Libgcrypt after they become
+   part of OpenPGP.  */
+int
+map_md_openpgp_to_gcry (int algo)
+{
+  switch (algo)
+    {
+    case DIGEST_ALGO_WHIRLPOOL: return 305;
+    default: return algo;
+    }
+}
+
+/* The inverse function of above.  */
+int
+map_md_gcry_to_openpgp (int algo)
+{
+  switch (algo)
+    {
+    case 305: return DIGEST_ALGO_WHIRLPOOL;
+    default: return algo;
+    }
+}
 
 /* Return the block length of an OpenPGP cipher algorithm.  */
 int 
@@ -488,7 +511,16 @@
      next revision of the standard.  */
   if (algo < 0 || algo > 110 || (algo >= 4 && algo <= 7))
     return gpg_error (GPG_ERR_DIGEST_ALGO);
-  return gcry_md_test_algo (algo);
+  return gcry_md_test_algo (map_md_openpgp_to_gcry (algo));
+}
+
+/* Map the OpenPGP digest algorithm whose ID is contained in ALGORITHM to a
+   string representation of the algorithm name.  For unknown algorithm
+   IDs this function returns "?".  */
+const char *
+openpgp_md_algo_name (int algo) 
+{
+  return gcry_md_algo_name (map_md_openpgp_to_gcry (algo));
 }
 
 #ifdef USE_IDEA
@@ -821,7 +853,7 @@
 { 
   int val;
 
-  val = gcry_md_map_name (string);
+  val = map_md_gcry_to_openpgp (gcry_md_map_name (string));
   if (!val && string && (string[0]=='H' || string[0]=='h'))
     {
       char *endptr;
_______________________________________________
Gnupg-users mailing list
Gnupg-users@gnupg.org
http://lists.gnupg.org/mailman/listinfo/gnupg-users

Reply via email to