/* 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 "TPM_Types.h" #include "TpmBuildSwitches.h" #include "CryptoEngine.h" #include "CpriECC_fp.h" #include "CpriRSA_fp.h" #include "tpm_types.h" #include "Global.h" #include "Hierarchy_fp.h" #include "InternalRoutines.h" #include "Manufacture_fp.h" #include "NV_Write_fp.h" #include "NV_DefineSpace_fp.h" #include "console.h" #include "extension.h" #include "flash.h" #include "flash_config.h" #include "flash_info.h" #include "printf.h" #include "registers.h" #include "system.h" #include "tpm_manufacture.h" #include "tpm_registers.h" #include "dcrypto.h" #include #include #define CPRINTF(format, args...) cprintf(CC_EXTENSION, format, ## args) #define EK_CERT_NV_START_INDEX 0x01C00000 #define INFO1_EPS_SIZE PRIMARY_SEED_SIZE #define INFO1_EPS_OFFSET FLASH_INFO_MANUFACTURE_STATE_OFFSET #define RO_CERTS_START_ADDR 0x43800 #define RO_CERTS_REGION_SIZE 0x0800 enum cros_perso_component_type { CROS_PERSO_COMPONENT_TYPE_EPS = 128, CROS_PERSO_COMPONENT_TYPE_RSA_CERT = 129, CROS_PERSO_COMPONENT_TYPE_P256_CERT = 130 }; struct cros_perso_response_component_info_v0 { uint16_t component_size; uint8_t component_type; uint8_t reserved[5]; } __packed; /* Size: 8B */ /* key_id: key for which this is the certificate */ /* cert_len: length of the following certificate */ /* cert: the certificate bytes */ struct cros_perso_certificate_response_v0 { uint8_t key_id[4]; uint32_t cert_len; uint8_t cert[0]; } __packed; /* Size: 8B */ /* Personalization response. */ BUILD_ASSERT(sizeof(struct cros_perso_response_component_info_v0) == 8); BUILD_ASSERT(sizeof(struct cros_perso_certificate_response_v0) == 8); /* * Uncomment the #define below to enable fallback certificate installatin * capability. * #define CR50_INCLUDE_FALLBACK_CERT */ #ifdef CR50_INCLUDE_FALLBACK_CERT /* This is a fixed seed (and corresponding certificates) for use in a * developer environment. Use of this fixed seed will be triggered if * the HMAC on the certificate region (i.e. read-only certificates * written at manufacture) fails to verify. * * The HMAC verification failure itself only occurs in the event that * RO & RW are signed in a mode that does correspond to the * manufacture process, i.e. a PRODUCTION mode chip installed with DEV * signed RO/RW (or vice-versa) or a PRODUCTION signed RO and DEV * signed RW (or vice-versa). * * The fixed seed and its corresponding certificates are not trusted * by production infrastructure, and are hence useful for development * and testing. */ const uint8_t FIXED_ENDORSEMENT_SEED[PRIMARY_SEED_SIZE] = { 0x1c, 0xb0, 0xde, 0x0e, 0x96, 0xe5, 0x58, 0xb0, 0xad, 0x1d, 0x3a, 0x08, 0x22, 0x41, 0x7f, 0x45, 0x37, 0xe7, 0x17, 0x42, 0x5d, 0x87, 0xc4, 0x77, 0xf2, 0x97, 0xf8, 0xdd, 0xb9, 0xa0, 0xe5, 0x3a }; const uint8_t FIXED_RSA_ENDORSEMENT_CERT[1007] = { 0x30, 0x82, 0x03, 0xeb, 0x30, 0x82, 0x02, 0xd3, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x57, 0xd7, 0x5a, 0xbc, 0x74, 0xa8, 0x2e, 0x11, 0x9c, 0x73, 0x70, 0x2d, 0x3e, 0x15, 0xdf, 0x4e, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x80, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x1b, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x17, 0x43, 0x52, 0x4f, 0x53, 0x20, 0x54, 0x50, 0x4d, 0x20, 0x44, 0x45, 0x56, 0x20, 0x45, 0x4b, 0x20, 0x52, 0x4f, 0x4f, 0x54, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x30, 0x32, 0x30, 0x30, 0x30, 0x34, 0x39, 0x33, 0x36, 0x5a, 0x17, 0x0d, 0x32, 0x36, 0x31, 0x30, 0x31, 0x38, 0x30, 0x30, 0x34, 0x39, 0x33, 0x36, 0x5a, 0x30, 0x00, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xae, 0x3f, 0x7e, 0x66, 0x78, 0x26, 0x7a, 0x38, 0x93, 0xaf, 0x9c, 0xe4, 0x2c, 0x3c, 0x9e, 0x11, 0xb7, 0xae, 0x2f, 0x71, 0x8d, 0x4f, 0x2e, 0x3f, 0xd2, 0x35, 0x18, 0xb0, 0x27, 0x04, 0x4e, 0x04, 0x66, 0xb2, 0x16, 0xd4, 0xa8, 0xfc, 0x51, 0x60, 0x1b, 0x05, 0x1c, 0x02, 0xb5, 0x77, 0x1b, 0xf6, 0x40, 0xc4, 0x0e, 0x01, 0xbf, 0x70, 0xc1, 0x68, 0x53, 0x8b, 0x20, 0x4c, 0xa3, 0x39, 0x09, 0xd4, 0x4e, 0x28, 0x7c, 0x1d, 0xda, 0x57, 0x5c, 0x41, 0xae, 0x9b, 0xf3, 0xd5, 0xd3, 0x46, 0x12, 0x3d, 0x43, 0xcc, 0x39, 0x29, 0x79, 0x9d, 0xe5, 0x87, 0x84, 0x22, 0x85, 0x4b, 0x49, 0x35, 0x16, 0x4f, 0x3b, 0xdd, 0xd8, 0xaf, 0xe3, 0x99, 0xfa, 0x37, 0xaf, 0xbd, 0xa9, 0x38, 0xb4, 0x47, 0x58, 0x1e, 0x71, 0xb2, 0x46, 0xf2, 0x14, 0x85, 0x43, 0x12, 0x55, 0x8b, 0xc3, 0x5b, 0x78, 0x86, 0xd0, 0x0b, 0x08, 0x87, 0x1d, 0xf7, 0x4c, 0x69, 0x47, 0x91, 0xd1, 0x16, 0x5c, 0x0e, 0xf7, 0x0d, 0xad, 0x4a, 0x2d, 0xd8, 0x74, 0xe2, 0x89, 0xe1, 0xaf, 0xd7, 0x54, 0xb6, 0xe0, 0x36, 0x76, 0x7b, 0xd4, 0x6d, 0x50, 0x64, 0x13, 0x5b, 0x86, 0xa8, 0xa7, 0xee, 0xed, 0xf9, 0x50, 0x4d, 0xac, 0x1d, 0x1f, 0x9c, 0x1b, 0x58, 0x19, 0xa5, 0x20, 0x19, 0x75, 0xb7, 0xcf, 0xf6, 0x37, 0x59, 0x2a, 0xc7, 0x5b, 0x14, 0x51, 0xe6, 0x64, 0x70, 0xcc, 0x0e, 0x90, 0x9f, 0xe8, 0xf3, 0xc5, 0x95, 0x41, 0x74, 0x24, 0xb4, 0x6d, 0x37, 0x4a, 0x90, 0x17, 0x0e, 0x11, 0xea, 0xde, 0x74, 0x0e, 0x05, 0x4d, 0x1f, 0x9c, 0x11, 0xea, 0x06, 0xbd, 0x90, 0x9a, 0x9f, 0x44, 0x55, 0x0f, 0x93, 0x82, 0x96, 0xfc, 0x29, 0xb7, 0x26, 0x5e, 0x01, 0x25, 0x55, 0x4b, 0x80, 0xda, 0xd6, 0x2d, 0xe0, 0xd9, 0x65, 0xcf, 0xcb, 0x7a, 0x2b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xdf, 0x30, 0x81, 0xdc, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x00, 0x20, 0x30, 0x51, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x01, 0x01, 0xff, 0x04, 0x47, 0x30, 0x45, 0xa4, 0x43, 0x30, 0x41, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x67, 0x81, 0x05, 0x02, 0x01, 0x0c, 0x0b, 0x69, 0x64, 0x3a, 0x34, 0x37, 0x34, 0x46, 0x34, 0x46, 0x34, 0x37, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x05, 0x67, 0x81, 0x05, 0x02, 0x02, 0x0c, 0x04, 0x48, 0x31, 0x42, 0x32, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x67, 0x81, 0x05, 0x02, 0x03, 0x0c, 0x0b, 0x69, 0x64, 0x3a, 0x30, 0x30, 0x31, 0x33, 0x30, 0x30, 0x33, 0x37, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0c, 0x30, 0x0a, 0x30, 0x08, 0x06, 0x06, 0x67, 0x81, 0x0c, 0x01, 0x02, 0x02, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xd5, 0xfd, 0x4b, 0xf1, 0xbe, 0x05, 0xfb, 0x13, 0x28, 0xe2, 0x5f, 0x39, 0xd3, 0x9d, 0x70, 0x4a, 0x48, 0x91, 0x6b, 0xb0, 0x30, 0x10, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x09, 0x30, 0x07, 0x06, 0x05, 0x67, 0x81, 0x05, 0x08, 0x01, 0x30, 0x21, 0x06, 0x03, 0x55, 0x1d, 0x09, 0x04, 0x1a, 0x30, 0x18, 0x30, 0x16, 0x06, 0x05, 0x67, 0x81, 0x05, 0x02, 0x10, 0x31, 0x0d, 0x30, 0x0b, 0x0c, 0x03, 0x32, 0x2e, 0x30, 0x02, 0x01, 0x00, 0x02, 0x01, 0x10, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4c, 0x65, 0x3f, 0x58, 0x73, 0xb6, 0x21, 0x72, 0xb3, 0x2c, 0xc3, 0x94, 0xf4, 0xb3, 0xe0, 0x74, 0xa3, 0x2e, 0x47, 0xa7, 0x63, 0x12, 0xa3, 0x0f, 0xc5, 0x18, 0x45, 0x06, 0xab, 0xa9, 0xba, 0x64, 0xf0, 0xeb, 0x18, 0x7c, 0xba, 0x57, 0x09, 0xd0, 0x11, 0x60, 0x6f, 0xbd, 0x52, 0x73, 0xab, 0x39, 0x81, 0x29, 0xab, 0x78, 0x84, 0xec, 0x00, 0xe3, 0x87, 0xec, 0xf1, 0x7d, 0x2e, 0x15, 0x3f, 0xad, 0x1b, 0x3a, 0x3f, 0x03, 0x53, 0x91, 0xee, 0x72, 0x7a, 0x87, 0x74, 0xa8, 0x09, 0x7d, 0x83, 0x37, 0x0d, 0x46, 0x22, 0x12, 0xf3, 0x79, 0x61, 0xaf, 0x80, 0xf3, 0xf4, 0x76, 0x7d, 0xbd, 0xb3, 0x1f, 0x87, 0xb8, 0x66, 0xc9, 0x24, 0x15, 0xe9, 0xc7, 0x5b, 0x19, 0xdf, 0x04, 0x0a, 0x47, 0xec, 0x88, 0x46, 0x7f, 0x20, 0x6c, 0x4b, 0x23, 0xdb, 0x65, 0x67, 0x54, 0xde, 0x3a, 0xc3, 0x64, 0xbb, 0x77, 0x4d, 0x6d, 0x4b, 0x1e, 0x43, 0x9a, 0x35, 0x20, 0x7e, 0x28, 0xce, 0x4e, 0xe5, 0xb7, 0x0b, 0xae, 0xd0, 0x26, 0xc0, 0xac, 0x2f, 0x79, 0x35, 0x71, 0xbd, 0x74, 0x68, 0x8d, 0x51, 0x6f, 0x84, 0x4d, 0xaa, 0xca, 0x0d, 0xf0, 0xa8, 0x41, 0x5c, 0xa9, 0x6e, 0x3b, 0x70, 0x15, 0x73, 0x8d, 0xf0, 0x70, 0xd3, 0xb3, 0x0e, 0xa7, 0x3a, 0x34, 0x12, 0xd2, 0x1e, 0xa4, 0x18, 0x4c, 0x31, 0xee, 0x26, 0x44, 0x24, 0xe0, 0xa5, 0xca, 0x56, 0x5d, 0x76, 0x9e, 0xf4, 0x9a, 0x6e, 0x2b, 0xd6, 0x4a, 0xe9, 0x47, 0xd9, 0x29, 0x94, 0x2d, 0x23, 0xf7, 0xbb, 0x13, 0x0c, 0x48, 0x73, 0x93, 0xe3, 0x49, 0xc7, 0xd8, 0xca, 0x5d, 0x63, 0xf5, 0x68, 0xb2, 0xe9, 0x1a, 0xe6, 0x87, 0x39, 0xf8, 0x12, 0xa7, 0x5c, 0xb2, 0x6e, 0x04, 0xd0, 0x73, 0x3a, 0x05, 0x77, 0xc0, 0x9f, 0x23, 0xa7, 0x1a, 0x71, 0x38, 0x55, 0x70 }; const uint8_t FIXED_ECC_ENDORSEMENT_CERT[804] = { 0x30, 0x82, 0x03, 0x20, 0x30, 0x82, 0x02, 0x08, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x67, 0x02, 0x3f, 0x35, 0xc3, 0x17, 0xad, 0xcf, 0x0a, 0x76, 0xed, 0x50, 0x17, 0xd8, 0x4e, 0x50, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x80, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x1b, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x17, 0x43, 0x52, 0x4f, 0x53, 0x20, 0x54, 0x50, 0x4d, 0x20, 0x44, 0x45, 0x56, 0x20, 0x45, 0x4b, 0x20, 0x52, 0x4f, 0x4f, 0x54, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x30, 0x32, 0x30, 0x30, 0x30, 0x34, 0x39, 0x33, 0x36, 0x5a, 0x17, 0x0d, 0x32, 0x36, 0x31, 0x30, 0x31, 0x38, 0x30, 0x30, 0x34, 0x39, 0x33, 0x36, 0x5a, 0x30, 0x00, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x6e, 0xcc, 0xf0, 0x96, 0x69, 0x9b, 0x3f, 0xea, 0x95, 0xb7, 0xd5, 0x00, 0x27, 0x20, 0x81, 0x8e, 0x57, 0x00, 0x6f, 0x67, 0x98, 0xce, 0x8e, 0xdf, 0xc7, 0xda, 0xae, 0xa8, 0xa3, 0xed, 0x3e, 0x7a, 0xb3, 0x27, 0xbf, 0x92, 0xee, 0xb2, 0xa2, 0x76, 0x81, 0xc1, 0x71, 0x4d, 0x8c, 0xa8, 0x9d, 0xfd, 0x8e, 0xd0, 0x29, 0xb5, 0x01, 0x20, 0xec, 0x78, 0xc0, 0x17, 0x8f, 0xf6, 0xf8, 0x67, 0x5f, 0xe8, 0xa3, 0x81, 0xdf, 0x30, 0x81, 0xdc, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x00, 0x20, 0x30, 0x51, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x01, 0x01, 0xff, 0x04, 0x47, 0x30, 0x45, 0xa4, 0x43, 0x30, 0x41, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x67, 0x81, 0x05, 0x02, 0x01, 0x0c, 0x0b, 0x69, 0x64, 0x3a, 0x34, 0x37, 0x34, 0x46, 0x34, 0x46, 0x34, 0x37, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x05, 0x67, 0x81, 0x05, 0x02, 0x02, 0x0c, 0x04, 0x48, 0x31, 0x42, 0x32, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x67, 0x81, 0x05, 0x02, 0x03, 0x0c, 0x0b, 0x69, 0x64, 0x3a, 0x30, 0x30, 0x31, 0x33, 0x30, 0x30, 0x33, 0x37, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0c, 0x30, 0x0a, 0x30, 0x08, 0x06, 0x06, 0x67, 0x81, 0x0c, 0x01, 0x02, 0x02, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xd5, 0xfd, 0x4b, 0xf1, 0xbe, 0x05, 0xfb, 0x13, 0x28, 0xe2, 0x5f, 0x39, 0xd3, 0x9d, 0x70, 0x4a, 0x48, 0x91, 0x6b, 0xb0, 0x30, 0x10, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x09, 0x30, 0x07, 0x06, 0x05, 0x67, 0x81, 0x05, 0x08, 0x01, 0x30, 0x21, 0x06, 0x03, 0x55, 0x1d, 0x09, 0x04, 0x1a, 0x30, 0x18, 0x30, 0x16, 0x06, 0x05, 0x67, 0x81, 0x05, 0x02, 0x10, 0x31, 0x0d, 0x30, 0x0b, 0x0c, 0x03, 0x32, 0x2e, 0x30, 0x02, 0x01, 0x00, 0x02, 0x01, 0x10, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x21, 0xab, 0x9e, 0x92, 0x4d, 0xb0, 0x50, 0x04, 0xeb, 0x2b, 0xb6, 0xcc, 0x87, 0x8c, 0xa8, 0x27, 0xe3, 0x5a, 0xbf, 0x03, 0x5d, 0xb1, 0x4d, 0x24, 0xda, 0xdf, 0x44, 0xdb, 0x4a, 0x37, 0x5c, 0x3e, 0x70, 0xf3, 0x35, 0x5d, 0x26, 0x2e, 0xaa, 0x85, 0xc6, 0xbe, 0x1c, 0x9d, 0x1e, 0x5f, 0xf6, 0x6c, 0xb8, 0x94, 0x41, 0x25, 0x20, 0x55, 0x28, 0x53, 0x55, 0x67, 0x9a, 0xb5, 0xfb, 0x6b, 0x57, 0x09, 0xf0, 0x5b, 0xe2, 0x66, 0xc5, 0xe8, 0xd1, 0x9e, 0xb8, 0xb7, 0xed, 0xd8, 0x41, 0xb5, 0xbd, 0x44, 0xd9, 0x53, 0xab, 0x2d, 0x17, 0x4c, 0x73, 0x05, 0x19, 0x2c, 0x9d, 0x18, 0x98, 0xd8, 0x55, 0xbe, 0xbd, 0xb6, 0xa5, 0xf6, 0x5f, 0x3d, 0x70, 0x98, 0xd6, 0xd0, 0xcf, 0x1c, 0x0d, 0xc6, 0x78, 0x6d, 0x2e, 0x9c, 0x44, 0xf6, 0x9e, 0x0a, 0x80, 0x12, 0xcd, 0x9b, 0x4b, 0x1f, 0xbc, 0xfe, 0xe7, 0x3f, 0x45, 0x81, 0x78, 0x43, 0x40, 0xf2, 0xb0, 0x6b, 0x2c, 0x23, 0xc8, 0xc8, 0x57, 0xc6, 0x33, 0x08, 0x3e, 0x17, 0x43, 0x16, 0xf0, 0x3f, 0xbf, 0x24, 0x54, 0xba, 0xe6, 0x85, 0x4c, 0xc8, 0x2e, 0x7f, 0x88, 0x41, 0x6c, 0x4e, 0x03, 0xa6, 0x35, 0x00, 0x4d, 0xdb, 0x65, 0x68, 0x78, 0x01, 0x40, 0xc6, 0xa0, 0x95, 0xd9, 0xe9, 0x27, 0xe1, 0x90, 0x20, 0xc8, 0xe6, 0xa7, 0x7c, 0x4d, 0x9c, 0x1c, 0x44, 0x47, 0xfe, 0x9e, 0xc9, 0x25, 0x7a, 0x07, 0xa9, 0x86, 0x60, 0x58, 0x18, 0x1c, 0x16, 0x18, 0x7e, 0x04, 0xd6, 0x5a, 0xb6, 0xcb, 0xb6, 0xa6, 0x0f, 0xd9, 0x42, 0xf3, 0x19, 0x8c, 0xbe, 0x26, 0x98, 0xdd, 0x07, 0x05, 0x76, 0xc0, 0xf9, 0xa4, 0xeb, 0x53, 0xff, 0x13, 0x27, 0x61, 0x87, 0x66, 0x99, 0x76, 0x9c, 0x5f, 0x03, 0x52, 0x95, 0x13, 0x6e, 0xb7, 0x33, 0x1f, 0x8d, 0xc6, 0x22, 0xd8, 0xe4 }; static int store_eps(const uint8_t eps[PRIMARY_SEED_SIZE]); static int store_cert(enum cros_perso_component_type component_type, const uint8_t *cert, size_t cert_len); static int install_fixed_certs(void) { if (!store_eps(FIXED_ENDORSEMENT_SEED)) return 0; if (!store_cert(CROS_PERSO_COMPONENT_TYPE_RSA_CERT, FIXED_RSA_ENDORSEMENT_CERT, sizeof(FIXED_RSA_ENDORSEMENT_CERT))) return 0; if (!store_cert(CROS_PERSO_COMPONENT_TYPE_P256_CERT, FIXED_ECC_ENDORSEMENT_CERT, sizeof(FIXED_ECC_ENDORSEMENT_CERT))) return 0; return 1; } #endif /* Test endorsement CA root. */ static const uint32_t TEST_ENDORSEMENT_CA_RSA_N[64] = { 0xfa3b34ed, 0x3c59ad05, 0x912d6623, 0x83302402, 0xd43b6755, 0x5777021a, 0xaf37e9a1, 0x45c0e8ad, 0x9728f946, 0x4391523d, 0xdf7a9164, 0x88f1a9ae, 0x036c557e, 0x5d9df43e, 0x3e65de68, 0xe172008a, 0x709dc81f, 0x27a75fe0, 0x3e77f89e, 0x4f400ecc, 0x51a17dae, 0x2ff9c652, 0xd1d83cdb, 0x20d26349, 0xbbad71dd, 0x30051b2b, 0x276b2459, 0x809bb8e1, 0xb8737049, 0xdbe94466, 0x8287072b, 0x070ef311, 0x6e2a26de, 0x29d69f11, 0x96463d95, 0xb4dc6950, 0x097d4dfe, 0x1b4a88cc, 0xbd6b50c8, 0x9f7a5b34, 0xda22c199, 0x9d1ac04b, 0x136af5e5, 0xb1a0e824, 0x4a065b34, 0x1f67fb46, 0xa1f91ab1, 0x27bb769f, 0xb704c992, 0xb669cbf4, 0x9299bb6c, 0xcb1b2208, 0x2dc0d9db, 0xe1513e13, 0xc7f24923, 0xa74c6bcc, 0xca1a9a69, 0x1b994244, 0x4f64b0d9, 0x78607fd6, 0x486fb315, 0xa1098c31, 0x5dc50dd6, 0xcdc10874 }; /* Production endorsement CA root. */ static const uint32_t PROD_ENDORSEMENT_CA_RSA_N[64] = { 0xeb6a07bf, 0x6cf8eca6, 0x4756e85e, 0x2fc3874c, 0xa4c23e87, 0xc364dffe, 0x2a2ddb95, 0x2f7f0e1e, 0xdb485bd8, 0xce8aa808, 0xe062001b, 0x187811c3, 0x0e400462, 0xb7097a01, 0xb988152b, 0xba9d058a, 0x814b6691, 0xc70a694f, 0x8108c7f0, 0x4c7a1f33, 0x5cfda48e, 0xef303dbc, 0x84f5a3ea, 0x14607435, 0xc72f1e60, 0x345d0b38, 0x0ac16927, 0xbdf903c7, 0x11b660ed, 0x21ebfe0e, 0x8c8b303c, 0xd6eff6cb, 0x76156bf7, 0x57735ce4, 0x8b7a87ed, 0x7a757188, 0xd4fb3eb0, 0xc67fa05d, 0x163f0cf5, 0x69d8abf3, 0xec105749, 0x1de78f37, 0xb885a62f, 0x81344a82, 0x390df2b7, 0x58a7c56a, 0xa938f471, 0x506ee7d4, 0x2ca0f2a3, 0x2aa5392c, 0x39052797, 0x199e837c, 0x0d367b81, 0xb7bbff6f, 0x0ea99f5f, 0xfbac0d2a, 0x7bbe018d, 0x265fc995, 0x34f73008, 0x5e2cd747, 0x42096e33, 0x0c15f816, 0xffa7f7d2, 0xbd6f0198 }; static const struct RSA TEST_ENDORSEMENT_CA_RSA_PUB = { .e = RSA_F4, .N = { .dmax = sizeof(TEST_ENDORSEMENT_CA_RSA_N) / sizeof(uint32_t), .d = (struct access_helper *) TEST_ENDORSEMENT_CA_RSA_N, }, .d = { .dmax = 0, .d = NULL, }, }; static const struct RSA PROD_ENDORSEMENT_CA_RSA_PUB = { .e = RSA_F4, .N = { .dmax = sizeof(PROD_ENDORSEMENT_CA_RSA_N) / sizeof(uint32_t), .d = (struct access_helper *) PROD_ENDORSEMENT_CA_RSA_N, }, .d = { .dmax = 0, .d = NULL, }, }; static int validate_cert( const struct cros_perso_response_component_info_v0 *cert_info, const struct cros_perso_certificate_response_v0 *cert, const uint8_t eps[PRIMARY_SEED_SIZE]) { if (cert_info->component_type != CROS_PERSO_COMPONENT_TYPE_RSA_CERT && cert_info->component_type != CROS_PERSO_COMPONENT_TYPE_P256_CERT) return 0; /* Invalid component type. */ /* TODO(ngm): verify key_id against HIK/FRK0. */ if (cert->cert_len > MAX_NV_BUFFER_SIZE) return 0; /* Verify certificate signature; accept either root CA. * Getting here implies that the previous mac check on the * endorsement seed passed, and that one of these two CA * certificates serve as roots for the installed endorsement * certificate. */ return DCRYPTO_x509_verify(cert->cert, cert->cert_len, &PROD_ENDORSEMENT_CA_RSA_PUB) || DCRYPTO_x509_verify(cert->cert, cert->cert_len, &TEST_ENDORSEMENT_CA_RSA_PUB); } static int store_cert(enum cros_perso_component_type component_type, const uint8_t *cert, size_t cert_len) { const uint32_t rsa_ek_nv_index = EK_CERT_NV_START_INDEX; const uint32_t ecc_ek_nv_index = EK_CERT_NV_START_INDEX + 1; uint32_t nv_index; NV_DefineSpace_In define_space; TPMA_NV space_attributes; NV_Write_In in; /* Clear up structures potentially uszed only partially. */ memset(&define_space, 0, sizeof(define_space)); memset(&space_attributes, 0, sizeof(space_attributes)); memset(&in, 0, sizeof(in)); /* Indicate that a system reset has occurred, and currently * running with Platform auth. */ HierarchyStartup(SU_RESET); if (component_type == CROS_PERSO_COMPONENT_TYPE_RSA_CERT) nv_index = rsa_ek_nv_index; else /* P256 certificate. */ nv_index = ecc_ek_nv_index; /* EK Credential attributes specified in the "TCG PC Client * Platform, TPM Profile (PTP) Specification" document. */ /* REQUIRED: Writeable under platform auth. */ space_attributes.TPMA_NV_PPWRITE = 1; /* OPTIONAL: Write-once; space must be deleted to be re-written. */ space_attributes.TPMA_NV_WRITEDEFINE = 1; /* REQUIRED: Space created with platform auth. */ space_attributes.TPMA_NV_PLATFORMCREATE = 1; /* REQUIRED: Readable under empty password? */ space_attributes.TPMA_NV_AUTHREAD = 1; /* REQUIRED: Disable dictionary attack protection. */ space_attributes.TPMA_NV_NO_DA = 1; define_space.authHandle = TPM_RH_PLATFORM; define_space.auth.t.size = 0; define_space.publicInfo.t.size = sizeof( define_space.publicInfo.t.nvPublic); define_space.publicInfo.t.nvPublic.nvIndex = nv_index; define_space.publicInfo.t.nvPublic.nameAlg = TPM_ALG_SHA256; define_space.publicInfo.t.nvPublic.attributes = space_attributes; define_space.publicInfo.t.nvPublic.authPolicy.t.size = 0; define_space.publicInfo.t.nvPublic.dataSize = cert_len; /* Define the required space first. */ if (TPM2_NV_DefineSpace(&define_space) != TPM_RC_SUCCESS) return 0; /* TODO(ngm): call TPM2_NV_WriteLock(nvIndex) on tpm_init(); * this prevents delete? */ in.nvIndex = nv_index; in.authHandle = TPM_RH_PLATFORM; in.data.t.size = cert_len; memcpy(in.data.t.buffer, cert, cert_len); in.offset = 0; if (TPM2_NV_Write(&in) != TPM_RC_SUCCESS) return 0; if (NvCommit()) return 1; return 0; } static void flash_cert_region_enable(void) { /* Enable R access to CERT block. */ GREG32(GLOBALSEC, FLASH_REGION6_BASE_ADDR) = RO_CERTS_START_ADDR; GREG32(GLOBALSEC, FLASH_REGION6_SIZE) = RO_CERTS_REGION_SIZE - 1; GREG32(GLOBALSEC, FLASH_REGION6_CTRL) = GC_GLOBALSEC_FLASH_REGION6_CTRL_EN_MASK | 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]) { int i; uint8_t frk2[AES256_BLOCK_CIPHER_KEY_SIZE]; CPRINTF("%s: getting eps\n", __func__); if (!DCRYPTO_ladder_compute_frk2(K_CROS_FW_MAJOR_VERSION, frk2)) return 0; for (i = 0; i < INFO1_EPS_SIZE; i += sizeof(uint32_t)) { uint32_t word; if (flash_physical_info_read_word( INFO1_EPS_OFFSET + i, &word) != EC_SUCCESS) { always_memset(frk2, 0, sizeof(frk2)); return 0; /* Flash read INFO1 failed. */ } memcpy(eps + i, &word, sizeof(word)); } /* One-time-pad decrypt EPS. */ for (i = 0; i < PRIMARY_SEED_SIZE; i++) eps[i] ^= frk2[i]; always_memset(frk2, 0, sizeof(frk2)); return 1; } static int store_eps(const uint8_t eps[PRIMARY_SEED_SIZE]) { /* gp is a TPM global state structure, declared in Global.h. */ memcpy(gp.EPSeed.t.buffer, eps, PRIMARY_SEED_SIZE); /* Persist the seed to flash. */ NvWriteReserved(NV_EP_SEED, &gp.EPSeed); return NvCommit(); } static void endorsement_complete(void) { CPRINTF("%s(): SUCCESS\n", __func__); } static int handle_cert( const struct cros_perso_response_component_info_v0 *cert_info, const struct cros_perso_certificate_response_v0 *cert, const uint8_t *eps) { /* Write RSA / P256 endorsement certificate. */ if (!validate_cert(cert_info, cert, eps)) return 0; /* TODO(ngm): verify that storage succeeded. */ if (!store_cert(cert_info->component_type, cert->cert, cert->cert_len)) { CPRINTF("%s(): cert storage failed, type: %d\n", __func__, cert_info->component_type); return 0; /* Internal failure. */ } return 1; } enum manufacturing_status tpm_endorse(void) { struct ro_cert_response { uint8_t key_id[4]; uint32_t cert_len; uint8_t cert[0]; } __packed; struct ro_cert { const struct cros_perso_response_component_info_v0 cert_info; const struct ro_cert_response cert_response; } __packed; /* 2-kB RO cert region is setup like so: * * | struct ro_cert | rsa_cert | struct ro_cert | ecc_cert | * * last 32 bytes is hmac over (2048 - 32) preceding bytes. * using hmac(eps, "RSA", 4) as key */ const uint8_t *p = (const uint8_t *) RO_CERTS_START_ADDR; const uint32_t *c = (const uint32_t *) RO_CERTS_START_ADDR; const struct ro_cert *rsa_cert; const struct ro_cert *ecc_cert; enum manufacturing_status result; uint8_t eps[PRIMARY_SEED_SIZE]; struct hmac_sha256_ctx hmac; flash_cert_region_enable(); /* First boot, certs not yet installed. */ if (*c == 0xFFFFFFFF) return mnf_no_certs; if (!get_decrypted_eps(eps)) { CPRINTF("%s(): failed to read eps\n", __func__); return mnf_eps_decr; } /* Unpack rsa cert struct. */ rsa_cert = (const struct ro_cert *) p; /* Sanity check cert region contents. */ if ((2 * sizeof(struct ro_cert)) + rsa_cert->cert_response.cert_len > RO_CERTS_REGION_SIZE) return mnf_bad_rsa_size; /* Unpack ecc cert struct. */ ecc_cert = (const struct ro_cert *) (p + sizeof(struct ro_cert) + rsa_cert->cert_response.cert_len); /* Sanity check cert region contents. */ if ((2 * sizeof(struct ro_cert)) + rsa_cert->cert_response.cert_len + ecc_cert->cert_response.cert_len > RO_CERTS_REGION_SIZE) return mnf_bad_total_size; /* Verify expected component types. */ if (rsa_cert->cert_info.component_type != CROS_PERSO_COMPONENT_TYPE_RSA_CERT) { return mnf_bad_rsa_type; } if (ecc_cert->cert_info.component_type != CROS_PERSO_COMPONENT_TYPE_P256_CERT) { return mnf_bad_ecc_type; } do { /* Check cert region hmac. * * This will fail if we are not running w/ expected keyladder. */ HMAC_SHA256_hw_init(&hmac, eps, sizeof(eps)); HMAC_SHA256_update(&hmac, "RSA", 4); HMAC_SHA256_hw_init(&hmac, HMAC_SHA256_hw_final(&hmac), 32); HMAC_SHA256_update(&hmac, p, RO_CERTS_REGION_SIZE - 32); if (!DCRYPTO_equals(p + RO_CERTS_REGION_SIZE - 32, HMAC_SHA256_hw_final(&hmac), 32)) { CPRINTF("%s: bad cert region hmac;", __func__); #ifdef CR50_INCLUDE_FALLBACK_CERT /* HMAC verification failure indicates either * a manufacture fault, or mis-match in * production mode and currently running * firmware (e.g. PRODUCTION mode chip, now * flashed with DEV mode firmware. * * In either case, fall back to a fixed * endorsement seed, which will not be trusted * by production infrastructure. */ if (!install_fixed_certs()) { CPRINTF(" failed to install fixed " "endorsement certs;"); result = mnf_hmac_mismatch; break; } #else if (board_in_prod_mode()) { /* TODO(ngm): is this state considered * endorsement failure? */ CPRINTF("NO certs installed\n"); result = mnf_hmac_mismatch; break; } /* * This will install bogus certificate, will happen * only when Cr50 image is signed with dev key. * * Installing bogus certificate helps with simple TPM * operations, as it allows to prevent TPM going * through manufacturing process after every reset, * but the generated RSA endorsement will not * correspond to the certificate, which will cause * problems when TPM identity is required. */ result = mnf_unverified_cert; CPRINTF("instaling UNVERIFIED certs\n"); #endif } if (!handle_cert( &rsa_cert->cert_info, (struct cros_perso_certificate_response_v0 *) &rsa_cert->cert_response, eps)) { CPRINTF("%s: Failed to process RSA cert\n", __func__); result = mnf_rsa_proc; break; } CPRINTF("%s: RSA cert install success\n", __func__); if (!handle_cert( &ecc_cert->cert_info, (struct cros_perso_certificate_response_v0 *) &ecc_cert->cert_response, eps)) { CPRINTF("%s: Failed to process ECC cert\n", __func__); result = mnf_ecc_proc; break; } CPRINTF("%s: ECC cert install success\n", __func__); /* Copy EPS from INFO1 to flash data region. */ if (!store_eps(eps)) { CPRINTF("%s(): eps storage failed\n", __func__); result = mnf_store; break; } /* Mark as endorsed. */ endorsement_complete(); /* Chip has been marked as manufactured. */ result = mnf_success; } while (0); always_memset(eps, 0, sizeof(eps)); return result; }