Skip to content

Commit

Permalink
Support high range NV indexes in getekcert
Browse files Browse the repository at this point in the history
Signed-off-by: loic.sikidi <[email protected]>
  • Loading branch information
loic.sikidi authored and loicsikidi committed Dec 9, 2024
1 parent 0a401f4 commit ad1da5a
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 24 deletions.
38 changes: 38 additions & 0 deletions test/integration/tests/getekcertificate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ diff test_ecc_ek.pem test_ek.pem
# Retrieve EK certificates from NV indices
RSA_EK_CERT_NV_INDEX=0x01C00002
ECC_EK_CERT_NV_INDEX=0x01C0000A
RSA_3072_EK_CERT_NV_INDEX=0x01C0001C
ECC_NIST_P384_EK_CERT_NV_INDEX=0x01C00016

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

rm nv_rsa_ek_cert.der rsa_ek_cert.der nv_ecc_ek_cert.der ecc_ek_cert.der -f

## RSA & ECC self-signed EK certs stored in high range NV indexes
tpm2 nvundefine -C p $RSA_EK_CERT_NV_INDEX
tpm2 nvundefine -C p $ECC_EK_CERT_NV_INDEX

create_self_signed_ek_cert(){
case "$1" in
*rsa_3072)
openssl genpkey -algorithm RSA -out priv_key.pem \
-pkeyopt rsa_keygen_bits:3072 > /dev/null 2>&1
openssl req -new -key priv_key.pem -x509 -days 1 \
-subj "/" -outform DER -out $2
;;
*ecc_nist_p384)
openssl ecparam -name secp384r1 -genkey -out priv_key.pem > /dev/null 2>&1
openssl req -new -key priv_key.pem -x509 -days 1 \
-subj "/" -outform DER -out $2
;;
*) echo "Unsupported key type $1"; return 1;;
esac
}

create_self_signed_ek_cert rsa_3072 rsa_ek_cert.der
create_self_signed_ek_cert ecc_nist_p384 ecc_ek_cert.der

define_ek_cert_nv_index rsa_ek_cert.der $RSA_3072_EK_CERT_NV_INDEX
define_ek_cert_nv_index ecc_ek_cert.der $ECC_NIST_P384_EK_CERT_NV_INDEX

tpm2 getekcertificate -o nv_rsa_ek_cert.der -o nv_ecc_ek_cert.der

diff nv_rsa_ek_cert.der rsa_ek_cert.der
diff nv_ecc_ek_cert.der ecc_ek_cert.der

rm nv_rsa_ek_cert.der rsa_ek_cert.der nv_ecc_ek_cert.der ecc_ek_cert.der priv_key.pem -f

exit 0
114 changes: 90 additions & 24 deletions tools/tpm2_getekcertificate.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
#include "tpm2_tool.h"


/*
* Sourced from TCG Vendor ID Registry v1.06:
* https://trustedcomputinggroup.org/resource/vendor-id-registry/
*
*/

typedef enum tpm_manufacturer tpm_manufacturer;
enum tpm_manufacturer {
VENDOR_AMD = 0x414D4400,
Expand Down Expand Up @@ -57,6 +63,25 @@ enum pubkey_enc_mode {
ENC_AMD = 2,
};

/*
* Sourced from TCG PC Client Platform TPM Profile Specification v1.05 rev 14:
* https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/
*
*/

typedef enum ek_nv_index ek_nv_index;
enum ek_nv_index {
RSA_EK_CERT_NV_INDEX = 0x01C00002,
ECC_EK_CERT_NV_INDEX = 0x01C0000A,
RSA_2048_EK_CERT_NV_INDEX = 0x01C00012,
RSA_3072_EK_CERT_NV_INDEX = 0x01C0001C,
RSA_4096_EK_CERT_NV_INDEX = 0x01C0001E,
ECC_NIST_P256_EK_CERT_NV_INDEX = 0x01C00014,
ECC_NIST_P384_EK_CERT_NV_INDEX = 0x01C00016,
ECC_NIST_P521_EK_CERT_NV_INDEX = 0x01C00018,
ECC_SM2_P256_EK_CERT_NV_INDEX = 0x01C0001A,
};

#define EK_SERVER_INTEL "https://ekop.intel.com/ekcertservice/"
#define EK_SERVER_AMD "https://ftpm.amd.com/pki/aia/"

Expand All @@ -68,6 +93,8 @@ struct tpm_getekcertificate_ctx {
tpm_manufacturer manufacturer;
bool is_rsa_ek_cert_nv_location_defined;
bool is_ecc_ek_cert_nv_location_defined;
ek_nv_index rsa_ek_cert_nv_location;
ek_nv_index ecc_ek_cert_nv_location;
bool is_tpmgeneratedeps;
// Certficate data handling
uint8_t cert_count;
Expand All @@ -90,18 +117,6 @@ struct tpm_getekcertificate_ctx {
TPM2B_PUBLIC *out_public;
};

/*
* Sourced from TCG Vendor ID Registry v1.06:
* https://trustedcomputinggroup.org/resource/vendor-id-registry/
*
*/

typedef enum ek_nv_index ek_nv_index;
enum ek_nv_index {
RSA_EK_CERT_NV_INDEX = 0x01C00002,
ECC_EK_CERT_NV_INDEX = 0x01C0000A
};

static tpm_getekcertificate_ctx ctx = {
.is_tpm2_device_active = true,
.is_cert_on_nv = true,
Expand All @@ -110,6 +125,46 @@ static tpm_getekcertificate_ctx ctx = {
};


typedef enum key_type key_type;
enum key_type {
KTYPE_RSA = 0,
KTYPE_ECC = 1,
};

typedef struct ek_index_map ek_index_map;
struct ek_index_map
{
const char *name;
key_type key_type;
ek_nv_index index;
TPMI_ALG_HASH hash_alg;
};

static ek_index_map ek_index_maps[] = {
{"rsa", KTYPE_RSA, RSA_EK_CERT_NV_INDEX, TPM2_ALG_SHA256},
{"rsa2048", KTYPE_RSA, RSA_2048_EK_CERT_NV_INDEX, TPM2_ALG_SHA256},
{"rsa3072", KTYPE_RSA, RSA_3072_EK_CERT_NV_INDEX, TPM2_ALG_SHA384},
{"rsa4096", KTYPE_RSA, RSA_4096_EK_CERT_NV_INDEX, TPM2_ALG_SHA512},
{"ecc", KTYPE_ECC, ECC_EK_CERT_NV_INDEX, TPM2_ALG_SHA256},
{"ecc_nist_p256", KTYPE_ECC, ECC_NIST_P256_EK_CERT_NV_INDEX, TPM2_ALG_SHA256},
{"ecc_nist_p384", KTYPE_ECC, ECC_NIST_P384_EK_CERT_NV_INDEX, TPM2_ALG_SHA384},
{"ecc_nist_p521", KTYPE_ECC, ECC_NIST_P521_EK_CERT_NV_INDEX, TPM2_ALG_SHA512},
{"ecc_sm2_p256", KTYPE_ECC, ECC_SM2_P256_EK_CERT_NV_INDEX, TPM2_ALG_SM3_256},
};

static const ek_index_map *lookup_ek_index_map(const TPMI_RH_NV_INDEX index) {
size_t i;

for (i = 0; i < ARRAY_LEN(ek_index_maps); i++)
{
if (index == ek_index_maps[i].index) {
return &ek_index_maps[i];
}
}
return NULL;
}


static char *get_ek_server_address(void) {
if (ctx.ek_server_addr) // set by CLI
{
Expand Down Expand Up @@ -613,11 +668,20 @@ tool_rc get_tpm_properties(ESYS_CONTEXT *ectx) {
UINT32 i;
for (i = 0; i < capability_data->data.handles.count; i++) {
TPMI_RH_NV_INDEX index = capability_data->data.handles.handle[i];
if (index == RSA_EK_CERT_NV_INDEX) {
const ek_index_map *m = lookup_ek_index_map(index);
if (!m) {
continue;
}

if (m->key_type == KTYPE_RSA) {
LOG_INFO("Found pre-provisioned RSA EK certificate at %u [type=%s]", index, m->name);
ctx.is_rsa_ek_cert_nv_location_defined = true;
ctx.rsa_ek_cert_nv_location = m->index;
}
if (index == ECC_EK_CERT_NV_INDEX) {
if (m->key_type == KTYPE_ECC) {
LOG_INFO("Found pre-provisioned ECC EK certificate at %u [type=%s]", index, m->name);
ctx.is_ecc_ek_cert_nv_location_defined = true;
ctx.ecc_ek_cert_nv_location = m->index;
}
}

Expand All @@ -638,13 +702,15 @@ static tool_rc nv_read(ESYS_CONTEXT *ectx, TPMI_RH_NV_INDEX nv_index) {
* with attributes:
* ppwrite|ppread|ownerread|authread|no_da|written|platformcreate
*/
const bool is_rsa = nv_index == RSA_EK_CERT_NV_INDEX;
char index_string[11];
if (is_rsa) {
strcpy(index_string, "0x01C00002");
} else {
strcpy(index_string, "0x01C0000A");
const ek_index_map *m = lookup_ek_index_map(nv_index);
if (!m) {
LOG_ERR("Unsupported NV INDEX, got \"%u\"", nv_index);
return tool_rc_unsupported;
}

const bool is_rsa = m->key_type == KTYPE_RSA;
char index_string[11];
snprintf(index_string, sizeof(index_string), "%u", m->index);
tpm2_loaded_object object;
tool_rc tmp_rc = tool_rc_success;
tool_rc rc = tpm2_util_object_load_auth(ectx, index_string, NULL, &object,
Expand All @@ -658,11 +724,11 @@ static tool_rc nv_read(ESYS_CONTEXT *ectx, TPMI_RH_NV_INDEX nv_index) {
uint16_t nv_buf_size = 0;
rc = is_rsa ?
tpm2_util_nv_read(ectx, nv_index, 0, 0, &object, &ctx.rsa_cert_buffer,
&nv_buf_size, &cp_hash, &rp_hash, TPM2_ALG_SHA256, 0,
&nv_buf_size, &cp_hash, &rp_hash, m->hash_alg, 0,
ESYS_TR_NONE, ESYS_TR_NONE, NULL) :

tpm2_util_nv_read(ectx, nv_index, 0, 0, &object, &ctx.ecc_cert_buffer,
&nv_buf_size, &cp_hash, &rp_hash, TPM2_ALG_SHA256, 0,
&nv_buf_size, &cp_hash, &rp_hash, m->hash_alg, 0,
ESYS_TR_NONE, ESYS_TR_NONE, NULL);
if (is_rsa) {
ctx.rsa_cert_buffer_size = nv_buf_size;
Expand Down Expand Up @@ -707,14 +773,14 @@ static tool_rc get_nv_ek_certificate(ESYS_CONTEXT *ectx) {

tool_rc rc = tool_rc_success;
if (ctx.is_rsa_ek_cert_nv_location_defined) {
rc = nv_read(ectx, RSA_EK_CERT_NV_INDEX);
rc = nv_read(ectx, ctx.rsa_ek_cert_nv_location);
if (rc != tool_rc_success) {
return rc;
}
}

if (ctx.is_ecc_ek_cert_nv_location_defined) {
rc = nv_read(ectx, ECC_EK_CERT_NV_INDEX);
rc = nv_read(ectx, ctx.ecc_ek_cert_nv_location);
}

return rc;
Expand Down

0 comments on commit ad1da5a

Please sign in to comment.