summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2016-09-14 12:55:20 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-10-01 00:01:13 -0700
commit8130e503414f16b9e4c5395b3acad69ad34b7baf (patch)
tree132c33a9ecf65cfdebbf1de3bccd12a485421a0c
parent3b44f30597e6ff86ddd8fd9e77ea278b935b15ea (diff)
downloadvboot-8130e503414f16b9e4c5395b3acad69ad34b7baf.tar.gz
bdb: Add bdb_extend
bdb_extend prints out secrets derived from the given BDS based on the given BDB. BUG=chromium:649555 BRANCH=none TEST=make runtests. Ran bdb_extend -s bds.bin -b bdb.bin (with/without -m) Change-Id: I8d9f73468992dad4cb93a422c0eae0977be9a16f Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/385539
-rw-r--r--Makefile7
-rw-r--r--firmware/bdb/rsa.c18
-rw-r--r--firmware/bdb/sha.c20
-rw-r--r--utility/bdb_extend.c189
4 files changed, 224 insertions, 10 deletions
diff --git a/Makefile b/Makefile
index 08e07367..575db232 100644
--- a/Makefile
+++ b/Makefile
@@ -381,6 +381,7 @@ BDBLIB_SRCS = \
firmware/bdb/misc.c \
firmware/bdb/rsa.c \
firmware/bdb/secrets.c \
+ firmware/bdb/sha.c \
firmware/bdb/stub.c \
firmware/bdb/nvm.c
@@ -610,6 +611,7 @@ endif
# TODO: Do we still need eficompress and efidecompress for anything?
ifeq (${MINIMAL},)
UTIL_NAMES += \
+ utility/bdb_extend \
utility/bmpblk_font \
utility/bmpblk_utility \
utility/eficompress \
@@ -1249,6 +1251,11 @@ ${BUILD}/utility/dumpRSAPublicKey: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/utility/pad_digest_utility: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/utility/signature_digest_utility: LDLIBS += ${CRYPTO_LIBS}
+${BUILD}/utility/bdb_extend: ${FWLIB2X} ${UTILBDB}
+${BUILD}/utility/bdb_extend.o: INCLUDES += -Ifirmware/bdb
+${BUILD}/utility/bdb_extend: LDLIBS += ${CRYPTO_LIBS}
+${BUILD}/utility/bdb_extend: LIBS += ${UTILBDB} ${FWLIB2X}
+
${BUILD}/host/linktest/main: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/tests/vboot_common2_tests: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/tests/vboot_common3_tests: LDLIBS += ${CRYPTO_LIBS}
diff --git a/firmware/bdb/rsa.c b/firmware/bdb/rsa.c
index 932c9733..88d32dc3 100644
--- a/firmware/bdb/rsa.c
+++ b/firmware/bdb/rsa.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
+/* Copyright 2016 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.
*
@@ -91,7 +91,7 @@ static void montMul(const struct public_key *key,
}
}
-int vb2_safe_memcmp(const void *s1, const void *s2, size_t size)
+static int safe_memcmp(const void *s1, const void *s2, size_t size)
{
const unsigned char *us1 = s1;
const unsigned char *us2 = s2;
@@ -150,9 +150,9 @@ int vb2_check_padding(const uint8_t *sig, const struct public_key *key,
/*
* Then the tail. Even though there are probably no timing issues
- * here, we use vb2_safe_memcmp() just to be on the safe side.
+ * here, we use safe_memcmp() just to be on the safe side.
*/
- result |= vb2_safe_memcmp(sig, sha256_tail, tail_size);
+ result |= safe_memcmp(sig, sha256_tail, tail_size);
return result ? BDB_ERROR_DIGEST : BDB_SUCCESS;
}
@@ -239,11 +239,10 @@ int bdb_rsa4096_verify(const uint8_t *key_data,
/*
* Check digest. Even though there are probably no timing issues here,
- * use vb2_safe_memcmp() just to be on the safe side. (That's also why
+ * use safe_memcmp() just to be on the safe side. (That's also why
* we don't return before this check if the padding check failed.)
*/
- if (vb2_safe_memcmp(sig_work + pad_size, digest,
- BDB_SHA256_DIGEST_SIZE))
+ if (safe_memcmp(sig_work + pad_size, digest, BDB_SHA256_DIGEST_SIZE))
rv = BDB_ERROR_DIGEST;
return rv;
@@ -328,11 +327,10 @@ int bdb_rsa3072b_verify(const uint8_t *key_data,
/*
* Check digest. Even though there are probably no timing issues here,
- * use vb2_safe_memcmp() just to be on the safe side. (That's also why
+ * use safe_memcmp() just to be on the safe side. (That's also why
* we don't return before this check if the padding check failed.)
*/
- if (vb2_safe_memcmp(sig_work + pad_size, digest,
- BDB_SHA256_DIGEST_SIZE))
+ if (safe_memcmp(sig_work + pad_size, digest, BDB_SHA256_DIGEST_SIZE))
rv = BDB_ERROR_DIGEST;
return rv;
diff --git a/firmware/bdb/sha.c b/firmware/bdb/sha.c
new file mode 100644
index 00000000..d73098df
--- /dev/null
+++ b/firmware/bdb/sha.c
@@ -0,0 +1,20 @@
+/* Copyright 2016 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.
+ */
+
+#include <string.h>
+
+#include "2sha.h"
+#include "bdb.h"
+
+int bdb_sha256(void *digest, const void *buf, size_t size)
+{
+ struct vb2_sha256_context ctx;
+
+ vb2_sha256_init(&ctx);
+ vb2_sha256_update(&ctx, buf, size);
+ vb2_sha256_finalize(&ctx, digest);
+
+ return BDB_SUCCESS;
+}
diff --git a/utility/bdb_extend.c b/utility/bdb_extend.c
new file mode 100644
index 00000000..c66f8bb2
--- /dev/null
+++ b/utility/bdb_extend.c
@@ -0,0 +1,189 @@
+/* Copyright 2016 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "2sha.h"
+#include "bdb.h"
+#include "bdb_api.h"
+#include "host.h"
+
+static f_extend extend = vb2_sha256_extend;
+
+static void help(void)
+{
+ fprintf(stderr,
+ "Usage: bdb_extend -b bdb_file -s bds_file "
+ "[-d digest_file] [-m]\n"
+ "\n"
+ "Extends BDS based on a given BDB. When '-m' is given, a "
+ "MVMAP2315's sha256_extend algorithm will be used. When "
+ "digest_file is specified, the validity of the BDB key is "
+ "checked and the secrets will be derived differently.\n");
+}
+
+#define PACK32(str, x) \
+ { \
+ *(x) = ((uint32_t) *((str) + 3) ) \
+ | ((uint32_t) *((str) + 2) << 8) \
+ | ((uint32_t) *((str) + 1) << 16) \
+ | ((uint32_t) *((str) + 0) << 24); \
+ }
+
+/**
+ * MVMAP2315's implementation of sha256 extend
+ *
+ * This performs incorrect but still cryptographically secure sha256 extension.
+ * This is provided for test purpose only.
+ *
+ * See vb2_sha256_extend for details on arguments.
+ */
+static void mvmap2315_sha256_extend(const uint8_t *from, const uint8_t *by,
+ uint8_t *to)
+{
+ struct vb2_sha256_context dc;
+ int i;
+
+ vb2_sha256_init(&dc);
+ for (i = 0; i < 8; i++) {
+ PACK32(from, &dc.h[i]);
+ from += 4;
+ }
+ vb2_sha256_update(&dc, by, VB2_SHA256_BLOCK_SIZE);
+ vb2_sha256_finalize(&dc, to);
+}
+
+static void dump_secret(const uint8_t *secret, const char *label)
+{
+ int i;
+ printf("%s = {", label);
+ for (i = 0; i < BDB_SECRET_SIZE; i++) {
+ if (i % 8 == 0)
+ printf("\n\t");
+ else
+ printf(" ");
+ printf("0x%02x,", secret[i]);
+ }
+ printf("\n}\n");
+}
+
+static void dump_secrets(struct vba_context *ctx, const uint8_t *wsr)
+{
+ dump_secret(ctx->secrets->bdb, "bdb");
+ dump_secret(ctx->secrets->boot_path, "boot_path");
+ dump_secret(ctx->secrets->boot_verified, "boot_verified");
+ dump_secret(ctx->secrets->nvm_wp, "nvm_wp");
+ dump_secret(ctx->secrets->nvm_rw, "nvm_rw");
+ dump_secret(wsr, "wsr");
+}
+
+static int derive_secrets(struct vba_context *ctx,
+ const uint8_t *bdb, uint8_t *wsr)
+{
+ struct bdb_secrets secrets;
+
+ memset(&secrets, 0, sizeof(secrets));
+
+ ctx->secrets = &secrets;
+ if (vba_extend_secrets_ro(ctx, bdb, wsr, extend)) {
+ fprintf(stderr, "ERROR: Failed to derive secrets\n");
+ return -1;
+ }
+
+ fprintf(stderr, "LOG: Secrets are derived as follows\n");
+ dump_secrets(ctx, wsr);
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ struct vba_context ctx;
+ uint8_t *bdb, *bds;
+ uint8_t *key_digest = NULL;
+ uint32_t bdb_size, bds_size, digest_size;
+ const char *bdb_file = NULL;
+ const char *digest_file = NULL;
+ const char *bds_file = NULL;
+ int rv;
+ int opt;
+
+ while ((opt = getopt(argc, argv, "b:d:hms:")) != -1) {
+ switch(opt) {
+ case 'b':
+ bdb_file = optarg;
+ break;
+ case 'd':
+ digest_file = optarg;
+ break;
+ case 'h':
+ help();
+ return 0;
+ case 'm':
+ extend = mvmap2315_sha256_extend;
+ break;
+ case 's':
+ bds_file = optarg;
+ break;
+ default:
+ help();
+ return -1;
+ }
+ }
+
+ if (!bdb_file || !bds_file) {
+ fprintf(stderr, "ERROR: BDB and BDS aren't specified\n\n");
+ help();
+ return -1;
+ }
+
+ /* Read BDB */
+ bdb = read_file(bdb_file, &bdb_size);
+ if (!bdb) {
+ fprintf(stderr, "ERROR: Unable to read %s\n", bdb_file);
+ return -1;
+ }
+
+ /* Read BDS */
+ bds = read_file(bds_file, &bds_size);
+ if (!bds) {
+ fprintf(stderr, "ERROR: Unable to read %s\n", bds_file);
+ return -1;
+ }
+ if (bds_size != BDB_SECRET_SIZE) {
+ fprintf(stderr, "ERROR: Invalid BDS size: %d\n", bds_size);
+ return -1;
+ }
+
+ /* Read key digest if provided */
+ if (digest_file) {
+ key_digest = read_file(digest_file, &digest_size);
+ if (!key_digest) {
+ fprintf(stderr,
+ "ERROR: Unable to read %s\n", digest_file);
+ return -1;
+ }
+ }
+
+ /* Verify BDB and set a flag based on the result */
+ memset(&ctx, 0, sizeof(ctx));
+ rv = bdb_verify(bdb, bdb_size, key_digest);
+ if (rv) {
+ if (rv != BDB_GOOD_OTHER_THAN_KEY) {
+ fprintf(stderr, "ERROR: BDB is invalid: %d\n", rv);
+ return -1;
+ }
+ fprintf(stderr,
+ "WARNING: BDB is valid but key digest doesn't match\n");
+ } else {
+ ctx.flags |= VBA_CONTEXT_FLAG_BDB_KEY_EFUSED;
+ fprintf(stderr, "BDB is successfully verified by eFused key\n");
+ }
+
+ /* Derive secrets and dump the values */
+ return derive_secrets(&ctx, bdb, bds);
+}