mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 10:14:55 +00:00
add vb2api_get_pcr_digest
this api allows firmware to get the digest indicating boot mode status. BUG=chromium:451609 TEST=VBOOT2=1 make run2tests BRANCH=tot Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Change-Id: Idca7bc5f6aed947689ad7cf219805aad35047c7d Reviewed-on: https://chromium-review.googlesource.com/244542
This commit is contained in:
committed by
ChromeOS Commit Bot
parent
2559338dbd
commit
62d482ecdd
3
Makefile
3
Makefile
@@ -307,7 +307,8 @@ FWLIB2X_SRCS = \
|
||||
firmware/2lib/2sha1.c \
|
||||
firmware/2lib/2sha256.c \
|
||||
firmware/2lib/2sha512.c \
|
||||
firmware/2lib/2sha_utility.c
|
||||
firmware/2lib/2sha_utility.c \
|
||||
firmware/2lib/2tpm_bootmode.c
|
||||
|
||||
FWLIB20_SRCS = \
|
||||
firmware/lib20/api.c \
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "2secdata.h"
|
||||
#include "2sha.h"
|
||||
#include "2rsa.h"
|
||||
#include "2tpm_bootmode.h"
|
||||
|
||||
int vb2api_secdata_check(const struct vb2_context *ctx)
|
||||
{
|
||||
@@ -123,3 +124,33 @@ int vb2api_extend_hash(struct vb2_context *ctx,
|
||||
else
|
||||
return vb2_digest_extend(dc, buf, size);
|
||||
}
|
||||
|
||||
int vb2api_get_pcr_digest(struct vb2_context *ctx,
|
||||
enum vb2_pcr_digest which_digest,
|
||||
uint8_t *dest,
|
||||
uint32_t *dest_size)
|
||||
{
|
||||
const uint8_t *digest;
|
||||
uint32_t digest_size;
|
||||
|
||||
switch (which_digest) {
|
||||
case BOOT_MODE_PCR:
|
||||
digest = vb2_get_boot_state_digest(ctx);
|
||||
digest_size = VB2_SHA1_DIGEST_SIZE;
|
||||
break;
|
||||
case HWID_DIGEST_PCR:
|
||||
digest = vb2_get_sd(ctx)->gbb_hwid_digest;
|
||||
digest_size = VB2_GBB_HWID_DIGEST_SIZE;
|
||||
break;
|
||||
default:
|
||||
return VB2_ERROR_API_PCR_DIGEST;
|
||||
}
|
||||
|
||||
if (digest == NULL || *dest_size < digest_size)
|
||||
return VB2_ERROR_API_PCR_DIGEST_BUF;
|
||||
|
||||
memcpy(dest, digest, digest_size);
|
||||
*dest_size = digest_size;
|
||||
|
||||
return VB2_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -196,6 +196,7 @@ int vb2_fw_parse_gbb(struct vb2_context *ctx)
|
||||
sd->gbb_flags = gbb->flags;
|
||||
sd->gbb_rootkey_offset = gbb->rootkey_offset;
|
||||
sd->gbb_rootkey_size = gbb->rootkey_size;
|
||||
memcpy(sd->gbb_hwid_digest, gbb->hwid_digest, VB2_GBB_HWID_DIGEST_SIZE);
|
||||
|
||||
return VB2_SUCCESS;
|
||||
}
|
||||
|
||||
54
firmware/2lib/2tpm_bootmode.c
Normal file
54
firmware/2lib/2tpm_bootmode.c
Normal file
@@ -0,0 +1,54 @@
|
||||
/* Copyright 2015 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.
|
||||
*
|
||||
* Functions for updating the TPM state with the status of boot path.
|
||||
*/
|
||||
|
||||
#include "2sysincludes.h"
|
||||
#include "2common.h"
|
||||
#include "2sha.h"
|
||||
#include "2tpm_bootmode.h"
|
||||
|
||||
/*
|
||||
* Input digests for PCR extend.
|
||||
* These are calculated as:
|
||||
* SHA1("|Developer_Mode||Recovery_Mode||Keyblock_Mode|").
|
||||
* Developer_Mode can be 0 or 1.
|
||||
* Recovery_Mode can be 0 or 1.
|
||||
* Keyblock flags are defined in 2struct.h and assumed always 0 in recovery mode
|
||||
* or 7 in non-recovery mode.
|
||||
*
|
||||
* We map them to Keyblock_Mode as follows:
|
||||
* -----------------------------------------
|
||||
* Keyblock Flags | Keyblock Mode
|
||||
* -----------------------------------------
|
||||
* 0 recovery mode | 0
|
||||
* 7 Normal-signed firmware | 1
|
||||
*/
|
||||
|
||||
const uint8_t kBootStateSHA1Digests[][VB2_SHA1_DIGEST_SIZE] = {
|
||||
/* SHA1(0x00|0x00|0x01) */
|
||||
{0x25, 0x47, 0xcc, 0x73, 0x6e, 0x95, 0x1f, 0xa4, 0x91, 0x98, 0x53, 0xc4,
|
||||
0x3a, 0xe8, 0x90, 0x86, 0x1a, 0x3b, 0x32, 0x64},
|
||||
|
||||
/* SHA1(0x01|0x00|0x01) */
|
||||
{0xc4, 0x2a, 0xc1, 0xc4, 0x6f, 0x1d, 0x4e, 0x21, 0x1c, 0x73, 0x5c, 0xc7,
|
||||
0xdf, 0xad, 0x4f, 0xf8, 0x39, 0x11, 0x10, 0xe9},
|
||||
|
||||
/* SHA1(0x00|0x01|0x00) */
|
||||
{0x62, 0x57, 0x18, 0x91, 0x21, 0x5b, 0x4e, 0xfc, 0x1c, 0xea, 0xb7, 0x44,
|
||||
0xce, 0x59, 0xdd, 0x0b, 0x66, 0xea, 0x6f, 0x73},
|
||||
|
||||
/* SHA1(0x01|0x01|0x00) */
|
||||
{0x47, 0xec, 0x8d, 0x98, 0x36, 0x64, 0x33, 0xdc, 0x00, 0x2e, 0x77, 0x21,
|
||||
0xc9, 0xe3, 0x7d, 0x50, 0x67, 0x54, 0x79, 0x37},
|
||||
};
|
||||
|
||||
const uint8_t *vb2_get_boot_state_digest(struct vb2_context *ctx)
|
||||
{
|
||||
int index = (ctx->flags & VB2_CONTEXT_RECOVERY_MODE ? 2 : 0) +
|
||||
(ctx->flags & VB2_CONTEXT_DEVELOPER_MODE ? 1 : 0);
|
||||
|
||||
return kBootStateSHA1Digests[index];
|
||||
}
|
||||
@@ -42,6 +42,9 @@
|
||||
*/
|
||||
#define VB2_WORKBUF_RECOMMENDED_SIZE (12 * 1024)
|
||||
|
||||
/* Recommended buffer size for vb2api_get_pcr_digest */
|
||||
#define VB2_PCR_DIGEST_RECOMMENDED_SIZE 32
|
||||
|
||||
/* Flags for vb2_context.
|
||||
*
|
||||
* Unless otherwise noted, flags are set by verified boot and may be read (but
|
||||
@@ -160,6 +163,15 @@ enum vb2_resource_index {
|
||||
VB2_RES_FW_VBLOCK,
|
||||
};
|
||||
|
||||
/* Digest ID for vbapi_get_pcr_digest() */
|
||||
enum vb2_pcr_digest {
|
||||
/* Digest based on current developer and recovery mode flags */
|
||||
BOOT_MODE_PCR,
|
||||
|
||||
/* SHA-256 hash digest of HWID, from GBB */
|
||||
HWID_DIGEST_PCR,
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* APIs provided by verified boot.
|
||||
*
|
||||
@@ -338,6 +350,22 @@ int vb2api_extend_hash(struct vb2_context *ctx,
|
||||
*/
|
||||
int vb2api_check_hash(struct vb2_context *ctx);
|
||||
|
||||
/**
|
||||
* Get a PCR digest
|
||||
*
|
||||
* @param ctx Vboot context
|
||||
* @param which_digest PCR index of the digest
|
||||
* @param dest Destination where the digest is copied.
|
||||
* Recommended size is VB2_PCR_DIGEST_RECOMMENDED_SIZE.
|
||||
* @param dest_size IN: size of the buffer pointed by dest
|
||||
* OUT: size of the copied digest
|
||||
* @return VB2_SUCCESS, or error code on error
|
||||
*/
|
||||
int vb2api_get_pcr_digest(struct vb2_context *ctx,
|
||||
enum vb2_pcr_digest which_digest,
|
||||
uint8_t *dest,
|
||||
uint32_t *dest_size);
|
||||
|
||||
/*****************************************************************************/
|
||||
/* APIs provided by the caller to verified boot */
|
||||
|
||||
|
||||
@@ -423,6 +423,12 @@ enum vb2_return_code {
|
||||
/* Siganature mismatch in vb2api_check_hash() */
|
||||
VB2_ERROR_API_CHECK_HASH_SIG,
|
||||
|
||||
/* Invalid enum vb2_pcr_digest requested to vb2api_get_pcr_digest */
|
||||
VB2_ERROR_API_PCR_DIGEST,
|
||||
|
||||
/* Buffer size for the digest is too small for vb2api_get_pcr_digest */
|
||||
VB2_ERROR_API_PCR_DIGEST_BUF,
|
||||
|
||||
/**********************************************************************
|
||||
* Errors which may be generated by implementations of vb2ex functions.
|
||||
* Implementation may also return its own specific errors, which should
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define VB2_KEY_BLOCK_FLAG_DEVELOPER_1 0x02 /* Developer switch on */
|
||||
#define VB2_KEY_BLOCK_FLAG_RECOVERY_0 0x04 /* Not recovery mode */
|
||||
#define VB2_KEY_BLOCK_FLAG_RECOVERY_1 0x08 /* Recovery mode */
|
||||
#define VB2_GBB_HWID_DIGEST_SIZE 32
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
@@ -103,6 +104,9 @@ struct vb2_shared_data {
|
||||
uint32_t gbb_rootkey_offset;
|
||||
uint32_t gbb_rootkey_size;
|
||||
|
||||
/* HWID digest from GBB header */
|
||||
uint8_t gbb_hwid_digest[VB2_GBB_HWID_DIGEST_SIZE];
|
||||
|
||||
/* Offset of preamble from start of vblock */
|
||||
uint32_t vblock_preamble_offset;
|
||||
|
||||
@@ -231,7 +235,7 @@ struct vb2_gbb_header {
|
||||
uint32_t recovery_key_size;
|
||||
|
||||
/* Added in version 1.2 */
|
||||
uint8_t hwid_digest[32]; /* SHA-256 of HWID */
|
||||
uint8_t hwid_digest[VB2_GBB_HWID_DIGEST_SIZE]; /* SHA-256 of HWID */
|
||||
|
||||
/* Pad to match EXPECETED_VB2_GBB_HEADER_SIZE. Initialize to 0. */
|
||||
uint8_t pad[48];
|
||||
|
||||
21
firmware/2lib/include/2tpm_bootmode.h
Normal file
21
firmware/2lib/include/2tpm_bootmode.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/* Copyright 2015 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.
|
||||
*
|
||||
* Functions for updating the TPM state with the status of boot path.
|
||||
*/
|
||||
|
||||
#ifndef VBOOT_REFERENCE_2TPM_BOOTMODE_H_
|
||||
#define VBOOT_REFERENCE_2TPM_BOOTMODE_H_
|
||||
|
||||
#include "2api.h"
|
||||
|
||||
/**
|
||||
* Return digest indicating the boot state
|
||||
*
|
||||
* @param ctx Vboot context
|
||||
* @return Pointer to sha1 digest of size VB2_SHA1_DIGEST_SIZE
|
||||
*/
|
||||
const uint8_t *vb2_get_boot_state_digest(struct vb2_context *ctx);
|
||||
|
||||
#endif /* VBOOT_REFERENCE_2TPM_BOOTMODE_H_ */
|
||||
@@ -26,6 +26,12 @@ const char mock_body[320] = "Mock body";
|
||||
const int mock_body_size = sizeof(mock_body);
|
||||
const int mock_algorithm = VB2_ALG_RSA2048_SHA256;
|
||||
const int mock_hash_alg = VB2_HASH_SHA256;
|
||||
static const uint8_t mock_hwid_digest[VB2_GBB_HWID_DIGEST_SIZE] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
};
|
||||
|
||||
/* Mocked function data */
|
||||
|
||||
@@ -59,6 +65,9 @@ static void reset_common_data(enum reset_type t)
|
||||
retval_vb2_check_dev_switch = VB2_SUCCESS;
|
||||
retval_vb2_check_tpm_clear = VB2_SUCCESS;
|
||||
retval_vb2_select_fw_slot = VB2_SUCCESS;
|
||||
|
||||
memcpy(sd->gbb_hwid_digest, mock_hwid_digest,
|
||||
sizeof(sd->gbb_hwid_digest));
|
||||
};
|
||||
|
||||
/* Mocked functions */
|
||||
@@ -166,11 +175,52 @@ static void phase2_tests(void)
|
||||
VB2_RECOVERY_FW_SLOT, " recovery reason");
|
||||
}
|
||||
|
||||
static void get_pcr_digest_tests(void)
|
||||
{
|
||||
uint8_t digest[VB2_PCR_DIGEST_RECOMMENDED_SIZE];
|
||||
uint8_t digest_org[VB2_PCR_DIGEST_RECOMMENDED_SIZE];
|
||||
uint32_t digest_size;
|
||||
|
||||
reset_common_data(FOR_MISC);
|
||||
memset(digest_org, 0, sizeof(digest_org));
|
||||
|
||||
digest_size = sizeof(digest);
|
||||
memset(digest, 0, sizeof(digest));
|
||||
TEST_SUCC(vb2api_get_pcr_digest(
|
||||
&cc, BOOT_MODE_PCR, digest, &digest_size),
|
||||
"BOOT_MODE_PCR");
|
||||
TEST_EQ(digest_size, VB2_SHA1_DIGEST_SIZE, "BOOT_MODE_PCR digest size");
|
||||
TEST_TRUE(memcmp(digest, digest_org, digest_size),
|
||||
"BOOT_MODE_PCR digest");
|
||||
|
||||
digest_size = sizeof(digest);
|
||||
memset(digest, 0, sizeof(digest));
|
||||
TEST_SUCC(vb2api_get_pcr_digest(
|
||||
&cc, HWID_DIGEST_PCR, digest, &digest_size),
|
||||
"HWID_DIGEST_PCR");
|
||||
TEST_EQ(digest_size, VB2_GBB_HWID_DIGEST_SIZE,
|
||||
"HWID_DIGEST_PCR digest size");
|
||||
TEST_FALSE(memcmp(digest, mock_hwid_digest, digest_size),
|
||||
"HWID_DIGEST_PCR digest");
|
||||
|
||||
digest_size = 1;
|
||||
TEST_EQ(vb2api_get_pcr_digest(&cc, BOOT_MODE_PCR, digest, &digest_size),
|
||||
VB2_ERROR_API_PCR_DIGEST_BUF,
|
||||
"BOOT_MODE_PCR buffer too small");
|
||||
|
||||
TEST_EQ(vb2api_get_pcr_digest(
|
||||
&cc, HWID_DIGEST_PCR + 1, digest, &digest_size),
|
||||
VB2_ERROR_API_PCR_DIGEST,
|
||||
"invalid enum vb2_pcr_digest");
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
misc_tests();
|
||||
phase1_tests();
|
||||
phase2_tests();
|
||||
|
||||
get_pcr_digest_tests();
|
||||
|
||||
return gTestSuccess ? 0 : 255;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user