summaryrefslogtreecommitdiffstats
path: root/cipher
diff options
context:
space:
mode:
Diffstat (limited to 'cipher')
-rw-r--r--cipher/ChangeLog13
-rw-r--r--cipher/Makefile.am4
-rw-r--r--cipher/des.c205
-rw-r--r--cipher/md.c81
-rw-r--r--cipher/pubkey.c2
-rw-r--r--cipher/tiger.c2
6 files changed, 240 insertions, 67 deletions
diff --git a/cipher/ChangeLog b/cipher/ChangeLog
index cbcea5f9e..251f4df9d 100644
--- a/cipher/ChangeLog
+++ b/cipher/ChangeLog
@@ -1,3 +1,16 @@
+Mon Sep 28 13:23:09 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c (md_digest): New.
+ (md_reset): New.
+
+Wed Sep 23 12:27:02 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * tiger.c (TIGER_CONTEXT): moved "buf", so that it is 64 bit aligned.
+
+Mon Sep 21 06:22:53 1998 Werner Koch (wk@(none))
+
+ * des.c: Some patches from Michael.
+
Thu Sep 17 19:00:06 1998 Werner Koch (wk@(none))
* des.c : New file from Michael Roth <mroth@nessie.de>
diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index 09edd4df9..26c625dcb 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -48,11 +48,11 @@ EXTRA_twofish_SOURCES = twofish.c
tiger: $(srcdir)/tiger.c
- `echo $(COMPILE) -shared -fPIC -o tiger $(srcdir)/tiger.c | \
+ `echo $(COMPILE) -shared -fPIC -lc -o tiger $(srcdir)/tiger.c | \
sed -e 's/-O2/-O1/' `
twofish: $(srcdir)/twofish.c
- `echo $(COMPILE) -shared -fPIC -o twofish $(srcdir)/twofish.c | \
+ `echo $(COMPILE) -shared -fPIC -lc -o twofish $(srcdir)/twofish.c | \
sed -e 's/-O2/ /' `
diff --git a/cipher/des.c b/cipher/des.c
index f10716a2e..ef8ce7de3 100644
--- a/cipher/des.c
+++ b/cipher/des.c
@@ -152,7 +152,6 @@
*/
typedef struct _des_ctx
{
- int mode;
u32 encrypt_subkeys[32];
u32 decrypt_subkeys[32];
}
@@ -163,19 +162,19 @@ des_ctx[1];
*/
typedef struct _tripledes_ctx
{
- int mode;
u32 encrypt_subkeys[96];
u32 decrypt_subkeys[96];
}
tripledes_ctx[1];
-static void des_key_schedule (const byte *, u32 *, int);
+static void des_key_schedule (const byte *, u32 *);
static int des_setkey (struct _des_ctx *, const byte *);
static int des_ecb_crypt (struct _des_ctx *, const byte *, byte *, int);
static int tripledes_set2keys (struct _tripledes_ctx *, const byte *, const byte *);
static int tripledes_set3keys (struct _tripledes_ctx *, const byte *, const byte *, const byte *);
static int tripledes_ecb_crypt (struct _tripledes_ctx *, const byte *, byte *, int);
+static int is_weak_key ( const byte *key );
static const char *selftest (void);
@@ -308,18 +307,58 @@ u32 rightkey_swap[16] =
/*
* Numbers of left shifts per round for encryption subkey schedule
+ * To calculate the decryption key scheduling we just reverse the
+ * ordering of the subkeys so we can omit the table for decryption
+ * subkey schedule.
*/
static byte encrypt_rotate_tab[16] =
{
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
};
+
+
/*
- * Numbers of right shifts per round for decryption subkey schedule
+ * Table with weak DES keys sorted in ascending order.
+ * In DES their are 64 known keys wich are weak. They are weak
+ * because they produce only one, two or four different
+ * subkeys in the subkey scheduling process.
+ * The keys in this table have all their parity bits cleared.
*/
-static byte decrypt_rotate_tab[16] =
+static byte weak_keys[64][8] =
{
- 0, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e },
+ { 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0 }, { 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe },
+ { 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e }, { 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00 },
+ { 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe }, { 0x00, 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0 },
+ { 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0 }, { 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe },
+ { 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00 }, { 0x00, 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e },
+ { 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe }, { 0x00, 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0 },
+ { 0x00, 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e }, { 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00 },
+ { 0x0e, 0x0e, 0x0e, 0x0e, 0xf0, 0xf0, 0xf0, 0xf0 }, { 0x1e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x0e },
+ { 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 }, { 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0, 0xfe },
+ { 0x1e, 0x00, 0xfe, 0xe0, 0x0e, 0x00, 0xfe, 0xf0 }, { 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00 },
+ { 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e }, { 0x1e, 0x1e, 0xe0, 0xe0, 0x0e, 0x0e, 0xf0, 0xf0 },
+ { 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe, 0xfe }, { 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00, 0xfe },
+ { 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 }, { 0x1e, 0xe0, 0xe0, 0x1e, 0x0e, 0xf0, 0xf0, 0x0e },
+ { 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe, 0x00 }, { 0x1e, 0xfe, 0x00, 0xe0, 0x0e, 0xfe, 0x00, 0xf0 },
+ { 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe }, { 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0, 0x00 },
+ { 0x1e, 0xfe, 0xfe, 0x1e, 0x0e, 0xfe, 0xfe, 0x0e }, { 0xe0, 0x00, 0x00, 0xe0, 0xf0, 0x00, 0x00, 0xf0 },
+ { 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e, 0xfe }, { 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 },
+ { 0xe0, 0x00, 0xfe, 0x1e, 0xf0, 0x00, 0xfe, 0x0e }, { 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00, 0xfe },
+ { 0xe0, 0x1e, 0x1e, 0xe0, 0xf0, 0x0e, 0x0e, 0xf0 }, { 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e },
+ { 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe, 0x00 }, { 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00 },
+ { 0xe0, 0xe0, 0x1e, 0x1e, 0xf0, 0xf0, 0x0e, 0x0e }, { 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe, 0xfe },
+ { 0xe0, 0xfe, 0x00, 0x1e, 0xf0, 0xfe, 0x00, 0x0e }, { 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e, 0x00 },
+ { 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe }, { 0xe0, 0xfe, 0xfe, 0xe0, 0xf0, 0xfe, 0xfe, 0xf0 },
+ { 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe }, { 0xfe, 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0 },
+ { 0xfe, 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e }, { 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00 },
+ { 0xfe, 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0 }, { 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe },
+ { 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00 }, { 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e },
+ { 0xfe, 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e }, { 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00 },
+ { 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe }, { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 },
+ { 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00 }, { 0xfe, 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e },
+ { 0xfe, 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0 }, { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe }
};
@@ -359,7 +398,7 @@ static byte decrypt_rotate_tab[16] =
/*
- * A full DES round including 'expansion funtion', 'sbox substitution'
+ * A full DES round including 'expansion function', 'sbox substitution'
* and 'primitive function P' but without swapping the left and right word.
*/
#define DES_ROUND(from, to, work, subkey) \
@@ -403,23 +442,22 @@ static byte decrypt_rotate_tab[16] =
/*
- * des_key_schedule(): Calculate 16 subkeys pairs (even/odd) for one DES round
+ * des_key_schedule(): Calculate 16 subkeys pairs (even/odd) for
+ * 16 encryption rounds.
+ * To calculate subkeys for decryption the caller
+ * have to reorder the generated subkeys.
*
* rawkey: 8 Bytes of key data
* subkey: Array of at least 32 u32s. Will be filled
* with calculated subkeys.
- * mode: Key schedule mode.
- * mode == 0: Calculate subkeys to encrypt
- * mode != 0: Calculate subkeys to decrypt
*
*/
static void
-des_key_schedule (const byte * rawkey, u32 * subkey, int mode)
+des_key_schedule (const byte * rawkey, u32 * subkey)
{
u32 left, right, work;
int round;
-
READ_64BIT_DATA (rawkey, left, right)
DO_PERMUTATION (right, work, left, 4, 0x0f0f0f0f)
@@ -441,20 +479,8 @@ des_key_schedule (const byte * rawkey, u32 * subkey, int mode)
for (round = 0; round < 16; ++round)
{
- if (mode)
- {
- /* decrypt */
-
- left = ((left >> decrypt_rotate_tab[round]) | (left << (28 - decrypt_rotate_tab[round]))) & 0x0fffffff;
- right = ((right >> decrypt_rotate_tab[round]) | (right << (28 - decrypt_rotate_tab[round]))) & 0x0fffffff;
- }
- else
- {
- /* encrypt */
-
- left = ((left << encrypt_rotate_tab[round]) | (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
- right = ((right << encrypt_rotate_tab[round]) | (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
- }
+ left = ((left << encrypt_rotate_tab[round]) | (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
+ right = ((right << encrypt_rotate_tab[round]) | (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
*subkey++ = ((left << 4) & 0x24000000)
| ((left << 28) & 0x10000000)
@@ -514,11 +540,15 @@ des_key_schedule (const byte * rawkey, u32 * subkey, int mode)
static int
des_setkey (struct _des_ctx *ctx, const byte * key)
{
- if (!ctx || !key)
- return -1;
+ int i;
- des_key_schedule (key, ctx->encrypt_subkeys, 0);
- des_key_schedule (key, ctx->decrypt_subkeys, 1);
+ des_key_schedule (key, ctx->encrypt_subkeys);
+
+ for(i=0; i<32; i+=2)
+ {
+ ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[30-i];
+ ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[31-i];
+ }
return 0;
}
@@ -535,9 +565,6 @@ des_ecb_crypt (struct _des_ctx *ctx, const byte * from, byte * to, int mode)
u32 left, right, work;
u32 *keys;
- if (!ctx || !from || !to)
- return -1;
-
keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
READ_64BIT_DATA (from, left, right)
@@ -570,17 +597,25 @@ tripledes_set2keys (struct _tripledes_ctx *ctx,
const byte * key1,
const byte * key2)
{
- if (!ctx || !key1 || !key2)
- return -1;
+ int i;
+
+ des_key_schedule (key1, ctx->encrypt_subkeys);
+ des_key_schedule (key2, &(ctx->decrypt_subkeys[32]));
- des_key_schedule (key1, ctx->encrypt_subkeys, 0);
- des_key_schedule (key1, ctx->decrypt_subkeys, 1);
+ for(i=0; i<32; i+=2)
+ {
+ ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[30-i];
+ ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[31-i];
+
+ ctx->encrypt_subkeys[i+32] = ctx->decrypt_subkeys[62-i];
+ ctx->encrypt_subkeys[i+33] = ctx->decrypt_subkeys[63-i];
- des_key_schedule (key2, &(ctx->encrypt_subkeys[32]), 1);
- des_key_schedule (key2, &(ctx->decrypt_subkeys[32]), 0);
+ ctx->encrypt_subkeys[i+64] = ctx->encrypt_subkeys[i];
+ ctx->encrypt_subkeys[i+65] = ctx->encrypt_subkeys[i+1];
- des_key_schedule (key1, &(ctx->encrypt_subkeys[64]), 0);
- des_key_schedule (key1, &(ctx->decrypt_subkeys[64]), 1);
+ ctx->decrypt_subkeys[i+64] = ctx->decrypt_subkeys[i];
+ ctx->decrypt_subkeys[i+65] = ctx->decrypt_subkeys[i+1];
+ }
return 0;
}
@@ -598,17 +633,23 @@ tripledes_set3keys (struct _tripledes_ctx *ctx,
const byte * key2,
const byte * key3)
{
- if (!ctx || !key1 || !key2 || !key3)
- return -1;
+ int i;
- des_key_schedule (key1, ctx->encrypt_subkeys, 0);
- des_key_schedule (key1, ctx->decrypt_subkeys, 1);
+ des_key_schedule (key1, ctx->encrypt_subkeys);
+ des_key_schedule (key2, &(ctx->decrypt_subkeys[32]));
+ des_key_schedule (key3, &(ctx->encrypt_subkeys[64]));
- des_key_schedule (key2, &(ctx->encrypt_subkeys[32]), 1);
- des_key_schedule (key2, &(ctx->decrypt_subkeys[32]), 0);
+ for(i=0; i<32; i+=2)
+ {
+ ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[94-i];
+ ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[95-i];
+
+ ctx->encrypt_subkeys[i+32] = ctx->decrypt_subkeys[62-i];
+ ctx->encrypt_subkeys[i+33] = ctx->decrypt_subkeys[63-i];
- des_key_schedule (key3, &(ctx->encrypt_subkeys[64]), 0);
- des_key_schedule (key3, &(ctx->decrypt_subkeys[64]), 1);
+ ctx->decrypt_subkeys[i+64] = ctx->encrypt_subkeys[30-i];
+ ctx->decrypt_subkeys[i+65] = ctx->encrypt_subkeys[31-i];
+ }
return 0;
}
@@ -617,6 +658,7 @@ tripledes_set3keys (struct _tripledes_ctx *ctx,
/*
* Electronic Codebook Mode Triple-DES encryption/decryption of data according to 'mode'.
+ * Sometimes this mode is named 'EDE' mode (Encryption-Decryption-Encryption).
*/
static int
tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from, byte * to, int mode)
@@ -624,9 +666,6 @@ tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from, byte * to, i
u32 left, right, work;
u32 *keys;
- if (!ctx || !from || !to)
- return -1;
-
keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
READ_64BIT_DATA (from, left, right)
@@ -666,17 +705,45 @@ tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from, byte * to, i
}
+
/*
* Check whether the 8 byte key is weak.
+ * Dose not check the parity bits of the key but simple ignore them.
*/
-
static int
-is_weak_key ( byte *key )
+is_weak_key ( const byte *key )
{
- return 0; /* FIXME */
+ byte work[8];
+ int i, left, right, middle, cmp_result;
+
+ /* clear parity bits */
+ for(i=0; i<8; ++i)
+ work[i] = key[i] & 0xfe;
+
+ /* binary search in the weak key table */
+ left = 0;
+ right = 63;
+ while(1)
+ {
+ middle = (left + right) / 2;
+
+ if ( !(cmp_result=memcmp(work, weak_keys[middle], 8)) )
+ return -1;
+
+ if ( left == right )
+ break;
+
+ if ( cmp_result > 0 )
+ left = middle + 1;
+ else
+ right = middle - 1;
+ }
+
+ return 0;
}
+
/*
* Performs a selftest of this DES/Triple-DES implementation.
* Returns an string with the error text on failure.
@@ -717,12 +784,14 @@ selftest (void)
memcpy (input, temp1, 8);
}
if (memcmp (temp3, result, 8))
- return "DES maintenace test failed.";
+ return "DES maintenance test failed.";
}
/*
- * Triple-DES test (Does somebody known on official test?)
+ * Triple-DES test (Do somebody known on official test?)
+ *
+ * FIXME: This test doesn't use tripledes_set3keys() !
*/
{
int i;
@@ -749,6 +818,20 @@ selftest (void)
return "TRIPLE-DES test failed.";
}
+
+ /*
+ * Check the weak key detection. We simply assume the table with
+ * weak keys is ok and check every key in the table if it is
+ * detected... (This test is a little bit stupid)
+ */
+ {
+ int i;
+
+ for (i = 0; i < 64; ++i)
+ if (!is_weak_key(weak_keys[i]))
+ return "DES weak key detection failed";
+ }
+
return 0;
}
@@ -759,11 +842,11 @@ do_tripledes_setkey ( struct _tripledes_ctx *ctx, byte *key, unsigned keylen )
if( keylen != 24 )
return G10ERR_WRONG_KEYLEN;
+ tripledes_set3keys ( ctx, key, key+8, key+16);
+
if( is_weak_key( key ) || is_weak_key( key+8 ) || is_weak_key( key+16 ) )
return G10ERR_WEAK_KEY;
- tripledes_set3keys ( ctx, key, key+8, key+16);
-
return 0;
}
@@ -800,7 +883,7 @@ des_get_info( int algo, size_t *keylen,
if( !did_selftest ) {
const char *s = selftest();
if( s )
- log_fatal("selftest failed: %s", s );
+ log_fatal("selftest failed: %s\n", s );
did_selftest = 1;
}
diff --git a/cipher/md.c b/cipher/md.c
index 56f639cfd..a04155235 100644
--- a/cipher/md.c
+++ b/cipher/md.c
@@ -256,7 +256,7 @@ md_copy( MD_HANDLE a )
: m_alloc( sizeof *b );
memcpy( b, a, sizeof *a );
b->list = NULL;
- /* and now copy the compelte list of algorithms */
+ /* and now copy the complete list of algorithms */
/* I know that the copied list is reversed, but that doesn't matter */
for( ar=a->list; ar; ar = ar->next ) {
br = a->secure ? m_alloc_secure( sizeof *br + ar->contextsize )
@@ -269,6 +269,23 @@ md_copy( MD_HANDLE a )
}
+/****************
+ * Reset all contexts and discard any buffered stuuf. This may be used
+ * instead of a md_close(); md_open().
+ */
+void
+md_reset( MD_HANDLE a )
+{
+ struct md_digest_list_s *r;
+
+ a->bufcount = 0;
+ for( r=a->list; r; r = r->next ) {
+ memset( r->context, 0, r->contextsize );
+ (*r->init)( &r->context );
+ }
+}
+
+
void
md_close(MD_HANDLE a)
{
@@ -331,7 +348,7 @@ md_read( MD_HANDLE a, int algo )
if( !algo ) { /* return the first algorithm */
if( (r=a->list) ) {
if( r->next )
- log_error("warning: more than algorithm in md_read(0)\n");
+ log_debug("more than algorithm in md_read(0)\n");
return (*r->read)( &r->context );
}
}
@@ -344,6 +361,58 @@ md_read( MD_HANDLE a, int algo )
return NULL;
}
+
+/****************
+ * This function combines md_final and md_read but keeps the context
+ * intact. This function can be used to calculate intermediate
+ * digests. The digest is copied into buffer and the digestlength is
+ * returned. If buffer is NULL only the needed size for buffer is returned.
+ * buflen gives the max size of buffer. If the buffer is too shourt to
+ * hold the complete digest, the buffer is filled with as many bytes are
+ * possible and this value is returned.
+ */
+int
+md_digest( MD_HANDLE a, int algo, byte *buffer, int buflen )
+{
+ struct md_digest_list_s *r = NULL;
+ char *context;
+ char *digest;
+
+ if( a->bufcount )
+ md_write( a, NULL, 0 );
+
+ if( !algo ) { /* return digest for the first algorithm */
+ if( (r=a->list) && r->next )
+ log_debug("more than algorithm in md_digest(0)\n");
+ }
+ else {
+ for(r=a->list; r; r = r->next )
+ if( r->algo == algo )
+ break;
+ }
+ if( !r )
+ BUG();
+
+ if( !buffer )
+ return r->mdlen;
+
+ /* I don't want to change the interface, so I simply work on a copy
+ * the context (extra overhead - should be fixed)*/
+ context = a->secure ? m_alloc_secure( r->contextsize )
+ : m_alloc( r->contextsize );
+ memcpy( context, r->context, r->contextsize );
+ (*r->final)( context );
+ digest = (*r->read)( context );
+
+ if( buflen > r->mdlen )
+ buflen = r->mdlen;
+ memcpy( buffer, digest, buflen );
+
+ m_free(context);
+ return buflen;
+}
+
+
int
md_get_algo( MD_HANDLE a )
{
@@ -423,5 +492,13 @@ md_stop_debug( MD_HANDLE md )
fclose(md->debug);
md->debug = NULL;
}
+ #ifdef HAVE_U64_TYPEDEF
+ { /* a kludge to pull in the __muldi3 for Solaris */
+ volatile u32 a = (u32)md;
+ volatile u32 b = 42;
+ volatile u64 c;
+ c = a * b;
+ }
+ #endif
}
diff --git a/cipher/pubkey.c b/cipher/pubkey.c
index a78f788c0..62a48a6d8 100644
--- a/cipher/pubkey.c
+++ b/cipher/pubkey.c
@@ -480,7 +480,7 @@ pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
/****************
* This is the interface to the public key signing.
- * Sign hash with skey and put the result into resarr which
+ * Sign data with skey and put the result into resarr which
* should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the
* algorithm allows this - check with pubkey_get_nsig() )
*/
diff --git a/cipher/tiger.c b/cipher/tiger.c
index d02f5cb86..c473e92d3 100644
--- a/cipher/tiger.c
+++ b/cipher/tiger.c
@@ -29,9 +29,9 @@
typedef struct {
u64 a, b, c;
- u32 nblocks;
byte buf[64];
int count;
+ u32 nblocks;
} TIGER_CONTEXT;