Make SHA library accessible to calling firmware

And add a vb2_digest_buffer() call which produces the hash of a buffer
all in a single function call.  That function actually already
existed, but was in a unit test file rather than in the library
itself.  It's a small function, so adding it won't increase the size
of the library significantly - or at all, on platforms which compile
with -ffunction-sections.

This allows coreboot to reuse this SHA library for hashing CBFS
entries and file data.  All it has to do is #define
NEED_VB2_SHA_LIBRARY and then #include "vb2_api.h".

BUG=chromium:482652
BRANCH=none
TEST=make -j runtests

Change-Id: Ice2d0929324b58b2665f3989b5b887225f6ef61e
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/269523
Reviewed-by: Julius Werner <jwerner@chromium.org>
diff --git a/firmware/2lib/2sha_utility.c b/firmware/2lib/2sha_utility.c
index 6f76b4e..b75f0e5 100644
--- a/firmware/2lib/2sha_utility.c
+++ b/firmware/2lib/2sha_utility.c
@@ -7,7 +7,6 @@
 
 #include "2sysincludes.h"
 #include "2common.h"
-#include "2rsa.h"
 #include "2sha.h"
 
 #if VB2_SUPPORT_SHA1
@@ -43,15 +42,6 @@
 	CTH_SHA512,
 };
 
-/**
- * Convert vb2_crypto_algorithm to vb2_hash_algorithm.
- *
- * @param algorithm	Crypto algorithm (vb2_crypto_algorithm)
- *
- * @return The hash algorithm for that crypto algorithm, or VB2_HASH_INVALID if
- * the crypto algorithm or its corresponding hash algorithm is invalid or not
- * supported.
- */
 enum vb2_hash_algorithm vb2_crypto_to_hash(uint32_t algorithm)
 {
 	if (algorithm < ARRAY_SIZE(crypto_to_hash))
@@ -159,3 +149,23 @@
 		return VB2_ERROR_SHA_FINALIZE_ALGORITHM;
 	}
 }
+
+int vb2_digest_buffer(const uint8_t *buf,
+		      uint32_t size,
+		      enum vb2_hash_algorithm hash_alg,
+		      uint8_t *digest,
+		      uint32_t digest_size)
+{
+	struct vb2_digest_context dc;
+	int rv;
+
+	rv = vb2_digest_init(&dc, hash_alg);
+	if (rv)
+		return rv;
+
+	rv = vb2_digest_extend(&dc, buf, size);
+	if (rv)
+		return rv;
+
+	return vb2_digest_finalize(&dc, digest, digest_size);
+}
diff --git a/firmware/2lib/include/2sha.h b/firmware/2lib/include/2sha.h
index 221d185..2459024 100644
--- a/firmware/2lib/include/2sha.h
+++ b/firmware/2lib/include/2sha.h
@@ -1,13 +1,17 @@
 /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
+ *
+ * These APIs may be called by external firmware as well as vboot.  External
+ * firmware must NOT include this header file directly; instead, define
+ * NEED_VB2_SHA_LIBRARY and include vb2api.h.  This is permissible because the
+ * SHA library routines below don't interact with the rest of vboot.
  */
 
 #ifndef VBOOT_REFERENCE_2SHA_H_
 #define VBOOT_REFERENCE_2SHA_H_
 
 #include "2crypto.h"
-#include "2struct.h"
 
 /* Hash algorithms may be disabled individually to save code space */
 
@@ -174,4 +178,20 @@
 			uint8_t *digest,
 			uint32_t digest_size);
 
+/**
+ * Calculate the digest of a buffer and store the result.
+ *
+ * @param buf		Data to hash
+ * @param size		Length of data in bytes
+ * @param hash_alg	Hash algorithm
+ * @param digest	Destination for digest
+ * @param digest_size	Length of digest buffer in bytes.
+ * @return VB2_SUCCESS, or non-zero on error.
+ */
+int vb2_digest_buffer(const uint8_t *buf,
+		      uint32_t size,
+		      enum vb2_hash_algorithm hash_alg,
+		      uint8_t *digest,
+		      uint32_t digest_size);
+
 #endif  /* VBOOT_REFERENCE_2SHA_H_ */
diff --git a/firmware/include/vb2_api.h b/firmware/include/vb2_api.h
index d8746d0..2f63cc1 100644
--- a/firmware/include/vb2_api.h
+++ b/firmware/include/vb2_api.h
@@ -6,6 +6,10 @@
 /* APIs between calling firmware and vboot_reference
  *
  * DO NOT INCLUDE THE HEADERS BELOW DIRECTLY!  ONLY INCLUDE THIS FILE!
+ *
+ * Using vb2api.h as the single point of contact between calling firmware and
+ * vboot allows subsequent refactoring of vboot (renaming of headers, etc.)
+ * without churning other projects' source code.
  */
 
 #ifndef VBOOT_VB2_API_H_
@@ -14,6 +18,11 @@
 /* Standard APIs */
 #include "../2lib/include/2api.h"
 
+/* SHA library */
+#ifdef NEED_VB2_SHA_LIBRARY
+#include "../2lib/include/2sha.h"
+#endif
+
 /*
  * Coreboot should not need access to vboot2 internals.  But right now it does.
  * At least this forces it to do so through a relatively narrow hole so vboot2
diff --git a/tests/vb2_sha_tests.c b/tests/vb2_sha_tests.c
index 501f90e..0919ff9 100644
--- a/tests/vb2_sha_tests.c
+++ b/tests/vb2_sha_tests.c
@@ -13,26 +13,6 @@
 #include "sha_test_vectors.h"
 #include "test_common.h"
 
-static int vb2_digest(const uint8_t *buf,
-		      uint32_t size,
-		      enum vb2_hash_algorithm hash_alg,
-		      uint8_t *digest,
-		      uint32_t digest_size)
-{
-	struct vb2_digest_context dc;
-	int rv;
-
-	rv = vb2_digest_init(&dc, hash_alg);
-	if (rv)
-		return rv;
-
-	rv = vb2_digest_extend(&dc, buf, size);
-	if (rv)
-		return rv;
-
-	return vb2_digest_finalize(&dc, digest, digest_size);
-}
-
 void sha1_tests(void)
 {
 	uint8_t digest[VB2_SHA1_DIGEST_SIZE];
@@ -44,17 +24,20 @@
 	test_inputs[2] = (uint8_t *) long_msg;
 
 	for (i = 0; i < 3; i++) {
-		TEST_SUCC(vb2_digest(test_inputs[i],
-				     strlen((char *)test_inputs[i]),
-				     VB2_HASH_SHA1, digest, sizeof(digest)),
-			  "vb2_digest() SHA1");
+		TEST_SUCC(vb2_digest_buffer(test_inputs[i],
+					    strlen((char *)test_inputs[i]),
+					    VB2_HASH_SHA1,
+					    digest, sizeof(digest)),
+			  "vb2_digest_buffer() SHA1");
 		TEST_EQ(memcmp(digest, sha1_results[i], sizeof(digest)),
 			0, "SHA1 digest");
 	}
 
-	TEST_EQ(vb2_digest(test_inputs[0], strlen((char *)test_inputs[0]),
-			   VB2_HASH_SHA1, digest, sizeof(digest) - 1),
-		VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE, "vb2_digest() too small");
+	TEST_EQ(vb2_digest_buffer(test_inputs[0],
+				  strlen((char *)test_inputs[0]),
+				  VB2_HASH_SHA1, digest, sizeof(digest) - 1),
+		VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE,
+		"vb2_digest_buffer() too small");
 }
 
 void sha256_tests(void)
@@ -68,17 +51,20 @@
 	test_inputs[2] = (uint8_t *) long_msg;
 
 	for (i = 0; i < 3; i++) {
-		TEST_SUCC(vb2_digest(test_inputs[i],
-				     strlen((char *)test_inputs[i]),
-				     VB2_HASH_SHA256, digest, sizeof(digest)),
-			  "vb2_digest() SHA256");
+		TEST_SUCC(vb2_digest_buffer(test_inputs[i],
+					    strlen((char *)test_inputs[i]),
+					    VB2_HASH_SHA256,
+					    digest, sizeof(digest)),
+			  "vb2_digest_buffer() SHA256");
 		TEST_EQ(memcmp(digest, sha256_results[i], sizeof(digest)),
 			0, "SHA-256 digest");
 	}
 
-	TEST_EQ(vb2_digest(test_inputs[0], strlen((char *)test_inputs[0]),
-			   VB2_HASH_SHA256, digest, sizeof(digest) - 1),
-		VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE, "vb2_digest() too small");
+	TEST_EQ(vb2_digest_buffer(test_inputs[0],
+				  strlen((char *)test_inputs[0]),
+				  VB2_HASH_SHA256, digest, sizeof(digest) - 1),
+		VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE,
+		"vb2_digest_buffer() too small");
 }
 
 void sha512_tests(void)
@@ -92,18 +78,20 @@
 	test_inputs[2] = (uint8_t *) long_msg;
 
 	for (i = 0; i < 3; i++) {
-		TEST_SUCC(vb2_digest(test_inputs[i],
-				     strlen((char *)test_inputs[i]),
-				     VB2_HASH_SHA512, digest,
-				     sizeof(digest)),
-			  "vb2_digest() SHA512");
+		TEST_SUCC(vb2_digest_buffer(test_inputs[i],
+					    strlen((char *)test_inputs[i]),
+					    VB2_HASH_SHA512,
+					    digest, sizeof(digest)),
+			  "vb2_digest_buffer() SHA512");
 		TEST_EQ(memcmp(digest, sha512_results[i], sizeof(digest)),
 			0, "SHA-512 digest");
 	}
 
-	TEST_EQ(vb2_digest(test_inputs[0], strlen((char *)test_inputs[0]),
-			   VB2_HASH_SHA512, digest, sizeof(digest) - 1),
-		VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE, "vb2_digest() too small");
+	TEST_EQ(vb2_digest_buffer(test_inputs[0],
+				  strlen((char *)test_inputs[0]),
+				  VB2_HASH_SHA512, digest, sizeof(digest) - 1),
+		VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE,
+		"vb2_digest_buffer() too small");
 }
 
 void misc_tests(void)
@@ -126,10 +114,10 @@
 	TEST_EQ(vb2_digest_size(VB2_HASH_INVALID), 0,
 		"digest size invalid alg");
 
-	TEST_EQ(vb2_digest((uint8_t *)oneblock_msg, strlen(oneblock_msg),
-			   VB2_HASH_INVALID, digest, sizeof(digest)),
+	TEST_EQ(vb2_digest_buffer((uint8_t *)oneblock_msg, strlen(oneblock_msg),
+				  VB2_HASH_INVALID, digest, sizeof(digest)),
 		VB2_ERROR_SHA_INIT_ALGORITHM,
-		"vb2_digest() invalid alg");
+		"vb2_digest_buffer() invalid alg");
 
 	/* Test bad algorithm inside extend and finalize */
 	vb2_digest_init(&dc, VB2_HASH_SHA256);