diff --git a/ChangeLog.d/sha256-update-ilen-over-4gib.txt b/ChangeLog.d/sha256-update-ilen-over-4gib.txt new file mode 100644 index 0000000000..efbb7b4dc5 --- /dev/null +++ b/ChangeLog.d/sha256-update-ilen-over-4gib.txt @@ -0,0 +1,12 @@ +Bugfix + * Fix MD5, SHA1, SHA224, SHA256 and RIPEMD160 computing the wrong + digest when 4GiB of data or more are processed in a single call. + That can happen either when using the one-shot APIs + (psa_hash_compute(), psa_hash_compare(), mbedtls_md(), + mbedtls_md5(), mbedtls_sha1(), mbedtls_ripemd160(), + mbedtls_sha256()) with more than 4GiB of input, or when using the + streaming API and passing more than 4GiB in a single call to the + update function (psa_hash_update(), mbedtls_md_update(), + mbedtls_md5_update(), mbedtls_sha1_update(), + mbedtls_ripemd160_update(), mbedtls_sha256_update()). Reported by + TimothyPMann in #10964. diff --git a/library/md5.c b/library/md5.c index e4a87a2e09..088061930c 100644 --- a/library/md5.c +++ b/library/md5.c @@ -222,6 +222,10 @@ int mbedtls_md5_update(mbedtls_md5_context *ctx, ctx->total[1]++; } +#if SIZE_MAX > 0xFFFFFFFF + ctx->total[1] += (uint32_t) (ilen >> 32); +#endif + if (left && ilen >= fill) { memcpy((void *) (ctx->buffer + left), input, fill); if ((ret = mbedtls_internal_md5_process(ctx, ctx->buffer)) != 0) { diff --git a/library/ripemd160.c b/library/ripemd160.c index b4fc3cdba1..6a8f3123d3 100644 --- a/library/ripemd160.c +++ b/library/ripemd160.c @@ -285,6 +285,10 @@ int mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx, ctx->total[1]++; } +#if SIZE_MAX > 0xFFFFFFFF + ctx->total[1] += (uint32_t) (ilen >> 32); +#endif + if (left && ilen >= fill) { memcpy((void *) (ctx->buffer + left), input, fill); diff --git a/library/sha1.c b/library/sha1.c index dfbe481f39..fe28022ae2 100644 --- a/library/sha1.c +++ b/library/sha1.c @@ -257,6 +257,10 @@ int mbedtls_sha1_update(mbedtls_sha1_context *ctx, ctx->total[1]++; } +#if SIZE_MAX > 0xFFFFFFFF + ctx->total[1] += (uint32_t) (ilen >> 32); +#endif + if (left && ilen >= fill) { memcpy((void *) (ctx->buffer + left), input, fill); diff --git a/library/sha256.c b/library/sha256.c index 4f1ac3e0fb..06d2f53bc3 100644 --- a/library/sha256.c +++ b/library/sha256.c @@ -667,6 +667,10 @@ int mbedtls_sha256_update(mbedtls_sha256_context *ctx, ctx->total[1]++; } +#if SIZE_MAX > 0xFFFFFFFF + ctx->total[1] += (uint32_t) (ilen >> 32); +#endif + if (left && ilen >= fill) { memcpy((void *) (ctx->buffer + left), input, fill);