summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2016-05-06 12:32:38 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-06-22 20:01:58 -0700
commit7931177cc35f5dcd2505e1efa448511ba8a0b3b1 (patch)
tree1fbfb4397bfecffca574c79ef6f095640b3e0080
parent05cd8ce75f97a76c4ef155734d191cd275bac231 (diff)
downloadvboot-7931177cc35f5dcd2505e1efa448511ba8a0b3b1.tar.gz
bdb: Add vba_update_buc
vba_update_buc writes a BUC (boot unlock code) to NVM-RW. It will be called by AP-RW to update a BUC. BUG=chrome-os-partner:51907 BRANCH=tot TEST=make runtests Change-Id: Ic91f34b60b11ebce948bce01993ddb44519a59b8 Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/346233
-rw-r--r--firmware/bdb/bdb.h3
-rw-r--r--firmware/bdb/bdb_api.h33
-rw-r--r--firmware/bdb/nvm.c36
-rw-r--r--firmware/bdb/stub.c14
-rw-r--r--tests/bdb_sprw_test.c51
5 files changed, 137 insertions, 0 deletions
diff --git a/firmware/bdb/bdb.h b/firmware/bdb/bdb.h
index 9f3b9c6b..5163401d 100644
--- a/firmware/bdb/bdb.h
+++ b/firmware/bdb/bdb.h
@@ -88,6 +88,9 @@ enum bdb_return_code {
BDB_ERROR_NVM_STRUCT_VERSION,
BDB_ERROR_NVM_VBE_READ,
BDB_ERROR_NVM_RW_BUFFER_SMALL,
+ BDB_ERROR_DECRYPT_BUC,
+ BDB_ERROR_ENCRYPT_BUC,
+ BDB_ERROR_WRITE_BUC,
};
/*****************************************************************************/
diff --git a/firmware/bdb/bdb_api.h b/firmware/bdb/bdb_api.h
index 9979824e..7ef935c0 100644
--- a/firmware/bdb/bdb_api.h
+++ b/firmware/bdb/bdb_api.h
@@ -68,6 +68,15 @@ int vba_update_kernel_version(struct vba_context *ctx,
uint32_t kernel_version);
/**
+ * Write new boot unlock code to NVM-RW
+ *
+ * @param ctx
+ * @param new_buc New BUC to be written
+ * @return BDB_SUCCESS or BDB_ERROR_*
+ */
+int vba_update_buc(struct vba_context *ctx, uint8_t *new_buc);
+
+/**
* Get vboot register value
*
* Implemented by each chip
@@ -119,4 +128,28 @@ int vbe_read_nvm(enum nvm_type type, uint8_t *buf, uint32_t size);
*/
int vbe_write_nvm(enum nvm_type type, void *buf, uint32_t size);
+/**
+ * Encrypt data by AES-256
+ *
+ * @param msg Message to be encrypted
+ * @param len Length of <msg> in bytes
+ * @param key Key used for encryption
+ * @param out Buffer where encrypted message is stored
+ * @return BDB_SUCCESS or BDB_ERROR_*
+ */
+int vbe_aes256_encrypt(const uint8_t *msg, uint32_t len, const uint8_t *key,
+ uint8_t *out);
+
+/**
+ * Decrypt data by AES-256
+ *
+ * @param msg Message to be decrypted
+ * @param len Length of <msg> in bytes
+ * @param key Key used for decryption
+ * @param out Buffer where decrypted message is stored
+ * @return BDB_SUCCESS or BDB_ERROR_*
+ */
+int vbe_aes256_decrypt(const uint8_t *msg, uint32_t len, const uint8_t *key,
+ uint8_t *out);
+
#endif
diff --git a/firmware/bdb/nvm.c b/firmware/bdb/nvm.c
index b5c53af9..a7c56b0b 100644
--- a/firmware/bdb/nvm.c
+++ b/firmware/bdb/nvm.c
@@ -229,3 +229,39 @@ int vba_update_kernel_version(struct vba_context *ctx,
return BDB_SUCCESS;
}
+
+int vba_update_buc(struct vba_context *ctx, uint8_t *new_buc)
+{
+ struct nvmrw *nvm = &ctx->nvmrw;
+ uint8_t buc[BUC_ENC_DIGEST_SIZE];
+ int rv1, rv2;
+
+ if (nvmrw_verify(ctx->ro_secrets, nvm, sizeof(*nvm))) {
+ if (nvmrw_init(ctx))
+ return BDB_ERROR_NVM_INIT;
+ }
+
+ /* Encrypt 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))
+ return BDB_ERROR_ENCRYPT_BUC;
+
+ /* Return if new BUC is same as current one. */
+ if (!memcmp(buc, nvm->buc_enc_digest, sizeof(buc)))
+ return BDB_SUCCESS;
+
+ memcpy(nvm->buc_enc_digest, buc, sizeof(buc));
+
+ /* Increment update counter */
+ nvm->update_count++;
+
+ /* Write new BUC */
+ rv1 = nvmrw_write(ctx, NVM_TYPE_RW_PRIMARY);
+ rv2 = nvmrw_write(ctx, NVM_TYPE_RW_SECONDARY);
+ if (rv1 || rv2)
+ return BDB_ERROR_WRITE_BUC;
+
+ return BDB_SUCCESS;
+}
diff --git a/firmware/bdb/stub.c b/firmware/bdb/stub.c
index 58a00967..4af9126c 100644
--- a/firmware/bdb/stub.c
+++ b/firmware/bdb/stub.c
@@ -35,3 +35,17 @@ int vbe_write_nvm(enum nvm_type type, void *buf, uint32_t size)
{
return BDB_ERROR_NOT_IMPLEMENTED;
}
+
+__attribute__((weak))
+int vbe_aes256_encrypt(const uint8_t *msg, uint32_t len, const uint8_t *key,
+ uint8_t *out)
+{
+ return BDB_ERROR_NOT_IMPLEMENTED;
+}
+
+__attribute__((weak))
+int vbe_aes256_decrypt(const uint8_t *msg, uint32_t len, const uint8_t *key,
+ uint8_t *out)
+{
+ return BDB_ERROR_NOT_IMPLEMENTED;
+}
diff --git a/tests/bdb_sprw_test.c b/tests/bdb_sprw_test.c
index 06739ae5..75deba63 100644
--- a/tests/bdb_sprw_test.c
+++ b/tests/bdb_sprw_test.c
@@ -8,6 +8,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <openssl/aes.h>
#include "2sha.h"
#include "2hmac.h"
@@ -34,6 +35,13 @@ struct bdb_ro_secrets secrets = {
.nvm_rw = {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,
+ 0xff, 0xff},
+};
+
static int vbe_write_nvm_failure = 0;
static struct bdb_header *create_bdb(const char *key_dir,
@@ -554,6 +562,48 @@ static void test_update_kernel_version(void)
verify_kernel_version(0, 0, 1, 0, BDB_SUCCESS);
}
+int vbe_aes256_encrypt(const uint8_t *msg, uint32_t len, const uint8_t *key,
+ uint8_t *out)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ out[i] = msg[i] ^ key[i % 256/8];
+
+ return BDB_SUCCESS;
+}
+
+int vbe_aes256_decrypt(const uint8_t *msg, uint32_t len, const uint8_t *key,
+ uint8_t *out)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ out[i] = msg[i] ^ key[i % 256/8];
+
+ return BDB_SUCCESS;
+}
+
+static void test_update_buc(void)
+{
+ uint8_t new_buc[BUC_ENC_DIGEST_SIZE];
+ uint8_t enc_buc[BUC_ENC_DIGEST_SIZE];
+ struct nvmrw *nvm = (struct nvmrw *)nvmrw1;
+ struct vba_context ctx = {
+ .bdb = NULL,
+ .ro_secrets = &secrets,
+ .rw_secrets = &rw_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,
+ enc_buc);
+ TEST_SUCC(memcmp(nvm->buc_enc_digest, enc_buc, sizeof(new_buc)), NULL);
+}
+
int main(int argc, char *argv[])
{
if (argc != 2) {
@@ -566,6 +616,7 @@ int main(int argc, char *argv[])
test_nvm_read();
test_nvm_write();
test_update_kernel_version();
+ test_update_buc();
return gTestSuccess ? 0 : 255;
}