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 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 92 93 assert(processing_is_tee_digest(proc_params->id)); 94 95 rc = allocate_tee_operation(session, proc_params); 96 if (!rc) 97 session->processing->mecha_type = proc_params->id; 98 99 return rc; 100 } 101 102 /* 103 * step_digest_operation - processing digest operation step 104 * 105 * @session - current session 106 * @step - step ID in the processing (oneshot, update, final) 107 * @obj - PKCS#11 object for key based operations 108 * @ptype - invocation parameter types 109 * @params - invocation parameter references 110 */ 111 enum pkcs11_rc step_digest_operation(struct pkcs11_session *session, 112 enum processing_step step, 113 struct pkcs11_object *obj, 114 uint32_t ptypes, TEE_Param *params) 115 { 116 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 117 TEE_Result res = TEE_ERROR_GENERIC; 118 void *in_buf = NULL; 119 size_t in_size = 0; 120 void *out_buf = NULL; 121 size_t out_size = 0; 122 void *secret_value = NULL; 123 uint32_t secret_value_size = 0; 124 enum pkcs11_key_type key_type = PKCS11_CKK_UNDEFINED_ID; 125 struct active_processing *proc = session->processing; 126 127 if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 128 in_buf = params[1].memref.buffer; 129 in_size = params[1].memref.size; 130 if (in_size && !in_buf) 131 return PKCS11_CKR_ARGUMENTS_BAD; 132 } 133 if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 134 out_buf = params[2].memref.buffer; 135 out_size = params[2].memref.size; 136 if (out_size && !out_buf) 137 return PKCS11_CKR_ARGUMENTS_BAD; 138 } 139 if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 140 return PKCS11_CKR_ARGUMENTS_BAD; 141 142 switch (step) { 143 case PKCS11_FUNC_STEP_ONESHOT: 144 case PKCS11_FUNC_STEP_UPDATE: 145 case PKCS11_FUNC_STEP_UPDATE_KEY: 146 case PKCS11_FUNC_STEP_FINAL: 147 break; 148 default: 149 TEE_Panic(step); 150 break; 151 } 152 153 assert(proc->tee_op_handle != TEE_HANDLE_NULL); 154 155 assert(processing_is_tee_digest(proc->mecha_type)); 156 157 /* 158 * Feed active operation with data 159 */ 160 161 switch (step) { 162 case PKCS11_FUNC_STEP_UPDATE_KEY: 163 assert(obj); 164 165 if (!IS_ENABLED(CFG_PKCS11_TA_ALLOW_DIGEST_KEY)) 166 return PKCS11_CKR_KEY_INDIGESTIBLE; 167 168 if (get_class(obj->attributes) != PKCS11_CKO_SECRET_KEY) 169 return PKCS11_CKR_KEY_INDIGESTIBLE; 170 171 key_type = get_key_type(obj->attributes); 172 173 if (key_type != PKCS11_CKK_GENERIC_SECRET && 174 key_type != PKCS11_CKK_AES) 175 return PKCS11_CKR_KEY_INDIGESTIBLE; 176 177 rc = get_attribute_ptr(obj->attributes, PKCS11_CKA_VALUE, 178 &secret_value, &secret_value_size); 179 assert(!rc && secret_value && secret_value_size); 180 181 TEE_DigestUpdate(proc->tee_op_handle, secret_value, 182 secret_value_size); 183 return PKCS11_CKR_OK; 184 185 case PKCS11_FUNC_STEP_UPDATE: 186 if (!in_buf || !in_size) 187 return PKCS11_CKR_OK; 188 189 TEE_DigestUpdate(proc->tee_op_handle, in_buf, in_size); 190 return PKCS11_CKR_OK; 191 192 case PKCS11_FUNC_STEP_ONESHOT: 193 if (!out_buf) 194 return PKCS11_CKR_ARGUMENTS_BAD; 195 196 goto do_final; 197 198 case PKCS11_FUNC_STEP_FINAL: 199 if (in_buf || !out_buf) 200 return PKCS11_CKR_ARGUMENTS_BAD; 201 202 goto do_final; 203 204 default: 205 TEE_Panic(step); 206 break; 207 } 208 209 do_final: 210 res = TEE_DigestDoFinal(proc->tee_op_handle, 211 in_buf, in_size, out_buf, 212 &out_size); 213 rc = tee2pkcs_error(res); 214 215 if (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL) 216 params[2].memref.size = out_size; 217 218 return rc; 219 } 220