1512cbf1dSJens Wiklander // SPDX-License-Identifier: BSD-2-Clause 2512cbf1dSJens Wiklander /* 3512cbf1dSJens Wiklander * Copyright (c) 2017-2020, Linaro Limited 4512cbf1dSJens Wiklander */ 5512cbf1dSJens Wiklander 6512cbf1dSJens Wiklander #include <assert.h> 7512cbf1dSJens Wiklander #include <pkcs11_ta.h> 8512cbf1dSJens Wiklander #include <string.h> 9512cbf1dSJens Wiklander #include <tee_api_defines.h> 10512cbf1dSJens Wiklander #include <tee_internal_api.h> 11512cbf1dSJens Wiklander #include <tee_internal_api_extensions.h> 12512cbf1dSJens Wiklander #include <utee_defines.h> 13512cbf1dSJens Wiklander #include <util.h> 14512cbf1dSJens Wiklander 15512cbf1dSJens Wiklander #include "attributes.h" 16512cbf1dSJens Wiklander #include "object.h" 17512cbf1dSJens Wiklander #include "pkcs11_attributes.h" 18512cbf1dSJens Wiklander #include "pkcs11_helpers.h" 19512cbf1dSJens Wiklander #include "pkcs11_token.h" 20512cbf1dSJens Wiklander #include "processing.h" 21512cbf1dSJens Wiklander #include "serializer.h" 22512cbf1dSJens Wiklander 23512cbf1dSJens Wiklander bool processing_is_tee_symm(enum pkcs11_mechanism_id proc_id) 24512cbf1dSJens Wiklander { 25512cbf1dSJens Wiklander switch (proc_id) { 26689f4e5bSRuchika Gupta /* Authentication */ 27689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 28689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 29689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 30689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 31689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 32689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 33512cbf1dSJens Wiklander /* Cipherering */ 34512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 35512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 36512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 37512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 38512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 39512cbf1dSJens Wiklander return true; 40512cbf1dSJens Wiklander default: 41512cbf1dSJens Wiklander return false; 42512cbf1dSJens Wiklander } 43512cbf1dSJens Wiklander } 44512cbf1dSJens Wiklander 45512cbf1dSJens Wiklander static enum pkcs11_rc 46512cbf1dSJens Wiklander pkcs2tee_algorithm(uint32_t *tee_id, struct pkcs11_attribute_head *proc_params) 47512cbf1dSJens Wiklander { 48512cbf1dSJens Wiklander static const struct { 49512cbf1dSJens Wiklander enum pkcs11_mechanism_id mech_id; 50512cbf1dSJens Wiklander uint32_t tee_id; 51512cbf1dSJens Wiklander } pkcs2tee_algo[] = { 52512cbf1dSJens Wiklander /* AES flavors */ 53512cbf1dSJens Wiklander { PKCS11_CKM_AES_ECB, TEE_ALG_AES_ECB_NOPAD }, 54512cbf1dSJens Wiklander { PKCS11_CKM_AES_CBC, TEE_ALG_AES_CBC_NOPAD }, 55512cbf1dSJens Wiklander { PKCS11_CKM_AES_CBC_PAD, TEE_ALG_AES_CBC_NOPAD }, 56512cbf1dSJens Wiklander { PKCS11_CKM_AES_CTR, TEE_ALG_AES_CTR }, 57512cbf1dSJens Wiklander { PKCS11_CKM_AES_CTS, TEE_ALG_AES_CTS }, 58689f4e5bSRuchika Gupta /* HMAC flavors */ 59689f4e5bSRuchika Gupta { PKCS11_CKM_MD5_HMAC, TEE_ALG_HMAC_MD5 }, 60689f4e5bSRuchika Gupta { PKCS11_CKM_SHA_1_HMAC, TEE_ALG_HMAC_SHA1 }, 61689f4e5bSRuchika Gupta { PKCS11_CKM_SHA224_HMAC, TEE_ALG_HMAC_SHA224 }, 62689f4e5bSRuchika Gupta { PKCS11_CKM_SHA256_HMAC, TEE_ALG_HMAC_SHA256 }, 63689f4e5bSRuchika Gupta { PKCS11_CKM_SHA384_HMAC, TEE_ALG_HMAC_SHA384 }, 64689f4e5bSRuchika Gupta { PKCS11_CKM_SHA512_HMAC, TEE_ALG_HMAC_SHA512 }, 65512cbf1dSJens Wiklander }; 66512cbf1dSJens Wiklander size_t n = 0; 67512cbf1dSJens Wiklander 68512cbf1dSJens Wiklander for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) { 69512cbf1dSJens Wiklander if (proc_params->id == pkcs2tee_algo[n].mech_id) { 70512cbf1dSJens Wiklander *tee_id = pkcs2tee_algo[n].tee_id; 71512cbf1dSJens Wiklander return PKCS11_CKR_OK; 72512cbf1dSJens Wiklander } 73512cbf1dSJens Wiklander } 74512cbf1dSJens Wiklander 75512cbf1dSJens Wiklander return PKCS11_RV_NOT_IMPLEMENTED; 76512cbf1dSJens Wiklander } 77512cbf1dSJens Wiklander 78512cbf1dSJens Wiklander static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type, 79512cbf1dSJens Wiklander struct pkcs11_object *obj) 80512cbf1dSJens Wiklander { 81512cbf1dSJens Wiklander static const struct { 82512cbf1dSJens Wiklander enum pkcs11_key_type key_type; 83512cbf1dSJens Wiklander uint32_t tee_id; 84512cbf1dSJens Wiklander } pkcs2tee_key_type[] = { 85512cbf1dSJens Wiklander { PKCS11_CKK_AES, TEE_TYPE_AES }, 86512cbf1dSJens Wiklander { PKCS11_CKK_GENERIC_SECRET, TEE_TYPE_GENERIC_SECRET }, 87512cbf1dSJens Wiklander { PKCS11_CKK_MD5_HMAC, TEE_TYPE_HMAC_MD5 }, 88512cbf1dSJens Wiklander { PKCS11_CKK_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 }, 89512cbf1dSJens Wiklander { PKCS11_CKK_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 }, 90512cbf1dSJens Wiklander { PKCS11_CKK_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 }, 91512cbf1dSJens Wiklander { PKCS11_CKK_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 }, 92512cbf1dSJens Wiklander { PKCS11_CKK_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 }, 93512cbf1dSJens Wiklander }; 94512cbf1dSJens Wiklander size_t n = 0; 95512cbf1dSJens Wiklander enum pkcs11_key_type key_type = get_key_type(obj->attributes); 96512cbf1dSJens Wiklander 97512cbf1dSJens Wiklander assert(get_class(obj->attributes) == PKCS11_CKO_SECRET_KEY); 98512cbf1dSJens Wiklander 99512cbf1dSJens Wiklander for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) { 100512cbf1dSJens Wiklander if (pkcs2tee_key_type[n].key_type == key_type) { 101512cbf1dSJens Wiklander *tee_type = pkcs2tee_key_type[n].tee_id; 102512cbf1dSJens Wiklander return PKCS11_CKR_OK; 103512cbf1dSJens Wiklander } 104512cbf1dSJens Wiklander } 105512cbf1dSJens Wiklander 106512cbf1dSJens Wiklander return PKCS11_RV_NOT_FOUND; 107512cbf1dSJens Wiklander } 108512cbf1dSJens Wiklander 109de94d6f8SRuchika Gupta static enum pkcs11_rc pkcsmech2tee_key_type(uint32_t *tee_type, 110de94d6f8SRuchika Gupta enum pkcs11_mechanism_id mech_id) 111de94d6f8SRuchika Gupta { 112de94d6f8SRuchika Gupta static const struct { 113de94d6f8SRuchika Gupta enum pkcs11_mechanism_id mech; 114de94d6f8SRuchika Gupta uint32_t tee_id; 115de94d6f8SRuchika Gupta } pkcs2tee_key_type[] = { 116de94d6f8SRuchika Gupta { PKCS11_CKM_MD5_HMAC, TEE_TYPE_HMAC_MD5 }, 117de94d6f8SRuchika Gupta { PKCS11_CKM_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 }, 118de94d6f8SRuchika Gupta { PKCS11_CKM_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 }, 119de94d6f8SRuchika Gupta { PKCS11_CKM_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 }, 120de94d6f8SRuchika Gupta { PKCS11_CKM_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 }, 121de94d6f8SRuchika Gupta { PKCS11_CKM_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 }, 122de94d6f8SRuchika Gupta }; 123de94d6f8SRuchika Gupta size_t n = 0; 124de94d6f8SRuchika Gupta 125de94d6f8SRuchika Gupta for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) { 126de94d6f8SRuchika Gupta if (pkcs2tee_key_type[n].mech == mech_id) { 127de94d6f8SRuchika Gupta *tee_type = pkcs2tee_key_type[n].tee_id; 128de94d6f8SRuchika Gupta return PKCS11_CKR_OK; 129de94d6f8SRuchika Gupta } 130de94d6f8SRuchika Gupta } 131de94d6f8SRuchika Gupta 132de94d6f8SRuchika Gupta return PKCS11_RV_NOT_FOUND; 133de94d6f8SRuchika Gupta } 134de94d6f8SRuchika Gupta 1352158ea6cSRuchika Gupta static enum pkcs11_rc hmac_to_tee_hash(uint32_t *algo, 1362158ea6cSRuchika Gupta enum pkcs11_mechanism_id mech_id) 1372158ea6cSRuchika Gupta { 1382158ea6cSRuchika Gupta static const struct { 1392158ea6cSRuchika Gupta enum pkcs11_mechanism_id mech; 1402158ea6cSRuchika Gupta uint32_t tee_id; 1412158ea6cSRuchika Gupta } hmac_hash[] = { 1422158ea6cSRuchika Gupta { PKCS11_CKM_MD5_HMAC, TEE_ALG_MD5 }, 1432158ea6cSRuchika Gupta { PKCS11_CKM_SHA_1_HMAC, TEE_ALG_SHA1 }, 1442158ea6cSRuchika Gupta { PKCS11_CKM_SHA224_HMAC, TEE_ALG_SHA224 }, 1452158ea6cSRuchika Gupta { PKCS11_CKM_SHA256_HMAC, TEE_ALG_SHA256 }, 1462158ea6cSRuchika Gupta { PKCS11_CKM_SHA384_HMAC, TEE_ALG_SHA384 }, 1472158ea6cSRuchika Gupta { PKCS11_CKM_SHA512_HMAC, TEE_ALG_SHA512 }, 1482158ea6cSRuchika Gupta }; 1492158ea6cSRuchika Gupta size_t n = 0; 1502158ea6cSRuchika Gupta 1512158ea6cSRuchika Gupta for (n = 0; n < ARRAY_SIZE(hmac_hash); n++) { 1522158ea6cSRuchika Gupta if (hmac_hash[n].mech == mech_id) { 1532158ea6cSRuchika Gupta *algo = hmac_hash[n].tee_id; 1542158ea6cSRuchika Gupta return PKCS11_CKR_OK; 1552158ea6cSRuchika Gupta } 1562158ea6cSRuchika Gupta } 1572158ea6cSRuchika Gupta 1582158ea6cSRuchika Gupta return PKCS11_RV_NOT_FOUND; 1592158ea6cSRuchika Gupta } 1602158ea6cSRuchika Gupta 161512cbf1dSJens Wiklander static enum pkcs11_rc 162512cbf1dSJens Wiklander allocate_tee_operation(struct pkcs11_session *session, 163512cbf1dSJens Wiklander enum processing_func function, 164512cbf1dSJens Wiklander struct pkcs11_attribute_head *params, 165512cbf1dSJens Wiklander struct pkcs11_object *obj) 166512cbf1dSJens Wiklander { 167512cbf1dSJens Wiklander uint32_t size = (uint32_t)get_object_key_bit_size(obj); 168460ba621SRuchika Gupta uint32_t key_size = size / 8; 169512cbf1dSJens Wiklander uint32_t algo = 0; 170512cbf1dSJens Wiklander uint32_t mode = 0; 171460ba621SRuchika Gupta uint32_t max_key_size = 0; 172460ba621SRuchika Gupta uint32_t min_key_size = 0; 173512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 174512cbf1dSJens Wiklander 175512cbf1dSJens Wiklander assert(session->processing->tee_op_handle == TEE_HANDLE_NULL); 176512cbf1dSJens Wiklander 177512cbf1dSJens Wiklander if (pkcs2tee_algorithm(&algo, params)) 178512cbf1dSJens Wiklander return PKCS11_CKR_FUNCTION_FAILED; 179512cbf1dSJens Wiklander 180512cbf1dSJens Wiklander /* Sign/Verify with AES or generic key relate to TEE MAC operation */ 181689f4e5bSRuchika Gupta switch (params->id) { 182689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 183689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 184689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 185689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 186689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 187689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 188*2d0cd829SRuchika Gupta mechanism_supported_key_sizes_bytes(params->id, &min_key_size, 189460ba621SRuchika Gupta &max_key_size); 190460ba621SRuchika Gupta if (key_size < min_key_size) 191460ba621SRuchika Gupta return PKCS11_CKR_KEY_SIZE_RANGE; 1922158ea6cSRuchika Gupta 1932158ea6cSRuchika Gupta /* 1942158ea6cSRuchika Gupta * If size of generic key is greater than the size 1952158ea6cSRuchika Gupta * supported by TEE API, this is not considered an 1962158ea6cSRuchika Gupta * error. When loading TEE key, we will hash the key 1972158ea6cSRuchika Gupta * to generate the appropriate key for HMAC operation. 1982158ea6cSRuchika Gupta * This key size will not be greater than the 1992158ea6cSRuchika Gupta * max_key_size. So we can use max_key_size for 2002158ea6cSRuchika Gupta * TEE_AllocateOperation(). 2012158ea6cSRuchika Gupta */ 2022158ea6cSRuchika Gupta if (key_size > max_key_size) 2032158ea6cSRuchika Gupta size = max_key_size * 8; 2042158ea6cSRuchika Gupta 205689f4e5bSRuchika Gupta mode = TEE_MODE_MAC; 206689f4e5bSRuchika Gupta break; 207689f4e5bSRuchika Gupta default: 208512cbf1dSJens Wiklander pkcs2tee_mode(&mode, function); 209689f4e5bSRuchika Gupta break; 210689f4e5bSRuchika Gupta } 211512cbf1dSJens Wiklander 212512cbf1dSJens Wiklander res = TEE_AllocateOperation(&session->processing->tee_op_handle, 213512cbf1dSJens Wiklander algo, mode, size); 214512cbf1dSJens Wiklander if (res) 215512cbf1dSJens Wiklander EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32, 216512cbf1dSJens Wiklander algo, mode, size); 217512cbf1dSJens Wiklander 218512cbf1dSJens Wiklander if (res == TEE_ERROR_NOT_SUPPORTED) 219512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_INVALID; 220512cbf1dSJens Wiklander 221512cbf1dSJens Wiklander return tee2pkcs_error(res); 222512cbf1dSJens Wiklander } 223512cbf1dSJens Wiklander 2242158ea6cSRuchika Gupta static enum pkcs11_rc hash_secret_helper(enum pkcs11_mechanism_id mech_id, 2252158ea6cSRuchika Gupta struct pkcs11_object *obj, 2262158ea6cSRuchika Gupta TEE_Attribute *tee_attr, 2272158ea6cSRuchika Gupta void **ctx, 2282158ea6cSRuchika Gupta size_t *object_size_bits) 2292158ea6cSRuchika Gupta { 2302158ea6cSRuchika Gupta uint32_t algo = 0; 2312158ea6cSRuchika Gupta void *hash_ptr = NULL; 2322158ea6cSRuchika Gupta uint32_t hash_size = 0; 2332158ea6cSRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK; 2342158ea6cSRuchika Gupta 2352158ea6cSRuchika Gupta rc = hmac_to_tee_hash(&algo, mech_id); 2362158ea6cSRuchika Gupta if (rc) 2372158ea6cSRuchika Gupta return rc; 2382158ea6cSRuchika Gupta 2392158ea6cSRuchika Gupta hash_size = TEE_ALG_GET_DIGEST_SIZE(algo); 2402158ea6cSRuchika Gupta hash_ptr = TEE_Malloc(hash_size, 0); 2412158ea6cSRuchika Gupta if (!hash_ptr) 2422158ea6cSRuchika Gupta return PKCS11_CKR_DEVICE_MEMORY; 2432158ea6cSRuchika Gupta 2442158ea6cSRuchika Gupta rc = pkcs2tee_load_hashed_attr(tee_attr, TEE_ATTR_SECRET_VALUE, obj, 2452158ea6cSRuchika Gupta PKCS11_CKA_VALUE, algo, hash_ptr, 2462158ea6cSRuchika Gupta &hash_size); 2472158ea6cSRuchika Gupta if (rc) { 2482158ea6cSRuchika Gupta EMSG("No secret/hash error"); 2492158ea6cSRuchika Gupta TEE_Free(hash_ptr); 2502158ea6cSRuchika Gupta return rc; 2512158ea6cSRuchika Gupta } 2522158ea6cSRuchika Gupta 2532158ea6cSRuchika Gupta *ctx = hash_ptr; 2542158ea6cSRuchika Gupta 2552158ea6cSRuchika Gupta *object_size_bits = hash_size * 8; 2562158ea6cSRuchika Gupta 2572158ea6cSRuchika Gupta return PKCS11_CKR_OK; 2582158ea6cSRuchika Gupta } 2592158ea6cSRuchika Gupta 260512cbf1dSJens Wiklander static enum pkcs11_rc load_tee_key(struct pkcs11_session *session, 261de94d6f8SRuchika Gupta struct pkcs11_object *obj, 262de94d6f8SRuchika Gupta struct pkcs11_attribute_head *proc_params) 263512cbf1dSJens Wiklander { 264512cbf1dSJens Wiklander TEE_Attribute tee_attr = { }; 265512cbf1dSJens Wiklander size_t object_size = 0; 266512cbf1dSJens Wiklander uint32_t tee_key_type = 0; 267de94d6f8SRuchika Gupta enum pkcs11_key_type key_type = 0; 268512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 269512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 2702158ea6cSRuchika Gupta uint32_t max_key_size = 0; 2712158ea6cSRuchika Gupta uint32_t min_key_size = 0; 272512cbf1dSJens Wiklander 273512cbf1dSJens Wiklander if (obj->key_handle != TEE_HANDLE_NULL) { 274512cbf1dSJens Wiklander /* Key was already loaded and fits current need */ 275512cbf1dSJens Wiklander goto key_ready; 276512cbf1dSJens Wiklander } 277512cbf1dSJens Wiklander 2782158ea6cSRuchika Gupta object_size = get_object_key_bit_size(obj); 2792158ea6cSRuchika Gupta if (!object_size) 2802158ea6cSRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 281512cbf1dSJens Wiklander 282de94d6f8SRuchika Gupta switch (proc_params->id) { 283de94d6f8SRuchika Gupta case PKCS11_CKM_MD5_HMAC: 284de94d6f8SRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 285de94d6f8SRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 286de94d6f8SRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 287de94d6f8SRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 288de94d6f8SRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 289de94d6f8SRuchika Gupta key_type = get_key_type(obj->attributes); 290de94d6f8SRuchika Gupta /* 291de94d6f8SRuchika Gupta * If Object Key type is PKCS11_CKK_GENERIC_SECRET, 292de94d6f8SRuchika Gupta * determine the tee_key_type using the 293de94d6f8SRuchika Gupta * mechanism instead of object key_type. 294de94d6f8SRuchika Gupta */ 295de94d6f8SRuchika Gupta if (key_type == PKCS11_CKK_GENERIC_SECRET) 296de94d6f8SRuchika Gupta rc = pkcsmech2tee_key_type(&tee_key_type, 297de94d6f8SRuchika Gupta proc_params->id); 298de94d6f8SRuchika Gupta else 299512cbf1dSJens Wiklander rc = pkcs2tee_key_type(&tee_key_type, obj); 300de94d6f8SRuchika Gupta 301512cbf1dSJens Wiklander if (rc) 302512cbf1dSJens Wiklander return rc; 303512cbf1dSJens Wiklander 304*2d0cd829SRuchika Gupta mechanism_supported_key_sizes_bytes(proc_params->id, 3052158ea6cSRuchika Gupta &min_key_size, 3062158ea6cSRuchika Gupta &max_key_size); 3072158ea6cSRuchika Gupta 3082158ea6cSRuchika Gupta if ((object_size / 8) > max_key_size) { 3092158ea6cSRuchika Gupta rc = hash_secret_helper(proc_params->id, obj, &tee_attr, 3102158ea6cSRuchika Gupta &session->processing->extra_ctx, 3112158ea6cSRuchika Gupta &object_size); 3122158ea6cSRuchika Gupta if (rc) 3132158ea6cSRuchika Gupta return rc; 3142158ea6cSRuchika Gupta } else { 3152158ea6cSRuchika Gupta if (!pkcs2tee_load_attr(&tee_attr, 3162158ea6cSRuchika Gupta TEE_ATTR_SECRET_VALUE, 3172158ea6cSRuchika Gupta obj, 3182158ea6cSRuchika Gupta PKCS11_CKA_VALUE)) { 3192158ea6cSRuchika Gupta EMSG("No secret found"); 3202158ea6cSRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED; 3212158ea6cSRuchika Gupta } 3222158ea6cSRuchika Gupta } 3232158ea6cSRuchika Gupta break; 3242158ea6cSRuchika Gupta 3252158ea6cSRuchika Gupta default: 3262158ea6cSRuchika Gupta rc = pkcs2tee_key_type(&tee_key_type, obj); 3272158ea6cSRuchika Gupta if (rc) 3282158ea6cSRuchika Gupta return rc; 3292158ea6cSRuchika Gupta 3302158ea6cSRuchika Gupta if (!pkcs2tee_load_attr(&tee_attr, TEE_ATTR_SECRET_VALUE, 3312158ea6cSRuchika Gupta obj, PKCS11_CKA_VALUE)) { 3322158ea6cSRuchika Gupta EMSG("No secret found"); 3332158ea6cSRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED; 3342158ea6cSRuchika Gupta } 3352158ea6cSRuchika Gupta break; 3362158ea6cSRuchika Gupta } 337512cbf1dSJens Wiklander 338512cbf1dSJens Wiklander res = TEE_AllocateTransientObject(tee_key_type, object_size, 339512cbf1dSJens Wiklander &obj->key_handle); 340512cbf1dSJens Wiklander if (res) { 341512cbf1dSJens Wiklander DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 342512cbf1dSJens Wiklander return tee2pkcs_error(res); 343512cbf1dSJens Wiklander } 344512cbf1dSJens Wiklander 345512cbf1dSJens Wiklander res = TEE_PopulateTransientObject(obj->key_handle, &tee_attr, 1); 346512cbf1dSJens Wiklander if (res) { 347512cbf1dSJens Wiklander DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res); 348512cbf1dSJens Wiklander goto error; 349512cbf1dSJens Wiklander } 350512cbf1dSJens Wiklander 351512cbf1dSJens Wiklander key_ready: 352512cbf1dSJens Wiklander res = TEE_SetOperationKey(session->processing->tee_op_handle, 353512cbf1dSJens Wiklander obj->key_handle); 354512cbf1dSJens Wiklander if (res) { 355512cbf1dSJens Wiklander DMSG("TEE_SetOperationKey failed, %#"PRIx32, res); 356512cbf1dSJens Wiklander goto error; 357512cbf1dSJens Wiklander } 358512cbf1dSJens Wiklander 359512cbf1dSJens Wiklander return PKCS11_CKR_OK; 360512cbf1dSJens Wiklander 361512cbf1dSJens Wiklander error: 362512cbf1dSJens Wiklander TEE_FreeTransientObject(obj->key_handle); 363512cbf1dSJens Wiklander obj->key_handle = TEE_HANDLE_NULL; 364512cbf1dSJens Wiklander 365512cbf1dSJens Wiklander return tee2pkcs_error(res); 366512cbf1dSJens Wiklander } 367512cbf1dSJens Wiklander 368512cbf1dSJens Wiklander static enum pkcs11_rc 369512cbf1dSJens Wiklander init_tee_operation(struct pkcs11_session *session, 370512cbf1dSJens Wiklander struct pkcs11_attribute_head *proc_params) 371512cbf1dSJens Wiklander { 372512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 373512cbf1dSJens Wiklander 374512cbf1dSJens Wiklander switch (proc_params->id) { 375689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 376689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 377689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 378689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 379689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 380689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 381689f4e5bSRuchika Gupta if (proc_params->size) 382689f4e5bSRuchika Gupta return PKCS11_CKR_MECHANISM_PARAM_INVALID; 383689f4e5bSRuchika Gupta 384689f4e5bSRuchika Gupta TEE_MACInit(session->processing->tee_op_handle, NULL, 0); 385689f4e5bSRuchika Gupta rc = PKCS11_CKR_OK; 386689f4e5bSRuchika Gupta break; 387512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 388512cbf1dSJens Wiklander if (proc_params->size) 389512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_PARAM_INVALID; 390512cbf1dSJens Wiklander 391512cbf1dSJens Wiklander TEE_CipherInit(session->processing->tee_op_handle, NULL, 0); 392512cbf1dSJens Wiklander rc = PKCS11_CKR_OK; 393512cbf1dSJens Wiklander break; 394512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 395512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 396512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 397512cbf1dSJens Wiklander if (proc_params->size != 16) 398512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_PARAM_INVALID; 399512cbf1dSJens Wiklander 400512cbf1dSJens Wiklander TEE_CipherInit(session->processing->tee_op_handle, 401512cbf1dSJens Wiklander proc_params->data, 16); 402512cbf1dSJens Wiklander rc = PKCS11_CKR_OK; 403512cbf1dSJens Wiklander break; 404512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 405512cbf1dSJens Wiklander rc = tee_init_ctr_operation(session->processing, 406512cbf1dSJens Wiklander proc_params->data, 407512cbf1dSJens Wiklander proc_params->size); 408512cbf1dSJens Wiklander break; 409512cbf1dSJens Wiklander default: 410512cbf1dSJens Wiklander TEE_Panic(proc_params->id); 411512cbf1dSJens Wiklander break; 412512cbf1dSJens Wiklander } 413512cbf1dSJens Wiklander 414512cbf1dSJens Wiklander return rc; 415512cbf1dSJens Wiklander } 416512cbf1dSJens Wiklander 417512cbf1dSJens Wiklander enum pkcs11_rc init_symm_operation(struct pkcs11_session *session, 418512cbf1dSJens Wiklander enum processing_func function, 419512cbf1dSJens Wiklander struct pkcs11_attribute_head *proc_params, 420512cbf1dSJens Wiklander struct pkcs11_object *obj) 421512cbf1dSJens Wiklander { 422512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 423512cbf1dSJens Wiklander 424512cbf1dSJens Wiklander assert(processing_is_tee_symm(proc_params->id)); 425512cbf1dSJens Wiklander 426512cbf1dSJens Wiklander rc = allocate_tee_operation(session, function, proc_params, obj); 427512cbf1dSJens Wiklander if (rc) 428512cbf1dSJens Wiklander return rc; 429512cbf1dSJens Wiklander 430de94d6f8SRuchika Gupta rc = load_tee_key(session, obj, proc_params); 431512cbf1dSJens Wiklander if (rc) 432512cbf1dSJens Wiklander return rc; 433512cbf1dSJens Wiklander 434512cbf1dSJens Wiklander return init_tee_operation(session, proc_params); 435512cbf1dSJens Wiklander } 436512cbf1dSJens Wiklander 437512cbf1dSJens Wiklander /* Validate input buffer size as per PKCS#11 constraints */ 438512cbf1dSJens Wiklander static enum pkcs11_rc input_data_size_is_valid(struct active_processing *proc, 439512cbf1dSJens Wiklander enum processing_func function, 440512cbf1dSJens Wiklander size_t in_size) 441512cbf1dSJens Wiklander { 442512cbf1dSJens Wiklander switch (proc->mecha_type) { 443512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 444512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 445512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_ENCRYPT && 446512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 447512cbf1dSJens Wiklander return PKCS11_CKR_DATA_LEN_RANGE; 448512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 449512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 450512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 451512cbf1dSJens Wiklander break; 452512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 453512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 454512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 455512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 456512cbf1dSJens Wiklander break; 457512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 458512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_ENCRYPT && 459512cbf1dSJens Wiklander in_size < TEE_AES_BLOCK_SIZE) 460512cbf1dSJens Wiklander return PKCS11_CKR_DATA_LEN_RANGE; 461512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 462512cbf1dSJens Wiklander in_size < TEE_AES_BLOCK_SIZE) 463512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 464512cbf1dSJens Wiklander break; 465512cbf1dSJens Wiklander default: 466512cbf1dSJens Wiklander break; 467512cbf1dSJens Wiklander } 468512cbf1dSJens Wiklander 469512cbf1dSJens Wiklander return PKCS11_CKR_OK; 470512cbf1dSJens Wiklander } 471512cbf1dSJens Wiklander 472689f4e5bSRuchika Gupta /* Validate input buffer size as per PKCS#11 constraints */ 473689f4e5bSRuchika Gupta static enum pkcs11_rc input_sign_size_is_valid(struct active_processing *proc, 474689f4e5bSRuchika Gupta size_t in_size) 475689f4e5bSRuchika Gupta { 476689f4e5bSRuchika Gupta size_t sign_sz = 0; 477689f4e5bSRuchika Gupta 478689f4e5bSRuchika Gupta switch (proc->mecha_type) { 479689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 480689f4e5bSRuchika Gupta sign_sz = TEE_MD5_HASH_SIZE; 481689f4e5bSRuchika Gupta break; 482689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 483689f4e5bSRuchika Gupta sign_sz = TEE_SHA1_HASH_SIZE; 484689f4e5bSRuchika Gupta break; 485689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 486689f4e5bSRuchika Gupta sign_sz = TEE_SHA224_HASH_SIZE; 487689f4e5bSRuchika Gupta break; 488689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 489689f4e5bSRuchika Gupta sign_sz = TEE_SHA256_HASH_SIZE; 490689f4e5bSRuchika Gupta break; 491689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 492689f4e5bSRuchika Gupta sign_sz = TEE_SHA384_HASH_SIZE; 493689f4e5bSRuchika Gupta break; 494689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 495689f4e5bSRuchika Gupta sign_sz = TEE_SHA512_HASH_SIZE; 496689f4e5bSRuchika Gupta break; 497689f4e5bSRuchika Gupta default: 498689f4e5bSRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 499689f4e5bSRuchika Gupta } 500689f4e5bSRuchika Gupta 501689f4e5bSRuchika Gupta if (in_size < sign_sz) 502689f4e5bSRuchika Gupta return PKCS11_CKR_SIGNATURE_LEN_RANGE; 503689f4e5bSRuchika Gupta 504689f4e5bSRuchika Gupta return PKCS11_CKR_OK; 505689f4e5bSRuchika Gupta } 506689f4e5bSRuchika Gupta 507512cbf1dSJens Wiklander /* 508512cbf1dSJens Wiklander * step_sym_cipher - processing symmetric (and related) cipher operation step 509512cbf1dSJens Wiklander * 510512cbf1dSJens Wiklander * @session - current session 511512cbf1dSJens Wiklander * @function - processing function (encrypt, decrypt, sign, ...) 512512cbf1dSJens Wiklander * @step - step ID in the processing (oneshot, update, final) 513512cbf1dSJens Wiklander * @ptype - invocation parameter types 514512cbf1dSJens Wiklander * @params - invocation parameter references 515512cbf1dSJens Wiklander */ 516512cbf1dSJens Wiklander enum pkcs11_rc step_symm_operation(struct pkcs11_session *session, 517512cbf1dSJens Wiklander enum processing_func function, 518512cbf1dSJens Wiklander enum processing_step step, 519512cbf1dSJens Wiklander uint32_t ptypes, TEE_Param *params) 520512cbf1dSJens Wiklander { 521512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 522512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 523512cbf1dSJens Wiklander void *in_buf = NULL; 524512cbf1dSJens Wiklander size_t in_size = 0; 525512cbf1dSJens Wiklander void *out_buf = NULL; 526512cbf1dSJens Wiklander uint32_t out_size = 0; 527512cbf1dSJens Wiklander void *in2_buf = NULL; 528512cbf1dSJens Wiklander uint32_t in2_size = 0; 529512cbf1dSJens Wiklander bool output_data = false; 530512cbf1dSJens Wiklander struct active_processing *proc = session->processing; 531512cbf1dSJens Wiklander 532512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 533512cbf1dSJens Wiklander in_buf = params[1].memref.buffer; 534512cbf1dSJens Wiklander in_size = params[1].memref.size; 535512cbf1dSJens Wiklander if (in_size && !in_buf) 536512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 537512cbf1dSJens Wiklander } 538512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) { 539512cbf1dSJens Wiklander in2_buf = params[2].memref.buffer; 540512cbf1dSJens Wiklander in2_size = params[2].memref.size; 541512cbf1dSJens Wiklander if (in2_size && !in2_buf) 542512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 543512cbf1dSJens Wiklander } 544512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 545512cbf1dSJens Wiklander out_buf = params[2].memref.buffer; 546512cbf1dSJens Wiklander out_size = params[2].memref.size; 547512cbf1dSJens Wiklander if (out_size && !out_buf) 548512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 549512cbf1dSJens Wiklander } 550512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 551512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 552512cbf1dSJens Wiklander 553512cbf1dSJens Wiklander switch (step) { 554512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_ONESHOT: 555512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_UPDATE: 556512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_FINAL: 557512cbf1dSJens Wiklander break; 558512cbf1dSJens Wiklander default: 559512cbf1dSJens Wiklander return PKCS11_CKR_GENERAL_ERROR; 560512cbf1dSJens Wiklander } 561512cbf1dSJens Wiklander 562512cbf1dSJens Wiklander if (step != PKCS11_FUNC_STEP_FINAL) { 563512cbf1dSJens Wiklander rc = input_data_size_is_valid(proc, function, in_size); 564512cbf1dSJens Wiklander if (rc) 565512cbf1dSJens Wiklander return rc; 566512cbf1dSJens Wiklander } 567512cbf1dSJens Wiklander 568512cbf1dSJens Wiklander /* 569512cbf1dSJens Wiklander * Feed active operation with data 570512cbf1dSJens Wiklander */ 571512cbf1dSJens Wiklander switch (proc->mecha_type) { 572689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 573689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 574689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 575689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 576689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 577689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 578689f4e5bSRuchika Gupta if (step == PKCS11_FUNC_STEP_FINAL || 579689f4e5bSRuchika Gupta step == PKCS11_FUNC_STEP_ONESHOT) 580689f4e5bSRuchika Gupta break; 581689f4e5bSRuchika Gupta 582689f4e5bSRuchika Gupta if (!in_buf) { 583689f4e5bSRuchika Gupta DMSG("No input data"); 584689f4e5bSRuchika Gupta return PKCS11_CKR_ARGUMENTS_BAD; 585689f4e5bSRuchika Gupta } 586689f4e5bSRuchika Gupta 587689f4e5bSRuchika Gupta switch (function) { 588689f4e5bSRuchika Gupta case PKCS11_FUNCTION_SIGN: 589689f4e5bSRuchika Gupta case PKCS11_FUNCTION_VERIFY: 590689f4e5bSRuchika Gupta TEE_MACUpdate(proc->tee_op_handle, in_buf, in_size); 591689f4e5bSRuchika Gupta rc = PKCS11_CKR_OK; 592689f4e5bSRuchika Gupta break; 593689f4e5bSRuchika Gupta default: 594689f4e5bSRuchika Gupta TEE_Panic(function); 595689f4e5bSRuchika Gupta break; 596689f4e5bSRuchika Gupta } 597689f4e5bSRuchika Gupta break; 598689f4e5bSRuchika Gupta 599512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 600512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 601512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 602512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 603512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 604512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_FINAL || 605512cbf1dSJens Wiklander step == PKCS11_FUNC_STEP_ONESHOT) 606512cbf1dSJens Wiklander break; 607512cbf1dSJens Wiklander 608512cbf1dSJens Wiklander if (!in_buf) { 609512cbf1dSJens Wiklander EMSG("No input data"); 610512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 611512cbf1dSJens Wiklander } 612512cbf1dSJens Wiklander 613512cbf1dSJens Wiklander switch (function) { 614512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 615512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 616512cbf1dSJens Wiklander res = TEE_CipherUpdate(proc->tee_op_handle, 617512cbf1dSJens Wiklander in_buf, in_size, 618512cbf1dSJens Wiklander out_buf, &out_size); 619512cbf1dSJens Wiklander output_data = true; 620512cbf1dSJens Wiklander rc = tee2pkcs_error(res); 621512cbf1dSJens Wiklander break; 622512cbf1dSJens Wiklander default: 623512cbf1dSJens Wiklander TEE_Panic(function); 624512cbf1dSJens Wiklander break; 625512cbf1dSJens Wiklander } 626512cbf1dSJens Wiklander break; 627512cbf1dSJens Wiklander 628512cbf1dSJens Wiklander default: 629512cbf1dSJens Wiklander TEE_Panic(proc->mecha_type); 630512cbf1dSJens Wiklander break; 631512cbf1dSJens Wiklander } 632512cbf1dSJens Wiklander 633512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_UPDATE) 634512cbf1dSJens Wiklander goto out; 635512cbf1dSJens Wiklander 636512cbf1dSJens Wiklander /* 637512cbf1dSJens Wiklander * Finalize (PKCS11_FUNC_STEP_ONESHOT/_FINAL) operation 638512cbf1dSJens Wiklander */ 639512cbf1dSJens Wiklander switch (session->processing->mecha_type) { 640689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 641689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 642689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 643689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 644689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 645689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 646689f4e5bSRuchika Gupta switch (function) { 647689f4e5bSRuchika Gupta case PKCS11_FUNCTION_SIGN: 648689f4e5bSRuchika Gupta res = TEE_MACComputeFinal(proc->tee_op_handle, 649689f4e5bSRuchika Gupta in_buf, in_size, out_buf, 650689f4e5bSRuchika Gupta &out_size); 651689f4e5bSRuchika Gupta output_data = true; 652689f4e5bSRuchika Gupta rc = tee2pkcs_error(res); 653689f4e5bSRuchika Gupta break; 654689f4e5bSRuchika Gupta case PKCS11_FUNCTION_VERIFY: 655689f4e5bSRuchika Gupta rc = input_sign_size_is_valid(proc, in2_size); 656689f4e5bSRuchika Gupta if (rc) 657689f4e5bSRuchika Gupta return rc; 658689f4e5bSRuchika Gupta res = TEE_MACCompareFinal(proc->tee_op_handle, 659689f4e5bSRuchika Gupta in_buf, in_size, in2_buf, 660689f4e5bSRuchika Gupta in2_size); 661689f4e5bSRuchika Gupta rc = tee2pkcs_error(res); 662689f4e5bSRuchika Gupta break; 663689f4e5bSRuchika Gupta default: 664689f4e5bSRuchika Gupta TEE_Panic(function); 665689f4e5bSRuchika Gupta break; 666689f4e5bSRuchika Gupta } 6672158ea6cSRuchika Gupta 668689f4e5bSRuchika Gupta break; 669689f4e5bSRuchika Gupta 670512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 671512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 672512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 673512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 674512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 675512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_ONESHOT && !in_buf) { 676512cbf1dSJens Wiklander EMSG("No input data"); 677512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 678512cbf1dSJens Wiklander } 679512cbf1dSJens Wiklander 680512cbf1dSJens Wiklander switch (function) { 681512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 682512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 683512cbf1dSJens Wiklander res = TEE_CipherDoFinal(proc->tee_op_handle, 684512cbf1dSJens Wiklander in_buf, in_size, 685512cbf1dSJens Wiklander out_buf, &out_size); 686512cbf1dSJens Wiklander output_data = true; 687512cbf1dSJens Wiklander rc = tee2pkcs_error(res); 688512cbf1dSJens Wiklander break; 689512cbf1dSJens Wiklander default: 690512cbf1dSJens Wiklander TEE_Panic(function); 691512cbf1dSJens Wiklander break; 692512cbf1dSJens Wiklander } 693512cbf1dSJens Wiklander break; 694512cbf1dSJens Wiklander default: 695512cbf1dSJens Wiklander TEE_Panic(proc->mecha_type); 696512cbf1dSJens Wiklander break; 697512cbf1dSJens Wiklander } 698512cbf1dSJens Wiklander 699512cbf1dSJens Wiklander out: 700512cbf1dSJens Wiklander if (output_data && 701512cbf1dSJens Wiklander (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) { 702512cbf1dSJens Wiklander switch (TEE_PARAM_TYPE_GET(ptypes, 2)) { 703512cbf1dSJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 704512cbf1dSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 705512cbf1dSJens Wiklander params[2].memref.size = out_size; 706512cbf1dSJens Wiklander break; 707512cbf1dSJens Wiklander default: 708512cbf1dSJens Wiklander rc = PKCS11_CKR_ARGUMENTS_BAD; 709512cbf1dSJens Wiklander break; 710512cbf1dSJens Wiklander } 711512cbf1dSJens Wiklander } 712512cbf1dSJens Wiklander 713512cbf1dSJens Wiklander return rc; 714512cbf1dSJens Wiklander } 715