1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2021, Vaisala Oyj 4 */ 5 6 #include <assert.h> 7 #include <config.h> 8 #include <pkcs11_ta.h> 9 #include <string.h> 10 #include <tee_api_defines.h> 11 #include <tee_internal_api.h> 12 #include <tee_internal_api_extensions.h> 13 #include <utee_defines.h> 14 #include <util.h> 15 16 #include "attributes.h" 17 #include "object.h" 18 #include "pkcs11_attributes.h" 19 #include "pkcs11_helpers.h" 20 #include "pkcs11_token.h" 21 #include "processing.h" 22 #include "serializer.h" 23 24 bool processing_is_tee_digest(enum pkcs11_mechanism_id mecha_id) 25 { 26 switch (mecha_id) { 27 case PKCS11_CKM_MD5: 28 case PKCS11_CKM_SHA_1: 29 case PKCS11_CKM_SHA224: 30 case PKCS11_CKM_SHA256: 31 case PKCS11_CKM_SHA384: 32 case PKCS11_CKM_SHA512: 33 return true; 34 default: 35 return false; 36 } 37 } 38 39 static enum pkcs11_rc 40 pkcs2tee_algorithm(uint32_t *tee_id, struct pkcs11_attribute_head *proc_params) 41 { 42 static const struct { 43 enum pkcs11_mechanism_id mech_id; 44 uint32_t tee_id; 45 } pkcs2tee_algo[] = { 46 { PKCS11_CKM_MD5, TEE_ALG_MD5 }, 47 { PKCS11_CKM_SHA_1, TEE_ALG_SHA1 }, 48 { PKCS11_CKM_SHA224, TEE_ALG_SHA224 }, 49 { PKCS11_CKM_SHA256, TEE_ALG_SHA256 }, 50 { PKCS11_CKM_SHA384, TEE_ALG_SHA384 }, 51 { PKCS11_CKM_SHA512, TEE_ALG_SHA512 }, 52 }; 53 size_t n = 0; 54 55 for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) { 56 if (proc_params->id == pkcs2tee_algo[n].mech_id) { 57 *tee_id = pkcs2tee_algo[n].tee_id; 58 return PKCS11_CKR_OK; 59 } 60 } 61 62 return PKCS11_RV_NOT_IMPLEMENTED; 63 } 64 65 static enum pkcs11_rc 66 allocate_tee_operation(struct pkcs11_session *session, 67 struct pkcs11_attribute_head *params) 68 { 69 uint32_t algo = 0; 70 TEE_Result res = TEE_ERROR_GENERIC; 71 72 assert(session->processing->tee_op_handle == TEE_HANDLE_NULL); 73 74 if (pkcs2tee_algorithm(&algo, params)) 75 return PKCS11_CKR_FUNCTION_FAILED; 76 77 res = TEE_AllocateOperation(&session->processing->tee_op_handle, 78 algo, TEE_MODE_DIGEST, 0); 79 if (res) 80 EMSG("TEE_AllocateOp. failed %#"PRIx32, algo); 81 82 if (res == TEE_ERROR_NOT_SUPPORTED) 83 return PKCS11_CKR_MECHANISM_INVALID; 84 85 return tee2pkcs_error(res); 86 } 87 88 enum pkcs11_rc init_digest_operation(struct pkcs11_session *session, 89 struct pkcs11_attribute_head *proc_params) 90 { 91 assert(processing_is_tee_digest(proc_params->id)); 92 93 return allocate_tee_operation(session, proc_params); 94 } 95 96 /* 97 * step_digest_operation - processing digest operation step 98 * 99 * @session - current session 100 * @step - step ID in the processing (oneshot, update, final) 101 * @obj - PKCS#11 object for key based operations 102 * @ptype - invocation parameter types 103 * @params - invocation parameter references 104 */ 105 enum pkcs11_rc step_digest_operation(struct pkcs11_session *session, 106 enum processing_step step, 107 struct pkcs11_object *obj, 108 uint32_t ptypes, TEE_Param *params) 109 { 110 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 111 TEE_Result res = TEE_ERROR_GENERIC; 112 void *in_buf = NULL; 113 size_t in_size = 0; 114 void *out_buf = NULL; 115 uint32_t out_size = 0; 116 void *secret_value = NULL; 117 uint32_t secret_value_size = 0; 118 enum pkcs11_key_type key_type = PKCS11_CKK_UNDEFINED_ID; 119 struct active_processing *proc = session->processing; 120 121 if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 122 in_buf = params[1].memref.buffer; 123 in_size = params[1].memref.size; 124 if (in_size && !in_buf) 125 return PKCS11_CKR_ARGUMENTS_BAD; 126 } 127 if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 128 out_buf = params[2].memref.buffer; 129 out_size = params[2].memref.size; 130 if (out_size && !out_buf) 131 return PKCS11_CKR_ARGUMENTS_BAD; 132 } 133 if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 134 return PKCS11_CKR_ARGUMENTS_BAD; 135 136 switch (step) { 137 case PKCS11_FUNC_STEP_ONESHOT: 138 case PKCS11_FUNC_STEP_UPDATE: 139 case PKCS11_FUNC_STEP_UPDATE_KEY: 140 case PKCS11_FUNC_STEP_FINAL: 141 break; 142 default: 143 TEE_Panic(step); 144 break; 145 } 146 147 assert(proc->tee_op_handle != TEE_HANDLE_NULL); 148 149 assert(processing_is_tee_digest(proc->mecha_type)); 150 151 /* 152 * Feed active operation with data 153 */ 154 155 switch (step) { 156 case PKCS11_FUNC_STEP_UPDATE_KEY: 157 assert(obj); 158 159 if (!IS_ENABLED(CFG_PKCS11_TA_ALLOW_DIGEST_KEY)) 160 return PKCS11_CKR_KEY_INDIGESTIBLE; 161 162 if (get_class(obj->attributes) != PKCS11_CKO_SECRET_KEY) 163 return PKCS11_CKR_KEY_INDIGESTIBLE; 164 165 key_type = get_key_type(obj->attributes); 166 167 if (key_type != PKCS11_CKK_GENERIC_SECRET && 168 key_type != PKCS11_CKK_AES) 169 return PKCS11_CKR_KEY_INDIGESTIBLE; 170 171 rc = get_attribute_ptr(obj->attributes, PKCS11_CKA_VALUE, 172 &secret_value, &secret_value_size); 173 assert(!rc && secret_value && secret_value_size); 174 175 TEE_DigestUpdate(proc->tee_op_handle, secret_value, 176 secret_value_size); 177 return PKCS11_CKR_OK; 178 179 case PKCS11_FUNC_STEP_UPDATE: 180 if (!in_buf || !in_size) 181 return PKCS11_CKR_OK; 182 183 TEE_DigestUpdate(proc->tee_op_handle, in_buf, in_size); 184 return PKCS11_CKR_OK; 185 186 case PKCS11_FUNC_STEP_ONESHOT: 187 if (!out_buf) 188 return PKCS11_CKR_ARGUMENTS_BAD; 189 190 goto do_final; 191 192 case PKCS11_FUNC_STEP_FINAL: 193 if (in_buf || !out_buf) 194 return PKCS11_CKR_ARGUMENTS_BAD; 195 196 goto do_final; 197 198 default: 199 TEE_Panic(step); 200 break; 201 } 202 203 do_final: 204 res = TEE_DigestDoFinal(proc->tee_op_handle, 205 in_buf, in_size, out_buf, 206 &out_size); 207 rc = tee2pkcs_error(res); 208 209 if (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL) 210 params[2].memref.size = out_size; 211 212 return rc; 213 } 214