From c3ab532c43a69b6fbcf3554435022615c1497326 Mon Sep 17 00:00:00 2001 From: Shrikant Temburwar Date: Wed, 10 Jan 2024 12:37:15 +0530 Subject: [PATCH] Add support to store TPM private keys and device CSR inside TPM NV storage Signed-off-by: Shrikant Temburwar --- cmake/blob_path.cmake | 10 -- crypto/common/fdo_hmac.c | 26 +++-- crypto/include/tpm20_Utils.h | 7 +- crypto/openssl/tpm20_ECDSA_sign_routines.c | 41 ++++++-- crypto/openssl/tpm20_Utils.c | 112 ++++++++------------- include/fdomodules.h | 10 +- lib/credentials_from_file.c | 19 ++-- lib/m-string.c | 14 ++- storage/include/storage_al.h | 10 +- storage/include/tpm2_nv_storage.h | 15 ++- storage/linux/storage_if_linux.c | 69 ++++--------- storage/linux/tpm2_nv_storage.c | 3 +- utils/clear_tpm_nv.sh | 7 ++ utils/tpm_make_ready_ecdsa.sh | 37 ++++++- 14 files changed, 199 insertions(+), 181 deletions(-) create mode 100644 utils/clear_tpm_nv.sh diff --git a/cmake/blob_path.cmake b/cmake/blob_path.cmake index 0ec57d79..7d6d6b32 100644 --- a/cmake/blob_path.cmake +++ b/cmake/blob_path.cmake @@ -35,16 +35,6 @@ if(TARGET_OS MATCHES linux) if (${DA} MATCHES tpm) client_sdk_compile_definitions( -DDEVICE_TPM20_ENABLED - -DTPM_DEVICE_CSR=\"${BLOB_PATH}/data/tpm_device_csr\" - -DTPM_ECDSA_DEVICE_KEY=\"${BLOB_PATH}/data/tpm_ecdsa_priv_pub_blob.key\" - -DTPM_INPUT_DATA_TEMP_FILE=\"${BLOB_PATH}/data/tpm_input_data_temp_file\" - -DTPM_OUTPUT_DATA_TEMP_FILE=\"${BLOB_PATH}/data/tpm_output_data_temp_file\" - -DTPM_HMAC_PUB_KEY=\"${BLOB_PATH}/data/tpm_hmac_pub.key\" - -DTPM_HMAC_PRIV_KEY=\"${BLOB_PATH}/data/tpm_hmac_priv.key\" - -DTPM_HMAC_REPLACEMENT_PUB_KEY=\"${BLOB_PATH}/data/tpm_hmac_replacement_pub.key\" - -DTPM_HMAC_REPLACEMENT_PRIV_KEY=\"${BLOB_PATH}/data/tpm_hmac_replacement_priv.key\" - -DTPM_HMAC_DATA_PUB_KEY=\"${BLOB_PATH}/data/tpm_hmac_data_pub.key\" - -DTPM_HMAC_DATA_PRIV_KEY=\"${BLOB_PATH}/data/tpm_hmac_data_priv.key\" ) endif() diff --git a/crypto/common/fdo_hmac.c b/crypto/common/fdo_hmac.c index c347eb37..daee3e41 100644 --- a/crypto/common/fdo_hmac.c +++ b/crypto/common/fdo_hmac.c @@ -14,6 +14,7 @@ #if defined(DEVICE_TPM20_ENABLED) #include "tpm20_Utils.h" +#include "tpm2_nv_storage.h" #endif #if defined(DEVICE_CSE_ENABLED) @@ -151,15 +152,16 @@ int32_t fdo_device_ov_hmac(uint8_t *OVHdr, size_t OVHdr_len, uint8_t *hmac, if (is_replacement_hmac) { #if defined(DEVICE_TPM20_ENABLED) return fdo_tpm_get_hmac(OVHdr, OVHdr_len, hmac, hmac_len, - TPM_HMAC_REPLACEMENT_PUB_KEY, - TPM_HMAC_REPLACEMENT_PRIV_KEY); + TPM_HMAC_REPLACEMENT_PUB_KEY_NV_IDX, + TPM_HMAC_REPLACEMENT_PRIV_KEY_NV_IDX); #else keyset = get_replacement_OV_key(); #endif } else { #if defined(DEVICE_TPM20_ENABLED) return fdo_tpm_get_hmac(OVHdr, OVHdr_len, hmac, hmac_len, - TPM_HMAC_PUB_KEY, TPM_HMAC_PRIV_KEY); + TPM_HMAC_PUB_KEY_NV_IDX, + TPM_HMAC_PRIV_KEY_NV_IDX); #else keyset = get_OV_key(); #endif @@ -225,8 +227,8 @@ int32_t fdo_generate_ov_hmac_key(void) int32_t ret = -1; #if defined(DEVICE_TPM20_ENABLED) - if (0 != - fdo_tpm_generate_hmac_key(TPM_HMAC_PUB_KEY, TPM_HMAC_PRIV_KEY)) { + if (0 != fdo_tpm_generate_hmac_key(TPM_HMAC_PUB_KEY_NV_IDX, + TPM_HMAC_PRIV_KEY_NV_IDX)) { LOG(LOG_ERROR, "Failed to generate device HMAC key" " from TPM.\n"); return ret; @@ -270,8 +272,9 @@ int32_t fdo_generate_ov_replacement_hmac_key(void) int32_t ret = -1; #if defined(DEVICE_TPM20_ENABLED) - if (0 != fdo_tpm_generate_hmac_key(TPM_HMAC_REPLACEMENT_PUB_KEY, - TPM_HMAC_REPLACEMENT_PRIV_KEY)) { + if (0 != + fdo_tpm_generate_hmac_key(TPM_HMAC_REPLACEMENT_PUB_KEY_NV_IDX, + TPM_HMAC_REPLACEMENT_PRIV_KEY_NV_IDX)) { LOG(LOG_ERROR, "Failed to generate device replacement HMAC key" " from TPM.\n"); return ret; @@ -367,8 +370,9 @@ int32_t fdo_compute_storage_hmac(const uint8_t *data, uint32_t data_length, #if defined(DEVICE_TPM20_ENABLED) if (0 != fdo_tpm_get_hmac(data, data_length, computed_hmac, - computed_hmac_size, TPM_HMAC_DATA_PUB_KEY, - TPM_HMAC_DATA_PRIV_KEY)) { + computed_hmac_size, + TPM_HMAC_DATA_PUB_KEY_NV_IDX, + TPM_HMAC_DATA_PRIV_KEY_NV_IDX)) { LOG(LOG_ERROR, "TPM HMAC Computation failed!\n"); goto error; } @@ -420,8 +424,8 @@ int32_t fdo_generate_storage_hmac_key(void) return 0; #elif defined(DEVICE_TPM20_ENABLED) - if (0 != fdo_tpm_generate_hmac_key(TPM_HMAC_DATA_PUB_KEY, - TPM_HMAC_DATA_PRIV_KEY)) { + if (0 != fdo_tpm_generate_hmac_key(TPM_HMAC_DATA_PUB_KEY_NV_IDX, + TPM_HMAC_DATA_PRIV_KEY_NV_IDX)) { LOG(LOG_ERROR, "Failed to generate TPM data protection " "key.\n"); return ret; diff --git a/crypto/include/tpm20_Utils.h b/crypto/include/tpm20_Utils.h index fc4fde4d..889b1bb8 100644 --- a/crypto/include/tpm20_Utils.h +++ b/crypto/include/tpm20_Utils.h @@ -103,9 +103,10 @@ static const TPM2B_PUBLIC in_publicHMACKey_template = { }; int32_t fdo_tpm_get_hmac(const uint8_t *data, size_t data_length, uint8_t *hmac, - size_t hmac_length, char *tpmHMACPub_key, - char *tpmHMACPriv_key); -int32_t fdo_tpm_generate_hmac_key(char *tpmHMACPub_key, char *tpmHMACPriv_key); + size_t hmac_length, uint32_t tpmHMACPub_key_nv, + uint32_t tpmHMACPriv_key_nv); +int32_t fdo_tpm_generate_hmac_key(uint32_t tpmHMACPub_key_nv, + uint32_t tpmHMACPriv_key_nv); int32_t fdo_tpm_commit_replacement_hmac_key(void); void fdo_tpm_clear_replacement_hmac_key(void); int32_t is_valid_tpm_data_protection_key_present(void); diff --git a/crypto/openssl/tpm20_ECDSA_sign_routines.c b/crypto/openssl/tpm20_ECDSA_sign_routines.c index aa82bf25..169499b1 100644 --- a/crypto/openssl/tpm20_ECDSA_sign_routines.c +++ b/crypto/openssl/tpm20_ECDSA_sign_routines.c @@ -15,9 +15,12 @@ #include #include #include +#include #include "safe_lib.h" #include "util.h" #include "fdo_crypto_hal.h" +#include "tpm20_Utils.h" +#include "tpm2_nv_storage.h" /** * Sign a message using provided ECDSA Private Keys. @@ -45,6 +48,8 @@ int32_t crypto_hal_ecdsa_sign(const uint8_t *data, size_t data_len, EVP_MD_CTX *mdctx = NULL; OSSL_STORE_CTX *ctx = NULL; OSSL_STORE_INFO *info = NULL; + BIO *mem = NULL; + unsigned char *pri_key = NULL; if (!data || !data_len || !message_signature || !signature_length) { LOG(LOG_ERROR, "Invalid Parameters received."); @@ -58,23 +63,31 @@ int32_t crypto_hal_ecdsa_sign(const uint8_t *data, size_t data_len, } // Read the key - if ((ctx = OSSL_STORE_open(TPM_ECDSA_DEVICE_KEY, NULL, NULL, NULL, - NULL)) == NULL) { - LOG(LOG_ERROR, "Error during OSSL_STORE_open\n"); + size_t file_size = fdo_tpm_nvread_size(TPM_ECDSA_DEVICE_KEY_NV_IDX); + + pri_key = fdo_alloc(file_size); + if (!pri_key) { + LOG(LOG_ERROR, "Failed to allocate memory for private key.\n"); goto error; } - while (!OSSL_STORE_eof(ctx) && (info = OSSL_STORE_load(ctx)) != NULL) { - if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) { - pkey = OSSL_STORE_INFO_get1_PKEY(info); - break; - } - OSSL_STORE_INFO_free(info); - info = NULL; + if (fdo_tpm_nvread(TPM_ECDSA_DEVICE_KEY_NV_IDX, file_size, &pri_key) == + -1) { + LOG(LOG_ERROR, + "Failed to load TPM HMAC Private Key into buffer.\n"); + goto error; } - if (!pkey) { + mem = BIO_new_mem_buf(pri_key, file_size); + if (mem == NULL) { + LOG(LOG_ERROR, "Failed to create memory BIO\n"); + goto error; + } + + pkey = PEM_read_bio_PrivateKey(mem, NULL, NULL, NULL); + if (pkey == NULL) { LOG(LOG_ERROR, "Error during reading Private key.\n"); + BIO_free(mem); goto error; } @@ -198,6 +211,12 @@ int32_t crypto_hal_ecdsa_sign(const uint8_t *data, size_t data_len, ret = 0; error: + if (pri_key) { + fdo_free(pri_key); + } + if (mem) { + BIO_free(mem); + } if (pkey) { EVP_PKEY_free(pkey); } diff --git a/crypto/openssl/tpm20_Utils.c b/crypto/openssl/tpm20_Utils.c index 7df8c004..461324c4 100644 --- a/crypto/openssl/tpm20_Utils.c +++ b/crypto/openssl/tpm20_Utils.c @@ -10,6 +10,7 @@ */ #include "util.h" #include "safe_lib.h" +#include "tpm2_nv_storage.h" #include "tpm20_Utils.h" #include "fdo_crypto_hal.h" #include "storage_al.h" @@ -39,8 +40,8 @@ static int32_t fdoTPMGenerate_primary_key_context(ESYS_CONTEXT **esys_context, * -1, on failure */ int32_t fdo_tpm_get_hmac(const uint8_t *data, size_t data_length, uint8_t *hmac, - size_t hmac_length, char *tpmHMACPub_key, - char *tpmHMACPriv_key) + size_t hmac_length, uint32_t tpmHMACPub_key_nv, + uint32_t tpmHMACPriv_key_nv) { int32_t ret = -1, ret_val = -1, file_size = 0; size_t hashed_length = 0; @@ -63,8 +64,9 @@ int32_t fdo_tpm_get_hmac(const uint8_t *data, size_t data_length, uint8_t *hmac, /* Validating all input parameters are passed in the function call*/ - if (!data || !data_length || !tpmHMACPub_key || !tpmHMACPriv_key || - !hmac || (hmac_length != PLATFORM_HMAC_SIZE)) { + if (!data || !data_length || !tpmHMACPub_key_nv || + !tpmHMACPriv_key_nv || !hmac || + (hmac_length != PLATFORM_HMAC_SIZE)) { LOG(LOG_ERROR, "Failed to generate HMAC from TPM, invalid parameter" " received.\n"); @@ -87,7 +89,7 @@ int32_t fdo_tpm_get_hmac(const uint8_t *data, size_t data_length, uint8_t *hmac, /* Unmarshalling the HMAC Private key from the HMAC Private key file*/ - file_size = get_file_size(tpmHMACPriv_key); + file_size = fdo_tpm_nvread_size(tpmHMACPriv_key_nv); if (file_size != TPM_HMAC_PRIV_KEY_CONTEXT_SIZE_128 && file_size != TPM_HMAC_PRIV_KEY_CONTEXT_SIZE) { @@ -98,10 +100,8 @@ int32_t fdo_tpm_get_hmac(const uint8_t *data, size_t data_length, uint8_t *hmac, LOG(LOG_DEBUG, "TPM HMAC Private Key file size retreived successfully.\n"); - ret_val = read_buffer_from_file(tpmHMACPriv_key, bufferTPMHMACPriv_key, - file_size); - - if (ret_val != 0) { + if (fdo_tpm_read_nv(tpmHMACPriv_key_nv, FDO_SDK_RAW_DATA, + bufferTPMHMACPriv_key, file_size) == -1) { LOG(LOG_ERROR, "Failed to load TPM HMAC Private Key into buffer.\n"); goto err; @@ -123,7 +123,7 @@ int32_t fdo_tpm_get_hmac(const uint8_t *data, size_t data_length, uint8_t *hmac, /* Unmarshalling the HMAC Public key from the HMAC public key file*/ - file_size = get_file_size(tpmHMACPub_key); + file_size = fdo_tpm_nvread_size(tpmHMACPub_key_nv); if (file_size != TPM_HMAC_PUB_KEY_CONTEXT_SIZE) { LOG(LOG_ERROR, "TPM HMAC Private Key file size incorrect.\n"); @@ -133,12 +133,10 @@ int32_t fdo_tpm_get_hmac(const uint8_t *data, size_t data_length, uint8_t *hmac, LOG(LOG_DEBUG, "TPM HMAC Public Key file size retreived successfully.\n"); - ret_val = read_buffer_from_file(tpmHMACPub_key, bufferTPMHMACPub_key, - file_size); - - if (ret_val != 0) { + if (fdo_tpm_read_nv(tpmHMACPub_key_nv, FDO_SDK_RAW_DATA, + bufferTPMHMACPub_key, file_size) == -1) { LOG(LOG_ERROR, - "Failed to load TPM HMAC Public key into buffer.\n"); + "Failed to load TPM HMAC Public Key into buffer.\n"); goto err; } @@ -353,7 +351,8 @@ int32_t fdo_tpm_get_hmac(const uint8_t *data, size_t data_length, uint8_t *hmac, * 0, on success * -1, on failure */ -int32_t fdo_tpm_generate_hmac_key(char *tpmHMACPub_key, char *tpmHMACPriv_key) +int32_t fdo_tpm_generate_hmac_key(uint32_t tpmHMACPub_key_nv, + uint32_t tpmHMACPriv_key_nv) { int32_t ret = -1; TSS2_RC ret_val = TPM2_RC_FAILURE; @@ -374,22 +373,12 @@ int32_t fdo_tpm_generate_hmac_key(char *tpmHMACPub_key, char *tpmHMACPriv_key) uint8_t buffer[TPM_HMAC_PRIV_KEY_CONTEXT_SIZE] = {0}; size_t offset = 0; - if (!tpmHMACPub_key || !tpmHMACPriv_key) { + if (!tpmHMACPub_key_nv || !tpmHMACPriv_key_nv) { LOG(LOG_ERROR, "Failed to generate HMAC Key," "invalid parameters received.\n"); goto err; } - if ((file_exists(tpmHMACPub_key) && !remove(tpmHMACPub_key)) && - (file_exists(tpmHMACPriv_key) && !remove(tpmHMACPriv_key))) { - LOG(LOG_DEBUG, "Successfully deleted old HMAC key.\n"); - } else if (file_exists(tpmHMACPub_key) || - file_exists(tpmHMACPriv_key)) { - LOG(LOG_DEBUG, "HMAC key generation failed," - "failed to delete the old HMAC key.\n"); - goto err; - } - if (0 != fdoTPMGenerate_primary_key_context(&esys_context, &primary_key_handle, &auth_session_handle)) { @@ -417,8 +406,9 @@ int32_t fdo_tpm_generate_hmac_key(char *tpmHMACPub_key, char *tpmHMACPriv_key) goto err; } - if ((int32_t)offset != - fdo_blob_write(tpmHMACPub_key, FDO_SDK_RAW_DATA, buffer, offset)) { + if ((int32_t)offset != fdo_tpm_write_nv(tpmHMACPub_key_nv, + FDO_SDK_RAW_DATA, buffer, + offset)) { LOG(LOG_ERROR, "Failed to save the public HMAC key context.\n"); goto err; } @@ -433,8 +423,9 @@ int32_t fdo_tpm_generate_hmac_key(char *tpmHMACPub_key, char *tpmHMACPriv_key) goto err; } - if ((int32_t)offset != - fdo_blob_write(tpmHMACPriv_key, FDO_SDK_RAW_DATA, buffer, offset)) { + if ((int32_t)offset != fdo_tpm_write_nv(tpmHMACPriv_key_nv, + FDO_SDK_RAW_DATA, buffer, + offset)) { LOG(LOG_ERROR, "Failed to save the private HMAC key context.\n"); goto err; @@ -689,23 +680,14 @@ static int32_t fdoTPMTSSContext_clean_up(ESYS_CONTEXT **esys_context, int32_t fdo_tpm_commit_replacement_hmac_key(void) { size_t file_size = 0; - // internal return value - int32_t ret_val = -1; // function return value int32_t ret = -1; uint8_t bufferTPMHMACPriv_key[TPM_HMAC_PRIV_KEY_CONTEXT_SIZE] = {0}; uint8_t bufferTPMHMACPub_key[TPM_HMAC_PUB_KEY_CONTEXT_SIZE] = {0}; - if (!file_exists(TPM_HMAC_PRIV_KEY) || !file_exists(TPM_HMAC_PUB_KEY) || - !file_exists(TPM_HMAC_REPLACEMENT_PRIV_KEY) || - !file_exists(TPM_HMAC_REPLACEMENT_PUB_KEY)) { - LOG(LOG_ERROR, "One or more HMAC objects are missing.\n"); - goto err; - } - // read TPM_HMAC_REPLACEMENT_PRIV_KEY contents and write it into // TPM_HMAC_PRIV_KEY - file_size = get_file_size(TPM_HMAC_REPLACEMENT_PRIV_KEY); + file_size = fdo_tpm_nvread_size(TPM_HMAC_REPLACEMENT_PRIV_KEY_NV_IDX); if (file_size != TPM_HMAC_PRIV_KEY_CONTEXT_SIZE_128 && file_size != TPM_HMAC_PRIV_KEY_CONTEXT_SIZE) { @@ -717,18 +699,17 @@ int32_t fdo_tpm_commit_replacement_hmac_key(void) LOG(LOG_DEBUG, "TPM HMAC Replacement Private Key file size retreived " "successfully.\n"); - ret_val = read_buffer_from_file(TPM_HMAC_REPLACEMENT_PRIV_KEY, - bufferTPMHMACPriv_key, file_size); - - if (ret_val != 0) { + if (fdo_tpm_read_nv(TPM_HMAC_REPLACEMENT_PRIV_KEY_NV_IDX, + FDO_SDK_RAW_DATA, bufferTPMHMACPriv_key, + file_size) == -1) { LOG(LOG_ERROR, "Failed to load TPM HMAC Replacement Private " "Key into buffer.\n"); goto err; } if ((int32_t)file_size != - fdo_blob_write(TPM_HMAC_PRIV_KEY, FDO_SDK_RAW_DATA, - bufferTPMHMACPriv_key, file_size)) { + fdo_tpm_write_nv(TPM_HMAC_PRIV_KEY_NV_IDX, FDO_SDK_RAW_DATA, + bufferTPMHMACPriv_key, file_size)) { LOG(LOG_ERROR, "Failed to save the private HMAC key context.\n"); goto err; @@ -736,7 +717,7 @@ int32_t fdo_tpm_commit_replacement_hmac_key(void) // now, read TPM_HMAC_REPLACEMENT_PUB_KEY contents and write it into // TPM_HMAC_PUB_KEY - file_size = get_file_size(TPM_HMAC_REPLACEMENT_PUB_KEY); + file_size = fdo_tpm_nvread_size(TPM_HMAC_REPLACEMENT_PUB_KEY_NV_IDX); if (file_size != TPM_HMAC_PUB_KEY_CONTEXT_SIZE) { LOG(LOG_ERROR, @@ -747,18 +728,17 @@ int32_t fdo_tpm_commit_replacement_hmac_key(void) LOG(LOG_DEBUG, "TPM HMAC Replacement Public Key file size retreived " "successfully.\n"); - ret_val = read_buffer_from_file(TPM_HMAC_REPLACEMENT_PUB_KEY, - bufferTPMHMACPub_key, file_size); - - if (ret_val != 0) { + if (fdo_tpm_read_nv(TPM_HMAC_REPLACEMENT_PUB_KEY_NV_IDX, + FDO_SDK_RAW_DATA, bufferTPMHMACPub_key, + file_size) == -1) { LOG(LOG_ERROR, "Failed to load TPM HMAC Replacement Public key " "into buffer.\n"); goto err; } if ((int32_t)file_size != - fdo_blob_write(TPM_HMAC_PUB_KEY, FDO_SDK_RAW_DATA, - bufferTPMHMACPub_key, file_size)) { + fdo_tpm_write_nv(TPM_HMAC_PUB_KEY_NV_IDX, FDO_SDK_RAW_DATA, + bufferTPMHMACPub_key, file_size)) { LOG(LOG_ERROR, "Failed to save the public HMAC key context.\n"); goto err; } @@ -774,15 +754,13 @@ int32_t fdo_tpm_commit_replacement_hmac_key(void) void fdo_tpm_clear_replacement_hmac_key(void) { // remove the files if they exist, else return - if (file_exists(TPM_HMAC_REPLACEMENT_PRIV_KEY)) { - if (0 != remove(TPM_HMAC_REPLACEMENT_PRIV_KEY)) { - LOG(LOG_ERROR, "Failed to cleanup private object\n"); - } + + if (0 != fdo_tpm_nvdel(TPM_HMAC_REPLACEMENT_PRIV_KEY_NV_IDX)) { + LOG(LOG_ERROR, "Failed to cleanup private object\n"); } - if (file_exists(TPM_HMAC_REPLACEMENT_PUB_KEY)) { - if (0 != remove(TPM_HMAC_REPLACEMENT_PUB_KEY)) { - LOG(LOG_ERROR, "Failed to cleanup public object\n"); - } + + if (0 != fdo_tpm_nvdel(TPM_HMAC_REPLACEMENT_PUB_KEY_NV_IDX)) { + LOG(LOG_ERROR, "Failed to cleanup public object\n"); } } @@ -795,12 +773,10 @@ void fdo_tpm_clear_replacement_hmac_key(void) */ int32_t is_valid_tpm_data_protection_key_present(void) { - return (file_exists(TPM_HMAC_DATA_PUB_KEY) && - (TPM_HMAC_PUB_KEY_CONTEXT_SIZE == - get_file_size(TPM_HMAC_DATA_PUB_KEY)) && - file_exists(TPM_HMAC_DATA_PRIV_KEY) && + return ((TPM_HMAC_PUB_KEY_CONTEXT_SIZE == + fdo_tpm_nvread_size(TPM_HMAC_DATA_PUB_KEY_NV_IDX)) && (TPM_HMAC_PRIV_KEY_CONTEXT_SIZE_128 == - get_file_size(TPM_HMAC_DATA_PRIV_KEY) || + fdo_tpm_nvread_size(TPM_HMAC_DATA_PRIV_KEY_NV_IDX) || TPM_HMAC_PRIV_KEY_CONTEXT_SIZE == - get_file_size(TPM_HMAC_DATA_PRIV_KEY))); + fdo_tpm_nvread_size(TPM_HMAC_DATA_PRIV_KEY_NV_IDX))); } diff --git a/include/fdomodules.h b/include/fdomodules.h index 00fed560..8a85d814 100644 --- a/include/fdomodules.h +++ b/include/fdomodules.h @@ -39,10 +39,12 @@ typedef enum { } fdo_sdk_si_type; // enum for Sv_info module CB return value -enum { FDO_SI_CONTENT_ERROR, - FDO_SI_INTERNAL_ERROR, - FDO_SI_SUCCESS, - FDO_SI_INVALID_MOD_ERROR }; +enum { + FDO_SI_CONTENT_ERROR, + FDO_SI_INTERNAL_ERROR, + FDO_SI_SUCCESS, + FDO_SI_INVALID_MOD_ERROR +}; typedef struct fdo_sdk_si_key_value { char *key; diff --git a/lib/credentials_from_file.c b/lib/credentials_from_file.c index a7622361..2866e112 100644 --- a/lib/credentials_from_file.c +++ b/lib/credentials_from_file.c @@ -559,7 +559,7 @@ bool write_tpm_device_credentials(uint32_t nv, fdo_sdk_blob_flags flags, } fdow->b.block_size = encoded_cred_length; - if (fdo_blob_write_nv(nv, flags, fdow->b.block, fdow->b.block_size) == + if (fdo_tpm_write_nv(nv, flags, fdow->b.block, fdow->b.block_size) == -1) { LOG(LOG_ERROR, "Failed to write DeviceCredential blob\n"); ret = false; @@ -607,7 +607,7 @@ bool read_tpm_device_credentials(uint32_t nv, fdo_sdk_blob_flags flags, goto end; } - dev_cred_len = fdo_blob_size_nv(nv, flags); + dev_cred_len = fdo_tpm_size_nv(nv); // Device has not yet been initialized. // Since, Normal.blob is empty, the file size will be 0 if (dev_cred_len == 0) { @@ -627,7 +627,7 @@ bool read_tpm_device_credentials(uint32_t nv, fdo_sdk_blob_flags flags, goto end; } - if (fdo_blob_read_nv(nv, flags, fdor->b.block, fdor->b.block_size) == + if (fdo_tpm_read_nv(nv, flags, fdor->b.block, fdor->b.block_size) == -1) { LOG(LOG_ERROR, "Failed to read DeviceCredential blob : Normal.blob\n"); @@ -744,8 +744,8 @@ int store_tpm_credential(fdo_dev_cred_t *ocred) { /* Write in the file and save the Normal device credentials */ LOG(LOG_DEBUG, "Writing to TPm NV storage\n"); - if (!write_tpm_device_credentials(FDO_CRED_NORMAL_NV_IDX, - FDO_SDK_NORMAL_DATA, ocred)) { + if (!write_tpm_device_credentials(FDO_CRED_NV_IDX, FDO_SDK_NORMAL_DATA, + ocred)) { LOG(LOG_ERROR, "Could not write to Normal Credentials blob\n"); return -1; } @@ -913,9 +913,9 @@ int load_credential(fdo_dev_cred_t *ocred) return -1; } #elif defined(DEVICE_TPM20_ENABLED) - /* Read in the blob and save the device credentials */ - if (!read_tpm_device_credentials(FDO_CRED_NORMAL_NV_IDX, - FDO_SDK_NORMAL_DATA, ocred)) { + /* Read and save the device credentials */ + if (!read_tpm_device_credentials(FDO_CRED_NV_IDX, FDO_SDK_NORMAL_DATA, + ocred)) { LOG(LOG_ERROR, "Could not parse the Device Credentials blob\n"); return -1; } @@ -977,8 +977,7 @@ bool load_device_status(fdo_sdk_device_status *state) return false; } #elif defined(DEVICE_TPM20_ENABLED) - size_t dev_cred_len = - fdo_blob_size_nv(FDO_CRED_NORMAL_NV_IDX, FDO_SDK_NORMAL_DATA); + size_t dev_cred_len = fdo_tpm_size_nv(FDO_CRED_NV_IDX); #else size_t dev_cred_len = fdo_blob_size((char *)FDO_CRED_NORMAL, FDO_SDK_NORMAL_DATA); diff --git a/lib/m-string.c b/lib/m-string.c index 4a62fb5e..df0f2338 100644 --- a/lib/m-string.c +++ b/lib/m-string.c @@ -20,6 +20,11 @@ #include "cse_utils.h" #include "cse_tools.h" #endif +#if defined(DEVICE_TPM20_ENABLED) +#include "tpm20_Utils.h" +#include "fdo_crypto.h" +#include "tpm2_nv_storage.h" +#endif #include @@ -247,7 +252,7 @@ int ps_get_m_string(fdo_prot_t *ps) /* Get the CSR data */ #if defined(DEVICE_TPM20_ENABLED) - size_t m_string_sz = get_file_size(TPM_DEVICE_CSR); + size_t m_string_sz = fdo_tpm_nvread_size(TPM_DEVICE_CSR_NV_IDX); csr = fdo_byte_array_alloc(m_string_sz); if (!csr) { @@ -256,11 +261,12 @@ int ps_get_m_string(fdo_prot_t *ps) goto err; } - ret = read_buffer_from_file(TPM_DEVICE_CSR, csr->bytes, csr->byte_sz); - if (0 != ret) { - LOG(LOG_ERROR, "Failed to read %s file!\n", TPM_DEVICE_CSR); + if (fdo_tpm_read_nv(TPM_DEVICE_CSR_NV_IDX, FDO_SDK_RAW_DATA, csr->bytes, + csr->byte_sz) == -1) { + LOG(LOG_ERROR, "Failed to load TPM DEVICE CSR into buffer.\n"); goto err; } + ret = 0; #elif defined(DEVICE_CSE_ENABLED) // CSR will be NULL for CSE csr = fdo_byte_array_alloc(0); diff --git a/storage/include/storage_al.h b/storage/include/storage_al.h index ae3f6523..70ca04fc 100644 --- a/storage/include/storage_al.h +++ b/storage/include/storage_al.h @@ -47,13 +47,13 @@ size_t fdo_blob_size(const char *blob_name, fdo_sdk_blob_flags flags); int32_t create_hmac_normal_blob(void); #if defined(DEVICE_TPM20_ENABLED) -int32_t fdo_blob_read_nv(uint32_t nv, fdo_sdk_blob_flags flags, uint8_t *buffer, - uint32_t length); +int32_t fdo_tpm_read_nv(uint32_t nv, fdo_sdk_blob_flags flags, uint8_t *buffer, + uint32_t length); -int32_t fdo_blob_write_nv(uint32_t nv, fdo_sdk_blob_flags flags, - const uint8_t *buffer, uint32_t length); +int32_t fdo_tpm_write_nv(uint32_t nv, fdo_sdk_blob_flags flags, + const uint8_t *buffer, uint32_t length); -size_t fdo_blob_size_nv(uint32_t nv, fdo_sdk_blob_flags flags); +size_t fdo_tpm_size_nv(uint32_t nv); #endif #ifdef __cplusplus } // endof externc (CPP code) diff --git a/storage/include/tpm2_nv_storage.h b/storage/include/tpm2_nv_storage.h index 6f8e1049..e0f59694 100644 --- a/storage/include/tpm2_nv_storage.h +++ b/storage/include/tpm2_nv_storage.h @@ -5,8 +5,19 @@ #include #include -#define FDO_CRED_NORMAL_NV_IDX 0x1000001 -#define FDO_CRED_SECURE_NV_IDX 0x1000002 +#define FDO_CRED_NV_IDX 0x1000001 + +#define TPM_HMAC_PUB_KEY_NV_IDX 0x1000002 +#define TPM_HMAC_PRIV_KEY_NV_IDX 0x1000003 + +#define TPM_HMAC_DATA_PUB_KEY_NV_IDX 0x1000004 +#define TPM_HMAC_DATA_PRIV_KEY_NV_IDX 0x1000005 + +#define TPM_HMAC_REPLACEMENT_PUB_KEY_NV_IDX 0x1000006 +#define TPM_HMAC_REPLACEMENT_PRIV_KEY_NV_IDX 0x1000007 + +#define TPM_ECDSA_DEVICE_KEY_NV_IDX 0x1000008 +#define TPM_DEVICE_CSR_NV_IDX 0x1000009 #if defined(ECDSA256_DA) #define FDO_TPM2_ALG_SHA TPM2_ALG_SHA256 diff --git a/storage/linux/storage_if_linux.c b/storage/linux/storage_if_linux.c index 9859aedd..75c7a1d7 100644 --- a/storage/linux/storage_if_linux.c +++ b/storage/linux/storage_if_linux.c @@ -568,69 +568,40 @@ int32_t fdo_blob_write(const char *name, fdo_sdk_blob_flags flags, #if defined(DEVICE_TPM20_ENABLED) /** - * fdo_blob_size Get specified FDO blob(file) size - * Note: FDO_SDK_OTP_DATA flag is not supported for this platform. + * fdo_tpm_size_nv Get specified FDO nv size * @param nv - ptpm nv index - * @param flags - descriptor telling type of file * @return file size on success, 0 if file does not exist or on other failure */ -size_t fdo_blob_size_nv(uint32_t nv, fdo_sdk_blob_flags flags) +size_t fdo_tpm_size_nv(uint32_t nv) { size_t retval = 0; - const size_t NORMAL_BLOB_OVERHEAD = + const size_t NORMAL_NV_OVERHEAD = PLATFORM_HMAC_SIZE + BLOB_CONTENT_SIZE; - const size_t SECURE_BLOB_OVERHEAD = - AES_TAG_LEN + PLATFORM_IV_DEFAULT_LEN + BLOB_CONTENT_SIZE; if (!nv) { LOG(LOG_ERROR, "Invalid parameters!\n"); goto end; } + /* Normal cred is stored as: + * [HMAC(32bytes)||data-content-size(4bytes)||data-content(?)] + */ + retval = fdo_tpm_nvread_size(nv); + // Return 0 if the file is empty. - if (fdo_tpm_nvread_size(nv) == 0) { + if (retval == 0) { LOG(LOG_DEBUG, "NV is empty!\n"); retval = 0; goto end; } - switch (flags) { - case FDO_SDK_RAW_DATA: - /* Raw Files are stored as plain files */ - retval = fdo_tpm_nvread_size(nv); - break; - case FDO_SDK_NORMAL_DATA: - /* Normal blob is stored as: - * [HMAC(32bytes)||data-content-size(4bytes)||data-content(?)] - */ - retval = fdo_tpm_nvread_size(nv); - - if (retval >= NORMAL_BLOB_OVERHEAD) { - retval -= NORMAL_BLOB_OVERHEAD; - } else { - /* File format is not correct, not enough data in the - * file */ - retval = 0; - } - break; - case FDO_SDK_SECURE_DATA: - /* Secure blob is stored as: - * [IV_data(12byte)||TAG(16bytes)|| - * data-content-size(4bytes)||data-content(?)] - */ - retval = fdo_tpm_nvread_size(nv); - if (retval >= SECURE_BLOB_OVERHEAD) { - retval -= SECURE_BLOB_OVERHEAD; - } else { - /* File format is not correct, not enough data in the - * file */ - retval = 0; - } - break; - default: - LOG(LOG_ERROR, "Invalid storage flag:%d!\n", flags); - goto end; + if (retval >= NORMAL_NV_OVERHEAD) { + retval -= NORMAL_NV_OVERHEAD; + } else { + /* File format is not correct, not enough data in the + * file */ + retval = 0; } end: @@ -652,8 +623,8 @@ size_t fdo_blob_size_nv(uint32_t nv, fdo_sdk_blob_flags flags) * @param n_bytes - length of data(in bytes) to be read * @return num of bytes read if success, -1 on error */ -int32_t fdo_blob_read_nv(uint32_t nv, fdo_sdk_blob_flags flags, uint8_t *buf, - uint32_t n_bytes) +int32_t fdo_tpm_read_nv(uint32_t nv, fdo_sdk_blob_flags flags, uint8_t *buf, + uint32_t n_bytes) { int retval = -1; uint8_t *data = NULL; @@ -882,8 +853,8 @@ int32_t fdo_blob_read_nv(uint32_t nv, fdo_sdk_blob_flags flags, uint8_t *buf, * @return num of bytes write if success, -1 on error */ -int32_t fdo_blob_write_nv(uint32_t nv, fdo_sdk_blob_flags flags, - const uint8_t *buf, uint32_t n_bytes) +int32_t fdo_tpm_write_nv(uint32_t nv, fdo_sdk_blob_flags flags, + const uint8_t *buf, uint32_t n_bytes) { int retval = -1; FILE *f = NULL; @@ -1044,7 +1015,7 @@ int32_t fdo_blob_write_nv(uint32_t nv, fdo_sdk_blob_flags flags, } if (fdo_tpm_nvwrite(write_context, write_context_len, nv)) { - LOG(LOG_ERROR, "Could not get platform AES Key!\n"); + LOG(LOG_ERROR, "Failed to write in TPM NV!\n"); goto exit; } diff --git a/storage/linux/tpm2_nv_storage.c b/storage/linux/tpm2_nv_storage.c index 93609e1b..7fef660f 100644 --- a/storage/linux/tpm2_nv_storage.c +++ b/storage/linux/tpm2_nv_storage.c @@ -599,7 +599,8 @@ int fdo_tpm_nvdel(uint32_t nv) int exists = (capability_data->data.handles.count > 0 && capability_data->data.handles.handle[0] == nv); if (exists != 1) { - LOG(LOG_ERROR, "NV index doesn't exist.\n"); + LOG(LOG_DEBUG, "NV index doesn't exist.\n"); + ret = 0; goto err; } diff --git a/utils/clear_tpm_nv.sh b/utils/clear_tpm_nv.sh new file mode 100644 index 00000000..ebf65e7d --- /dev/null +++ b/utils/clear_tpm_nv.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +for n in {1..9}; +do + tpm2_nvundefine $n +done +echo "TPM NV storage cleared!" diff --git a/utils/tpm_make_ready_ecdsa.sh b/utils/tpm_make_ready_ecdsa.sh index 3a9972a7..a0ca2839 100644 --- a/utils/tpm_make_ready_ecdsa.sh +++ b/utils/tpm_make_ready_ecdsa.sh @@ -106,19 +106,50 @@ execute_cmd_on_failure_exit "\$cmd" "\$success_string" "\$failure_string" 1 1 task="Load primary key inside persistance memory at $TPM_ENDORSEMENT_PRIMARY_KEY_PERSISTANT_HANDLE" cmd="tpm2_evictcontrol -C o $TPM_ENDORSEMENT_PRIMARY_KEY_PERSISTANT_HANDLE -c $tpm_endorsement_primary_key_ctx -V" -success_string="$task completed successfully at $TPM_ENDORSEMENT_PRIMARY_KEY_PERSISTANT_HANDLE !!" +success_string="$task completed successfully at!!" failure_string="$task failed" execute_cmd_on_failure_exit "\$cmd" "\$success_string" "\$failure_string" 1 1 task="TPM ECDSA key generation using $curve" cmd="$OPENSSL3_BIN/openssl genpkey -provider tpm2 -algorithm EC -pkeyopt group:P-$ecc -pkeyopt parent:$TPM_ENDORSEMENT_PRIMARY_KEY_PERSISTANT_HANDLE -out $tpm_device_key_file" -success_string="$task completed successfully at $tpm_device_key_file !!" +success_string="$task completed successfully!!" failure_string="$task failed" execute_cmd_on_failure_exit "\${cmd}" "\${success_string}" "\${failure_string}" 1 1 task="Device CSR generation from TPM" cmd="$OPENSSL3_BIN/openssl req -new -provider tpm2 -provider default -outform DER -out $device_csr_file -key $tpm_device_key_file -subj \"/CN=sdo-tpm-device\" -verbose" -success_string="$task completed successfully at $device_csr_file !!" +success_string="$task completed successfully!!" +failure_string="$task failed" +execute_cmd_on_failure_exit "\$cmd" "\$success_string" "\$failure_string" 1 1 + +# write tpm device key and device csr inside tpm +task="Define a TPM Non-Volatile (NV) index for TPM KEY" +key_size=$(wc -c < $tpm_device_key_file) +cmd="tpm2_nvdefine -Q 0x1000008 -C o -s $key_size -a \"ownerwrite|authwrite|write_stclear|ownerread|authread|read_stclear\"" +success_string="$task completed successfully!!" failure_string="$task failed" execute_cmd_on_failure_exit "\$cmd" "\$success_string" "\$failure_string" 1 1 +task="Define a TPM Non-Volatile (NV) index for TPM Device CSR" +csr_size=$(wc -c < $device_csr_file) +cmd="tpm2_nvdefine -Q 0x1000009 -C o -s $csr_size -a \"ownerwrite|authwrite|write_stclear|ownerread|authread|read_stclear\"" +success_string="$task completed successfully!!" +failure_string="$task failed" +execute_cmd_on_failure_exit "\$cmd" "\$success_string" "\$failure_string" 1 1 + +task="Write TPM ECDSA KEY to a Non-Volatile (NV) index" +cmd="tpm2_nvwrite -Q 0x1000008 -C o -i $tpm_device_key_file" +success_string="$task completed successfully!!" +failure_string="$task failed" +execute_cmd_on_failure_exit "\$cmd" "\$success_string" "\$failure_string" 1 1 + +task="Write TPM Device CSR to a Non-Volatile (NV) index" +cmd="tpm2_nvwrite -Q 0x1000009 -C o -i $device_csr_file" +success_string="$task completed successfully!!" +failure_string="$task failed" +execute_cmd_on_failure_exit "\$cmd" "\$success_string" "\$failure_string" 1 1 + +rm -f $tpm_device_key_file +rm -f $device_csr_file +rm -f $tpm_endorsement_primary_key_ctx +