diff options
Diffstat (limited to 'src/crypto/hmac.c')
-rw-r--r-- | src/crypto/hmac.c | 96 |
1 files changed, 32 insertions, 64 deletions
diff --git a/src/crypto/hmac.c b/src/crypto/hmac.c index f898619c8..7109bbf6a 100644 --- a/src/crypto/hmac.c +++ b/src/crypto/hmac.c @@ -47,93 +47,61 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <ipxe/hmac.h> /** - * Reduce HMAC key length - * - * @v digest Digest algorithm to use - * @v digest_ctx Digest context - * @v key Key - * @v key_len Length of key - */ -static void hmac_reduce_key ( struct digest_algorithm *digest, - void *key, size_t *key_len ) { - uint8_t digest_ctx[digest->ctxsize]; - - digest_init ( digest, digest_ctx ); - digest_update ( digest, digest_ctx, key, *key_len ); - digest_final ( digest, digest_ctx, key ); - *key_len = digest->digestsize; -} - -/** * Initialise HMAC * * @v digest Digest algorithm to use - * @v digest_ctx Digest context + * @v ctx HMAC context * @v key Key * @v key_len Length of key - * - * The length of the key should be less than the block size of the - * digest algorithm being used. (If the key length is greater, it - * will be replaced with its own digest, and key_len will be updated - * accordingly). */ -void hmac_init ( struct digest_algorithm *digest, void *digest_ctx, - void *key, size_t *key_len ) { - unsigned char k_ipad[digest->blocksize]; +void hmac_init ( struct digest_algorithm *digest, void *ctx, const void *key, + size_t key_len ) { + hmac_context_t ( digest ) *hctx = ctx; unsigned int i; - /* Reduce key if necessary */ - if ( *key_len > sizeof ( k_ipad ) ) - hmac_reduce_key ( digest, key, key_len ); - /* Construct input pad */ - memset ( k_ipad, 0, sizeof ( k_ipad ) ); - memcpy ( k_ipad, key, *key_len ); - for ( i = 0 ; i < sizeof ( k_ipad ) ; i++ ) { - k_ipad[i] ^= 0x36; + memset ( hctx->pad, 0, sizeof ( hctx->pad ) ); + if ( key_len <= sizeof ( hctx->pad ) ) { + memcpy ( hctx->pad, key, key_len ); + } else { + digest_init ( digest, hctx->ctx ); + digest_update ( digest, hctx->ctx, key, key_len ); + digest_final ( digest, hctx->ctx, hctx->pad ); + } + for ( i = 0 ; i < sizeof ( hctx->pad ) ; i++ ) { + hctx->pad[i] ^= 0x36; } - + /* Start inner hash */ - digest_init ( digest, digest_ctx ); - digest_update ( digest, digest_ctx, k_ipad, sizeof ( k_ipad ) ); + digest_init ( digest, hctx->ctx ); + digest_update ( digest, hctx->ctx, hctx->pad, sizeof ( hctx->pad ) ); } /** * Finalise HMAC * * @v digest Digest algorithm to use - * @v digest_ctx Digest context - * @v key Key - * @v key_len Length of key + * @v ctx HMAC context * @v hmac HMAC digest to fill in - * - * The length of the key should be less than the block size of the - * digest algorithm being used. (If the key length is greater, it - * will be replaced with its own digest, and key_len will be updated - * accordingly). */ -void hmac_final ( struct digest_algorithm *digest, void *digest_ctx, - void *key, size_t *key_len, void *hmac ) { - unsigned char k_opad[digest->blocksize]; +void hmac_final ( struct digest_algorithm *digest, void *ctx, void *hmac ) { + hmac_context_t ( digest ) *hctx = ctx; unsigned int i; - /* Reduce key if necessary */ - if ( *key_len > sizeof ( k_opad ) ) - hmac_reduce_key ( digest, key, key_len ); - - /* Construct output pad */ - memset ( k_opad, 0, sizeof ( k_opad ) ); - memcpy ( k_opad, key, *key_len ); - for ( i = 0 ; i < sizeof ( k_opad ) ; i++ ) { - k_opad[i] ^= 0x5c; + /* Construct output pad from input pad */ + for ( i = 0 ; i < sizeof ( hctx->pad ) ; i++ ) { + hctx->pad[i] ^= 0x6a; } - + /* Finish inner hash */ - digest_final ( digest, digest_ctx, hmac ); + digest_final ( digest, hctx->ctx, hmac ); /* Perform outer hash */ - digest_init ( digest, digest_ctx ); - digest_update ( digest, digest_ctx, k_opad, sizeof ( k_opad ) ); - digest_update ( digest, digest_ctx, hmac, digest->digestsize ); - digest_final ( digest, digest_ctx, hmac ); + digest_init ( digest, hctx->ctx ); + digest_update ( digest, hctx->ctx, hctx->pad, sizeof ( hctx->pad ) ); + digest_update ( digest, hctx->ctx, hmac, digest->digestsize ); + digest_final ( digest, hctx->ctx, hmac ); + + /* Erase output pad (from which the key may be derivable) */ + memset ( hctx->pad, 0, sizeof ( hctx->pad ) ); } |