1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2018-2020, Linaro Limited 4 */ 5 6 #include <assert.h> 7 #include <compiler.h> 8 #include <tee_api_defines.h> 9 #include <tee_internal_api.h> 10 #include <tee_internal_api_extensions.h> 11 12 #include "attributes.h" 13 #include "pkcs11_helpers.h" 14 #include "pkcs11_token.h" 15 #include "processing.h" 16 #include "serializer.h" 17 18 bool processing_is_tee_asymm(uint32_t proc_id) 19 { 20 switch (proc_id) { 21 /* EC flavors */ 22 case PKCS11_CKM_ECDSA: 23 case PKCS11_CKM_ECDSA_SHA1: 24 case PKCS11_CKM_ECDSA_SHA224: 25 case PKCS11_CKM_ECDSA_SHA256: 26 case PKCS11_CKM_ECDSA_SHA384: 27 case PKCS11_CKM_ECDSA_SHA512: 28 return true; 29 default: 30 return false; 31 } 32 } 33 34 static enum pkcs11_rc 35 pkcs2tee_algorithm(uint32_t *tee_id, uint32_t *tee_hash_id, 36 enum processing_func function __unused, 37 struct pkcs11_attribute_head *proc_params, 38 struct pkcs11_object *obj) 39 { 40 static const struct { 41 enum pkcs11_mechanism_id mech_id; 42 uint32_t tee_id; 43 uint32_t tee_hash_id; 44 } pkcs2tee_algo[] = { 45 /* EC flavors (Must find key size from the object) */ 46 { PKCS11_CKM_ECDSA, 1, 0 }, 47 { PKCS11_CKM_ECDSA_SHA1, 1, TEE_ALG_SHA1 }, 48 { PKCS11_CKM_ECDSA_SHA224, 1, TEE_ALG_SHA224 }, 49 { PKCS11_CKM_ECDSA_SHA256, 1, TEE_ALG_SHA256 }, 50 { PKCS11_CKM_ECDSA_SHA384, 1, TEE_ALG_SHA384 }, 51 { PKCS11_CKM_ECDSA_SHA512, 1, TEE_ALG_SHA512 }, 52 }; 53 size_t n = 0; 54 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 55 56 for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) { 57 if (pkcs2tee_algo[n].mech_id == proc_params->id) { 58 *tee_id = pkcs2tee_algo[n].tee_id; 59 *tee_hash_id = pkcs2tee_algo[n].tee_hash_id; 60 break; 61 } 62 } 63 64 if (n == ARRAY_SIZE(pkcs2tee_algo)) 65 return PKCS11_RV_NOT_IMPLEMENTED; 66 67 switch (proc_params->id) { 68 case PKCS11_CKM_ECDSA: 69 case PKCS11_CKM_ECDSA_SHA1: 70 case PKCS11_CKM_ECDSA_SHA224: 71 case PKCS11_CKM_ECDSA_SHA256: 72 case PKCS11_CKM_ECDSA_SHA384: 73 case PKCS11_CKM_ECDSA_SHA512: 74 rc = pkcs2tee_algo_ecdsa(tee_id, proc_params, obj); 75 break; 76 default: 77 rc = PKCS11_CKR_OK; 78 break; 79 } 80 81 return rc; 82 } 83 84 static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type, 85 struct pkcs11_object *obj, 86 enum processing_func function) 87 { 88 enum pkcs11_class_id class = get_class(obj->attributes); 89 enum pkcs11_key_type type = get_key_type(obj->attributes); 90 91 switch (class) { 92 case PKCS11_CKO_PUBLIC_KEY: 93 case PKCS11_CKO_PRIVATE_KEY: 94 break; 95 default: 96 TEE_Panic(class); 97 break; 98 } 99 100 switch (type) { 101 case PKCS11_CKK_EC: 102 assert(function != PKCS11_FUNCTION_DERIVE); 103 104 if (class == PKCS11_CKO_PRIVATE_KEY) 105 *tee_type = TEE_TYPE_ECDSA_KEYPAIR; 106 else 107 *tee_type = TEE_TYPE_ECDSA_PUBLIC_KEY; 108 break; 109 default: 110 TEE_Panic(type); 111 break; 112 } 113 114 return PKCS11_CKR_OK; 115 } 116 117 static enum pkcs11_rc 118 allocate_tee_operation(struct pkcs11_session *session, 119 enum processing_func function, 120 struct pkcs11_attribute_head *params, 121 struct pkcs11_object *obj) 122 { 123 uint32_t size = (uint32_t)get_object_key_bit_size(obj); 124 uint32_t algo = 0; 125 uint32_t hash_algo = 0; 126 uint32_t mode = 0; 127 uint32_t hash_mode = 0; 128 TEE_Result res = TEE_ERROR_GENERIC; 129 struct active_processing *processing = session->processing; 130 131 assert(processing->tee_op_handle == TEE_HANDLE_NULL); 132 assert(processing->tee_hash_op_handle == TEE_HANDLE_NULL); 133 134 if (pkcs2tee_algorithm(&algo, &hash_algo, function, params, obj)) 135 return PKCS11_CKR_FUNCTION_FAILED; 136 137 pkcs2tee_mode(&mode, function); 138 139 if (hash_algo) { 140 pkcs2tee_mode(&hash_mode, PKCS11_FUNCTION_DIGEST); 141 142 res = TEE_AllocateOperation(&processing->tee_hash_op_handle, 143 hash_algo, hash_mode, 0); 144 if (res) { 145 EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32, 146 hash_algo, hash_mode); 147 148 if (res == TEE_ERROR_NOT_SUPPORTED) 149 return PKCS11_CKR_MECHANISM_INVALID; 150 return tee2pkcs_error(res); 151 } 152 processing->tee_hash_algo = hash_algo; 153 } 154 155 res = TEE_AllocateOperation(&processing->tee_op_handle, 156 algo, mode, size); 157 if (res) 158 EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32, 159 algo, mode, size); 160 161 if (res == TEE_ERROR_NOT_SUPPORTED) 162 return PKCS11_CKR_MECHANISM_INVALID; 163 164 if (res != TEE_SUCCESS && 165 processing->tee_hash_op_handle != TEE_HANDLE_NULL) { 166 TEE_FreeOperation(session->processing->tee_hash_op_handle); 167 processing->tee_hash_op_handle = TEE_HANDLE_NULL; 168 processing->tee_hash_algo = 0; 169 } 170 171 return tee2pkcs_error(res); 172 } 173 174 static enum pkcs11_rc load_tee_key(struct pkcs11_session *session, 175 struct pkcs11_object *obj, 176 enum processing_func function) 177 { 178 TEE_Attribute *tee_attrs = NULL; 179 size_t tee_attrs_count = 0; 180 size_t object_size = 0; 181 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 182 TEE_Result res = TEE_ERROR_GENERIC; 183 enum pkcs11_class_id __maybe_unused class = get_class(obj->attributes); 184 enum pkcs11_key_type type = get_key_type(obj->attributes); 185 186 assert(class == PKCS11_CKO_PUBLIC_KEY || 187 class == PKCS11_CKO_PRIVATE_KEY); 188 189 if (obj->key_handle != TEE_HANDLE_NULL) { 190 switch (type) { 191 case PKCS11_CKK_EC: 192 /* Reuse EC TEE key only if already DSA or DH */ 193 switch (obj->key_type) { 194 case TEE_TYPE_ECDSA_PUBLIC_KEY: 195 case TEE_TYPE_ECDSA_KEYPAIR: 196 if (function != PKCS11_FUNCTION_DERIVE) 197 goto key_ready; 198 break; 199 default: 200 assert(0); 201 break; 202 } 203 break; 204 default: 205 assert(0); 206 break; 207 } 208 209 TEE_CloseObject(obj->key_handle); 210 obj->key_handle = TEE_HANDLE_NULL; 211 } 212 213 rc = pkcs2tee_key_type(&obj->key_type, obj, function); 214 if (rc) 215 return rc; 216 217 object_size = get_object_key_bit_size(obj); 218 if (!object_size) 219 return PKCS11_CKR_GENERAL_ERROR; 220 221 switch (type) { 222 case PKCS11_CKK_EC: 223 rc = load_tee_ec_key_attrs(&tee_attrs, &tee_attrs_count, obj); 224 break; 225 default: 226 break; 227 } 228 if (rc) 229 return rc; 230 231 res = TEE_AllocateTransientObject(obj->key_type, object_size, 232 &obj->key_handle); 233 if (res) { 234 DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 235 236 return tee2pkcs_error(res); 237 } 238 239 res = TEE_PopulateTransientObject(obj->key_handle, 240 tee_attrs, tee_attrs_count); 241 242 TEE_Free(tee_attrs); 243 244 if (res) { 245 DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res); 246 247 goto error; 248 } 249 250 key_ready: 251 res = TEE_SetOperationKey(session->processing->tee_op_handle, 252 obj->key_handle); 253 if (res) { 254 DMSG("TEE_SetOperationKey failed, %#"PRIx32, res); 255 256 goto error; 257 } 258 259 return PKCS11_CKR_OK; 260 261 error: 262 TEE_FreeTransientObject(obj->key_handle); 263 obj->key_handle = TEE_HANDLE_NULL; 264 return tee2pkcs_error(res); 265 } 266 267 static enum pkcs11_rc 268 init_tee_operation(struct pkcs11_session *session __unused, 269 struct pkcs11_attribute_head *proc_params __unused) 270 { 271 return PKCS11_CKR_OK; 272 } 273 274 enum pkcs11_rc init_asymm_operation(struct pkcs11_session *session, 275 enum processing_func function, 276 struct pkcs11_attribute_head *proc_params, 277 struct pkcs11_object *obj) 278 { 279 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 280 281 assert(processing_is_tee_asymm(proc_params->id)); 282 283 rc = allocate_tee_operation(session, function, proc_params, obj); 284 if (rc) 285 return rc; 286 287 rc = load_tee_key(session, obj, function); 288 if (rc) 289 return rc; 290 291 return init_tee_operation(session, proc_params); 292 } 293 294 /* 295 * step_sym_step - step (update/oneshot/final) on a symmetric crypto operation 296 * 297 * @session - current session 298 * @function - processing function (encrypt, decrypt, sign, ...) 299 * @step - step ID in the processing (oneshot, update, final) 300 * @ptypes - invocation parameter types 301 * @params - invocation parameter references 302 */ 303 enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session, 304 enum processing_func function, 305 enum processing_step step, 306 uint32_t ptypes, TEE_Param *params) 307 { 308 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 309 TEE_Result res = TEE_ERROR_GENERIC; 310 void *in_buf = NULL; 311 void *in2_buf = NULL; 312 void *out_buf = NULL; 313 void *hash_buf = NULL; 314 uint32_t in_size = 0; 315 uint32_t in2_size = 0; 316 uint32_t out_size = 0; 317 uint32_t hash_size = 0; 318 TEE_Attribute *tee_attrs = NULL; 319 size_t tee_attrs_count = 0; 320 bool output_data = false; 321 struct active_processing *proc = session->processing; 322 size_t sz = 0; 323 324 if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 325 in_buf = params[1].memref.buffer; 326 in_size = params[1].memref.size; 327 if (in_size && !in_buf) 328 return PKCS11_CKR_ARGUMENTS_BAD; 329 } 330 if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) { 331 in2_buf = params[2].memref.buffer; 332 in2_size = params[2].memref.size; 333 if (in2_size && !in2_buf) 334 return PKCS11_CKR_ARGUMENTS_BAD; 335 } 336 if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 337 out_buf = params[2].memref.buffer; 338 out_size = params[2].memref.size; 339 if (out_size && !out_buf) 340 return PKCS11_CKR_ARGUMENTS_BAD; 341 } 342 if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 343 return PKCS11_CKR_ARGUMENTS_BAD; 344 345 switch (step) { 346 case PKCS11_FUNC_STEP_ONESHOT: 347 case PKCS11_FUNC_STEP_UPDATE: 348 case PKCS11_FUNC_STEP_FINAL: 349 break; 350 default: 351 return PKCS11_CKR_GENERAL_ERROR; 352 } 353 354 /* 355 * Handle multi stage update step for mechas needing hash 356 * calculation 357 */ 358 if (step == PKCS11_FUNC_STEP_UPDATE) { 359 switch (proc->mecha_type) { 360 case PKCS11_CKM_ECDSA_SHA1: 361 case PKCS11_CKM_ECDSA_SHA224: 362 case PKCS11_CKM_ECDSA_SHA256: 363 case PKCS11_CKM_ECDSA_SHA384: 364 case PKCS11_CKM_ECDSA_SHA512: 365 assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL); 366 367 TEE_DigestUpdate(proc->tee_hash_op_handle, in_buf, 368 in_size); 369 break; 370 default: 371 /* 372 * Other mechanism do not expect multi stage 373 * operation 374 */ 375 rc = PKCS11_CKR_GENERAL_ERROR; 376 break; 377 } 378 379 goto out; 380 } 381 382 /* 383 * Handle multi stage one shot and final steps for mechas needing hash 384 * calculation 385 */ 386 switch (proc->mecha_type) { 387 case PKCS11_CKM_ECDSA_SHA1: 388 case PKCS11_CKM_ECDSA_SHA224: 389 case PKCS11_CKM_ECDSA_SHA256: 390 case PKCS11_CKM_ECDSA_SHA384: 391 case PKCS11_CKM_ECDSA_SHA512: 392 assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL); 393 394 hash_size = TEE_ALG_GET_DIGEST_SIZE(proc->tee_hash_algo); 395 hash_buf = TEE_Malloc(hash_size, 0); 396 if (!hash_buf) 397 return PKCS11_CKR_DEVICE_MEMORY; 398 399 res = TEE_DigestDoFinal(proc->tee_hash_op_handle, 400 in_buf, in_size, hash_buf, 401 &hash_size); 402 403 rc = tee2pkcs_error(res); 404 if (rc != PKCS11_CKR_OK) 405 goto out; 406 407 break; 408 default: 409 break; 410 } 411 412 /* 413 * Finalize either provided hash or calculated hash with signing 414 * operation 415 */ 416 417 /* First determine amount of bytes for signing operation */ 418 switch (proc->mecha_type) { 419 case PKCS11_CKM_ECDSA: 420 sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle); 421 if (!in_size || !sz) { 422 rc = PKCS11_CKR_FUNCTION_FAILED; 423 goto out; 424 } 425 426 /* 427 * Note 3) Input the entire raw digest. Internally, this will 428 * be truncated to the appropriate number of bits. 429 */ 430 if (in_size > sz) 431 in_size = sz; 432 433 if (function == PKCS11_FUNCTION_VERIFY && in2_size != 2 * sz) { 434 rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 435 goto out; 436 } 437 break; 438 case PKCS11_CKM_ECDSA_SHA1: 439 case PKCS11_CKM_ECDSA_SHA224: 440 case PKCS11_CKM_ECDSA_SHA256: 441 case PKCS11_CKM_ECDSA_SHA384: 442 case PKCS11_CKM_ECDSA_SHA512: 443 /* Get key size in bytes */ 444 sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle); 445 if (!sz) { 446 rc = PKCS11_CKR_FUNCTION_FAILED; 447 goto out; 448 } 449 450 if (function == PKCS11_FUNCTION_VERIFY && 451 in2_size != 2 * sz) { 452 rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 453 goto out; 454 } 455 break; 456 default: 457 break; 458 } 459 460 /* Next perform actual signing operation */ 461 switch (proc->mecha_type) { 462 case PKCS11_CKM_ECDSA: 463 /* For operations using provided input data */ 464 switch (function) { 465 case PKCS11_FUNCTION_ENCRYPT: 466 res = TEE_AsymmetricEncrypt(proc->tee_op_handle, 467 tee_attrs, tee_attrs_count, 468 in_buf, in_size, 469 out_buf, &out_size); 470 output_data = true; 471 rc = tee2pkcs_error(res); 472 break; 473 474 case PKCS11_FUNCTION_DECRYPT: 475 res = TEE_AsymmetricDecrypt(proc->tee_op_handle, 476 tee_attrs, tee_attrs_count, 477 in_buf, in_size, 478 out_buf, &out_size); 479 output_data = true; 480 rc = tee2pkcs_error(res); 481 break; 482 483 case PKCS11_FUNCTION_SIGN: 484 res = TEE_AsymmetricSignDigest(proc->tee_op_handle, 485 tee_attrs, 486 tee_attrs_count, 487 in_buf, in_size, 488 out_buf, &out_size); 489 output_data = true; 490 rc = tee2pkcs_error(res); 491 break; 492 493 case PKCS11_FUNCTION_VERIFY: 494 res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle, 495 tee_attrs, 496 tee_attrs_count, 497 in_buf, in_size, 498 in2_buf, in2_size); 499 rc = tee2pkcs_error(res); 500 break; 501 502 default: 503 TEE_Panic(function); 504 break; 505 } 506 break; 507 case PKCS11_CKM_ECDSA_SHA1: 508 case PKCS11_CKM_ECDSA_SHA224: 509 case PKCS11_CKM_ECDSA_SHA256: 510 case PKCS11_CKM_ECDSA_SHA384: 511 case PKCS11_CKM_ECDSA_SHA512: 512 /* For operations having hash operation use calculated hash */ 513 switch (function) { 514 case PKCS11_FUNCTION_SIGN: 515 res = TEE_AsymmetricSignDigest(proc->tee_op_handle, 516 tee_attrs, 517 tee_attrs_count, 518 hash_buf, hash_size, 519 out_buf, &out_size); 520 output_data = true; 521 rc = tee2pkcs_error(res); 522 break; 523 524 case PKCS11_FUNCTION_VERIFY: 525 res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle, 526 tee_attrs, 527 tee_attrs_count, 528 hash_buf, hash_size, 529 in2_buf, in2_size); 530 rc = tee2pkcs_error(res); 531 break; 532 533 default: 534 TEE_Panic(function); 535 break; 536 } 537 break; 538 default: 539 TEE_Panic(proc->mecha_type); 540 break; 541 } 542 543 out: 544 if (output_data && 545 (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) { 546 switch (TEE_PARAM_TYPE_GET(ptypes, 2)) { 547 case TEE_PARAM_TYPE_MEMREF_OUTPUT: 548 case TEE_PARAM_TYPE_MEMREF_INOUT: 549 params[2].memref.size = out_size; 550 break; 551 default: 552 rc = PKCS11_CKR_GENERAL_ERROR; 553 break; 554 } 555 } 556 557 TEE_Free(hash_buf); 558 TEE_Free(tee_attrs); 559 560 return rc; 561 } 562