aboutsummaryrefslogtreecommitdiffstats
path: root/cipher/md.c
diff options
context:
space:
mode:
Diffstat (limited to 'cipher/md.c')
-rw-r--r--cipher/md.c81
1 files changed, 79 insertions, 2 deletions
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
}