mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-23 17:55:01 +00:00
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
190 lines
4.3 KiB
C
190 lines
4.3 KiB
C
/* 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);
|
|
}
|