summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2016-09-19 13:37:12 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-10-04 00:33:20 -0700
commit351bc294ed73b57706e2b1650d6fbdae9418dd61 (patch)
treeb134470158c71e16ba92567e71b4e5f2cabb6981
parent84928a0baae6ef508f3dcdd6a4057fb505554dd1 (diff)
downloadvboot-351bc294ed73b57706e2b1650d6fbdae9418dd61.tar.gz
bdb: Add 'bdb --add' to futility
futility bdb --add appends a new hash entry to the given BDB. The resulting BDB does not have a valid signature and is expected to be resigned by 'resign' sub-command after all hashes are added. BUG=chromium:649554 BRANCH=none TEST=make runtest. Ran futility bdb --add, then --resign, then --verify (to be implemented) Change-Id: Icdf185f8ac268a23bb3954f5e78df6f80e749e18 Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/387117 Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--Makefile2
-rw-r--r--firmware/bdb/rsa.c12
-rw-r--r--futility/cmd_bdb.c76
3 files changed, 77 insertions, 13 deletions
diff --git a/Makefile b/Makefile
index 3a072656..1bd44e51 100644
--- a/Makefile
+++ b/Makefile
@@ -1191,7 +1191,7 @@ ${TEST20_BINS}: LIBS += ${FWLIB20}
${TESTBDB_BINS}: ${FWLIB2X} ${UTILBDB}
${TESTBDB_BINS}: INCLUDES += -Ifirmware/bdb
-${TESTBDB_BINS}: LIBS += ${UTILBDB_OBJS} ${BDBLIB_OBJS} ${FWLIB2X}
+${TESTBDB_BINS}: LIBS += ${UTILBDB} ${FWLIB2X}
${TESTLIB}: ${TESTLIB_OBJS}
@${PRINTF} " RM $(subst ${BUILD}/,,$@)\n"
diff --git a/firmware/bdb/rsa.c b/firmware/bdb/rsa.c
index 88d32dc3..61757dac 100644
--- a/firmware/bdb/rsa.c
+++ b/firmware/bdb/rsa.c
@@ -33,7 +33,7 @@ static void subM(const struct public_key *key, uint32_t *a)
/**
* Return a[] >= mod
*/
-int vb2_mont_ge(const struct public_key *key, uint32_t *a)
+static int mont_ge(const struct public_key *key, uint32_t *a)
{
uint32_t i;
for (i = key->arrsize; i;) {
@@ -132,7 +132,7 @@ static const uint8_t sha256_tail[] = {
0x05,0x00,0x04,0x20
};
-int vb2_check_padding(const uint8_t *sig, const struct public_key *key,
+static int check_padding(const uint8_t *sig, const struct public_key *key,
uint32_t pad_size)
{
/* Determine padding to use depending on the signature type */
@@ -192,7 +192,7 @@ static void modpowF4(const struct public_key *key, uint8_t *inout)
montMul(key, aaa, aR, a); /* aaa = aR * a / R mod M */
/* Make sure aaa < mod; aaa is at most 1x mod too large. */
- if (vb2_mont_ge(key, aaa)) {
+ if (mont_ge(key, aaa)) {
subM(key, aaa);
}
@@ -235,7 +235,7 @@ int bdb_rsa4096_verify(const uint8_t *key_data,
* reduce the risk of timing based attacks.
*/
pad_size = key.arrsize * sizeof(uint32_t) - BDB_SHA256_DIGEST_SIZE;
- rv = vb2_check_padding(sig_work, &key, pad_size);
+ rv = check_padding(sig_work, &key, pad_size);
/*
* Check digest. Even though there are probably no timing issues here,
@@ -280,7 +280,7 @@ static void modpow3(const struct public_key *key, uint8_t *inout)
montMul(key, aaa, aaR, a); /* aaa = aaR * a / R mod M */
/* Make sure aaa < mod; aaa is at most 1x mod too large. */
- if (vb2_mont_ge(key, aaa)) {
+ if (mont_ge(key, aaa)) {
subM(key, aaa);
}
@@ -323,7 +323,7 @@ int bdb_rsa3072b_verify(const uint8_t *key_data,
* reduce the risk of timing based attacks.
*/
pad_size = key.arrsize * sizeof(uint32_t) - BDB_SHA256_DIGEST_SIZE;
- rv = vb2_check_padding(sig_work, &key, pad_size);
+ rv = check_padding(sig_work, &key, pad_size);
/*
* Check digest. Even though there are probably no timing issues here,
diff --git a/futility/cmd_bdb.c b/futility/cmd_bdb.c
index f8b27f3c..a79bd9a0 100644
--- a/futility/cmd_bdb.c
+++ b/futility/cmd_bdb.c
@@ -6,13 +6,12 @@
*/
#include <getopt.h>
-#include <inttypes.h> /* For PRIu64 */
-#include <stddef.h>
#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <unistd.h>
+#include "2sysincludes.h"
+#include "2common.h"
+#include "bdb.h"
#include "bdb_struct.h"
#include "futility.h"
#include "host.h"
@@ -32,6 +31,7 @@ enum {
OPT_BDBKEY_PUB,
OPT_DATAKEY_PRI,
OPT_DATAKEY_PUB,
+ OPT_DATA,
/* key version */
OPT_BDBKEY_VERSION,
OPT_DATAKEY_VERSION,
@@ -55,6 +55,7 @@ static const struct option long_opts[] = {
{"datakey_pub", 1, 0, OPT_DATAKEY_PUB},
{"bdbkey_version", 1, 0, OPT_BDBKEY_VERSION},
{"datakey_version", 1, 0, OPT_DATAKEY_VERSION},
+ {"data", 1, 0, OPT_DATA},
{"offset", 1, 0, OPT_OFFSET},
{"partition", 1, 0, OPT_PARTITION},
{"type", 1, 0, OPT_TYPE},
@@ -74,8 +75,68 @@ static int do_add(const char *bdb_filename, const char *data_filename,
uint64_t offset, uint8_t partition,
uint8_t type, uint64_t load_address)
{
- fprintf(stderr, "'add' command is not implemented\n");
- return -1;
+ uint8_t *bdb, *data, *new_bdb;
+ uint32_t bdb_size, data_size;
+ struct bdb_header *bdb_header;
+ struct bdb_data *data_header;
+ struct bdb_hash *new_hash;
+ int rv = -1;
+
+ bdb = read_file(bdb_filename, &bdb_size);
+ data = read_file(data_filename, &data_size);
+ if (!bdb || !data) {
+ fprintf(stderr, "Unable to load BDB or data\n");
+ goto exit;
+ }
+
+ /* Create a copy of BDB */
+ new_bdb = calloc(1, bdb_size + sizeof(*new_hash));
+ if (!new_bdb) {
+ fprintf(stderr, "Unable to allocate memory\n");
+ goto exit;
+ }
+ /* Copy up to the end of hashes. This implicitly clears the data
+ * sig because it's not copied. */
+ memcpy(new_bdb, bdb, vb2_offset_of(bdb, bdb_get_data_sig(bdb)));
+
+ /* Update new BDB header */
+ bdb_header = (struct bdb_header *)bdb_get_header(new_bdb);
+ bdb_header->bdb_size += sizeof(*new_hash);
+
+ data_header = (struct bdb_data *)bdb_get_data(new_bdb);
+
+ /* Update new hash. We're overwriting the data signature, which
+ * is already invalid anyway. */
+ new_hash = (struct bdb_hash *)((uint8_t *)data_header
+ + data_header->signed_size);
+ new_hash->size = data_size;
+ new_hash->type = type;
+ new_hash->load_address = load_address;
+ new_hash->partition = partition;
+ new_hash->offset = offset;
+ if (bdb_sha256(new_hash->digest, data, data_size)) {
+ fprintf(stderr, "Unable to calculate hash\n");
+ goto exit;
+ }
+
+ /* Update data header */
+ data_header->num_hashes++;
+ data_header->signed_size += sizeof(*new_hash);
+
+ rv = write_file(bdb_filename, bdb_header, bdb_header->bdb_size);
+ if (rv) {
+ fprintf(stderr, "Unable to write BDB\n");
+ goto exit;
+ }
+
+ fprintf(stderr, "Hash is added to BDB successfully. Resign required\n");
+
+exit:
+ free(bdb);
+ free(data);
+ free(new_bdb);
+
+ return rv;
}
/**
@@ -252,6 +313,9 @@ static int do_bdb(int argc, char *argv[])
case OPT_DATAKEY_PUB:
datakey_pub_filename = optarg;
break;
+ case OPT_DATA:
+ data_filename = optarg;
+ break;
case OPT_BDBKEY_VERSION:
bdbkey_version = strtoul(optarg, &e, 0);
if (!*optarg || (e && *e)) {