Skip to content

Commit 1852ace

Browse files
loic.sikidiJuergenReppSIT
authored andcommitted
Support high range NV indexes in getekcert
Signed-off-by: loic.sikidi <loic.sikidi@gmail.com>
1 parent 7644adc commit 1852ace

File tree

2 files changed

+128
-24
lines changed

2 files changed

+128
-24
lines changed

test/integration/tests/getekcertificate.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ diff test_ecc_ek.pem test_ek.pem
9494
# Retrieve EK certificates from NV indices
9595
RSA_EK_CERT_NV_INDEX=0x01C00002
9696
ECC_EK_CERT_NV_INDEX=0x01C0000A
97+
RSA_3072_EK_CERT_NV_INDEX=0x01C0001C
98+
ECC_NIST_P384_EK_CERT_NV_INDEX=0x01C00016
9799

98100
define_ek_cert_nv_index() {
99101
file_size=`ls -l $1 | awk {'print $5'}`
@@ -134,4 +136,40 @@ tpm2 getekcertificate -o nv_rsa_ek_cert.der -o nv_ecc_ek_cert.der
134136
diff nv_rsa_ek_cert.der rsa_ek_cert.der
135137
diff nv_ecc_ek_cert.der ecc_ek_cert.der
136138

139+
rm nv_rsa_ek_cert.der rsa_ek_cert.der nv_ecc_ek_cert.der ecc_ek_cert.der -f
140+
141+
## RSA & ECC self-signed EK certs stored in high range NV indexes
142+
tpm2 nvundefine -C p $RSA_EK_CERT_NV_INDEX
143+
tpm2 nvundefine -C p $ECC_EK_CERT_NV_INDEX
144+
145+
create_self_signed_ek_cert(){
146+
case "$1" in
147+
*rsa_3072)
148+
openssl genpkey -algorithm RSA -out priv_key.pem \
149+
-pkeyopt rsa_keygen_bits:3072 > /dev/null 2>&1
150+
openssl req -new -key priv_key.pem -x509 -days 1 \
151+
-subj "/" -outform DER -out $2
152+
;;
153+
*ecc_nist_p384)
154+
openssl ecparam -name secp384r1 -genkey -out priv_key.pem > /dev/null 2>&1
155+
openssl req -new -key priv_key.pem -x509 -days 1 \
156+
-subj "/" -outform DER -out $2
157+
;;
158+
*) echo "Unsupported key type $1"; return 1;;
159+
esac
160+
}
161+
162+
create_self_signed_ek_cert rsa_3072 rsa_ek_cert.der
163+
create_self_signed_ek_cert ecc_nist_p384 ecc_ek_cert.der
164+
165+
define_ek_cert_nv_index rsa_ek_cert.der $RSA_3072_EK_CERT_NV_INDEX
166+
define_ek_cert_nv_index ecc_ek_cert.der $ECC_NIST_P384_EK_CERT_NV_INDEX
167+
168+
tpm2 getekcertificate -o nv_rsa_ek_cert.der -o nv_ecc_ek_cert.der
169+
170+
diff nv_rsa_ek_cert.der rsa_ek_cert.der
171+
diff nv_ecc_ek_cert.der ecc_ek_cert.der
172+
173+
rm nv_rsa_ek_cert.der rsa_ek_cert.der nv_ecc_ek_cert.der ecc_ek_cert.der priv_key.pem -f
174+
137175
exit 0

tools/tpm2_getekcertificate.c

Lines changed: 90 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
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+
2430
typedef enum tpm_manufacturer tpm_manufacturer;
2531
enum 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-
105120
static 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+
113168
static 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

Comments
 (0)