summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2016-09-12 12:47:14 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-10-01 00:01:10 -0700
commit626e0b034db4c3c395cc5eb716d8725b4f030fe0 (patch)
tree2597a16d9d3f60a3b82b18d90b72f99544510177
parent01fb293825877edb83e8ddb9555733876f7556ea (diff)
downloadvboot-626e0b034db4c3c395cc5eb716d8725b4f030fe0.tar.gz
bdb: Add secret deriving code for SP-RO
This patch adds code which dervies secrets from BDS. It's supposed to be done by SP-RO, hence the code is mostly useful for testing (or emulation). vba_extend_secrets_ro takes a function pointer to a hash extend function. It'll be used to try different sha256 extend algorithms. BUG=chromium:649555 BRANCH=none TEST=make runtests Change-Id: I8fef6b851fb84686d8bcdd948b36160016687c51 Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/384354 Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--firmware/bdb/bdb_api.h18
-rw-r--r--firmware/bdb/bdb_flag.h5
-rw-r--r--firmware/bdb/nvm.c18
-rw-r--r--firmware/bdb/secrets.c273
-rw-r--r--firmware/bdb/secrets.h59
-rw-r--r--tests/bdb_sprw_test.c49
6 files changed, 302 insertions, 120 deletions
diff --git a/firmware/bdb/bdb_api.h b/firmware/bdb/bdb_api.h
index 6c2e2a46..c0e850f9 100644
--- a/firmware/bdb/bdb_api.h
+++ b/firmware/bdb/bdb_api.h
@@ -23,8 +23,7 @@ struct vba_context {
uint8_t *bdb;
/* Secrets */
- struct bdb_ro_secrets *ro_secrets;
- struct bdb_rw_secrets *rw_secrets;
+ struct bdb_secrets *secrets;
/* NVM-RW buffer */
struct nvmrw nvmrw;
@@ -92,7 +91,7 @@ int vba_update_buc(struct vba_context *ctx, uint8_t *new_buc);
* @return BDB_SUCCESS or BDB_ERROR_*
*/
int vba_derive_secret(struct vba_context *ctx, enum bdb_secret_type type,
- const uint8_t *buf, uint32_t buf_size);
+ uint8_t *wsr, const uint8_t *buf, uint32_t buf_size);
/**
* Clear a secret
@@ -104,6 +103,19 @@ int vba_derive_secret(struct vba_context *ctx, enum bdb_secret_type type,
int vba_clear_secret(struct vba_context *ctx, enum bdb_secret_type type);
/**
+ * Extend secrets for SP-RO
+ *
+ * @param ctx struct vba_context
+ * @param bdb BDB
+ * @param wsr Pointer to working secret register contents
+ * @param extend Function to be called for extending a secret
+ * @return BDB_SUCCESS or BDB_ERROR_*
+ */
+typedef void (*f_extend)(const uint8_t *from, const uint8_t *by, uint8_t *to);
+int vba_extend_secrets_ro(struct vba_context *ctx, const uint8_t *bdb,
+ uint8_t *wsr, f_extend extend);
+
+/**
* Get vboot register value
*
* Implemented by each chip
diff --git a/firmware/bdb/bdb_flag.h b/firmware/bdb/bdb_flag.h
index 45f57567..a7bd8574 100644
--- a/firmware/bdb/bdb_flag.h
+++ b/firmware/bdb/bdb_flag.h
@@ -6,7 +6,10 @@
#ifndef VBOOT_REFERENCE_FIRMWARE_BDB_BDB_FLAG_H
#define VBOOT_REFERENCE_FIRMWARE_BDB_BDB_FLAG_H
+/* Indicate whether BDB key is verified */
+#define VBA_CONTEXT_FLAG_BDB_KEY_EFUSED (1 << 0)
+
/* Indicate whether kernel data key is verified */
-#define VBA_CONTEXT_FLAG_KERNEL_DATA_KEY_VERIFIED (1 << 0)
+#define VBA_CONTEXT_FLAG_KERNEL_DATA_KEY_VERIFIED (1 << 1)
#endif
diff --git a/firmware/bdb/nvm.c b/firmware/bdb/nvm.c
index 9c40ea55..85c301a2 100644
--- a/firmware/bdb/nvm.c
+++ b/firmware/bdb/nvm.c
@@ -39,7 +39,7 @@ static int nvmrw_validate(const void *buf, uint32_t size)
return BDB_SUCCESS;
}
-static int nvmrw_verify(const struct bdb_ro_secrets *secrets,
+static int nvmrw_verify(const struct bdb_secrets *secrets,
const struct nvmrw *nvm, uint32_t size)
{
uint8_t mac[NVM_HMAC_SIZE];
@@ -72,7 +72,7 @@ int nvmrw_write(struct vba_context *ctx, enum nvm_type type)
if (!ctx)
return BDB_ERROR_NVM_INVALID_PARAMETER;
- if (!ctx->ro_secrets)
+ if (!ctx->secrets)
return BDB_ERROR_NVM_INVALID_SECRET;
rv = nvmrw_validate(nvm, sizeof(*nvm));
@@ -80,7 +80,7 @@ int nvmrw_write(struct vba_context *ctx, enum nvm_type type)
return rv;
/* Update HMAC */
- hmac(VB2_HASH_SHA256, ctx->ro_secrets->nvm_rw, BDB_SECRET_SIZE,
+ hmac(VB2_HASH_SHA256, ctx->secrets->nvm_rw, BDB_SECRET_SIZE,
nvm, nvm->struct_size - sizeof(nvm->hmac),
nvm->hmac, sizeof(nvm->hmac));
@@ -101,7 +101,7 @@ int nvmrw_write(struct vba_context *ctx, enum nvm_type type)
}
static int read_verify_nvmrw(enum nvm_type type,
- const struct bdb_ro_secrets *secrets,
+ const struct bdb_secrets *secrets,
uint8_t *buf, uint32_t buf_size)
{
struct nvmrw *nvm = (struct nvmrw *)buf;
@@ -136,11 +136,11 @@ int nvmrw_read(struct vba_context *ctx)
int rv1, rv2;
/* Read and verify the 1st copy */
- rv1 = read_verify_nvmrw(NVM_TYPE_RW_PRIMARY, ctx->ro_secrets,
+ rv1 = read_verify_nvmrw(NVM_TYPE_RW_PRIMARY, ctx->secrets,
buf1, sizeof(buf1));
/* Read and verify the 2nd copy */
- rv2 = read_verify_nvmrw(NVM_TYPE_RW_SECONDARY, ctx->ro_secrets,
+ rv2 = read_verify_nvmrw(NVM_TYPE_RW_SECONDARY, ctx->secrets,
buf2, sizeof(buf2));
if (rv1 == BDB_SUCCESS && rv2 == BDB_SUCCESS) {
@@ -204,7 +204,7 @@ int vba_update_kernel_version(struct vba_context *ctx,
{
struct nvmrw *nvm = &ctx->nvmrw;
- if (nvmrw_verify(ctx->ro_secrets, nvm, sizeof(*nvm))) {
+ if (nvmrw_verify(ctx->secrets, nvm, sizeof(*nvm))) {
if (nvmrw_init(ctx))
return BDB_ERROR_NVM_INIT;
}
@@ -236,7 +236,7 @@ int vba_update_buc(struct vba_context *ctx, uint8_t *new_buc)
uint8_t buc[BUC_ENC_DIGEST_SIZE];
int rv1, rv2;
- if (nvmrw_verify(ctx->ro_secrets, nvm, sizeof(*nvm))) {
+ if (nvmrw_verify(ctx->secrets, nvm, sizeof(*nvm))) {
if (nvmrw_init(ctx))
return BDB_ERROR_NVM_INIT;
}
@@ -245,7 +245,7 @@ int vba_update_buc(struct vba_context *ctx, uint8_t *new_buc)
* Note that we do not need to decide whether we should use hardware
* crypto or not because this is supposed to be running in RW code. */
if (vbe_aes256_encrypt(new_buc, BUC_ENC_DIGEST_SIZE,
- ctx->rw_secrets->buc, buc))
+ ctx->secrets->buc, buc))
return BDB_ERROR_ENCRYPT_BUC;
/* Return if new BUC is same as current one. */
diff --git a/firmware/bdb/secrets.c b/firmware/bdb/secrets.c
index 08bca5f5..bd6c6fcf 100644
--- a/firmware/bdb/secrets.c
+++ b/firmware/bdb/secrets.c
@@ -11,8 +11,137 @@
#include "bdb.h"
#include "secrets.h"
-static int get_constant(const uint8_t *buf, uint32_t buf_size,
- const uint8_t *constant, uint8_t *out)
+const uint8_t secret_constant_a[] = {
+ 0xad, 0xf8, 0xd1, 0xd9, 0x48, 0xe6, 0xb3, 0xe4, 0xe0, 0xc4,
+ 0xd8, 0x66, 0x97, 0x95, 0x71, 0xa8, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x01};
+
+const uint8_t secret_constant_b[] = {
+ 0xba, 0x9d, 0x1d, 0x8b, 0x12, 0xbd, 0x8d, 0xcd, 0x4c, 0x89,
+ 0xd8, 0x18, 0x72, 0x98, 0xb5, 0x18, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x02};
+
+const uint8_t secret_constant_x[] = {
+ 0xfd, 0xc1, 0xe5, 0x57, 0x34, 0xf4, 0xf6, 0x89, 0x6d, 0x1b,
+ 0x6f, 0xf2, 0xd0, 0x36, 0xdb, 0xf4, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x09};
+
+const uint8_t secret_constant_y[] = {
+ 0x18, 0xef, 0x01, 0x8e, 0xcd, 0x62, 0xf1, 0xb0, 0x2d, 0xd4,
+ 0x11, 0xa4, 0xb5, 0x6e, 0x38, 0xf6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x0a};
+
+const uint8_t secret_constant_c[] = {
+ 0x46, 0xda, 0x52, 0x8d, 0x08, 0x56, 0x14, 0xde, 0x75, 0x9c,
+ 0x9a, 0xeb, 0x08, 0x93, 0x3d, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x0b};
+
+const uint8_t secret_constant_fv0[] = {
+ 0x93, 0x32, 0xf7, 0x8d, 0xec, 0x4b, 0x26, 0x2e, 0xb3, 0x5c,
+ 0x39, 0xd7, 0xfc, 0xc6, 0x9f, 0x09, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x05};
+
+const uint8_t secret_constant_fv1[] = {
+ 0x60, 0x8d, 0x96, 0x35, 0xdf, 0xf6, 0x31, 0x67, 0xab, 0xb8,
+ 0x9f, 0x50, 0x81, 0x28, 0x82, 0xec, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x06};
+
+const uint8_t secret_constant_kv0[] = {
+ 0x46, 0x6d, 0xef, 0x2c, 0x05, 0xc9, 0xbf, 0xa9, 0x6b, 0xee,
+ 0xaa, 0x6c, 0xb9, 0xb4, 0x6d, 0x37, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x07};
+
+const uint8_t secret_constant_kv1[] = {
+ 0x0a, 0x9e, 0xc9, 0x20, 0x29, 0xa3, 0x5d, 0xd7, 0x27, 0x55,
+ 0xb6, 0xa6, 0xb4, 0x80, 0x7c, 0x73, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x08};
+
+const uint8_t secret_constant_k[] = {
+ /*
+ * Digest of kernel data key struct fills first 32 bytes
+ */
+ 0x1e, 0x1d, 0xec, 0xf2, 0x6d, 0x27, 0xa6, 0xd9,
+ 0x67, 0x0f, 0x34, 0xc5, 0xfa, 0x01, 0x68, 0xf6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x03};
+
+const uint8_t secret_constant_l[] = {
+ /*
+ * Digest of kernel data key struct fills first 32 bytes
+ */
+ 0x9b, 0xc0, 0x29, 0xd3, 0xc3, 0x90, 0x7f, 0x82,
+ 0x56, 0xe2, 0x67, 0x79, 0x11, 0x74, 0xbe, 0xd0, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x04};
+
+const uint8_t secret_constant_p[] = {
+ /*
+ * Digest of KDB key struct fills first 32 bytes
+ */
+ 0xfe, 0x31, 0xed, 0xed, 0x45, 0xfd, 0x8a, 0x5d,
+ 0x87, 0x90, 0xac, 0x17, 0x02, 0x89, 0x2c, 0xba, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x0c};
+
+const uint8_t secret_constant_q[] = {
+ /*
+ * Digest of KDB key struct fills first 32 bytes
+ */
+ 0xc7, 0x60, 0x83, 0x0f, 0x20, 0x44, 0x5d, 0x9c,
+ 0x70, 0x96, 0x05, 0x2d, 0x51, 0x4b, 0x15, 0x99, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x0d};
+
+/**
+ * Get constant with digest
+ *
+ * This function computes a digest of the given buffer and concatenates it
+ * to the given constant.
+ *
+ * @param buf Data from which a digest is computed
+ * @param buf_size Size of <buf>
+ * @param constant Buffer containing constant
+ * @param out Buffer where the result is stored
+ * @return BDB_SUCCESS on success or !BDB_SUCCESS otherwise
+ */
+static int get_constant_with_digest(const uint8_t *buf, uint32_t buf_size,
+ const uint8_t *constant, uint8_t *out)
{
int digest_size = vb2_digest_size(VB2_HASH_SHA256);
const struct bdb_key *key = (const struct bdb_key *)buf;
@@ -32,42 +161,120 @@ static int get_constant(const uint8_t *buf, uint32_t buf_size,
return BDB_SUCCESS;
}
+/**
+ * Derive secrets for SP-RO
+ *
+ * This function extends a BDS to derive secrets as done by SP-RO (a.k.a. mask
+ * rom).
+ *
+ * @param ctx VBoot context
+ * @param type Type of secret to derive
+ * @param wsr Work secret register
+ * @param buf Data from which a digest is computed
+ * @param buf_size Size of <buf>
+ * @param extend sha256 extension function to be used
+ * @return BDB_SUCCESS on success or BDB_ERROR_* otherwise
+ */
+static int derive_secret_ro(struct vba_context *ctx, enum bdb_secret_type type,
+ uint8_t *wsr, const uint8_t *buf, uint32_t buf_size,
+ f_extend extend)
+{
+ uint8_t c[BDB_CONSTANT_BLOCK_SIZE];
+ uint8_t *from;
+ const uint8_t *by = (const uint8_t *)c;
+ uint8_t *to;
+
+ switch (type) {
+ case BDB_SECRET_TYPE_WSR:
+ from = to = wsr;
+ by = secret_constant_x;
+ break;
+ case BDB_SECRET_TYPE_BDB:
+ from = wsr;
+ to = ctx->secrets->bdb;
+ if (get_constant_with_digest(buf, buf_size,
+ secret_constant_p, c))
+ return BDB_ERROR_SECRET_BDB;
+ break;
+ case BDB_SECRET_TYPE_BOOT_PATH:
+ from = wsr;
+ to = ctx->secrets->boot_path;
+ if (get_constant_with_digest(buf, buf_size,
+ secret_constant_k, c))
+ return BDB_ERROR_SECRET_BOOT_PATH;
+ break;
+ case BDB_SECRET_TYPE_BOOT_VERIFIED:
+ from = wsr;
+ to = ctx->secrets->boot_verified;
+ if (ctx->flags & VBA_CONTEXT_FLAG_BDB_KEY_EFUSED)
+ by = secret_constant_fv0;
+ else
+ by = secret_constant_fv1;
+ break;
+ case BDB_SECRET_TYPE_NVM_WP:
+ from = wsr;
+ by = secret_constant_a;
+ to = ctx->secrets->nvm_wp;
+ break;
+ case BDB_SECRET_TYPE_NVM_RW:
+ from = ctx->secrets->nvm_wp;
+ by = secret_constant_b;
+ to = ctx->secrets->nvm_rw;
+ break;
+ default:
+ return BDB_ERROR_SECRET_TYPE;
+ }
+
+ if (extend)
+ extend(from, by, to);
+ else
+ vb2_sha256_extend(from, by, to);
+
+ return BDB_SUCCESS;
+}
+
int vba_derive_secret(struct vba_context *ctx, enum bdb_secret_type type,
- const uint8_t *buf, uint32_t buf_size)
+ uint8_t *wsr, const uint8_t *buf, uint32_t buf_size)
{
uint8_t c[BDB_CONSTANT_BLOCK_SIZE];
- const uint8_t *b = (const uint8_t *)c;
- uint8_t *s;
- uint8_t *o;
+ uint8_t *from;
+ const uint8_t *by = (const uint8_t *)c;
+ uint8_t *to;
switch (type) {
+ case BDB_SECRET_TYPE_WSR:
+ from = to = wsr;
+ by = secret_constant_y;
+ break;
case BDB_SECRET_TYPE_BDB:
- s = o = ctx->ro_secrets->bdb;
- if (get_constant(buf, buf_size, secret_constant_q, c))
+ from = to = ctx->secrets->bdb;
+ if (get_constant_with_digest(buf, buf_size,
+ secret_constant_q, c))
return BDB_ERROR_SECRET_BDB;
break;
case BDB_SECRET_TYPE_BOOT_PATH:
- s = o = ctx->ro_secrets->boot_path;
- if (get_constant(buf, buf_size, secret_constant_l, c))
+ from = to = ctx->secrets->boot_path;
+ if (get_constant_with_digest(buf, buf_size,
+ secret_constant_l, c))
return BDB_ERROR_SECRET_BOOT_PATH;
break;
case BDB_SECRET_TYPE_BOOT_VERIFIED:
- s = o = ctx->ro_secrets->boot_verified;
+ from = to = ctx->secrets->boot_verified;
if (ctx->flags & VBA_CONTEXT_FLAG_KERNEL_DATA_KEY_VERIFIED)
- b = secret_constant_kv1;
+ by = secret_constant_kv1;
else
- b = secret_constant_kv0;
+ by = secret_constant_kv0;
break;
case BDB_SECRET_TYPE_BUC:
- s = ctx->ro_secrets->boot_verified;
- b = secret_constant_c;
- o = ctx->rw_secrets->buc;
+ from = ctx->secrets->boot_verified;
+ by = secret_constant_c;
+ to = ctx->secrets->buc;
break;
default:
return BDB_ERROR_SECRET_TYPE;
}
- vb2_sha256_extend(s, b, o);
+ vb2_sha256_extend(from, by, to);
return BDB_SUCCESS;
}
@@ -78,19 +285,19 @@ int vba_clear_secret(struct vba_context *ctx, enum bdb_secret_type type)
switch (type) {
case BDB_SECRET_TYPE_NVM_RW:
- s = ctx->ro_secrets->nvm_rw;
+ s = ctx->secrets->nvm_rw;
break;
case BDB_SECRET_TYPE_BDB:
- s = ctx->ro_secrets->bdb;
+ s = ctx->secrets->bdb;
break;
case BDB_SECRET_TYPE_BOOT_PATH:
- s = ctx->ro_secrets->boot_path;
+ s = ctx->secrets->boot_path;
break;
case BDB_SECRET_TYPE_BOOT_VERIFIED:
- s = ctx->ro_secrets->boot_verified;
+ s = ctx->secrets->boot_verified;
break;
case BDB_SECRET_TYPE_BUC:
- s = ctx->rw_secrets->buc;
+ s = ctx->secrets->buc;
break;
default:
return BDB_ERROR_SECRET_TYPE;
@@ -99,3 +306,25 @@ int vba_clear_secret(struct vba_context *ctx, enum bdb_secret_type type)
memset(s, 0, BDB_SECRET_SIZE);
return BDB_SUCCESS;
}
+
+int vba_extend_secrets_ro(struct vba_context *ctx, const uint8_t *bdb,
+ uint8_t *wsr, f_extend extend)
+{
+ const struct bdb_key *bdbkey = bdb_get_bdbkey(bdb);
+ const struct bdb_key *datakey = bdb_get_datakey(bdb);
+
+ derive_secret_ro(ctx, BDB_SECRET_TYPE_BDB, wsr, (const uint8_t *)bdbkey,
+ bdbkey->struct_size, extend);
+ derive_secret_ro(ctx, BDB_SECRET_TYPE_BOOT_PATH, wsr,
+ (const uint8_t *)datakey, datakey->struct_size,
+ extend);
+ derive_secret_ro(ctx, BDB_SECRET_TYPE_BOOT_VERIFIED, wsr, NULL, 0,
+ extend);
+ derive_secret_ro(ctx, BDB_SECRET_TYPE_NVM_WP, wsr, NULL, 0, extend);
+ /* Deriving NVM-RW has to be done after NVM-WP */
+ derive_secret_ro(ctx, BDB_SECRET_TYPE_NVM_RW, wsr, NULL, 0, extend);
+ /* Extending WSR has to be done last. */
+ derive_secret_ro(ctx, BDB_SECRET_TYPE_WSR, wsr, NULL, 0, extend);
+
+ return BDB_SUCCESS;
+}
diff --git a/firmware/bdb/secrets.h b/firmware/bdb/secrets.h
index ed8973f2..59c27cf6 100644
--- a/firmware/bdb/secrets.h
+++ b/firmware/bdb/secrets.h
@@ -9,51 +9,6 @@
#define BDB_SECRET_SIZE 32
#define BDB_CONSTANT_BLOCK_SIZE 64
-const uint8_t secret_constant_c[] = {
- 0x46, 0xda, 0x52, 0x8d, 0x08, 0x56, 0x14, 0xde, 0x75, 0x9c,
- 0x9a, 0xeb, 0x08, 0x93, 0x3d, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0x0b};
-
-const uint8_t secret_constant_kv1[] = {
- 0x0a, 0x9e, 0xc9, 0x20, 0x29, 0xa3, 0x5d, 0xd7, 0x27, 0x55,
- 0xb6, 0xa6, 0xb4, 0x80, 0x7c, 0x73, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0x08};
-
-const uint8_t secret_constant_kv0[] = {
- 0x46, 0x6d, 0xef, 0x2c, 0x05, 0xc9, 0xbf, 0xa9, 0x6b, 0xee,
- 0xaa, 0x6c, 0xb9, 0xb4, 0x6d, 0x37, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0x07};
-
-const uint8_t secret_constant_l[] = {
- /*
- * Digest of kernel data key struct fills first 32 bytes
- */
- 0x9b, 0xc0, 0x29, 0xd3, 0xc3, 0x90, 0x7f, 0x82,
- 0x56, 0xe2, 0x67, 0x79, 0x11, 0x74, 0xbe, 0xd0, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0x04};
-
-const uint8_t secret_constant_q[] = {
- /*
- * Digest of KDB key struct fills first 32 bytes
- */
- 0xc7, 0x60, 0x83, 0x0f, 0x20, 0x44, 0x5d, 0x9c,
- 0x70, 0x96, 0x05, 0x2d, 0x51, 0x4b, 0x15, 0x99, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0x0d};
-
enum bdb_secret_type {
BDB_SECRET_TYPE_WSR,
BDB_SECRET_TYPE_NVM_WP,
@@ -66,22 +21,14 @@ enum bdb_secret_type {
};
/*
- * Secrets passed to SP-RW by SP-RO. How it's passed depends on chips.
- * These are hash-extended by SP-RW.
+ * Struct storing BDB secrets passed between SP-RO and SP-RW.
*/
-struct bdb_ro_secrets {
- uint8_t nvm_wp[BDB_SECRET_SIZE];
+struct bdb_secrets {
uint8_t nvm_rw[BDB_SECRET_SIZE];
uint8_t bdb[BDB_SECRET_SIZE];
uint8_t boot_verified[BDB_SECRET_SIZE];
uint8_t boot_path[BDB_SECRET_SIZE];
-};
-
-/*
- * Additional secrets SP-RW derives from RO secrets. This can be independently
- * updated as more secrets are needed.
- */
-struct bdb_rw_secrets {
+ uint8_t nvm_wp[BDB_SECRET_SIZE];
uint8_t buc[BDB_SECRET_SIZE];
};
diff --git a/tests/bdb_sprw_test.c b/tests/bdb_sprw_test.c
index f4750dae..12b0bd7f 100644
--- a/tests/bdb_sprw_test.c
+++ b/tests/bdb_sprw_test.c
@@ -31,18 +31,12 @@ static uint8_t reset_count;
static uint8_t nvmrw1[NVM_RW_MAX_STRUCT_SIZE];
static uint8_t nvmrw2[NVM_RW_MAX_STRUCT_SIZE];
-static struct bdb_ro_secrets secrets = {
+static struct bdb_secrets secrets = {
.nvm_wp = {0x00, },
.nvm_rw = {0x00, },
.bdb = {0x00, },
.boot_verified = {0x00, },
.boot_path = {0x00, },
-};
-
-/* TODO: Implement test for vba_clear_secret */
-//static uint8_t cleared_secret[BDB_SECRET_SIZE] = { 0x00, };
-
-struct bdb_rw_secrets rw_secrets = {
.buc = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -366,7 +360,7 @@ static void test_nvm_read(void)
{
struct vba_context ctx = {
.bdb = NULL,
- .ro_secrets = &secrets,
+ .secrets = &secrets,
};
struct nvmrw *nvm;
uint8_t nvmrw1_copy[NVM_RW_MAX_STRUCT_SIZE];
@@ -460,7 +454,7 @@ static void test_nvm_write(void)
{
struct vba_context ctx = {
.bdb = NULL,
- .ro_secrets = &secrets,
+ .secrets = &secrets,
};
struct nvmrw nvm = {
.struct_magic = NVM_RW_MAGIC,
@@ -518,7 +512,7 @@ static void verify_kernel_version(uint32_t min_kernel_data_key_version,
{
struct vba_context ctx = {
.bdb = NULL,
- .ro_secrets = &secrets,
+ .secrets = &secrets,
};
struct nvmrw *nvm = (struct nvmrw *)nvmrw1;
uint32_t expected_kernel_data_key_version = min_kernel_data_key_version;
@@ -598,15 +592,14 @@ static void test_update_buc(void)
struct nvmrw *nvm = (struct nvmrw *)nvmrw1;
struct vba_context ctx = {
.bdb = NULL,
- .ro_secrets = &secrets,
- .rw_secrets = &rw_secrets,
+ .secrets = &secrets,
};
install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0);
install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 0);
TEST_SUCC(vba_update_buc(&ctx, new_buc), NULL);
- vbe_aes256_encrypt(new_buc, sizeof(new_buc), ctx.rw_secrets->buc,
+ vbe_aes256_encrypt(new_buc, sizeof(new_buc), ctx.secrets->buc,
enc_buc);
TEST_SUCC(memcmp(nvm->buc_enc_digest, enc_buc, sizeof(new_buc)), NULL);
}
@@ -617,10 +610,9 @@ static void test_derive_secrets(void)
struct bdb_key *key = (struct bdb_key *)test_key;
struct vba_context ctx = {
.bdb = NULL,
- .ro_secrets = &secrets,
- .rw_secrets = &rw_secrets,
+ .secrets = &secrets,
};
- const struct bdb_ro_secrets expected = {
+ const struct bdb_secrets expected = {
.bdb = {
0x75, 0xb6, 0x24, 0xaa, 0x72, 0x50, 0xf9, 0x33,
0x59, 0x45, 0x8d, 0xbf, 0xfa, 0x42, 0xc4, 0xb7,
@@ -636,8 +628,6 @@ static void test_derive_secrets(void)
0x96, 0x5b, 0x69, 0x77, 0x9b, 0x67, 0x80, 0x39,
0x7a, 0xd4, 0xc5, 0x3b, 0xcf, 0x95, 0x3f, 0xec,
0x28, 0x49, 0x55, 0x49, 0x38, 0x27, 0x5d, 0x3c},
- };
- const struct bdb_rw_secrets rw_expected = {
.buc = {
0x63, 0xa5, 0x30, 0xd7, 0xca, 0xe1, 0x3e, 0x2e,
0x72, 0x7e, 0x29, 0xc9, 0x37, 0x66, 0x6a, 0x63,
@@ -654,23 +644,24 @@ static void test_derive_secrets(void)
key->sig_alg = BDB_SIG_ALG_RSA4096;
key->key_version = 1;
- TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BDB,
- test_key, sizeof(test_key)), NULL);
- TEST_SUCC(memcmp(ctx.ro_secrets->bdb, expected.bdb, BDB_SECRET_SIZE),
+ TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BDB, NULL,
+ test_key, sizeof(test_key)), NULL);
+ TEST_SUCC(memcmp(ctx.secrets->bdb, expected.bdb, BDB_SECRET_SIZE),
NULL);
- TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BOOT_VERIFIED,
- NULL, 0), NULL);
- TEST_SUCC(memcmp(ctx.ro_secrets->boot_verified, expected.boot_verified,
+ TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BOOT_VERIFIED, NULL,
+ NULL, 0), NULL);
+ TEST_SUCC(memcmp(ctx.secrets->boot_verified, expected.boot_verified,
BDB_SECRET_SIZE), NULL);
- TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BOOT_PATH,
- test_key, sizeof(test_key)), NULL);
- TEST_SUCC(memcmp(ctx.ro_secrets->boot_path, expected.boot_path,
+ TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BOOT_PATH, NULL,
+ test_key, sizeof(test_key)), NULL);
+ TEST_SUCC(memcmp(ctx.secrets->boot_path, expected.boot_path,
BDB_SECRET_SIZE), NULL);
- TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BUC, NULL, 0), NULL);
- TEST_SUCC(memcmp(ctx.rw_secrets->buc, rw_expected.buc,
+ TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BUC, NULL, NULL, 0),
+ NULL);
+ TEST_SUCC(memcmp(ctx.secrets->buc, expected.buc,
BDB_SECRET_SIZE), NULL);
}