diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2016-05-06 12:32:38 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-06-22 20:01:58 -0700 |
commit | 7931177cc35f5dcd2505e1efa448511ba8a0b3b1 (patch) | |
tree | 1fbfb4397bfecffca574c79ef6f095640b3e0080 | |
parent | 05cd8ce75f97a76c4ef155734d191cd275bac231 (diff) | |
download | vboot-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.h | 3 | ||||
-rw-r--r-- | firmware/bdb/bdb_api.h | 33 | ||||
-rw-r--r-- | firmware/bdb/nvm.c | 36 | ||||
-rw-r--r-- | firmware/bdb/stub.c | 14 | ||||
-rw-r--r-- | tests/bdb_sprw_test.c | 51 |
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; } |