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