]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[crypto] Define a structure for holding hybrid MD5+SHA1 HMAC keys
authorMichael Brown <mcb30@ipxe.org>
Tue, 30 Jun 2026 13:58:33 +0000 (14:58 +0100)
committerMichael Brown <mcb30@ipxe.org>
Thu, 2 Jul 2026 10:43:04 +0000 (11:43 +0100)
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 <mcb30@ipxe.org>
src/crypto/md5_sha1.c
src/include/ipxe/md5_sha1.h

index 88f4668bbaf9cad99ffa73c517b4962b2489d838..9d66e4dc6752be0ba6aa91419f67627eb9744263 100644 (file)
@@ -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 );
index 110e0b47fa616aaf1b6d21fd8451baaa97c3991c..6b186a875888442101edc38911e540d22adf0fb7 100644 (file)
@@ -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 */