libavb: Use size_t instead of uint32_t for lengths in avb_sha*() functions. am: 4f137c38f8
am: fb7a75a086

Change-Id: Ib5be93964eb38a78d267af614e6e00312fcf3b7f
diff --git a/libavb/avb_sha.h b/libavb/avb_sha.h
index c5a6a4c..82ac9a5 100644
--- a/libavb/avb_sha.h
+++ b/libavb/avb_sha.h
@@ -50,8 +50,8 @@
 /* Data structure used for SHA-256. */
 typedef struct {
   uint32_t h[8];
-  uint32_t tot_len;
-  uint32_t len;
+  uint64_t tot_len;
+  size_t len;
   uint8_t block[2 * AVB_SHA256_BLOCK_SIZE];
   uint8_t buf[AVB_SHA256_DIGEST_SIZE]; /* Used for storing the final digest. */
 } AvbSHA256Ctx;
@@ -59,8 +59,8 @@
 /* Data structure used for SHA-512. */
 typedef struct {
   uint64_t h[8];
-  uint32_t tot_len;
-  uint32_t len;
+  uint64_t tot_len;
+  size_t len;
   uint8_t block[2 * AVB_SHA512_BLOCK_SIZE];
   uint8_t buf[AVB_SHA512_DIGEST_SIZE]; /* Used for storing the final digest. */
 } AvbSHA512Ctx;
@@ -69,7 +69,7 @@
 void avb_sha256_init(AvbSHA256Ctx* ctx);
 
 /* Updates the SHA-256 context with |len| bytes from |data|. */
-void avb_sha256_update(AvbSHA256Ctx* ctx, const uint8_t* data, uint32_t len);
+void avb_sha256_update(AvbSHA256Ctx* ctx, const uint8_t* data, size_t len);
 
 /* Returns the SHA-256 digest. */
 uint8_t* avb_sha256_final(AvbSHA256Ctx* ctx) AVB_ATTR_WARN_UNUSED_RESULT;
@@ -78,7 +78,7 @@
 void avb_sha512_init(AvbSHA512Ctx* ctx);
 
 /* Updates the SHA-512 context with |len| bytes from |data|. */
-void avb_sha512_update(AvbSHA512Ctx* ctx, const uint8_t* data, uint32_t len);
+void avb_sha512_update(AvbSHA512Ctx* ctx, const uint8_t* data, size_t len);
 
 /* Returns the SHA-512 digest. */
 uint8_t* avb_sha512_final(AvbSHA512Ctx* ctx) AVB_ATTR_WARN_UNUSED_RESULT;
diff --git a/libavb/avb_sha256.c b/libavb/avb_sha256.c
index cdd143a..8a1c3ae 100644
--- a/libavb/avb_sha256.c
+++ b/libavb/avb_sha256.c
@@ -56,6 +56,18 @@
     *((str) + 0) = (uint8_t)((x) >> 24); \
   }
 
+#define UNPACK64(x, str)                         \
+  {                                              \
+    *((str) + 7) = (uint8_t)x;                   \
+    *((str) + 6) = (uint8_t)((uint64_t)x >> 8);  \
+    *((str) + 5) = (uint8_t)((uint64_t)x >> 16); \
+    *((str) + 4) = (uint8_t)((uint64_t)x >> 24); \
+    *((str) + 3) = (uint8_t)((uint64_t)x >> 32); \
+    *((str) + 2) = (uint8_t)((uint64_t)x >> 40); \
+    *((str) + 1) = (uint8_t)((uint64_t)x >> 48); \
+    *((str) + 0) = (uint8_t)((uint64_t)x >> 56); \
+  }
+
 #define PACK32(str, x)                                                    \
   {                                                                       \
     *(x) = ((uint32_t) * ((str) + 3)) | ((uint32_t) * ((str) + 2) << 8) | \
@@ -123,18 +135,18 @@
 
 static void SHA256_transform(AvbSHA256Ctx* ctx,
                              const uint8_t* message,
-                             unsigned int block_nb) {
+                             size_t block_nb) {
   uint32_t w[64];
   uint32_t wv[8];
   uint32_t t1, t2;
   const unsigned char* sub_block;
-  int i;
+  size_t i;
 
 #ifndef UNROLL_LOOPS
-  int j;
+  size_t j;
 #endif
 
-  for (i = 0; i < (int)block_nb; i++) {
+  for (i = 0; i < block_nb; i++) {
     sub_block = message + (i << 6);
 
 #ifndef UNROLL_LOOPS
@@ -320,9 +332,9 @@
   }
 }
 
-void avb_sha256_update(AvbSHA256Ctx* ctx, const uint8_t* data, uint32_t len) {
-  unsigned int block_nb;
-  unsigned int new_len, rem_len, tmp_len;
+void avb_sha256_update(AvbSHA256Ctx* ctx, const uint8_t* data, size_t len) {
+  size_t block_nb;
+  size_t new_len, rem_len, tmp_len;
   const uint8_t* shifted_data;
 
   tmp_len = AVB_SHA256_BLOCK_SIZE - ctx->len;
@@ -352,11 +364,11 @@
 }
 
 uint8_t* avb_sha256_final(AvbSHA256Ctx* ctx) {
-  unsigned int block_nb;
-  unsigned int pm_len;
-  unsigned int len_b;
+  size_t block_nb;
+  size_t pm_len;
+  uint64_t len_b;
 #ifndef UNROLL_LOOPS
-  int i;
+  size_t i;
 #endif
 
   block_nb =
@@ -367,7 +379,7 @@
 
   avb_memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
   ctx->block[ctx->len] = 0x80;
-  UNPACK32(len_b, ctx->block + pm_len - 4);
+  UNPACK64(len_b, ctx->block + pm_len - 8);
 
   SHA256_transform(ctx, ctx->block, block_nb);
 
diff --git a/libavb/avb_sha512.c b/libavb/avb_sha512.c
index 8df6319..6cdc494 100644
--- a/libavb/avb_sha512.c
+++ b/libavb/avb_sha512.c
@@ -154,14 +154,14 @@
 
 static void SHA512_transform(AvbSHA512Ctx* ctx,
                              const uint8_t* message,
-                             unsigned int block_nb) {
+                             size_t block_nb) {
   uint64_t w[80];
   uint64_t wv[8];
   uint64_t t1, t2;
   const uint8_t* sub_block;
-  int i, j;
+  size_t i, j;
 
-  for (i = 0; i < (int)block_nb; i++) {
+  for (i = 0; i < block_nb; i++) {
     sub_block = message + (i << 7);
 
 #ifdef UNROLL_LOOPS_SHA512
@@ -318,9 +318,9 @@
   }
 }
 
-void avb_sha512_update(AvbSHA512Ctx* ctx, const uint8_t* data, uint32_t len) {
-  unsigned int block_nb;
-  unsigned int new_len, rem_len, tmp_len;
+void avb_sha512_update(AvbSHA512Ctx* ctx, const uint8_t* data, size_t len) {
+  size_t block_nb;
+  size_t new_len, rem_len, tmp_len;
   const uint8_t* shifted_data;
 
   tmp_len = AVB_SHA512_BLOCK_SIZE - ctx->len;
@@ -350,12 +350,12 @@
 }
 
 uint8_t* avb_sha512_final(AvbSHA512Ctx* ctx) {
-  unsigned int block_nb;
-  unsigned int pm_len;
-  unsigned int len_b;
+  size_t block_nb;
+  size_t pm_len;
+  uint64_t len_b;
 
 #ifndef UNROLL_LOOPS_SHA512
-  int i;
+  size_t i;
 #endif
 
   block_nb =
@@ -366,7 +366,7 @@
 
   avb_memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
   ctx->block[ctx->len] = 0x80;
-  UNPACK32(len_b, ctx->block + pm_len - 4);
+  UNPACK64(len_b, ctx->block + pm_len - 8);
 
   SHA512_transform(ctx, ctx->block, block_nb);
 
diff --git a/test/avb_util_unittest.cc b/test/avb_util_unittest.cc
index 5670f85..defdfab 100644
--- a/test/avb_util_unittest.cc
+++ b/test/avb_util_unittest.cc
@@ -27,6 +27,7 @@
 
 #include <gtest/gtest.h>
 
+#include <libavb/avb_sha.h>
 #include <libavb/libavb.h>
 
 #include "avb_unittest_util.h"
@@ -542,4 +543,82 @@
   EXPECT_EQ("/", std::string(avb_basename("/")));
 }
 
+TEST_F(UtilTest, Sha256) {
+  AvbSHA256Ctx ctx;
+
+  /* Compare with
+   *
+   * $ echo -n foobar |sha256sum
+   * c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2 -
+   */
+  avb_sha256_init(&ctx);
+  avb_sha256_update(&ctx, (const uint8_t*)"foobar", 6);
+  EXPECT_EQ("c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2",
+            mem_to_hexstring(avb_sha256_final(&ctx), AVB_SHA256_DIGEST_SIZE));
+}
+
+// Disabled for now because it takes ~30 seconds to run.
+TEST_F(UtilTest, DISABLED_Sha256Large) {
+  AvbSHA256Ctx ctx;
+
+  /* Also check we this works with greater than 4GiB input. Compare with
+   *
+   * $ dd if=/dev/zero bs=1048576 count=4097 |sha256sum
+   * 829816e339ff597ec3ada4c30fc840d3f2298444169d242952a54bcf3fcd7747 -
+   */
+  const size_t kMebibyte = 1048576;
+  uint8_t* megabuf;
+  megabuf = new uint8_t[kMebibyte];
+  memset((char*)megabuf, '\0', kMebibyte);
+  avb_sha256_init(&ctx);
+  for (size_t n = 0; n < 4097; n++) {
+    avb_sha256_update(&ctx, megabuf, kMebibyte);
+  }
+  EXPECT_EQ("829816e339ff597ec3ada4c30fc840d3f2298444169d242952a54bcf3fcd7747",
+            mem_to_hexstring(avb_sha256_final(&ctx), AVB_SHA256_DIGEST_SIZE));
+  delete[] megabuf;
+}
+
+TEST_F(UtilTest, Sha512) {
+  AvbSHA512Ctx ctx;
+
+  /* Compare with
+   *
+   * $ echo -n foobar |sha512sum
+   * 0a50261ebd1a390fed2bf326f2673c145582a6342d523204973d0219337f81616a8069b012587cf5635f6925f1b56c360230c19b273500ee013e030601bf2425
+   * -
+   */
+  avb_sha512_init(&ctx);
+  avb_sha512_update(&ctx, (const uint8_t*)"foobar", 6);
+  EXPECT_EQ(
+      "0a50261ebd1a390fed2bf326f2673c145582a6342d523204973d0219337f81616a8069b0"
+      "12587cf5635f6925f1b56c360230c19b273500ee013e030601bf2425",
+      mem_to_hexstring(avb_sha512_final(&ctx), AVB_SHA512_DIGEST_SIZE));
+}
+
+// Disabled for now because it takes ~30 seconds to run.
+TEST_F(UtilTest, DISABLED_Sha512Large) {
+  AvbSHA512Ctx ctx;
+
+  /* Also check we this works with greater than 4GiB input. Compare with
+   *
+   * $ dd if=/dev/zero bs=1048576 count=4097 |sha512sum
+   * eac1685671cc2060315888746de072398116c0c83b7ee9463f0576e11bfdea9cdd5ddbf291fb3ffc4ee8a1b459c798d9fb9b50b7845e2871c4b1402470aaf4c0
+   * -
+   */
+  const size_t kMebibyte = 1048576;
+  uint8_t* megabuf;
+  megabuf = new uint8_t[kMebibyte];
+  memset((char*)megabuf, '\0', kMebibyte);
+  avb_sha512_init(&ctx);
+  for (size_t n = 0; n < 4097; n++) {
+    avb_sha512_update(&ctx, megabuf, kMebibyte);
+  }
+  EXPECT_EQ(
+      "eac1685671cc2060315888746de072398116c0c83b7ee9463f0576e11bfdea9cdd5ddbf2"
+      "91fb3ffc4ee8a1b459c798d9fb9b50b7845e2871c4b1402470aaf4c0",
+      mem_to_hexstring(avb_sha512_final(&ctx), AVB_SHA512_DIGEST_SIZE));
+  delete[] megabuf;
+}
+
 }  // namespace avb