Please review this patch in inclusion in 0.9.8. This patch adds some new HMAC context functions, maybe the exact naming of the functions needs some debate to fall into line with the rest of libcrypto.

In a way these patches are necessary to allow application user to do the following things:

* Allow the application to allocate the HMAC_CTX with malloc/free to isolate incompatibility with varying sized HMAC_CTX between different OpenSSL build options when the application doesn't really care exactly which version of OpenSSL DLL its finds at runtime providing the API calls are available. For example the 0.9.7f built for Fedora Code has HMAC_MAX_MD_CBLOCK=64, but 0.9.8b built has HMAC_MAX_MD_CBLOCK=128, but would be possible with the HMAC_CTX_create() and HMAC_CTX_destroy() options to allow a DLL upgrade to take place. Since its isolated from compile time restrictions.

* Provides a HMAC_CTX_sizeof() call to allow the application to enquire how much storage it needs at runtime. This allows a HMAC_CTX to be embeded inside another address block (obviously natural alignment of the start address would be necessary on most platforms).

* Provides a function to copy the working context of the HMAC. Maybe I am copying too much ? This is a performance critical function in some situations. The man page entry for EVP_MD_CTX_copy_ex() elegantly describes the need for this "EVP_MD_CTX_copy_ex() can be used to copy the message digest state from in to out. This is useful if large amounts of data are to be hashed which only differ in the last few bytes."

Request for comments (good and bad),

Thanks

--
Darryl L. Miles

diff -u -r -N -x '*~' openssl-0.9.8b/crypto/hmac/hmac.c openssl-0.9.8b-hmac/crypto/hmac/hmac.c
--- openssl-0.9.8b/crypto/hmac/hmac.c	2005-05-17 01:01:47.000000000 +0100
+++ openssl-0.9.8b-hmac/crypto/hmac/hmac.c	2006-06-22 21:34:59.000000000 +0100
@@ -171,3 +171,37 @@
 	return(md);
 	}
 
+void HMAC_CTX_copy(HMAC_CTX *dest, HMAC_CTX *src)
+	{
+	HMAC_CTX_cleanup(dest);
+
+	dest->md = src->md;
+	EVP_MD_CTX_init(&dest->md_ctx);
+	EVP_MD_CTX_copy_ex(&dest->md_ctx,&src->md_ctx);
+	EVP_MD_CTX_init(&dest->i_ctx);
+	EVP_MD_CTX_copy_ex(&dest->i_ctx,&src->i_ctx);
+	EVP_MD_CTX_init(&dest->o_ctx);
+	EVP_MD_CTX_copy_ex(&dest->o_ctx,&src->o_ctx);
+	dest->key_length=src->key_length;
+	memcpy(dest->key, src->key, sizeof(dest->key));
+	}
+
+void HMAC_CTX_destroy(HMAC_CTX *ctx)
+	{
+	HMAC_CTX_cleanup(ctx);
+	OPENSSL_free(ctx);
+	}
+
+HMAC_CTX *HMAC_CTX_create_ex(const void *key, int len, const EVP_MD *md, ENGINE *impl)
+	{
+	HMAC_CTX *ctx;
+	if((ctx = OPENSSL_malloc(sizeof(HMAC_CTX))) == NULL)
+		return(NULL);
+	HMAC_Init_ex(ctx, key, len, md, impl);
+	return(ctx);
+	}
+
+size_t HMAC_CTX_sizeof(void)
+	{
+	return sizeof(HMAC_CTX);
+	}
diff -u -r -N -x '*~' openssl-0.9.8b/crypto/hmac/hmac.h openssl-0.9.8b-hmac/crypto/hmac/hmac.h
--- openssl-0.9.8b/crypto/hmac/hmac.h	2004-05-31 14:28:23.000000000 +0100
+++ openssl-0.9.8b-hmac/crypto/hmac/hmac.h	2006-06-22 21:14:11.000000000 +0100
@@ -99,7 +99,11 @@
 unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
 		    const unsigned char *d, size_t n, unsigned char *md,
 		    unsigned int *md_len);
-
+void HMAC_CTX_copy(HMAC_CTX *dest, HMAC_CTX *src);
+void HMAC_CTX_destroy(HMAC_CTX *ctx);
+HMAC_CTX *HMAC_CTX_create_ex(const void *key, int len,
+		  const EVP_MD *md, ENGINE *impl);
+size_t HMAC_CTX_sizeof(void);
 
 #ifdef  __cplusplus
 }
diff -u -r -N -x '*~' openssl-0.9.8b/doc/crypto/hmac.pod openssl-0.9.8b-hmac/doc/crypto/hmac.pod
--- openssl-0.9.8b/doc/crypto/hmac.pod	2006-01-30 17:06:59.000000000 +0000
+++ openssl-0.9.8b-hmac/doc/crypto/hmac.pod	2006-06-22 21:14:11.000000000 +0100
@@ -14,15 +14,23 @@
                unsigned char *md, unsigned int *md_len);
 
  void HMAC_CTX_init(HMAC_CTX *ctx);
+ void HMAC_CTX_cleanup(HMAC_CTX *ctx);
+
+ void HMAC_CTX_destroy(HMAC_CTX *ctx);
+ HMAC_CTX *HMAC_CTX_create_ex(const void *key, int len, const EVP_MD *md,
+               ENGINE *impl);
 
  void HMAC_Init(HMAC_CTX *ctx, const void *key, int key_len,
                const EVP_MD *md);
  void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len,
-               	   const EVP_MD *md, ENGINE *impl);
+               const EVP_MD *md, ENGINE *impl);
  void HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len);
  void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
 
- void HMAC_CTX_cleanup(HMAC_CTX *ctx);
+ void HMAC_CTX_copy(HMAC_CTX *dest, HMAC_CTX *src);
+ size_t HMAC_CTX_sizeof(void);
+
+ /* deprecated functions */
  void HMAC_cleanup(HMAC_CTX *ctx);
 
 =head1 DESCRIPTION
@@ -76,12 +84,33 @@
 HMAC_Final() places the message authentication code in B<md>, which
 must have space for the hash function output.
 
+HMAC_CTX_destroy() destroys the previously allocated B<HMAC_CTX>
+structure from HMAC_CTX_create_ex().
+
+HMAC_CTX_create_ex() allocated a new B<HMAC_CTX> structure, then
+initalized it with the values and returns it.  May return NULL on
+allocation failure.
+
+HMAC_CTX_copy() can be used to copy the state information of the B<src>
+HMAC_CTX structure into the B<dest> HMAC_CTX structure.  The B<dest>
+must have been initialized with HMAC_CTX_init() before use.
+
+HMAC_CTX_sizeof() returns the sizeof(HMAC_CTX) value of the library was
+build it.
+
 =head1 RETURN VALUES
 
 HMAC() returns a pointer to the message authentication code.
 
-HMAC_CTX_init(), HMAC_Init_ex(), HMAC_Update(), HMAC_Final() and
-HMAC_CTX_cleanup() do not return values.
+HMAC_CTX_init(), HMAC_Init_ex(), HMAC_Update(), HMAC_Final(), 
+HMAC_CTX_cleanup(), HMAC_CTX_destroy and HMAC_CTX_destroy do not
+ return values.
+HMAC_CTX_create() returns an allocated and initilized handle, the
+ caller must use HMAC_CTX_destroy() the deallocate resources. May
+ return NULL on allocation failure.
+HMAC_CTX_sizeof() returns the sizeof(HMAC_CTX) the openssl library
+ was compiled with.  Useful for runtime checking of embeded type
+ HMAC_CTX.
 
 =head1 CONFORMING TO
 
@@ -99,4 +128,7 @@
 HMAC_CTX_init(), HMAC_Init_ex() and HMAC_CTX_cleanup() are available
 since OpenSSL 0.9.7.
 
+HMAC_CTX_copy(), HMAC_CTX_destroy(), HMAC_CTX_create_ex() and
+HMAC_CTX_sizeof() are available since OpenSSL 0.9.8c.
+
 =cut

Reply via email to