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