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 <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_symm(enum pkcs11_mechanism_id proc_id) 24 { 25 switch (proc_id) { 26 /* Cipherering */ 27 case PKCS11_CKM_AES_ECB: 28 case PKCS11_CKM_AES_CBC: 29 case PKCS11_CKM_AES_CBC_PAD: 30 case PKCS11_CKM_AES_CTS: 31 case PKCS11_CKM_AES_CTR: 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 /* AES flavors */ 46 { PKCS11_CKM_AES_ECB, TEE_ALG_AES_ECB_NOPAD }, 47 { PKCS11_CKM_AES_CBC, TEE_ALG_AES_CBC_NOPAD }, 48 { PKCS11_CKM_AES_CBC_PAD, TEE_ALG_AES_CBC_NOPAD }, 49 { PKCS11_CKM_AES_CTR, TEE_ALG_AES_CTR }, 50 { PKCS11_CKM_AES_CTS, TEE_ALG_AES_CTS }, 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 pkcs2tee_key_type(uint32_t *tee_type, 65 struct pkcs11_object *obj) 66 { 67 static const struct { 68 enum pkcs11_key_type key_type; 69 uint32_t tee_id; 70 } pkcs2tee_key_type[] = { 71 { PKCS11_CKK_AES, TEE_TYPE_AES }, 72 { PKCS11_CKK_GENERIC_SECRET, TEE_TYPE_GENERIC_SECRET }, 73 { PKCS11_CKK_MD5_HMAC, TEE_TYPE_HMAC_MD5 }, 74 { PKCS11_CKK_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 }, 75 { PKCS11_CKK_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 }, 76 { PKCS11_CKK_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 }, 77 { PKCS11_CKK_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 }, 78 { PKCS11_CKK_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 }, 79 }; 80 size_t n = 0; 81 enum pkcs11_key_type key_type = get_key_type(obj->attributes); 82 83 assert(get_class(obj->attributes) == PKCS11_CKO_SECRET_KEY); 84 85 for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) { 86 if (pkcs2tee_key_type[n].key_type == key_type) { 87 *tee_type = pkcs2tee_key_type[n].tee_id; 88 return PKCS11_CKR_OK; 89 } 90 } 91 92 return PKCS11_RV_NOT_FOUND; 93 } 94 95 static enum pkcs11_rc 96 allocate_tee_operation(struct pkcs11_session *session, 97 enum processing_func function, 98 struct pkcs11_attribute_head *params, 99 struct pkcs11_object *obj) 100 { 101 uint32_t size = (uint32_t)get_object_key_bit_size(obj); 102 uint32_t algo = 0; 103 uint32_t mode = 0; 104 TEE_Result res = TEE_ERROR_GENERIC; 105 106 assert(session->processing->tee_op_handle == TEE_HANDLE_NULL); 107 108 if (pkcs2tee_algorithm(&algo, params)) 109 return PKCS11_CKR_FUNCTION_FAILED; 110 111 /* Sign/Verify with AES or generic key relate to TEE MAC operation */ 112 pkcs2tee_mode(&mode, function); 113 114 res = TEE_AllocateOperation(&session->processing->tee_op_handle, 115 algo, mode, size); 116 if (res) 117 EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32, 118 algo, mode, size); 119 120 if (res == TEE_ERROR_NOT_SUPPORTED) 121 return PKCS11_CKR_MECHANISM_INVALID; 122 123 return tee2pkcs_error(res); 124 } 125 126 static enum pkcs11_rc load_tee_key(struct pkcs11_session *session, 127 struct pkcs11_object *obj) 128 { 129 TEE_Attribute tee_attr = { }; 130 size_t object_size = 0; 131 uint32_t tee_key_type = 0; 132 enum pkcs11_rc rc = PKCS11_CKR_OK; 133 TEE_Result res = TEE_ERROR_GENERIC; 134 135 if (obj->key_handle != TEE_HANDLE_NULL) { 136 /* Key was already loaded and fits current need */ 137 goto key_ready; 138 } 139 140 if (!pkcs2tee_load_attr(&tee_attr, TEE_ATTR_SECRET_VALUE, 141 obj, PKCS11_CKA_VALUE)) { 142 EMSG("No secret found"); 143 return PKCS11_CKR_FUNCTION_FAILED; 144 } 145 146 rc = pkcs2tee_key_type(&tee_key_type, obj); 147 if (rc) 148 return rc; 149 150 object_size = get_object_key_bit_size(obj); 151 if (!object_size) 152 return PKCS11_CKR_GENERAL_ERROR; 153 154 res = TEE_AllocateTransientObject(tee_key_type, object_size, 155 &obj->key_handle); 156 if (res) { 157 DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 158 return tee2pkcs_error(res); 159 } 160 161 res = TEE_PopulateTransientObject(obj->key_handle, &tee_attr, 1); 162 if (res) { 163 DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res); 164 goto error; 165 } 166 167 key_ready: 168 res = TEE_SetOperationKey(session->processing->tee_op_handle, 169 obj->key_handle); 170 if (res) { 171 DMSG("TEE_SetOperationKey failed, %#"PRIx32, res); 172 goto error; 173 } 174 175 return PKCS11_CKR_OK; 176 177 error: 178 TEE_FreeTransientObject(obj->key_handle); 179 obj->key_handle = TEE_HANDLE_NULL; 180 181 return tee2pkcs_error(res); 182 } 183 184 static enum pkcs11_rc 185 init_tee_operation(struct pkcs11_session *session, 186 struct pkcs11_attribute_head *proc_params) 187 { 188 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 189 190 switch (proc_params->id) { 191 case PKCS11_CKM_AES_ECB: 192 if (proc_params->size) 193 return PKCS11_CKR_MECHANISM_PARAM_INVALID; 194 195 TEE_CipherInit(session->processing->tee_op_handle, NULL, 0); 196 rc = PKCS11_CKR_OK; 197 break; 198 case PKCS11_CKM_AES_CBC: 199 case PKCS11_CKM_AES_CBC_PAD: 200 case PKCS11_CKM_AES_CTS: 201 if (proc_params->size != 16) 202 return PKCS11_CKR_MECHANISM_PARAM_INVALID; 203 204 TEE_CipherInit(session->processing->tee_op_handle, 205 proc_params->data, 16); 206 rc = PKCS11_CKR_OK; 207 break; 208 case PKCS11_CKM_AES_CTR: 209 rc = tee_init_ctr_operation(session->processing, 210 proc_params->data, 211 proc_params->size); 212 break; 213 default: 214 TEE_Panic(proc_params->id); 215 break; 216 } 217 218 return rc; 219 } 220 221 enum pkcs11_rc init_symm_operation(struct pkcs11_session *session, 222 enum processing_func function, 223 struct pkcs11_attribute_head *proc_params, 224 struct pkcs11_object *obj) 225 { 226 enum pkcs11_rc rc = PKCS11_CKR_OK; 227 228 assert(processing_is_tee_symm(proc_params->id)); 229 230 rc = allocate_tee_operation(session, function, proc_params, obj); 231 if (rc) 232 return rc; 233 234 rc = load_tee_key(session, obj); 235 if (rc) 236 return rc; 237 238 return init_tee_operation(session, proc_params); 239 } 240 241 /* Validate input buffer size as per PKCS#11 constraints */ 242 static enum pkcs11_rc input_data_size_is_valid(struct active_processing *proc, 243 enum processing_func function, 244 size_t in_size) 245 { 246 switch (proc->mecha_type) { 247 case PKCS11_CKM_AES_ECB: 248 case PKCS11_CKM_AES_CBC: 249 if (function == PKCS11_FUNCTION_ENCRYPT && 250 in_size % TEE_AES_BLOCK_SIZE) 251 return PKCS11_CKR_DATA_LEN_RANGE; 252 if (function == PKCS11_FUNCTION_DECRYPT && 253 in_size % TEE_AES_BLOCK_SIZE) 254 return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 255 break; 256 case PKCS11_CKM_AES_CBC_PAD: 257 if (function == PKCS11_FUNCTION_DECRYPT && 258 in_size % TEE_AES_BLOCK_SIZE) 259 return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 260 break; 261 case PKCS11_CKM_AES_CTS: 262 if (function == PKCS11_FUNCTION_ENCRYPT && 263 in_size < TEE_AES_BLOCK_SIZE) 264 return PKCS11_CKR_DATA_LEN_RANGE; 265 if (function == PKCS11_FUNCTION_DECRYPT && 266 in_size < TEE_AES_BLOCK_SIZE) 267 return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 268 break; 269 default: 270 break; 271 } 272 273 return PKCS11_CKR_OK; 274 } 275 276 /* 277 * step_sym_cipher - processing symmetric (and related) cipher operation step 278 * 279 * @session - current session 280 * @function - processing function (encrypt, decrypt, sign, ...) 281 * @step - step ID in the processing (oneshot, update, final) 282 * @ptype - invocation parameter types 283 * @params - invocation parameter references 284 */ 285 enum pkcs11_rc step_symm_operation(struct pkcs11_session *session, 286 enum processing_func function, 287 enum processing_step step, 288 uint32_t ptypes, TEE_Param *params) 289 { 290 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 291 TEE_Result res = TEE_ERROR_GENERIC; 292 void *in_buf = NULL; 293 size_t in_size = 0; 294 void *out_buf = NULL; 295 uint32_t out_size = 0; 296 void *in2_buf = NULL; 297 uint32_t in2_size = 0; 298 bool output_data = false; 299 struct active_processing *proc = session->processing; 300 301 if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 302 in_buf = params[1].memref.buffer; 303 in_size = params[1].memref.size; 304 if (in_size && !in_buf) 305 return PKCS11_CKR_ARGUMENTS_BAD; 306 } 307 if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) { 308 in2_buf = params[2].memref.buffer; 309 in2_size = params[2].memref.size; 310 if (in2_size && !in2_buf) 311 return PKCS11_CKR_ARGUMENTS_BAD; 312 } 313 if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 314 out_buf = params[2].memref.buffer; 315 out_size = params[2].memref.size; 316 if (out_size && !out_buf) 317 return PKCS11_CKR_ARGUMENTS_BAD; 318 } 319 if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 320 return PKCS11_CKR_ARGUMENTS_BAD; 321 322 switch (step) { 323 case PKCS11_FUNC_STEP_ONESHOT: 324 case PKCS11_FUNC_STEP_UPDATE: 325 case PKCS11_FUNC_STEP_FINAL: 326 break; 327 default: 328 return PKCS11_CKR_GENERAL_ERROR; 329 } 330 331 if (step != PKCS11_FUNC_STEP_FINAL) { 332 rc = input_data_size_is_valid(proc, function, in_size); 333 if (rc) 334 return rc; 335 } 336 337 /* 338 * Feed active operation with data 339 * (PKCS11_FUNC_STEP_UPDATE/_ONESHOT) 340 */ 341 switch (proc->mecha_type) { 342 case PKCS11_CKM_AES_ECB: 343 case PKCS11_CKM_AES_CBC: 344 case PKCS11_CKM_AES_CBC_PAD: 345 case PKCS11_CKM_AES_CTS: 346 case PKCS11_CKM_AES_CTR: 347 if (step == PKCS11_FUNC_STEP_FINAL || 348 step == PKCS11_FUNC_STEP_ONESHOT) 349 break; 350 351 if (!in_buf) { 352 EMSG("No input data"); 353 return PKCS11_CKR_ARGUMENTS_BAD; 354 } 355 356 switch (function) { 357 case PKCS11_FUNCTION_ENCRYPT: 358 case PKCS11_FUNCTION_DECRYPT: 359 res = TEE_CipherUpdate(proc->tee_op_handle, 360 in_buf, in_size, 361 out_buf, &out_size); 362 output_data = true; 363 rc = tee2pkcs_error(res); 364 break; 365 default: 366 TEE_Panic(function); 367 break; 368 } 369 break; 370 371 default: 372 TEE_Panic(proc->mecha_type); 373 break; 374 } 375 376 if (step == PKCS11_FUNC_STEP_UPDATE) 377 goto out; 378 379 /* 380 * Finalize (PKCS11_FUNC_STEP_ONESHOT/_FINAL) operation 381 */ 382 switch (session->processing->mecha_type) { 383 case PKCS11_CKM_AES_ECB: 384 case PKCS11_CKM_AES_CBC: 385 case PKCS11_CKM_AES_CBC_PAD: 386 case PKCS11_CKM_AES_CTS: 387 case PKCS11_CKM_AES_CTR: 388 if (step == PKCS11_FUNC_STEP_ONESHOT && !in_buf) { 389 EMSG("No input data"); 390 return PKCS11_CKR_ARGUMENTS_BAD; 391 } 392 393 switch (function) { 394 case PKCS11_FUNCTION_ENCRYPT: 395 case PKCS11_FUNCTION_DECRYPT: 396 res = TEE_CipherDoFinal(proc->tee_op_handle, 397 in_buf, in_size, 398 out_buf, &out_size); 399 output_data = true; 400 rc = tee2pkcs_error(res); 401 break; 402 default: 403 TEE_Panic(function); 404 break; 405 } 406 break; 407 default: 408 TEE_Panic(proc->mecha_type); 409 break; 410 } 411 412 out: 413 if (output_data && 414 (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) { 415 switch (TEE_PARAM_TYPE_GET(ptypes, 2)) { 416 case TEE_PARAM_TYPE_MEMREF_OUTPUT: 417 case TEE_PARAM_TYPE_MEMREF_INOUT: 418 params[2].memref.size = out_size; 419 break; 420 default: 421 rc = PKCS11_CKR_ARGUMENTS_BAD; 422 break; 423 } 424 } 425 426 return rc; 427 } 428