2121#include "tpm2_tool.h"
2222
2323
24+ /*
25+ * Sourced from TCG Vendor ID Registry v1.06:
26+ * https://trustedcomputinggroup.org/resource/vendor-id-registry/
27+ *
28+ */
29+
2430typedef enum tpm_manufacturer tpm_manufacturer ;
2531enum tpm_manufacturer {
2632 VENDOR_AMD = 0x414D4400 ,
@@ -57,6 +63,25 @@ enum pubkey_enc_mode {
5763 ENC_AMD = 2 ,
5864};
5965
66+ /*
67+ * Sourced from TCG PC Client Platform TPM Profile Specification v1.05 rev 14:
68+ * https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/
69+ *
70+ */
71+
72+ typedef enum ek_nv_index ek_nv_index ;
73+ enum ek_nv_index {
74+ RSA_EK_CERT_NV_INDEX = 0x01C00002 ,
75+ ECC_EK_CERT_NV_INDEX = 0x01C0000A ,
76+ RSA_2048_EK_CERT_NV_INDEX = 0x01C00012 ,
77+ RSA_3072_EK_CERT_NV_INDEX = 0x01C0001C ,
78+ RSA_4096_EK_CERT_NV_INDEX = 0x01C0001E ,
79+ ECC_NIST_P256_EK_CERT_NV_INDEX = 0x01C00014 ,
80+ ECC_NIST_P384_EK_CERT_NV_INDEX = 0x01C00016 ,
81+ ECC_NIST_P521_EK_CERT_NV_INDEX = 0x01C00018 ,
82+ ECC_SM2_P256_EK_CERT_NV_INDEX = 0x01C0001A ,
83+ };
84+
6085#define EK_SERVER_INTEL "https://ekop.intel.com/ekcertservice/"
6186#define EK_SERVER_AMD "https://ftpm.amd.com/pki/aia/"
6287
@@ -68,6 +93,8 @@ struct tpm_getekcertificate_ctx {
6893 tpm_manufacturer manufacturer ;
6994 bool is_rsa_ek_cert_nv_location_defined ;
7095 bool is_ecc_ek_cert_nv_location_defined ;
96+ ek_nv_index rsa_ek_cert_nv_location ;
97+ ek_nv_index ecc_ek_cert_nv_location ;
7198 bool is_tpmgeneratedeps ;
7299 // Certficate data handling
73100 uint8_t cert_count ;
@@ -90,18 +117,6 @@ struct tpm_getekcertificate_ctx {
90117 TPM2B_PUBLIC * out_public ;
91118};
92119
93- /*
94- * Sourced from TCG Vendor ID Registry v1.06:
95- * https://trustedcomputinggroup.org/resource/vendor-id-registry/
96- *
97- */
98-
99- typedef enum ek_nv_index ek_nv_index ;
100- enum ek_nv_index {
101- RSA_EK_CERT_NV_INDEX = 0x01C00002 ,
102- ECC_EK_CERT_NV_INDEX = 0x01C0000A
103- };
104-
105120static tpm_getekcertificate_ctx ctx = {
106121 .is_tpm2_device_active = true,
107122 .is_cert_on_nv = true,
@@ -110,6 +125,46 @@ static tpm_getekcertificate_ctx ctx = {
110125};
111126
112127
128+ typedef enum key_type key_type ;
129+ enum key_type {
130+ KTYPE_RSA = 0 ,
131+ KTYPE_ECC = 1 ,
132+ };
133+
134+ typedef struct ek_index_map ek_index_map ;
135+ struct ek_index_map
136+ {
137+ const char * name ;
138+ key_type key_type ;
139+ ek_nv_index index ;
140+ TPMI_ALG_HASH hash_alg ;
141+ };
142+
143+ static ek_index_map ek_index_maps [] = {
144+ {"rsa" , KTYPE_RSA , RSA_EK_CERT_NV_INDEX , TPM2_ALG_SHA256 },
145+ {"rsa2048" , KTYPE_RSA , RSA_2048_EK_CERT_NV_INDEX , TPM2_ALG_SHA256 },
146+ {"rsa3072" , KTYPE_RSA , RSA_3072_EK_CERT_NV_INDEX , TPM2_ALG_SHA384 },
147+ {"rsa4096" , KTYPE_RSA , RSA_4096_EK_CERT_NV_INDEX , TPM2_ALG_SHA512 },
148+ {"ecc" , KTYPE_ECC , ECC_EK_CERT_NV_INDEX , TPM2_ALG_SHA256 },
149+ {"ecc_nist_p256" , KTYPE_ECC , ECC_NIST_P256_EK_CERT_NV_INDEX , TPM2_ALG_SHA256 },
150+ {"ecc_nist_p384" , KTYPE_ECC , ECC_NIST_P384_EK_CERT_NV_INDEX , TPM2_ALG_SHA384 },
151+ {"ecc_nist_p521" , KTYPE_ECC , ECC_NIST_P521_EK_CERT_NV_INDEX , TPM2_ALG_SHA512 },
152+ {"ecc_sm2_p256" , KTYPE_ECC , ECC_SM2_P256_EK_CERT_NV_INDEX , TPM2_ALG_SM3_256 },
153+ };
154+
155+ static const ek_index_map * lookup_ek_index_map (const TPMI_RH_NV_INDEX index ) {
156+ size_t i ;
157+
158+ for (i = 0 ; i < ARRAY_LEN (ek_index_maps ); i ++ )
159+ {
160+ if (index == ek_index_maps [i ].index ) {
161+ return & ek_index_maps [i ];
162+ }
163+ }
164+ return NULL ;
165+ }
166+
167+
113168static char * get_ek_server_address (void ) {
114169 if (ctx .ek_server_addr ) // set by CLI
115170 {
@@ -613,11 +668,20 @@ tool_rc get_tpm_properties(ESYS_CONTEXT *ectx) {
613668 UINT32 i ;
614669 for (i = 0 ; i < capability_data -> data .handles .count ; i ++ ) {
615670 TPMI_RH_NV_INDEX index = capability_data -> data .handles .handle [i ];
616- if (index == RSA_EK_CERT_NV_INDEX ) {
671+ const ek_index_map * m = lookup_ek_index_map (index );
672+ if (!m ) {
673+ continue ;
674+ }
675+
676+ if (m -> key_type == KTYPE_RSA ) {
677+ LOG_INFO ("Found pre-provisioned RSA EK certificate at %u [type=%s]" , index , m -> name );
617678 ctx .is_rsa_ek_cert_nv_location_defined = true;
679+ ctx .rsa_ek_cert_nv_location = m -> index ;
618680 }
619- if (index == ECC_EK_CERT_NV_INDEX ) {
681+ if (m -> key_type == KTYPE_ECC ) {
682+ LOG_INFO ("Found pre-provisioned ECC EK certificate at %u [type=%s]" , index , m -> name );
620683 ctx .is_ecc_ek_cert_nv_location_defined = true;
684+ ctx .ecc_ek_cert_nv_location = m -> index ;
621685 }
622686 }
623687
@@ -638,13 +702,15 @@ static tool_rc nv_read(ESYS_CONTEXT *ectx, TPMI_RH_NV_INDEX nv_index) {
638702 * with attributes:
639703 * ppwrite|ppread|ownerread|authread|no_da|written|platformcreate
640704 */
641- const bool is_rsa = nv_index == RSA_EK_CERT_NV_INDEX ;
642- char index_string [11 ];
643- if (is_rsa ) {
644- strcpy (index_string , "0x01C00002" );
645- } else {
646- strcpy (index_string , "0x01C0000A" );
705+ const ek_index_map * m = lookup_ek_index_map (nv_index );
706+ if (!m ) {
707+ LOG_ERR ("Unsupported NV INDEX, got \"%u\"" , nv_index );
708+ return tool_rc_unsupported ;
647709 }
710+
711+ const bool is_rsa = m -> key_type == KTYPE_RSA ;
712+ char index_string [11 ];
713+ snprintf (index_string , sizeof (index_string ), "%u" , m -> index );
648714 tpm2_loaded_object object ;
649715 tool_rc tmp_rc = tool_rc_success ;
650716 tool_rc rc = tpm2_util_object_load_auth (ectx , index_string , NULL , & object ,
@@ -658,11 +724,11 @@ static tool_rc nv_read(ESYS_CONTEXT *ectx, TPMI_RH_NV_INDEX nv_index) {
658724 uint16_t nv_buf_size = 0 ;
659725 rc = is_rsa ?
660726 tpm2_util_nv_read (ectx , nv_index , 0 , 0 , & object , & ctx .rsa_cert_buffer ,
661- & nv_buf_size , & cp_hash , & rp_hash , TPM2_ALG_SHA256 , 0 ,
727+ & nv_buf_size , & cp_hash , & rp_hash , m -> hash_alg , 0 ,
662728 ESYS_TR_NONE , ESYS_TR_NONE , NULL ) :
663729
664730 tpm2_util_nv_read (ectx , nv_index , 0 , 0 , & object , & ctx .ecc_cert_buffer ,
665- & nv_buf_size , & cp_hash , & rp_hash , TPM2_ALG_SHA256 , 0 ,
731+ & nv_buf_size , & cp_hash , & rp_hash , m -> hash_alg , 0 ,
666732 ESYS_TR_NONE , ESYS_TR_NONE , NULL );
667733 if (is_rsa ) {
668734 ctx .rsa_cert_buffer_size = nv_buf_size ;
@@ -707,14 +773,14 @@ static tool_rc get_nv_ek_certificate(ESYS_CONTEXT *ectx) {
707773
708774 tool_rc rc = tool_rc_success ;
709775 if (ctx .is_rsa_ek_cert_nv_location_defined ) {
710- rc = nv_read (ectx , RSA_EK_CERT_NV_INDEX );
776+ rc = nv_read (ectx , ctx . rsa_ek_cert_nv_location );
711777 if (rc != tool_rc_success ) {
712778 return rc ;
713779 }
714780 }
715781
716782 if (ctx .is_ecc_ek_cert_nv_location_defined ) {
717- rc = nv_read (ectx , ECC_EK_CERT_NV_INDEX );
783+ rc = nv_read (ectx , ctx . ecc_ek_cert_nv_location );
718784 }
719785
720786 return rc ;
0 commit comments