From a2f6e4db5ee489ac3600ec5518e9914d017f85de Mon Sep 17 00:00:00 2001 From: jsing <> Date: Sun, 19 Jan 2025 07:51:41 +0000 Subject: Improve bit counter handling in MD5. Like most hashes, MD5 needs to keep count of the number of bits in the message being processed. However, rather than using a 64 bit counter this is implemented using two 32 bit values (which is exposed in the public API). Even with this hurdle, we can still use 64 bit math and let the compiler figure out how to best handle the situation (hopefully avoiding compiler warnings on 16 bit platforms in the process!). On amd64 this code now requires two instructions, instead of the previous five. While here remove a comment that is excessively visible and no longer completely accurate (and if you're going to redefine types like MD5_WORD you kinda need to know what you're doing). ok tb@ (who's going to miss the dear diary style comments) --- src/lib/libcrypto/crypto_internal.h | 12 +++++++++++- src/lib/libcrypto/md5/md5.c | 12 +++--------- src/lib/libcrypto/md5/md5.h | 13 ++++--------- 3 files changed, 18 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/lib/libcrypto/crypto_internal.h b/src/lib/libcrypto/crypto_internal.h index c5de5b7b51..09ae7fa466 100644 --- a/src/lib/libcrypto/crypto_internal.h +++ b/src/lib/libcrypto/crypto_internal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto_internal.h,v 1.14 2024/11/08 14:05:43 jsing Exp $ */ +/* $OpenBSD: crypto_internal.h,v 1.15 2025/01/19 07:51:41 jsing Exp $ */ /* * Copyright (c) 2023 Joel Sing * @@ -256,6 +256,16 @@ crypto_store_htole32(uint8_t *dst, uint32_t v) } #endif +#ifndef HAVE_CRYPTO_ADD_U32DW_U64 +static inline void +crypto_add_u32dw_u64(uint32_t *h, uint32_t *l, uint64_t v) +{ + v += ((uint64_t)*h << 32) | *l; + *h = v >> 32; + *l = v; +} +#endif + #ifndef HAVE_CRYPTO_ROL_U32 static inline uint32_t crypto_rol_u32(uint32_t v, size_t shift) diff --git a/src/lib/libcrypto/md5/md5.c b/src/lib/libcrypto/md5/md5.c index 744c66f005..3bc558f0f2 100644 --- a/src/lib/libcrypto/md5/md5.c +++ b/src/lib/libcrypto/md5/md5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: md5.c,v 1.23 2024/06/01 07:36:16 tb Exp $ */ +/* $OpenBSD: md5.c,v 1.24 2025/01/19 07:51:41 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -278,19 +278,13 @@ MD5_Update(MD5_CTX *c, const void *data_, size_t len) { const unsigned char *data = data_; unsigned char *p; - MD5_LONG l; size_t n; if (len == 0) return 1; - l = (c->Nl + (((MD5_LONG)len) << 3))&0xffffffffUL; - /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to - * Wei Dai for pointing it out. */ - if (l < c->Nl) /* overflow */ - c->Nh++; - c->Nh+=(MD5_LONG)(len>>29); /* might cause compiler warning on 16-bit */ - c->Nl = l; + /* Update message bit counter. */ + crypto_add_u32dw_u64(&c->Nh, &c->Nl, (uint64_t)len << 3); n = c->num; if (n != 0) { diff --git a/src/lib/libcrypto/md5/md5.h b/src/lib/libcrypto/md5/md5.h index a3529f486d..99e71783b9 100644 --- a/src/lib/libcrypto/md5/md5.h +++ b/src/lib/libcrypto/md5/md5.h @@ -1,4 +1,4 @@ -/* $OpenBSD: md5.h,v 1.23 2024/06/01 07:44:11 tb Exp $ */ +/* $OpenBSD: md5.h,v 1.24 2025/01/19 07:51:41 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -60,12 +60,13 @@ #ifndef HEADER_MD5_H #define HEADER_MD5_H + +#include + #if !defined(HAVE_ATTRIBUTE__BOUNDED__) && !defined(__OpenBSD__) #define __bounded__(x, y, z) #endif -#include - #ifdef __cplusplus extern "C" { #endif @@ -74,12 +75,6 @@ extern "C" { #error MD5 is disabled. #endif -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * ! MD5_LONG has to be at least 32 bits wide. ! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - */ - #define MD5_LONG unsigned int #define MD5_CBLOCK 64 -- cgit v1.2.3-55-g6feb