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