From: Michael Brown Date: Tue, 30 Jun 2026 13:58:33 +0000 (+0100) Subject: [crypto] Define a structure for holding hybrid MD5+SHA1 HMAC keys X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=37225fa9cd6c2491f779cd9d37f2ddd1b6700bad;p=thirdparty%2Fipxe.git [crypto] Define a structure for holding hybrid MD5+SHA1 HMAC keys The hybrid PRF used in TLS version 1.1 and earlier does not use HMAC with the hybrid MD5+SHA1 algorithm: it uses separate invocations of HMAC-MD5 and HMAC-SHA1. Using hmac_keysize(&md5_sha1_algorithm) would produce a size too small to hold the combined HMAC-MD5 and HMAC-SHA1 keys. One option would be to set the (currently unused) MD5+SHA1 block size to 128, thereby ensuring that hmac_keysize() would happen to return a length large enough to hold both HMAC keys. This would avoid the need to special-case the MD5+SHA1 algorithm when calculating the required HMAC key size for the PRF, but would inevitably cause confusion in future. Set the MD5+SHA1 block size to 64 (since both algorithms have the same underlying block size, and this would therefore produce the "correct" result if anything were ever to use HMAC directly with the hybrid MD5+SHA1 algorithm), and define a separate structure for holding the separated HMAC keys used by the PRF in TLS version 1.1 and earlier. Signed-off-by: Michael Brown --- diff --git a/src/crypto/md5_sha1.c b/src/crypto/md5_sha1.c index 88f4668bb..9d66e4dc6 100644 --- a/src/crypto/md5_sha1.c +++ b/src/crypto/md5_sha1.c @@ -84,7 +84,7 @@ static void md5_sha1_final ( struct digest_algorithm *digest __unused, struct digest_algorithm md5_sha1_algorithm = { .name = "md5+sha1", .ctxsize = sizeof ( struct md5_sha1_context ), - .blocksize = 0, /* Not applicable */ + .blocksize = sizeof ( union md5_sha1_block ), .digestsize = sizeof ( struct md5_sha1_digest ), .init = md5_sha1_init, .update = md5_sha1_update, @@ -97,3 +97,7 @@ struct rsa_digestinfo_prefix rsa_md5_sha1_prefix __rsa_digestinfo_prefix = { .data = NULL, /* MD5+SHA1 signatures have no digestInfo */ .len = 0, }; + +/* Sanity checks */ +static_assert ( MD5_SHA1_BLOCK_SIZE == MD5_BLOCK_SIZE ); +static_assert ( MD5_SHA1_BLOCK_SIZE == SHA1_BLOCK_SIZE ); diff --git a/src/include/ipxe/md5_sha1.h b/src/include/ipxe/md5_sha1.h index 110e0b47f..6b186a875 100644 --- a/src/include/ipxe/md5_sha1.h +++ b/src/include/ipxe/md5_sha1.h @@ -37,6 +37,30 @@ struct md5_sha1_digest { /** MD5+SHA1 digest size */ #define MD5_SHA1_DIGEST_SIZE sizeof ( struct md5_sha1_digest ) +/** An MD5+SHA1 data block */ +union md5_sha1_block { + /** MD5 data block */ + uint8_t md5[MD5_BLOCK_SIZE]; + /** SHA-1 data block */ + uint8_t sha1[SHA1_BLOCK_SIZE]; +}; + +/** MD5+SHA1 block size */ +#define MD5_SHA1_BLOCK_SIZE sizeof ( union md5_sha1_block ) + +/** An MD5+SHA1 HMAC key block + * + * The hybrid PRF used in TLS version 1.1 and earlier does not use + * HMAC with the hybrid MD5+SHA1 algorithm: it uses separate + * invocations of HMAC-MD5 and HMAC-SHA1. + */ +struct md5_sha1_hmac_keys { + /** MD5 HMAC key */ + uint8_t md5[MD5_BLOCK_SIZE]; + /** SHA-1 HMAC key */ + uint8_t sha1[SHA1_BLOCK_SIZE]; +}; + extern struct digest_algorithm md5_sha1_algorithm; #endif /* _IPXE_MD5_SHA1_H */