Use 64-bit arithmetic in sha1 length calculations. No need to do it by ourselves 32 bits at a time. Change-Id: Ie4621c88e031a21db3908dae511cfe3c1172174d Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/61932 Reviewed-by: Lei Zhang <thestig@chromium.org> Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fdrm/fx_crypt.h b/core/fdrm/fx_crypt.h index 6a1b976..e6c153f 100644 --- a/core/fdrm/fx_crypt.h +++ b/core/fdrm/fx_crypt.h
@@ -35,11 +35,10 @@ }; struct CRYPT_sha1_context { + uint64_t total_bytes; + uint32_t blkused; // Constrained to [0, 64). uint32_t h[5]; uint8_t block[64]; - uint32_t blkused; // Constrained to [0, 64). - uint32_t lenhi; - uint32_t lenlo; }; struct CRYPT_sha2_context {
diff --git a/core/fdrm/fx_crypt_sha.cpp b/core/fdrm/fx_crypt_sha.cpp index afda87d..d3bb9c4 100644 --- a/core/fdrm/fx_crypt_sha.cpp +++ b/core/fdrm/fx_crypt_sha.cpp
@@ -363,15 +363,14 @@ void CRYPT_SHA1Start(CRYPT_sha1_context* context) { SHA_Core_Init(context->h); + context->total_bytes = 0; context->blkused = 0; - context->lenhi = context->lenlo = 0; } void CRYPT_SHA1Update(CRYPT_sha1_context* context, const uint8_t* data, uint32_t size) { - context->lenlo += size; - context->lenhi += (context->lenlo < size); // Unsigned, so well-defined. + context->total_bytes += size; if (context->blkused && size < 64 - context->blkused) { memcpy(context->block + context->blkused, data, size); context->blkused += size; @@ -396,8 +395,7 @@ } void CRYPT_SHA1Finish(CRYPT_sha1_context* context, uint8_t digest[20]) { - uint32_t lenhi = (context->lenhi << 3) | (context->lenlo >> (32 - 3)); - uint32_t lenlo = (context->lenlo << 3); + uint64_t total_bits = 8 * context->total_bytes; // Prior to padding. uint8_t c[64]; uint8_t pad; if (context->blkused >= 56) { @@ -408,14 +406,14 @@ memset(c, 0, pad); c[0] = 0x80; CRYPT_SHA1Update(context, c, pad); - c[0] = (lenhi >> 24) & 0xFF; - c[1] = (lenhi >> 16) & 0xFF; - c[2] = (lenhi >> 8) & 0xFF; - c[3] = (lenhi >> 0) & 0xFF; - c[4] = (lenlo >> 24) & 0xFF; - c[5] = (lenlo >> 16) & 0xFF; - c[6] = (lenlo >> 8) & 0xFF; - c[7] = (lenlo >> 0) & 0xFF; + c[0] = (total_bits >> 56) & 0xFF; + c[1] = (total_bits >> 48) & 0xFF; + c[2] = (total_bits >> 40) & 0xFF; + c[3] = (total_bits >> 32) & 0xFF; + c[4] = (total_bits >> 24) & 0xFF; + c[5] = (total_bits >> 16) & 0xFF; + c[6] = (total_bits >> 8) & 0xFF; + c[7] = (total_bits >> 0) & 0xFF; CRYPT_SHA1Update(context, c, 8); for (int i = 0; i < 5; i++) { digest[i * 4] = (context->h[i] >> 24) & 0xFF;