1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (C) 2024, Institute of Information Security (IISEC) 4 */ 5 6 #include <base64.h> 7 #include <kernel/pseudo_ta.h> 8 #include <mempool.h> 9 #include <pta_veraison_attestation.h> 10 #include <stdlib.h> 11 #include <string.h> 12 13 #include "cbor.h" 14 #include "hash.h" 15 16 #define PTA_NAME "veraison_attestation.pta" 17 18 #define MAX_KEY_SIZE 4096 19 #define MAX_NONCE_SIZE 64 20 #define TEE_SHA256_HASH_SIZE 32 21 22 #define EAT_PROFILE "http://arm.com/psa/2.0.0" 23 #define CLIENT_ID 1 24 #define LIFECYCLE 12288 25 #define MEASURMENT_TYPE "PRoT" 26 #define SIGNER_ID_LEN 32 27 #define INSTANCE_ID_LEN 33 28 29 /* clang-format off */ 30 #define SIGNER_ID { \ 31 0xac, 0xbb, 0x11, 0xc7, 0xe4, 0xda, 0x21, 0x72, \ 32 0x05, 0x52, 0x3c, 0xe4, 0xce, 0x1a, 0x24, 0x5a, \ 33 0xe1, 0xa2, 0x39, 0xae, 0x3c, 0x6b, 0xfd, 0x9e, \ 34 0x78, 0x71, 0xf7, 0xe5, 0xd8, 0xba, 0xe8, 0x6b \ 35 } 36 #define INSTANCE_ID { \ 37 0x01, 0xce, 0xeb, 0xae, 0x7b, 0x89, 0x27, 0xa3, \ 38 0x22, 0x7e, 0x53, 0x03, 0xcf, 0x5e, 0x0f, 0x1f, \ 39 0x7b, 0x34, 0xbb, 0x54, 0x2a, 0xd7, 0x25, 0x0a, \ 40 0xc0, 0x3f, 0xbc, 0xde, 0x36, 0xec, 0x2f, 0x15, \ 41 0x08 \ 42 } 43 /* clang-format on */ 44 45 static TEE_Result cmd_get_cbor_evidence(uint32_t param_types, 46 TEE_Param params[TEE_NUM_PARAMS]) 47 { 48 const uint8_t *nonce = params[0].memref.buffer; 49 const size_t nonce_sz = params[0].memref.size; 50 uint8_t *output_buffer = params[1].memref.buffer; 51 size_t *output_buffer_len = ¶ms[1].memref.size; 52 const uint8_t *psa_implementation_id = params[2].memref.buffer; 53 const size_t psa_implementation_id_len = params[2].memref.size; 54 TEE_Result status = TEE_SUCCESS; 55 56 const char eat_profile[] = EAT_PROFILE; 57 const int psa_client_id = CLIENT_ID; 58 const int psa_security_lifecycle = LIFECYCLE; 59 const char measurement_type[] = MEASURMENT_TYPE; 60 const uint8_t signer_id[SIGNER_ID_LEN] = SIGNER_ID; 61 const uint8_t psa_instance_id[INSTANCE_ID_LEN] = INSTANCE_ID; 62 63 uint8_t measurement_value[TEE_SHA256_HASH_SIZE] = { 0 }; 64 size_t b64_measurement_value_len = TEE_SHA256_HASH_SIZE * 2; 65 char b64_measurement_value[TEE_SHA256_HASH_SIZE * 2] = { 0 }; 66 67 UsefulBufC ubc_cbor_evidence = { NULL, 0 }; 68 UsefulBufC ubc_cose_evidence = { NULL, 0 }; 69 70 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 71 TEE_PARAM_TYPE_MEMREF_OUTPUT, 72 TEE_PARAM_TYPE_MEMREF_INPUT, 73 TEE_PARAM_TYPE_NONE)) 74 return TEE_ERROR_BAD_PARAMETERS; 75 76 if (!nonce || !nonce_sz) 77 return TEE_ERROR_BAD_PARAMETERS; 78 79 if (!output_buffer && *output_buffer_len) 80 return TEE_ERROR_BAD_PARAMETERS; 81 82 /* Calculate measurement hash of memory */ 83 status = get_hash_ta_memory(measurement_value); 84 if (status != TEE_SUCCESS) 85 return status; 86 87 /* Encode measurement_value to base64 */ 88 if (!base64_enc(measurement_value, TEE_SHA256_HASH_SIZE, 89 b64_measurement_value, 90 &b64_measurement_value_len)) { 91 DMSG("Failed to encode measurement_value to base64"); 92 return TEE_ERROR_GENERIC; 93 } 94 DMSG("b64_measurement_value: %s", b64_measurement_value); 95 96 /* Encode evidence to CBOR */ 97 ubc_cbor_evidence = generate_cbor_evidence(eat_profile, 98 psa_client_id, 99 psa_security_lifecycle, 100 psa_implementation_id, 101 psa_implementation_id_len, 102 measurement_type, 103 signer_id, 104 SIGNER_ID_LEN, 105 psa_instance_id, 106 INSTANCE_ID_LEN, 107 nonce, 108 nonce_sz, 109 measurement_value, 110 TEE_SHA256_HASH_SIZE); 111 if (UsefulBuf_IsNULLC(ubc_cbor_evidence)) { 112 DMSG("Failed to encode evidence to CBOR"); 113 return TEE_ERROR_GENERIC; 114 } 115 116 /* Sign the CBOR and generate a COSE evidence */ 117 ubc_cose_evidence = generate_cose_evidence(ubc_cbor_evidence); 118 if (UsefulBuf_IsNULLC(ubc_cose_evidence)) { 119 DMSG("Failed to encode CBOR to COSE"); 120 status = TEE_ERROR_GENERIC; 121 goto free_ubc_cbor_evidence; 122 } 123 124 /* Copy COSE evidence for return buffer */ 125 if (ubc_cose_evidence.len > *output_buffer_len) { 126 *output_buffer_len = ubc_cose_evidence.len; 127 status = TEE_ERROR_SHORT_BUFFER; 128 goto free_ubc_cose_evidence; 129 } 130 memcpy(output_buffer, ubc_cose_evidence.ptr, ubc_cose_evidence.len); 131 *output_buffer_len = ubc_cose_evidence.len; 132 133 /* Free mempool allocation before returning to the caller */ 134 free_ubc_cose_evidence: 135 mempool_free(mempool_default, (void *)ubc_cose_evidence.ptr); 136 free_ubc_cbor_evidence: 137 mempool_free(mempool_default, (void *)ubc_cbor_evidence.ptr); 138 139 return status; 140 } 141 142 static TEE_Result invoke_command(void *sess_ctx __unused, uint32_t cmd_id, 143 uint32_t param_types, 144 TEE_Param params[TEE_NUM_PARAMS]) 145 { 146 switch (cmd_id) { 147 case PTA_VERAISON_ATTESTATION_GET_CBOR_EVIDENCE: 148 return cmd_get_cbor_evidence(param_types, params); 149 default: 150 break; 151 } 152 return TEE_ERROR_NOT_IMPLEMENTED; 153 } 154 155 pseudo_ta_register(.uuid = PTA_VERAISON_ATTESTATION_UUID, .name = PTA_NAME, 156 .flags = PTA_DEFAULT_FLAGS, 157 .invoke_command_entry_point = invoke_command); 158