mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-10 17:41:54 +00:00
g: move compute_frk2 function into dcrypto
This function belongs in dcrypto as it relies heavily on the crypto hardware; also, it will be handy to be able to use this function in other cases. BRANCH=none BUG=chrome-os-partner:55331 TEST=buildall still builds. TPM manufacturing still works too. Change-Id: If2e70eaa71a76e8374b98f4667cb54ea6253b760 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/428169 Reviewed-by: Marius Schilder <mschilder@chromium.org>
This commit is contained in:
committed by
chrome-bot
parent
755a1d02fe
commit
48e8e3faf0
@@ -39,7 +39,6 @@
|
||||
#define EK_CERT_NV_START_INDEX 0x01C00000
|
||||
#define INFO1_EPS_SIZE PRIMARY_SEED_SIZE
|
||||
#define INFO1_EPS_OFFSET FLASH_INFO_MANUFACTURE_STATE_OFFSET
|
||||
#define AES256_BLOCK_CIPHER_KEY_SIZE 32
|
||||
|
||||
#define RO_CERTS_START_ADDR 0x43800
|
||||
#define RO_CERTS_REGION_SIZE 0x0800
|
||||
@@ -408,93 +407,6 @@ static int store_cert(enum cros_perso_component_type component_type,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t hw_key_ladder_step(uint32_t cert)
|
||||
{
|
||||
uint32_t itop;
|
||||
|
||||
GREG32(KEYMGR, SHA_ITOP) = 0; /* clear status */
|
||||
|
||||
GREG32(KEYMGR, SHA_USE_CERT_INDEX) =
|
||||
(cert << GC_KEYMGR_SHA_USE_CERT_INDEX_LSB) |
|
||||
GC_KEYMGR_SHA_USE_CERT_ENABLE_MASK;
|
||||
|
||||
GREG32(KEYMGR, SHA_CFG_EN) =
|
||||
GC_KEYMGR_SHA_CFG_EN_INT_EN_DONE_MASK;
|
||||
GREG32(KEYMGR, SHA_TRIG) =
|
||||
GC_KEYMGR_SHA_TRIG_TRIG_GO_MASK;
|
||||
|
||||
do {
|
||||
itop = GREG32(KEYMGR, SHA_ITOP);
|
||||
} while (!itop);
|
||||
|
||||
GREG32(KEYMGR, SHA_ITOP) = 0; /* clear status */
|
||||
|
||||
return !!GREG32(KEYMGR, HKEY_ERR_FLAGS);
|
||||
}
|
||||
|
||||
|
||||
#define KEYMGR_CERT_0 0
|
||||
#define KEYMGR_CERT_3 3
|
||||
#define KEYMGR_CERT_4 4
|
||||
#define KEYMGR_CERT_5 5
|
||||
#define KEYMGR_CERT_7 7
|
||||
#define KEYMGR_CERT_15 15
|
||||
#define KEYMGR_CERT_20 20
|
||||
#define KEYMGR_CERT_25 25
|
||||
#define KEYMGR_CERT_26 26
|
||||
|
||||
#define K_CROS_FW_MAJOR_VERSION 0
|
||||
static const uint8_t k_cr50_max_fw_major_version = 254;
|
||||
|
||||
static int compute_frk2(uint8_t frk2[AES256_BLOCK_CIPHER_KEY_SIZE])
|
||||
{
|
||||
int i;
|
||||
|
||||
/* TODO(ngm): reading ITOP in hw_key_ladder_step hangs on
|
||||
* second run of this function (i.e. install of ECC cert,
|
||||
* which re-generates FRK2) unless the SHA engine is reset.
|
||||
*/
|
||||
GREG32(KEYMGR, SHA_TRIG) =
|
||||
GC_KEYMGR_SHA_TRIG_TRIG_RESET_MASK;
|
||||
|
||||
if (hw_key_ladder_step(KEYMGR_CERT_0))
|
||||
return 0;
|
||||
|
||||
/* Derive HC_PHIK --> Deposited into ISR0 */
|
||||
if (hw_key_ladder_step(KEYMGR_CERT_3))
|
||||
return 0;
|
||||
|
||||
/* Cryptographically mix OBS-FBS --> Deposited into ISR1 */
|
||||
if (hw_key_ladder_step(KEYMGR_CERT_4))
|
||||
return 0;
|
||||
|
||||
/* Derive HIK_RT --> Deposited into ISR0 */
|
||||
if (hw_key_ladder_step(KEYMGR_CERT_5))
|
||||
return 0;
|
||||
|
||||
/* Derive BL_HIK --> Deposited into ISR0 */
|
||||
if (hw_key_ladder_step(KEYMGR_CERT_7))
|
||||
return 0;
|
||||
|
||||
/* Generate FRK2 by executing certs 15, 20, 25, and 26 */
|
||||
if (hw_key_ladder_step(KEYMGR_CERT_15))
|
||||
return 0;
|
||||
|
||||
if (hw_key_ladder_step(KEYMGR_CERT_20))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < k_cr50_max_fw_major_version -
|
||||
K_CROS_FW_MAJOR_VERSION; i++) {
|
||||
if (hw_key_ladder_step(KEYMGR_CERT_25))
|
||||
return 0;
|
||||
}
|
||||
if (hw_key_ladder_step(KEYMGR_CERT_26))
|
||||
return 0;
|
||||
memcpy(frk2, (void *) GREG32_ADDR(KEYMGR, HKEY_FRR0),
|
||||
AES256_BLOCK_CIPHER_KEY_SIZE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void flash_info_read_enable(void)
|
||||
{
|
||||
/* Enable R access to INFO. */
|
||||
@@ -523,6 +435,8 @@ static void flash_cert_region_enable(void)
|
||||
GC_GLOBALSEC_FLASH_REGION6_CTRL_RD_EN_MASK;
|
||||
}
|
||||
|
||||
#define K_CROS_FW_MAJOR_VERSION 0
|
||||
|
||||
/* EPS is stored XOR'd with FRK2, so make sure that the sizes match. */
|
||||
BUILD_ASSERT(AES256_BLOCK_CIPHER_KEY_SIZE == PRIMARY_SEED_SIZE);
|
||||
static int get_decrypted_eps(uint8_t eps[PRIMARY_SEED_SIZE])
|
||||
@@ -531,7 +445,7 @@ static int get_decrypted_eps(uint8_t eps[PRIMARY_SEED_SIZE])
|
||||
uint8_t frk2[AES256_BLOCK_CIPHER_KEY_SIZE];
|
||||
|
||||
CPRINTF("%s: getting eps\n", __func__);
|
||||
if (!compute_frk2(frk2))
|
||||
if (!DCRYPTO_ladder_compute_frk2(K_CROS_FW_MAJOR_VERSION, frk2))
|
||||
return 0;
|
||||
|
||||
/* Setup flash region mapping. */
|
||||
|
||||
@@ -35,6 +35,7 @@ chip-$(CONFIG_DCRYPTO)+= dcrypto/compare.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/dcrypto_runtime.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/hkdf.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/hmac.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/key_ladder.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/p256.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/p256_ec.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/p256_ecies.o
|
||||
|
||||
@@ -42,6 +42,8 @@ enum hashing_mode {
|
||||
/*
|
||||
* AES implementation, based on a hardware AES block.
|
||||
*/
|
||||
#define AES256_BLOCK_CIPHER_KEY_SIZE 32
|
||||
|
||||
int DCRYPTO_aes_init(const uint8_t *key, uint32_t key_len, const uint8_t *iv,
|
||||
enum cipher_mode c_mode, enum encrypt_mode e_mode);
|
||||
int DCRYPTO_aes_block(const uint8_t *in, uint8_t *out);
|
||||
@@ -199,4 +201,9 @@ int DCRYPTO_x509_verify(const uint8_t *cert, size_t len,
|
||||
*/
|
||||
int DCRYPTO_equals(const void *a, const void *b, size_t len);
|
||||
|
||||
/*
|
||||
* Key ladder related functions.
|
||||
*/
|
||||
int DCRYPTO_ladder_compute_frk2(size_t major_fw_version, uint8_t *frk2);
|
||||
|
||||
#endif /* ! __EC_CHIP_G_DCRYPTO_DCRYPTO_H */
|
||||
|
||||
110
chip/g/dcrypto/key_ladder.c
Normal file
110
chip/g/dcrypto/key_ladder.c
Normal file
@@ -0,0 +1,110 @@
|
||||
/* 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 "dcrypto.h"
|
||||
#include "internal.h"
|
||||
#include "endian.h"
|
||||
#include "registers.h"
|
||||
|
||||
void DCRYPTO_ladder_init(void)
|
||||
{
|
||||
/* Do not reset keyladder engine here, as before.
|
||||
*
|
||||
* Should not be needed and if it is, it is indicative
|
||||
* of sync error between this and sha engine usage.
|
||||
* Reset will make this flow work, but will have broken
|
||||
* the other pending sha flow.
|
||||
* Hence leave as is and observe the error.
|
||||
*
|
||||
* TODO: hw sha engine usage and keyladder usage cannot
|
||||
* interleave and should share a semaphore.
|
||||
*/
|
||||
}
|
||||
|
||||
int DCRYPTO_ladder_step(uint32_t cert)
|
||||
{
|
||||
uint32_t itop;
|
||||
|
||||
GREG32(KEYMGR, SHA_ITOP) = 0; /* clear status */
|
||||
|
||||
GREG32(KEYMGR, SHA_USE_CERT_INDEX) =
|
||||
(cert << GC_KEYMGR_SHA_USE_CERT_INDEX_LSB) |
|
||||
GC_KEYMGR_SHA_USE_CERT_ENABLE_MASK;
|
||||
|
||||
GREG32(KEYMGR, SHA_CFG_EN) =
|
||||
GC_KEYMGR_SHA_CFG_EN_INT_EN_DONE_MASK;
|
||||
GREG32(KEYMGR, SHA_TRIG) =
|
||||
GC_KEYMGR_SHA_TRIG_TRIG_GO_MASK;
|
||||
|
||||
do {
|
||||
itop = GREG32(KEYMGR, SHA_ITOP);
|
||||
} while (!itop);
|
||||
|
||||
GREG32(KEYMGR, SHA_ITOP) = 0; /* clear status */
|
||||
|
||||
return !!GREG32(KEYMGR, HKEY_ERR_FLAGS);
|
||||
}
|
||||
|
||||
static int compute_certs(const uint32_t *certs, size_t num_certs)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_certs; i++) {
|
||||
if (DCRYPTO_ladder_step(certs[i]))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define KEYMGR_CERT_0 0
|
||||
#define KEYMGR_CERT_3 3
|
||||
#define KEYMGR_CERT_4 4
|
||||
#define KEYMGR_CERT_5 5
|
||||
#define KEYMGR_CERT_7 7
|
||||
#define KEYMGR_CERT_15 15
|
||||
#define KEYMGR_CERT_20 20
|
||||
#define KEYMGR_CERT_25 25
|
||||
#define KEYMGR_CERT_26 26
|
||||
|
||||
static const uint32_t FRK2_CERTS_PREFIX[] = {
|
||||
KEYMGR_CERT_0,
|
||||
KEYMGR_CERT_3,
|
||||
KEYMGR_CERT_4,
|
||||
KEYMGR_CERT_5,
|
||||
KEYMGR_CERT_7,
|
||||
KEYMGR_CERT_15,
|
||||
KEYMGR_CERT_20,
|
||||
};
|
||||
|
||||
static const uint32_t FRK2_CERTS_POSTFIX[] = {
|
||||
KEYMGR_CERT_26,
|
||||
};
|
||||
|
||||
#define MAX_MAJOR_FW_VERSION 254
|
||||
|
||||
int DCRYPTO_ladder_compute_frk2(size_t fw_version, uint8_t *frk2)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (fw_version > MAX_MAJOR_FW_VERSION)
|
||||
return 0;
|
||||
|
||||
DCRYPTO_ladder_init();
|
||||
|
||||
if (!compute_certs(FRK2_CERTS_PREFIX, ARRAY_SIZE(FRK2_CERTS_PREFIX)))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < MAX_MAJOR_FW_VERSION - fw_version; i++) {
|
||||
if (DCRYPTO_ladder_step(KEYMGR_CERT_25))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!compute_certs(FRK2_CERTS_POSTFIX, ARRAY_SIZE(FRK2_CERTS_POSTFIX)))
|
||||
return 0;
|
||||
|
||||
memcpy(frk2, (void *) GREG32_ADDR(KEYMGR, HKEY_FRR0),
|
||||
AES256_BLOCK_CIPHER_KEY_SIZE);
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user