1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2017-2020, Linaro Limited 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 <util.h> 13 14 #include "attributes.h" 15 #include "object.h" 16 #include "pkcs11_attributes.h" 17 #include "pkcs11_helpers.h" 18 #include "pkcs11_token.h" 19 #include "processing.h" 20 #include "serializer.h" 21 22 static enum pkcs11_rc get_ready_session(struct pkcs11_session *session) 23 { 24 if (session_is_active(session)) 25 return PKCS11_CKR_OPERATION_ACTIVE; 26 27 return PKCS11_CKR_OK; 28 } 29 30 static bool func_matches_state(enum processing_func function, 31 enum pkcs11_proc_state state) 32 { 33 switch (function) { 34 case PKCS11_FUNCTION_ENCRYPT: 35 return state == PKCS11_SESSION_ENCRYPTING || 36 state == PKCS11_SESSION_DIGESTING_ENCRYPTING || 37 state == PKCS11_SESSION_SIGNING_ENCRYPTING; 38 case PKCS11_FUNCTION_DECRYPT: 39 return state == PKCS11_SESSION_DECRYPTING || 40 state == PKCS11_SESSION_DECRYPTING_DIGESTING || 41 state == PKCS11_SESSION_DECRYPTING_VERIFYING; 42 case PKCS11_FUNCTION_DIGEST: 43 return state == PKCS11_SESSION_DIGESTING || 44 state == PKCS11_SESSION_DIGESTING_ENCRYPTING; 45 case PKCS11_FUNCTION_SIGN: 46 return state == PKCS11_SESSION_SIGNING || 47 state == PKCS11_SESSION_SIGNING_ENCRYPTING; 48 case PKCS11_FUNCTION_VERIFY: 49 return state == PKCS11_SESSION_VERIFYING || 50 state == PKCS11_SESSION_DECRYPTING_VERIFYING; 51 case PKCS11_FUNCTION_SIGN_RECOVER: 52 return state == PKCS11_SESSION_SIGNING_RECOVER; 53 case PKCS11_FUNCTION_VERIFY_RECOVER: 54 return state == PKCS11_SESSION_SIGNING_RECOVER; 55 default: 56 TEE_Panic(function); 57 return false; 58 } 59 } 60 61 static enum pkcs11_rc get_active_session(struct pkcs11_session *session, 62 enum processing_func function) 63 { 64 enum pkcs11_rc rc = PKCS11_CKR_OPERATION_NOT_INITIALIZED; 65 66 if (session->processing && 67 func_matches_state(function, session->processing->state)) 68 rc = PKCS11_CKR_OK; 69 70 return rc; 71 } 72 73 void release_active_processing(struct pkcs11_session *session) 74 { 75 if (!session->processing) 76 return; 77 78 if (session->processing->tee_op_handle != TEE_HANDLE_NULL) { 79 TEE_FreeOperation(session->processing->tee_op_handle); 80 session->processing->tee_op_handle = TEE_HANDLE_NULL; 81 } 82 83 TEE_Free(session->processing->extra_ctx); 84 85 TEE_Free(session->processing); 86 session->processing = NULL; 87 } 88 89 size_t get_object_key_bit_size(struct pkcs11_object *obj) 90 { 91 uint32_t a_size = 0; 92 struct obj_attrs *attrs = obj->attributes; 93 94 switch (get_key_type(attrs)) { 95 case PKCS11_CKK_AES: 96 case PKCS11_CKK_GENERIC_SECRET: 97 case PKCS11_CKK_MD5_HMAC: 98 case PKCS11_CKK_SHA_1_HMAC: 99 case PKCS11_CKK_SHA224_HMAC: 100 case PKCS11_CKK_SHA256_HMAC: 101 case PKCS11_CKK_SHA384_HMAC: 102 case PKCS11_CKK_SHA512_HMAC: 103 if (get_attribute_ptr(attrs, PKCS11_CKA_VALUE, NULL, &a_size)) 104 return 0; 105 106 return a_size * 8; 107 default: 108 TEE_Panic(0); 109 return 0; 110 } 111 } 112 113 static enum pkcs11_rc generate_random_key_value(struct obj_attrs **head) 114 { 115 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 116 void *data = NULL; 117 uint32_t data_size = 0; 118 uint32_t value_len = 0; 119 void *value = NULL; 120 121 if (!*head) 122 return PKCS11_CKR_TEMPLATE_INCONSISTENT; 123 124 rc = get_attribute_ptr(*head, PKCS11_CKA_VALUE_LEN, &data, &data_size); 125 if (rc || data_size != sizeof(uint32_t)) { 126 DMSG("%s", rc ? "No attribute value_len found" : 127 "Invalid size for attribute VALUE_LEN"); 128 129 return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 130 } 131 TEE_MemMove(&value_len, data, data_size); 132 133 if (get_key_type(*head) == PKCS11_CKK_GENERIC_SECRET) 134 value_len = (value_len + 7) / 8; 135 136 /* Remove the default empty value attribute if found */ 137 rc = remove_empty_attribute(head, PKCS11_CKA_VALUE); 138 if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND) 139 return PKCS11_CKR_GENERAL_ERROR; 140 141 value = TEE_Malloc(value_len, TEE_USER_MEM_HINT_NO_FILL_ZERO); 142 if (!value) 143 return PKCS11_CKR_DEVICE_MEMORY; 144 145 TEE_GenerateRandom(value, value_len); 146 147 rc = add_attribute(head, PKCS11_CKA_VALUE, value, value_len); 148 149 TEE_Free(value); 150 151 return rc; 152 } 153 154 enum pkcs11_rc entry_generate_secret(struct pkcs11_client *client, 155 uint32_t ptypes, TEE_Param *params) 156 { 157 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 158 TEE_PARAM_TYPE_NONE, 159 TEE_PARAM_TYPE_MEMREF_OUTPUT, 160 TEE_PARAM_TYPE_NONE); 161 TEE_Param *ctrl = params; 162 TEE_Param *out = params + 2; 163 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 164 struct serialargs ctrlargs = { }; 165 struct pkcs11_session *session = NULL; 166 struct pkcs11_attribute_head *proc_params = NULL; 167 struct obj_attrs *head = NULL; 168 struct pkcs11_object_head *template = NULL; 169 size_t template_size = 0; 170 uint32_t obj_handle = 0; 171 172 if (!client || ptypes != exp_pt || 173 out->memref.size != sizeof(obj_handle)) 174 return PKCS11_CKR_ARGUMENTS_BAD; 175 176 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 177 178 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 179 if (rc) 180 return rc; 181 182 rc = serialargs_alloc_get_one_attribute(&ctrlargs, &proc_params); 183 if (rc) 184 goto out; 185 186 rc = serialargs_alloc_get_attributes(&ctrlargs, &template); 187 if (rc) 188 goto out; 189 190 if (serialargs_remaining_bytes(&ctrlargs)) { 191 rc = PKCS11_CKR_ARGUMENTS_BAD; 192 goto out; 193 } 194 195 rc = get_ready_session(session); 196 if (rc) 197 goto out; 198 199 template_size = sizeof(*template) + template->attrs_size; 200 201 rc = check_mechanism_against_processing(session, proc_params->id, 202 PKCS11_FUNCTION_GENERATE, 203 PKCS11_FUNC_STEP_INIT); 204 if (rc) { 205 DMSG("Invalid mechanism %#"PRIx32": %#x", proc_params->id, rc); 206 goto out; 207 } 208 209 /* 210 * Prepare a clean initial state for the requested object attributes. 211 * Free temporary template once done. 212 */ 213 rc = create_attributes_from_template(&head, template, template_size, 214 NULL, PKCS11_FUNCTION_GENERATE, 215 proc_params->id, 216 PKCS11_CKO_UNDEFINED_ID); 217 if (rc) 218 goto out; 219 220 TEE_Free(template); 221 template = NULL; 222 223 rc = check_created_attrs(head, NULL); 224 if (rc) 225 goto out; 226 227 rc = check_created_attrs_against_processing(proc_params->id, head); 228 if (rc) 229 goto out; 230 231 rc = check_created_attrs_against_token(session, head); 232 if (rc) 233 goto out; 234 235 /* 236 * Execute target processing and add value as attribute 237 * PKCS11_CKA_VALUE. Symm key generation: depends on target 238 * processing to be used. 239 */ 240 switch (proc_params->id) { 241 case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 242 case PKCS11_CKM_AES_KEY_GEN: 243 /* Generate random of size specified by attribute VALUE_LEN */ 244 rc = generate_random_key_value(&head); 245 if (rc) 246 goto out; 247 break; 248 249 default: 250 rc = PKCS11_CKR_MECHANISM_INVALID; 251 goto out; 252 } 253 254 TEE_Free(proc_params); 255 proc_params = NULL; 256 257 /* 258 * Object is ready, register it and return a handle. 259 */ 260 rc = create_object(session, head, &obj_handle); 261 if (rc) 262 goto out; 263 264 /* 265 * Now obj_handle (through the related struct pkcs11_object instance) 266 * owns the serialized buffer that holds the object attributes. 267 * We reset head to NULL as it is no more the buffer owner and would 268 * be freed at function out. 269 */ 270 head = NULL; 271 272 TEE_MemMove(out->memref.buffer, &obj_handle, sizeof(obj_handle)); 273 out->memref.size = sizeof(obj_handle); 274 275 DMSG("PKCS11 session %"PRIu32": generate secret %#"PRIx32, 276 session->handle, obj_handle); 277 278 out: 279 TEE_Free(proc_params); 280 TEE_Free(template); 281 TEE_Free(head); 282 283 return rc; 284 } 285 286 /* 287 * entry_processing_init - Generic entry for initializing a processing 288 * 289 * @client = client reference 290 * @ptype = Invocation parameter types 291 * @params = Invocation parameters reference 292 * @function - encrypt, decrypt, sign, verify, digest, ... 293 */ 294 enum pkcs11_rc entry_processing_init(struct pkcs11_client *client, 295 uint32_t ptypes, TEE_Param *params, 296 enum processing_func function) 297 { 298 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 299 TEE_PARAM_TYPE_NONE, 300 TEE_PARAM_TYPE_NONE, 301 TEE_PARAM_TYPE_NONE); 302 TEE_Param *ctrl = params; 303 enum pkcs11_rc rc = PKCS11_CKR_OK; 304 struct serialargs ctrlargs = { }; 305 struct pkcs11_session *session = NULL; 306 struct pkcs11_attribute_head *proc_params = NULL; 307 uint32_t key_handle = 0; 308 struct pkcs11_object *obj = NULL; 309 310 if (!client || ptypes != exp_pt) 311 return PKCS11_CKR_ARGUMENTS_BAD; 312 313 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 314 315 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 316 if (rc) 317 return rc; 318 319 rc = serialargs_get(&ctrlargs, &key_handle, sizeof(uint32_t)); 320 if (rc) 321 return rc; 322 323 rc = serialargs_alloc_get_one_attribute(&ctrlargs, &proc_params); 324 if (rc) 325 return rc; 326 327 if (serialargs_remaining_bytes(&ctrlargs)) { 328 rc = PKCS11_CKR_ARGUMENTS_BAD; 329 goto out; 330 } 331 332 rc = get_ready_session(session); 333 if (rc) 334 goto out; 335 336 obj = pkcs11_handle2object(key_handle, session); 337 if (!obj) { 338 rc = PKCS11_CKR_KEY_HANDLE_INVALID; 339 goto out; 340 } 341 342 rc = set_processing_state(session, function, obj, NULL); 343 if (rc) 344 goto out; 345 346 rc = check_mechanism_against_processing(session, proc_params->id, 347 function, 348 PKCS11_FUNC_STEP_INIT); 349 if (rc) 350 goto out; 351 352 rc = check_parent_attrs_against_processing(proc_params->id, function, 353 obj->attributes); 354 if (rc) 355 goto out; 356 357 rc = check_access_attrs_against_token(session, obj->attributes); 358 if (rc) 359 goto out; 360 361 if (processing_is_tee_symm(proc_params->id)) 362 rc = init_symm_operation(session, function, proc_params, obj); 363 else 364 rc = PKCS11_CKR_MECHANISM_INVALID; 365 366 if (rc == PKCS11_CKR_OK) { 367 session->processing->mecha_type = proc_params->id; 368 DMSG("PKCS11 session %"PRIu32": init processing %s %s", 369 session->handle, id2str_proc(proc_params->id), 370 id2str_function(function)); 371 } 372 373 out: 374 if (rc && session) 375 release_active_processing(session); 376 377 TEE_Free(proc_params); 378 379 return rc; 380 } 381 382 /* 383 * entry_processing_step - Generic entry on active processing 384 * 385 * @client = client reference 386 * @ptype = Invocation parameter types 387 * @params = Invocation parameters reference 388 * @function - encrypt, decrypt, sign, verify, digest, ... 389 * @step - update, oneshot, final 390 */ 391 enum pkcs11_rc entry_processing_step(struct pkcs11_client *client, 392 uint32_t ptypes, TEE_Param *params, 393 enum processing_func function, 394 enum processing_step step) 395 { 396 TEE_Param *ctrl = params; 397 enum pkcs11_rc rc = PKCS11_CKR_OK; 398 struct serialargs ctrlargs = { }; 399 struct pkcs11_session *session = NULL; 400 enum pkcs11_mechanism_id mecha_type = PKCS11_CKM_UNDEFINED_ID; 401 402 if (!client || 403 TEE_PARAM_TYPE_GET(ptypes, 0) != TEE_PARAM_TYPE_MEMREF_INOUT) 404 return PKCS11_CKR_ARGUMENTS_BAD; 405 406 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 407 408 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 409 if (rc) 410 return rc; 411 412 if (serialargs_remaining_bytes(&ctrlargs)) 413 return PKCS11_CKR_ARGUMENTS_BAD; 414 415 rc = get_active_session(session, function); 416 if (rc) 417 return rc; 418 419 mecha_type = session->processing->mecha_type; 420 rc = check_mechanism_against_processing(session, mecha_type, 421 function, step); 422 if (rc) 423 goto out; 424 425 if (processing_is_tee_symm(mecha_type)) 426 rc = step_symm_operation(session, function, step, 427 ptypes, params); 428 else 429 rc = PKCS11_CKR_MECHANISM_INVALID; 430 431 if (rc == PKCS11_CKR_OK && step == PKCS11_FUNC_STEP_UPDATE) { 432 session->processing->updated = true; 433 DMSG("PKCS11 session%"PRIu32": processing %s %s", 434 session->handle, id2str_proc(mecha_type), 435 id2str_function(function)); 436 } 437 438 out: 439 switch (step) { 440 case PKCS11_FUNC_STEP_UPDATE: 441 if (rc != PKCS11_CKR_OK && rc != PKCS11_CKR_BUFFER_TOO_SMALL) 442 release_active_processing(session); 443 break; 444 default: 445 /* ONESHOT and FINAL terminates processing on success */ 446 if (rc != PKCS11_CKR_BUFFER_TOO_SMALL) 447 release_active_processing(session); 448 break; 449 } 450 451 return rc; 452 } 453