diff --git a/hmactest.c b/hmactest.c index 577b26d..2ffe35e 100644 --- a/hmactest.c +++ b/hmactest.c @@ -80,6 +80,28 @@ int main(void) { } printf("\n"); + hmac_sha256_init(hmac_sha256_context, key, sizeof(key)-1); + hmac_sha256_update(hmac_sha256_context, "T", 1); + hmac_sha256_update(hmac_sha256_context, msg+1, sizeof(msg)-2); + hmac_sha256_finalize(hmac_sha256_context); + + printf("HMAC-SHA256 (incremental calculation): "); + for (int i = 0; i < sizeof(hmac_sha256_context->u[0].ctx.hash); i++) { + printf("%02x", hmac_sha256_context->u[0].ctx.hash[i]); + } + printf("\n"); + + hmac_sha1_init(hmac_sha1_context, key, sizeof(key)-1); + hmac_sha1_update(hmac_sha1_context, "T", 1); + hmac_sha1_update(hmac_sha1_context, msg+1, sizeof(msg)-2); + hmac_sha1_finalize(hmac_sha1_context); + + printf("HMAC-SHA1 (incremental calculation): "); + for (int i = 0; i < sizeof(hmac_sha1_context->u[0].ctx.hash); i++) { + printf("%02x", hmac_sha1_context->u[0].ctx.hash[i]); + } + printf("\n"); + hmac_md5_init(hmac_md5_context, key, sizeof(key)-1); hmac_md5_update(hmac_md5_context, "T", 1); hmac_md5_update(hmac_md5_context, msg+1, sizeof(msg)-2); @@ -90,4 +112,15 @@ int main(void) { printf("%02x", hmac_md5_context->u[0].ctx.hash[i]); } printf("\n"); + + hmac_md4_init(hmac_md4_context, key, sizeof(key)-1); + hmac_md4_update(hmac_md4_context, "T", 1); + hmac_md4_update(hmac_md4_context, msg+1, sizeof(msg)-2); + hmac_md4_finalize(hmac_md4_context); + + printf("HMAC-MD4 (incremental calculation): "); + for (int i = 0; i < sizeof(hmac_md4_context->u[0].ctx.hash); i++) { + printf("%02x", hmac_md4_context->u[0].ctx.hash[i]); + } + printf("\n"); } diff --git a/md4.h b/md4.h index 52ee0f9..2909e53 100644 --- a/md4.h +++ b/md4.h @@ -60,18 +60,32 @@ void md4_processblock(struct md4_context *context); /* * Initialize a context for HMAC-MD4 computation with a specified key. - * This must be called before any calls to hmac_md4_compute. After - * initialization, the context can be used to compute the HMAC for any - * number of messages. + * This must be called before any other HMAC calls. After initialization, + * the context can be used with either hmac_md4_update/hmac_md4_finalize + * or hmac_md4_compute, but they should not be mixed. */ void hmac_md4_init(struct hmac_md4_context *context, const unsigned char *key, unsigned long key_length); /* - * Compute the HMAC-MD4 of a message, using an already-initialized context. + * Update an HMAC-MD4 context based on the specified data. + */ +void hmac_md4_update(struct hmac_md4_context *context, + const unsigned char *message_part, + unsigned long part_length); + +/* + * Finish HMAC-MD4 processing and generate the final HMAC. * The result will be in context->u[0].ctx.hash. */ +void hmac_md4_finalize(struct hmac_md4_context *context); + +/* + * Compute the HMAC-MD4 of a message as a single operation. + * The result will be in context->u[0].ctx.hash. + * The context can be reused for multiple hmac_md4_compute operations. + */ void hmac_md4_compute(struct hmac_md4_context *context, const unsigned char *message, unsigned long message_length); diff --git a/sha1.h b/sha1.h index 042ada4..d21668a 100644 --- a/sha1.h +++ b/sha1.h @@ -60,18 +60,32 @@ void sha1_processblock(struct sha1_context *context); /* * Initialize a context for HMAC-SHA1 computation with a specified key. - * This must be called before any calls to hmac_sha1_compute. After - * initialization, the context can be used to compute the HMAC for any - * number of messages. + * This must be called before any other HMAC calls. After initialization, + * the context can be used with either hmac_sha1_update/hmac_sha1_finalize + * or hmac_sha1_compute, but they should not be mixed. */ void hmac_sha1_init(struct hmac_sha1_context *context, const unsigned char *key, unsigned long key_length); /* - * Compute the HMAC-SHA1 of a message, using an already-initialized context. + * Update an HMAC-SHA1 context based on the specified data. + */ +void hmac_sha1_update(struct hmac_sha1_context *context, + const unsigned char *message_part, + unsigned long part_length); + +/* + * Finish HMAC-SHA1 processing and generate the final HMAC. * The result will be in context->u[0].ctx.hash. */ +void hmac_sha1_finalize(struct hmac_sha1_context *context); + +/* + * Compute the HMAC-SHA1 of a message as a single operation. + * The result will be in context->u[0].ctx.hash. + * The context can be reused for multiple hmac_sha1_compute operations. + */ void hmac_sha1_compute(struct hmac_sha1_context *context, const unsigned char *message, unsigned long message_length); diff --git a/sha256.h b/sha256.h index 63319ca..af87673 100644 --- a/sha256.h +++ b/sha256.h @@ -68,18 +68,32 @@ void sha256_processblock(struct sha256_context *context); /* * Initialize a context for HMAC-SHA256 computation with a specified key. - * This must be called before any calls to hmac_sha256_compute. After - * initialization, the context can be used to compute the HMAC for any - * number of messages. + * This must be called before any other HMAC calls. After initialization, + * the context can be used with either hmac_sha256_update/hmac_sha256_finalize + * or hmac_sha256_compute, but they should not be mixed. */ void hmac_sha256_init(struct hmac_sha256_context *context, const unsigned char *key, unsigned long key_length); /* - * Compute the HMAC-SHA256 of a message, using an already-initialized context. + * Update an HMAC-SHA256 context based on the specified data. + */ +void hmac_sha256_update(struct hmac_sha256_context *context, + const unsigned char *message_part, + unsigned long part_length); + +/* + * Finish HMAC-SHA256 processing and generate the final HMAC. * The result will be in context->u[0].ctx.hash. */ +void hmac_sha256_finalize(struct hmac_sha256_context *context); + +/* + * Compute the HMAC-SHA256 of a message as a single operation. + * The result will be in context->u[0].ctx.hash. + * The context can be reused for multiple hmac_sha256_compute operations. + */ void hmac_sha256_compute(struct hmac_sha256_context *context, const unsigned char *message, unsigned long message_length);