diff --git a/include/services/drtm_svc.h b/include/services/drtm_svc.h index 3503fa465..86110db87 100644 --- a/include/services/drtm_svc.h +++ b/include/services/drtm_svc.h @@ -14,6 +14,8 @@ #ifndef ARM_DRTM_SVC_H #define ARM_DRTM_SVC_H +#include + /* * SMC function IDs for DRTM Service * Upper word bits set: Fast call, SMC64, Standard Secure Svc. Call (OEN = 4) @@ -239,6 +241,21 @@ << ARM_DRTM_REGION_SIZE_TYPE_4K_PAGE_NUM_SHIFT)); \ } while (false) +#define DRTM_LAUNCH_FEAT_DLME_IMG_AUTH_SHIFT U(6) +#define DRTM_LAUNCH_FEAT_MEM_PROTECTION_TYPE_SHIFT U(3) +#define DRTM_LAUNCH_FEAT_PCR_USAGE_SCHEMA_SHIFT U(1) +#define DRTM_LAUNCH_FEAT_HASHING_TYPE_SHIFT U(0) + +#define DRTM_LAUNCH_FEAT_DLME_IMG_AUTH_MASK U(0x1) +#define DRTM_LAUNCH_FEAT_MEM_PROTECTION_TYPE_MASK U(0x7) +#define DRTM_LAUNCH_FEAT_PCR_USAGE_SCHEMA_MASK U(0x3) +#define DRTM_LAUNCH_FEAT_HASHING_TYPE_MASK U(0x1) + +#define DLME_IMG_AUTH U(0x1) +#define REG_MEM_PROTECTION_TYPE U(0x1) +#define DLME_AUTH_SCHEMA U(0x1) +#define TPM_BASED_HASHING U(0x1) + /* Initialization routine for the DRTM service */ int drtm_setup(void); diff --git a/services/std_svc/drtm/drtm_main.c b/services/std_svc/drtm/drtm_main.c index 117934f25..c3028635b 100644 --- a/services/std_svc/drtm/drtm_main.c +++ b/services/std_svc/drtm/drtm_main.c @@ -34,6 +34,8 @@ static drtm_features_t plat_drtm_features; /* DRTM-formatted memory map. */ static drtm_memory_region_descriptor_table_t *plat_drtm_mem_map; +static const plat_drtm_dma_prot_features_t *plat_dma_prot_feat; +static const plat_drtm_tpm_features_t *plat_tpm_feat; /* DLME header */ struct_dlme_data_header dlme_data_hdr_init; @@ -44,8 +46,6 @@ uint64_t dlme_data_min_size; int drtm_setup(void) { bool rc; - const plat_drtm_tpm_features_t *plat_tpm_feat; - const plat_drtm_dma_prot_features_t *plat_dma_prot_feat; INFO("DRTM service setup\n"); @@ -322,6 +322,43 @@ static enum drtm_retc drtm_dl_prepare_dlme_data(const struct_drtm_dl_args *args) return SUCCESS; } +/* Function to check if the value is valid for each bit field */ +static int drtm_dl_check_features_sanity(uint32_t val) +{ + /** + * Ensure that if DLME Authorities Schema (Bits [2:1]) is set, then + * DLME image authentication (Bit[6]) must also be set + */ + if ((EXTRACT_FIELD(val, DRTM_LAUNCH_FEAT_PCR_USAGE_SCHEMA_MASK, + DRTM_LAUNCH_FEAT_PCR_USAGE_SCHEMA_SHIFT) == DLME_AUTH_SCHEMA) && + (EXTRACT_FIELD(val, DRTM_LAUNCH_FEAT_DLME_IMG_AUTH_MASK, + DRTM_LAUNCH_FEAT_DLME_IMG_AUTH_SHIFT) != DLME_IMG_AUTH)) { + return INVALID_PARAMETERS; + } + + /** + * Check if Bits [5:3] (Memory protection type) matches with platform's + * memory protection type + */ + if (EXTRACT_FIELD(val, DRTM_LAUNCH_FEAT_MEM_PROTECTION_TYPE_MASK, + DRTM_LAUNCH_FEAT_MEM_PROTECTION_TYPE_SHIFT) != + __builtin_ctz(plat_dma_prot_feat->dma_protection_support)) { + return INVALID_PARAMETERS; + } + + /** + * Check if Bits [0] (Type of hashing) matches with platform's + * supported hash type. + */ + if (EXTRACT_FIELD(val, DRTM_LAUNCH_FEAT_HASHING_TYPE_MASK, + DRTM_LAUNCH_FEAT_HASHING_TYPE_SHIFT) != + plat_tpm_feat->tpm_based_hash_support) { + return INVALID_PARAMETERS; + } + + return 0; +} + /* * Note: accesses to the dynamic launch args, and to the DLME data are * little-endian as required, thanks to TF-A BL31 init requirements. @@ -369,7 +406,7 @@ static enum drtm_retc drtm_dl_check_args(uint64_t x1, args_buf = *a; rc = mmap_remove_dynamic_region(va_mapping, va_mapping_size); - if (rc) { + if (rc != 0) { ERROR("%s(): mmap_remove_dynamic_region() failed unexpectedly" " rc=%d\n", __func__, rc); panic(); @@ -383,6 +420,13 @@ static enum drtm_retc drtm_dl_check_args(uint64_t x1, return NOT_SUPPORTED; } + rc = drtm_dl_check_features_sanity(a->features); + if (rc != 0) { + ERROR("%s(): drtm_dl_check_features_sanity() failed.\n" + " rc=%d\n", __func__, rc); + return rc; + } + if (!(a->dlme_img_off < a->dlme_size && a->dlme_data_off < a->dlme_size)) { ERROR("DRTM: argument offset is outside of the DLME region\n");