bdb: Add bdb_get_hash_by_index

bdb_get_hash_by_index returns a hash entry from a BDB using an index.
bdb_get_hash is also renamed to bdb_get_hash_by_type. bdb_get_hash
is deprecated. Callers are expected to call bdb_get_hash_by_index(buf, 0)
instead.

BUG=none
BRANCH=none
TEST=make runtests

Change-Id: Id99926123c0ac9094574eb057c63f79eceda2867
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/392947
Reviewed-by: Randall Spangler <rspangler@chromium.org>
diff --git a/firmware/bdb/bdb.c b/firmware/bdb/bdb.c
index 4360ab7..e102d7b 100644
--- a/firmware/bdb/bdb.c
+++ b/firmware/bdb/bdb.c
@@ -271,14 +271,21 @@
 	return b8 + p->struct_size;
 }
 
-const struct bdb_hash *bdb_get_hash(const void *buf, enum bdb_data_type type)
+static const void *bdb_get_hash(const void *buf)
 {
 	const struct bdb_data *data = bdb_get_data(buf);
 	const uint8_t *b8 = bdb_get_oem_area_1(buf);
-	int i;
 
 	/* Hashes follow OEM area 0 */
-	b8 += data->oem_area_1_size;
+	return b8 + data->oem_area_1_size;
+}
+
+const struct bdb_hash *bdb_get_hash_by_type(const void *buf,
+					    enum bdb_data_type type)
+{
+	const struct bdb_data *data = bdb_get_data(buf);
+	const uint8_t *b8 = bdb_get_hash(buf);
+	int i;
 
 	/* Search for a matching hash */
 	for (i = 0; i < data->num_hashes; i++, b8 += data->hash_entry_size) {
@@ -291,6 +298,24 @@
 	return NULL;
 }
 
+const struct bdb_hash *bdb_get_hash_by_index(const void *buf, int index)
+{
+	const struct bdb_data *data = bdb_get_data(buf);
+	const uint8_t *p = bdb_get_hash(buf);
+	const struct bdb_hash *h = NULL;
+	int i;
+
+	/* Search for a matching hash */
+	for (i = 0; i < data->num_hashes; i++, p += data->hash_entry_size) {
+		if (i == index) {
+			h = (const struct bdb_hash *)p;
+			break;
+		}
+	}
+
+	return h;
+}
+
 const struct bdb_sig *bdb_get_data_sig(const void *buf)
 {
 	const struct bdb_data *data = bdb_get_data(buf);
diff --git a/firmware/bdb/bdb.h b/firmware/bdb/bdb.h
index 4f411c1..9e13696 100644
--- a/firmware/bdb/bdb.h
+++ b/firmware/bdb/bdb.h
@@ -154,7 +154,9 @@
 const struct bdb_sig *bdb_get_header_sig(const void *buf);
 const struct bdb_data *bdb_get_data(const void *buf);
 const void *bdb_get_oem_area_1(const void *buf);
-const struct bdb_hash *bdb_get_hash(const void *buf, enum bdb_data_type type);
+const struct bdb_hash *bdb_get_hash_by_type(const void *buf,
+					    enum bdb_data_type type);
+const struct bdb_hash *bdb_get_hash_by_index(const void *buf, int index);
 const struct bdb_sig *bdb_get_data_sig(const void *buf);
 
 /**
diff --git a/tests/bdb_sprw_test.c b/tests/bdb_sprw_test.c
index 12b0bd7..1f5be95 100644
--- a/tests/bdb_sprw_test.c
+++ b/tests/bdb_sprw_test.c
@@ -131,7 +131,7 @@
 	/* 1. Locate BDB */
 
 	/* 2. Get bdb_hash structure for AP-RW */
-	hash = bdb_get_hash(bdb, BDB_DATA_AP_RW);
+	hash = bdb_get_hash_by_type(bdb, BDB_DATA_AP_RW);
 	fprintf(stderr, "Got hash of AP-RW\n");
 
 	/* 3. Load & calculate digest of AP-RW */
diff --git a/tests/bdb_test.c b/tests/bdb_test.c
index 3c90e98..0dd7619 100644
--- a/tests/bdb_test.c
+++ b/tests/bdb_test.c
@@ -411,11 +411,12 @@
 	TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG);
 
 	memcpy(h, hgood, hsize);
-	((struct bdb_hash *)bdb_get_hash(h, BDB_DATA_SP_RW))->offset++;
+	((struct bdb_hash *)bdb_get_hash_by_type(h, BDB_DATA_SP_RW))->offset++;
 	TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG);
 
 	memcpy(h, hgood, hsize);
-	((struct bdb_hash *)bdb_get_hash(h, BDB_DATA_AP_RW))->digest[0] ^= 0x96;
+	((struct bdb_hash *)bdb_get_hash_by_type(h, BDB_DATA_AP_RW))
+			->digest[0] ^= 0x96;
 	TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG);
 
 	/*
@@ -454,10 +455,17 @@
 
 	/* Test getting hash entries */
 	memcpy(h, hgood, hsize);
-	TEST_EQ_S(bdb_get_hash(h, BDB_DATA_SP_RW)->offset, hash[0].offset);
-	TEST_EQ_S(bdb_get_hash(h, BDB_DATA_AP_RW)->offset, hash[1].offset);
+	TEST_EQ_S(bdb_get_hash_by_type(h, BDB_DATA_SP_RW)
+		  ->offset, hash[0].offset);
+	TEST_EQ_S(bdb_get_hash_by_index(h, 0)
+		  ->offset, hash[0].offset);
+	TEST_EQ_S(bdb_get_hash_by_type(h, BDB_DATA_AP_RW)
+		  ->offset, hash[1].offset);
+	TEST_EQ_S(bdb_get_hash_by_index(h, 1)
+		  ->offset, hash[1].offset);
 	/* And a non-existent one */
-	TEST_EQ_S(bdb_get_hash(h, BDB_DATA_MCU)!=NULL, 0);
+	TEST_PTR_EQ(bdb_get_hash_by_type(h, BDB_DATA_MCU), NULL, NULL);
+	TEST_PTR_EQ(bdb_get_hash_by_index(h, 2), NULL, NULL);
 
 	/*
 	 * TODO: Verify wraparound checks works.  That can only be tested on a