Skip to content

Commit

Permalink
Add support to store device credentials and device status inside TPM …
Browse files Browse the repository at this point in the history
…NV storage

Signed-off-by: Shrikant Temburwar <[email protected]>
  • Loading branch information
shrikant1407 committed Nov 13, 2023
1 parent e1dc9d0 commit 1f36645
Show file tree
Hide file tree
Showing 14 changed files with 1,558 additions and 28 deletions.
1 change: 1 addition & 0 deletions app/blob.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#if defined(DEVICE_TPM20_ENABLED)
#include "tpm20_Utils.h"
#include "fdo_crypto.h"
#include "tpm2_nv_storage.h"
#endif

#if !defined(DEVICE_TPM20_ENABLED)
Expand Down
2 changes: 1 addition & 1 deletion app/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ int app_main(bool is_resale)
}
#endif /* SECURE_ELEMENT */

#if !defined(DEVICE_CSE_ENABLED)
#if !defined(DEVICE_CSE_ENABLED) && !defined(DEVICE_TPM20_ENABLED)
LOG(LOG_DEBUG, "CSE not enabled, Normal Blob Modules loaded!\n");
if (-1 == configure_normal_blob()) {
LOG(LOG_ERROR,
Expand Down
16 changes: 9 additions & 7 deletions cmake/blob_path.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ if(TARGET_OS MATCHES linux)
-DDEVICE_CSE_ENABLED
)
endif()

if (${MTLS} MATCHES true)
client_sdk_compile_definitions(
-DSSL_CERT=\"${BLOB_PATH}/data/apiUser.pem\"
Expand Down Expand Up @@ -176,9 +176,11 @@ if(TARGET_OS MATCHES linux)
# Configure if needed at a later point
# configure_file(${BLOB_PATH}/data/Normal.blob NEWLINE_STYLE DOS)

file(WRITE ${BLOB_PATH}/data/platform_iv.bin "")
file(WRITE ${BLOB_PATH}/data/platform_hmac_key.bin "")
file(WRITE ${BLOB_PATH}/data/platform_aes_key.bin "")
file(WRITE ${BLOB_PATH}/data/Normal.blob "")
file(WRITE ${BLOB_PATH}/data/Secure.blob "")
file(WRITE ${BLOB_PATH}/data/raw.blob "")
if (NOT ${DA} MATCHES tpm)
file(WRITE ${BLOB_PATH}/data/platform_iv.bin "")
file(WRITE ${BLOB_PATH}/data/platform_hmac_key.bin "")
file(WRITE ${BLOB_PATH}/data/platform_aes_key.bin "")
file(WRITE ${BLOB_PATH}/data/Normal.blob "")
file(WRITE ${BLOB_PATH}/data/Secure.blob "")
file(WRITE ${BLOB_PATH}/data/raw.blob "")
endif()
299 changes: 297 additions & 2 deletions lib/credentials_from_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@
#include "cse_utils.h"
#include "cse_tools.h"
#endif
#if defined(DEVICE_TPM20_ENABLED)
#include "tpm2_nv_storage.h"
#endif

static bool validate_state(fdo_sdk_device_status current_status);

#if !defined(DEVICE_CSE_ENABLED)
#if !defined(DEVICE_CSE_ENABLED) && !defined(DEVICE_TPM20_ENABLED)
/**
* Write the Device Credentials blob, contains our state
* @param dev_cred_file - pointer of type const char to which credentails are
Expand Down Expand Up @@ -454,16 +457,298 @@ int store_credential(fdo_dev_cred_t *ocred)
return -1;
}

#if !defined(DEVICE_TPM20_ENABLED)
/* Write in the file and save the Secure device credentials */
LOG(LOG_DEBUG, "Writing to %s blob\n", "Secure.blob");
if (!write_secure_device_credentials((char *)FDO_CRED_SECURE,
FDO_SDK_SECURE_DATA, ocred)) {
LOG(LOG_ERROR, "Could not write to Secure Credentials blob\n");
return -1;
}

return 0;
}
#endif

#if defined(DEVICE_TPM20_ENABLED)
/**
* Write the Device Credentials to nv, contains our state
* @param dev_cred_file - pointer of type const char to which credentails are
* to be written.
* @param flags
* @param ocred - pointer of type fdo_dev_cred_t, holds the credentials for
* writing to dev_cred_file.
* @return true if write and parsed correctly, otherwise false
*/

bool write_tpm_device_credentials(uint32_t nv, fdo_sdk_blob_flags flags,
fdo_dev_cred_t *ocred)
{
bool ret = true;

if (!ocred || !nv) {
return false;
}
#ifndef NO_PERSISTENT_STORAGE

fdow_t *fdow = fdo_alloc(sizeof(fdow_t));
if (!fdow || !fdow_init(fdow) ||
!fdo_block_alloc_with_size(&fdow->b, BUFF_SIZE_4K_BYTES) ||
!fdow_encoder_init(fdow)) {
LOG(LOG_ERROR, "FDOW Initialization/Allocation failed!\n");
ret = false;
goto end;
}

/**
* Blob format: Complete DeviceCredential as per Section 3.4.1 of FDO
*Specification, except the DeviceCredential.DCHmacSecret, and addition
*of 'State'. DeviceCredential = [ State, DCActive, DCProtVer,
* DCDeviceInfo,
* DCGuid,
* DCRVInfo,
* DCPubKeyHash
* ]
*/
fdow_next_block(fdow, FDO_DI_SET_CREDENTIALS);
if (!fdow_start_array(fdow, 7)) {
ret = false;
goto end;
}
if (!fdow_signed_int(fdow, ocred->ST)) {
ret = false;
goto end;
}
if (!fdow_boolean(fdow, true)) {
ret = false;
goto end;
}
if (!fdow_signed_int(fdow, ocred->owner_blk->pv)) {
ret = false;
goto end;
}

if (!fdow_text_string(fdow, ocred->mfg_blk->d->bytes,
ocred->mfg_blk->d->byte_sz)) {
ret = false;
goto end;
}
if (!fdow_byte_string(fdow, ocred->owner_blk->guid->bytes,
ocred->owner_blk->guid->byte_sz)) {
ret = false;
goto end;
}
if (!fdo_rendezvous_list_write(fdow, ocred->owner_blk->rvlst)) {
ret = false;
goto end;
}
if (!fdo_hash_write(fdow, ocred->owner_blk->pkh)) {
ret = false;
goto end;
}
if (!fdow_end_array(fdow)) {
ret = false;
goto end;
}
size_t encoded_cred_length = 0;
if (!fdow_encoded_length(fdow, &encoded_cred_length) ||
encoded_cred_length == 0) {
LOG(LOG_ERROR,
"Failed to get DeviceCredential encoded length\n");
ret = false;
goto end;
}
fdow->b.block_size = encoded_cred_length;

if (fdo_blob_write_nv(nv, flags, fdow->b.block, fdow->b.block_size) ==
-1) {
LOG(LOG_ERROR, "Failed to write DeviceCredential blob\n");
ret = false;
goto end;
}

end:
if (fdow) {
fdow_flush(fdow);
fdo_free(fdow);
}
#endif
return ret;
}

/**
* Read the Device Credentials blob from tpm nv, contains our state & owner_blk
* @param dev_cred_file - the blob the credentials are saved in
* @param flags - descriptor telling type of file
* @param our_dev_cred - pointer to the device credentials block,
* @return true if read and parsed correctly, otherwise false.
*/
bool read_tpm_device_credentials(uint32_t nv, fdo_sdk_blob_flags flags,
fdo_dev_cred_t *our_dev_cred)
{
bool ret = false;
size_t dev_cred_len = 0;
fdor_t *fdor = NULL;
int dev_state = -1;

if (!nv || !our_dev_cred) {
LOG(LOG_ERROR, "Invalid params\n");
return false;
}

if (our_dev_cred->owner_blk != NULL) {
fdo_cred_owner_free(our_dev_cred->owner_blk);
our_dev_cred->owner_blk = NULL;
}

/* Memory allocating data.inside dev_cred. */
our_dev_cred->owner_blk = fdo_cred_owner_alloc();
if (!our_dev_cred->owner_blk) {
LOG(LOG_ERROR, "dev_cred's owner_blk allocation failed\n");
goto end;
}

dev_cred_len = fdo_blob_size_nv(nv, flags);
// Device has not yet been initialized.
// Since, Normal.blob is empty, the file size will be 0
if (dev_cred_len == 0) {
LOG(LOG_DEBUG,
"DeviceCredential not found. Proceeding with DI\n");
our_dev_cred->ST = FDO_DEVICE_STATE_PC;
return true;
}

LOG(LOG_DEBUG, "Reading DeviceCredential blob of length %" PRIu64 "\n",
dev_cred_len);

fdor = fdo_alloc(sizeof(fdor_t));
if (!fdor || !fdor_init(fdor) ||
!fdo_block_alloc_with_size(&fdor->b, dev_cred_len)) {
LOG(LOG_ERROR, "FDOR Initialization/Allocation failed!\n");
goto end;
}

if (fdo_blob_read_nv(nv, flags, fdor->b.block, fdor->b.block_size) ==
-1) {
LOG(LOG_ERROR,
"Failed to read DeviceCredential blob : Normal.blob\n");
goto end;
}

if (!fdor_parser_init(fdor)) {
LOG(LOG_ERROR, "FDOR Parser Initialization failed!\n");
goto end;
}

if (!fdor_start_array(fdor)) {
LOG(LOG_ERROR,
"DeviceCredential read: Begin Array not found\n");
goto end;
}

if (!fdor_signed_int(fdor, &dev_state)) {
LOG(LOG_ERROR, "DeviceCredential read: ST not found\n");
goto end;
}
our_dev_cred->ST = dev_state;

if (!validate_state(our_dev_cred->ST)) {
LOG(LOG_ERROR, "DeviceCredential read: Invalid ST\n");
goto end;
}

if (!fdor_boolean(fdor, &our_dev_cred->dc_active)) {
LOG(LOG_ERROR, "DeviceCredential read: DCActive not found\n");
goto end;
}

if (!fdor_signed_int(fdor, &our_dev_cred->owner_blk->pv)) {
LOG(LOG_ERROR, "DeviceCredential read: DCProtVer not found\n");
goto end;
}

size_t device_info_length = 0;
if (!fdor_string_length(fdor, &device_info_length) ||
device_info_length == 0) {
LOG(LOG_ERROR,
"DeviceCredential read: Invalid DCDeviceInfo length\n");
goto end;
}

our_dev_cred->mfg_blk = fdo_cred_mfg_alloc();
if (!our_dev_cred->mfg_blk) {
LOG(LOG_ERROR,
"DeviceCredential read: Malloc for DCDeviceInfo failed");
goto end;
}

our_dev_cred->mfg_blk->d = fdo_string_alloc_size(device_info_length);
if (!our_dev_cred->mfg_blk->d ||
!fdor_text_string(fdor, our_dev_cred->mfg_blk->d->bytes,
our_dev_cred->mfg_blk->d->byte_sz)) {
LOG(LOG_ERROR,
"DeviceCredential read: DCDeviceInfo not found\n");
goto end;
}
our_dev_cred->mfg_blk->d->bytes[device_info_length] = '\0';

size_t guid_length = 0;
if (!fdor_string_length(fdor, &guid_length) || guid_length == 0) {
LOG(LOG_ERROR,
"DeviceCredential read: Invalid DCGuid length\n");
goto end;
}
our_dev_cred->owner_blk->guid = fdo_byte_array_alloc(guid_length);
if (!our_dev_cred->owner_blk->guid ||
!fdor_byte_string(fdor, our_dev_cred->owner_blk->guid->bytes,
our_dev_cred->owner_blk->guid->byte_sz)) {
LOG(LOG_ERROR, "DeviceCredential read: DCGuid not found\n");
goto end;
}

our_dev_cred->owner_blk->rvlst = fdo_rendezvous_list_alloc();
if (!our_dev_cred->owner_blk->rvlst ||
!fdo_rendezvous_list_read(fdor, our_dev_cred->owner_blk->rvlst)) {
LOG(LOG_ERROR, "DeviceCredential read: DCRVInfo not found\n");
goto end;
}

our_dev_cred->owner_blk->pkh =
fdo_hash_alloc(FDO_CRYPTO_HASH_TYPE_USED, FDO_SHA_DIGEST_SIZE_USED);
if (!our_dev_cred->owner_blk->pkh ||
!fdo_hash_read(fdor, our_dev_cred->owner_blk->pkh)) {
LOG(LOG_ERROR,
"DeviceCredential read: DCPubKeyHash not found\n");
goto end;
}

if (!fdor_end_array(fdor)) {
LOG(LOG_ERROR, "DeviceCredential read: End Array not found\n");
goto end;
}
ret = true;
end:
if (fdor) {
fdor_flush(fdor);
fdo_free(fdor);
}
return ret;
}

/**
* Write and save the device credentials passed as an parameter ocred of type
* fdo_dev_cred_t.
* @param ocred - Pointer of type fdo_dev_cred_t, credentials to be copied
* @return 0 if success, else -1 on failure.
*/
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)) {
LOG(LOG_ERROR, "Could not write to Normal Credentials blob\n");
return -1;
}
return 0;
}
#endif
Expand Down Expand Up @@ -627,6 +912,13 @@ int load_credential(fdo_dev_cred_t *ocred)
"Could not parse the Device Credentials form CSE\n");
return -1;
}
#elif defined(DEVICE_TPM20_ENABLED)
/* Read in the blob and save the device credentials */
if (!read_normal_tpm_credentials(FDO_CRED_NORMAL_NV_IDX,
FDO_SDK_NORMAL_DATA, ocred)) {
LOG(LOG_ERROR, "Could not parse the Device Credentials blob\n");
return -1;
}
#else
/* Read in the blob and save the device credentials */
if (!read_normal_device_credentials((char *)FDO_CRED_NORMAL,
Expand Down Expand Up @@ -684,6 +976,9 @@ bool load_device_status(fdo_sdk_device_status *state)
"DeviceCredential read: Unable to load file form CSE\n");
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);
#else
size_t dev_cred_len =
fdo_blob_size((char *)FDO_CRED_NORMAL, FDO_SDK_NORMAL_DATA);
Expand Down
5 changes: 4 additions & 1 deletion lib/fdo.c
Original file line number Diff line number Diff line change
Expand Up @@ -1160,8 +1160,11 @@ fdo_sdk_status fdo_sdk_resale(void)
LOG(LOG_ERROR, "Reading {Mfg|Secret} blob failied!\n");
return FDO_ERROR;
}

#if defined(DEVICE_TPM20_ENABLED)
ret = store_tpm_credential(g_fdo_data->devcred);
#else
ret = store_credential(g_fdo_data->devcred);
#endif
#endif
if (!ret) {
LOG(LOG_INFO, "Set Resale complete\n");
Expand Down
Loading

0 comments on commit 1f36645

Please sign in to comment.