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 135*2158ea6cSRuchika Gupta static enum pkcs11_rc hmac_to_tee_hash(uint32_t *algo, 136*2158ea6cSRuchika Gupta enum pkcs11_mechanism_id mech_id) 137*2158ea6cSRuchika Gupta { 138*2158ea6cSRuchika Gupta static const struct { 139*2158ea6cSRuchika Gupta enum pkcs11_mechanism_id mech; 140*2158ea6cSRuchika Gupta uint32_t tee_id; 141*2158ea6cSRuchika Gupta } hmac_hash[] = { 142*2158ea6cSRuchika Gupta { PKCS11_CKM_MD5_HMAC, TEE_ALG_MD5 }, 143*2158ea6cSRuchika Gupta { PKCS11_CKM_SHA_1_HMAC, TEE_ALG_SHA1 }, 144*2158ea6cSRuchika Gupta { PKCS11_CKM_SHA224_HMAC, TEE_ALG_SHA224 }, 145*2158ea6cSRuchika Gupta { PKCS11_CKM_SHA256_HMAC, TEE_ALG_SHA256 }, 146*2158ea6cSRuchika Gupta { PKCS11_CKM_SHA384_HMAC, TEE_ALG_SHA384 }, 147*2158ea6cSRuchika Gupta { PKCS11_CKM_SHA512_HMAC, TEE_ALG_SHA512 }, 148*2158ea6cSRuchika Gupta }; 149*2158ea6cSRuchika Gupta size_t n = 0; 150*2158ea6cSRuchika Gupta 151*2158ea6cSRuchika Gupta for (n = 0; n < ARRAY_SIZE(hmac_hash); n++) { 152*2158ea6cSRuchika Gupta if (hmac_hash[n].mech == mech_id) { 153*2158ea6cSRuchika Gupta *algo = hmac_hash[n].tee_id; 154*2158ea6cSRuchika Gupta return PKCS11_CKR_OK; 155*2158ea6cSRuchika Gupta } 156*2158ea6cSRuchika Gupta } 157*2158ea6cSRuchika Gupta 158*2158ea6cSRuchika Gupta return PKCS11_RV_NOT_FOUND; 159*2158ea6cSRuchika Gupta } 160*2158ea6cSRuchika 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: 188460ba621SRuchika Gupta mechanism_supported_key_sizes(params->id, 189460ba621SRuchika Gupta &min_key_size, 190460ba621SRuchika Gupta &max_key_size); 191460ba621SRuchika Gupta if (key_size < min_key_size) 192460ba621SRuchika Gupta return PKCS11_CKR_KEY_SIZE_RANGE; 193*2158ea6cSRuchika Gupta 194*2158ea6cSRuchika Gupta /* 195*2158ea6cSRuchika Gupta * If size of generic key is greater than the size 196*2158ea6cSRuchika Gupta * supported by TEE API, this is not considered an 197*2158ea6cSRuchika Gupta * error. When loading TEE key, we will hash the key 198*2158ea6cSRuchika Gupta * to generate the appropriate key for HMAC operation. 199*2158ea6cSRuchika Gupta * This key size will not be greater than the 200*2158ea6cSRuchika Gupta * max_key_size. So we can use max_key_size for 201*2158ea6cSRuchika Gupta * TEE_AllocateOperation(). 202*2158ea6cSRuchika Gupta */ 203*2158ea6cSRuchika Gupta if (key_size > max_key_size) 204*2158ea6cSRuchika Gupta size = max_key_size * 8; 205*2158ea6cSRuchika Gupta 206689f4e5bSRuchika Gupta mode = TEE_MODE_MAC; 207689f4e5bSRuchika Gupta break; 208689f4e5bSRuchika Gupta default: 209512cbf1dSJens Wiklander pkcs2tee_mode(&mode, function); 210689f4e5bSRuchika Gupta break; 211689f4e5bSRuchika Gupta } 212512cbf1dSJens Wiklander 213512cbf1dSJens Wiklander res = TEE_AllocateOperation(&session->processing->tee_op_handle, 214512cbf1dSJens Wiklander algo, mode, size); 215512cbf1dSJens Wiklander if (res) 216512cbf1dSJens Wiklander EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32, 217512cbf1dSJens Wiklander algo, mode, size); 218512cbf1dSJens Wiklander 219512cbf1dSJens Wiklander if (res == TEE_ERROR_NOT_SUPPORTED) 220512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_INVALID; 221512cbf1dSJens Wiklander 222512cbf1dSJens Wiklander return tee2pkcs_error(res); 223512cbf1dSJens Wiklander } 224512cbf1dSJens Wiklander 225*2158ea6cSRuchika Gupta static enum pkcs11_rc hash_secret_helper(enum pkcs11_mechanism_id mech_id, 226*2158ea6cSRuchika Gupta struct pkcs11_object *obj, 227*2158ea6cSRuchika Gupta TEE_Attribute *tee_attr, 228*2158ea6cSRuchika Gupta void **ctx, 229*2158ea6cSRuchika Gupta size_t *object_size_bits) 230*2158ea6cSRuchika Gupta { 231*2158ea6cSRuchika Gupta uint32_t algo = 0; 232*2158ea6cSRuchika Gupta void *hash_ptr = NULL; 233*2158ea6cSRuchika Gupta uint32_t hash_size = 0; 234*2158ea6cSRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK; 235*2158ea6cSRuchika Gupta 236*2158ea6cSRuchika Gupta rc = hmac_to_tee_hash(&algo, mech_id); 237*2158ea6cSRuchika Gupta if (rc) 238*2158ea6cSRuchika Gupta return rc; 239*2158ea6cSRuchika Gupta 240*2158ea6cSRuchika Gupta hash_size = TEE_ALG_GET_DIGEST_SIZE(algo); 241*2158ea6cSRuchika Gupta hash_ptr = TEE_Malloc(hash_size, 0); 242*2158ea6cSRuchika Gupta if (!hash_ptr) 243*2158ea6cSRuchika Gupta return PKCS11_CKR_DEVICE_MEMORY; 244*2158ea6cSRuchika Gupta 245*2158ea6cSRuchika Gupta rc = pkcs2tee_load_hashed_attr(tee_attr, TEE_ATTR_SECRET_VALUE, obj, 246*2158ea6cSRuchika Gupta PKCS11_CKA_VALUE, algo, hash_ptr, 247*2158ea6cSRuchika Gupta &hash_size); 248*2158ea6cSRuchika Gupta if (rc) { 249*2158ea6cSRuchika Gupta EMSG("No secret/hash error"); 250*2158ea6cSRuchika Gupta TEE_Free(hash_ptr); 251*2158ea6cSRuchika Gupta return rc; 252*2158ea6cSRuchika Gupta } 253*2158ea6cSRuchika Gupta 254*2158ea6cSRuchika Gupta *ctx = hash_ptr; 255*2158ea6cSRuchika Gupta 256*2158ea6cSRuchika Gupta *object_size_bits = hash_size * 8; 257*2158ea6cSRuchika Gupta 258*2158ea6cSRuchika Gupta return PKCS11_CKR_OK; 259*2158ea6cSRuchika Gupta } 260*2158ea6cSRuchika Gupta 261512cbf1dSJens Wiklander static enum pkcs11_rc load_tee_key(struct pkcs11_session *session, 262de94d6f8SRuchika Gupta struct pkcs11_object *obj, 263de94d6f8SRuchika Gupta struct pkcs11_attribute_head *proc_params) 264512cbf1dSJens Wiklander { 265512cbf1dSJens Wiklander TEE_Attribute tee_attr = { }; 266512cbf1dSJens Wiklander size_t object_size = 0; 267512cbf1dSJens Wiklander uint32_t tee_key_type = 0; 268de94d6f8SRuchika Gupta enum pkcs11_key_type key_type = 0; 269512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 270512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 271*2158ea6cSRuchika Gupta uint32_t max_key_size = 0; 272*2158ea6cSRuchika Gupta uint32_t min_key_size = 0; 273512cbf1dSJens Wiklander 274512cbf1dSJens Wiklander if (obj->key_handle != TEE_HANDLE_NULL) { 275512cbf1dSJens Wiklander /* Key was already loaded and fits current need */ 276512cbf1dSJens Wiklander goto key_ready; 277512cbf1dSJens Wiklander } 278512cbf1dSJens Wiklander 279*2158ea6cSRuchika Gupta object_size = get_object_key_bit_size(obj); 280*2158ea6cSRuchika Gupta if (!object_size) 281*2158ea6cSRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 282512cbf1dSJens Wiklander 283de94d6f8SRuchika Gupta switch (proc_params->id) { 284de94d6f8SRuchika Gupta case PKCS11_CKM_MD5_HMAC: 285de94d6f8SRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 286de94d6f8SRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 287de94d6f8SRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 288de94d6f8SRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 289de94d6f8SRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 290de94d6f8SRuchika Gupta key_type = get_key_type(obj->attributes); 291de94d6f8SRuchika Gupta /* 292de94d6f8SRuchika Gupta * If Object Key type is PKCS11_CKK_GENERIC_SECRET, 293de94d6f8SRuchika Gupta * determine the tee_key_type using the 294de94d6f8SRuchika Gupta * mechanism instead of object key_type. 295de94d6f8SRuchika Gupta */ 296de94d6f8SRuchika Gupta if (key_type == PKCS11_CKK_GENERIC_SECRET) 297de94d6f8SRuchika Gupta rc = pkcsmech2tee_key_type(&tee_key_type, 298de94d6f8SRuchika Gupta proc_params->id); 299de94d6f8SRuchika Gupta else 300512cbf1dSJens Wiklander rc = pkcs2tee_key_type(&tee_key_type, obj); 301de94d6f8SRuchika Gupta 302512cbf1dSJens Wiklander if (rc) 303512cbf1dSJens Wiklander return rc; 304512cbf1dSJens Wiklander 305*2158ea6cSRuchika Gupta mechanism_supported_key_sizes(proc_params->id, 306*2158ea6cSRuchika Gupta &min_key_size, 307*2158ea6cSRuchika Gupta &max_key_size); 308*2158ea6cSRuchika Gupta 309*2158ea6cSRuchika Gupta if ((object_size / 8) > max_key_size) { 310*2158ea6cSRuchika Gupta rc = hash_secret_helper(proc_params->id, obj, &tee_attr, 311*2158ea6cSRuchika Gupta &session->processing->extra_ctx, 312*2158ea6cSRuchika Gupta &object_size); 313*2158ea6cSRuchika Gupta if (rc) 314*2158ea6cSRuchika Gupta return rc; 315*2158ea6cSRuchika Gupta } else { 316*2158ea6cSRuchika Gupta if (!pkcs2tee_load_attr(&tee_attr, 317*2158ea6cSRuchika Gupta TEE_ATTR_SECRET_VALUE, 318*2158ea6cSRuchika Gupta obj, 319*2158ea6cSRuchika Gupta PKCS11_CKA_VALUE)) { 320*2158ea6cSRuchika Gupta EMSG("No secret found"); 321*2158ea6cSRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED; 322*2158ea6cSRuchika Gupta } 323*2158ea6cSRuchika Gupta } 324*2158ea6cSRuchika Gupta break; 325*2158ea6cSRuchika Gupta 326*2158ea6cSRuchika Gupta default: 327*2158ea6cSRuchika Gupta rc = pkcs2tee_key_type(&tee_key_type, obj); 328*2158ea6cSRuchika Gupta if (rc) 329*2158ea6cSRuchika Gupta return rc; 330*2158ea6cSRuchika Gupta 331*2158ea6cSRuchika Gupta if (!pkcs2tee_load_attr(&tee_attr, TEE_ATTR_SECRET_VALUE, 332*2158ea6cSRuchika Gupta obj, PKCS11_CKA_VALUE)) { 333*2158ea6cSRuchika Gupta EMSG("No secret found"); 334*2158ea6cSRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED; 335*2158ea6cSRuchika Gupta } 336*2158ea6cSRuchika Gupta break; 337*2158ea6cSRuchika Gupta } 338512cbf1dSJens Wiklander 339512cbf1dSJens Wiklander res = TEE_AllocateTransientObject(tee_key_type, object_size, 340512cbf1dSJens Wiklander &obj->key_handle); 341512cbf1dSJens Wiklander if (res) { 342512cbf1dSJens Wiklander DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 343512cbf1dSJens Wiklander return tee2pkcs_error(res); 344512cbf1dSJens Wiklander } 345512cbf1dSJens Wiklander 346512cbf1dSJens Wiklander res = TEE_PopulateTransientObject(obj->key_handle, &tee_attr, 1); 347512cbf1dSJens Wiklander if (res) { 348512cbf1dSJens Wiklander DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res); 349512cbf1dSJens Wiklander goto error; 350512cbf1dSJens Wiklander } 351512cbf1dSJens Wiklander 352512cbf1dSJens Wiklander key_ready: 353512cbf1dSJens Wiklander res = TEE_SetOperationKey(session->processing->tee_op_handle, 354512cbf1dSJens Wiklander obj->key_handle); 355512cbf1dSJens Wiklander if (res) { 356512cbf1dSJens Wiklander DMSG("TEE_SetOperationKey failed, %#"PRIx32, res); 357512cbf1dSJens Wiklander goto error; 358512cbf1dSJens Wiklander } 359512cbf1dSJens Wiklander 360512cbf1dSJens Wiklander return PKCS11_CKR_OK; 361512cbf1dSJens Wiklander 362512cbf1dSJens Wiklander error: 363512cbf1dSJens Wiklander TEE_FreeTransientObject(obj->key_handle); 364512cbf1dSJens Wiklander obj->key_handle = TEE_HANDLE_NULL; 365512cbf1dSJens Wiklander 366512cbf1dSJens Wiklander return tee2pkcs_error(res); 367512cbf1dSJens Wiklander } 368512cbf1dSJens Wiklander 369512cbf1dSJens Wiklander static enum pkcs11_rc 370512cbf1dSJens Wiklander init_tee_operation(struct pkcs11_session *session, 371512cbf1dSJens Wiklander struct pkcs11_attribute_head *proc_params) 372512cbf1dSJens Wiklander { 373512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 374512cbf1dSJens Wiklander 375512cbf1dSJens Wiklander switch (proc_params->id) { 376689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 377689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 378689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 379689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 380689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 381689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 382689f4e5bSRuchika Gupta if (proc_params->size) 383689f4e5bSRuchika Gupta return PKCS11_CKR_MECHANISM_PARAM_INVALID; 384689f4e5bSRuchika Gupta 385689f4e5bSRuchika Gupta TEE_MACInit(session->processing->tee_op_handle, NULL, 0); 386689f4e5bSRuchika Gupta rc = PKCS11_CKR_OK; 387689f4e5bSRuchika Gupta break; 388512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 389512cbf1dSJens Wiklander if (proc_params->size) 390512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_PARAM_INVALID; 391512cbf1dSJens Wiklander 392512cbf1dSJens Wiklander TEE_CipherInit(session->processing->tee_op_handle, NULL, 0); 393512cbf1dSJens Wiklander rc = PKCS11_CKR_OK; 394512cbf1dSJens Wiklander break; 395512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 396512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 397512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 398512cbf1dSJens Wiklander if (proc_params->size != 16) 399512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_PARAM_INVALID; 400512cbf1dSJens Wiklander 401512cbf1dSJens Wiklander TEE_CipherInit(session->processing->tee_op_handle, 402512cbf1dSJens Wiklander proc_params->data, 16); 403512cbf1dSJens Wiklander rc = PKCS11_CKR_OK; 404512cbf1dSJens Wiklander break; 405512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 406512cbf1dSJens Wiklander rc = tee_init_ctr_operation(session->processing, 407512cbf1dSJens Wiklander proc_params->data, 408512cbf1dSJens Wiklander proc_params->size); 409512cbf1dSJens Wiklander break; 410512cbf1dSJens Wiklander default: 411512cbf1dSJens Wiklander TEE_Panic(proc_params->id); 412512cbf1dSJens Wiklander break; 413512cbf1dSJens Wiklander } 414512cbf1dSJens Wiklander 415512cbf1dSJens Wiklander return rc; 416512cbf1dSJens Wiklander } 417512cbf1dSJens Wiklander 418512cbf1dSJens Wiklander enum pkcs11_rc init_symm_operation(struct pkcs11_session *session, 419512cbf1dSJens Wiklander enum processing_func function, 420512cbf1dSJens Wiklander struct pkcs11_attribute_head *proc_params, 421512cbf1dSJens Wiklander struct pkcs11_object *obj) 422512cbf1dSJens Wiklander { 423512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 424512cbf1dSJens Wiklander 425512cbf1dSJens Wiklander assert(processing_is_tee_symm(proc_params->id)); 426512cbf1dSJens Wiklander 427512cbf1dSJens Wiklander rc = allocate_tee_operation(session, function, proc_params, obj); 428512cbf1dSJens Wiklander if (rc) 429512cbf1dSJens Wiklander return rc; 430512cbf1dSJens Wiklander 431de94d6f8SRuchika Gupta rc = load_tee_key(session, obj, proc_params); 432512cbf1dSJens Wiklander if (rc) 433512cbf1dSJens Wiklander return rc; 434512cbf1dSJens Wiklander 435512cbf1dSJens Wiklander return init_tee_operation(session, proc_params); 436512cbf1dSJens Wiklander } 437512cbf1dSJens Wiklander 438512cbf1dSJens Wiklander /* Validate input buffer size as per PKCS#11 constraints */ 439512cbf1dSJens Wiklander static enum pkcs11_rc input_data_size_is_valid(struct active_processing *proc, 440512cbf1dSJens Wiklander enum processing_func function, 441512cbf1dSJens Wiklander size_t in_size) 442512cbf1dSJens Wiklander { 443512cbf1dSJens Wiklander switch (proc->mecha_type) { 444512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 445512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 446512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_ENCRYPT && 447512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 448512cbf1dSJens Wiklander return PKCS11_CKR_DATA_LEN_RANGE; 449512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 450512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 451512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 452512cbf1dSJens Wiklander break; 453512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 454512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 455512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 456512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 457512cbf1dSJens Wiklander break; 458512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 459512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_ENCRYPT && 460512cbf1dSJens Wiklander in_size < TEE_AES_BLOCK_SIZE) 461512cbf1dSJens Wiklander return PKCS11_CKR_DATA_LEN_RANGE; 462512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 463512cbf1dSJens Wiklander in_size < TEE_AES_BLOCK_SIZE) 464512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 465512cbf1dSJens Wiklander break; 466512cbf1dSJens Wiklander default: 467512cbf1dSJens Wiklander break; 468512cbf1dSJens Wiklander } 469512cbf1dSJens Wiklander 470512cbf1dSJens Wiklander return PKCS11_CKR_OK; 471512cbf1dSJens Wiklander } 472512cbf1dSJens Wiklander 473689f4e5bSRuchika Gupta /* Validate input buffer size as per PKCS#11 constraints */ 474689f4e5bSRuchika Gupta static enum pkcs11_rc input_sign_size_is_valid(struct active_processing *proc, 475689f4e5bSRuchika Gupta size_t in_size) 476689f4e5bSRuchika Gupta { 477689f4e5bSRuchika Gupta size_t sign_sz = 0; 478689f4e5bSRuchika Gupta 479689f4e5bSRuchika Gupta switch (proc->mecha_type) { 480689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 481689f4e5bSRuchika Gupta sign_sz = TEE_MD5_HASH_SIZE; 482689f4e5bSRuchika Gupta break; 483689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 484689f4e5bSRuchika Gupta sign_sz = TEE_SHA1_HASH_SIZE; 485689f4e5bSRuchika Gupta break; 486689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 487689f4e5bSRuchika Gupta sign_sz = TEE_SHA224_HASH_SIZE; 488689f4e5bSRuchika Gupta break; 489689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 490689f4e5bSRuchika Gupta sign_sz = TEE_SHA256_HASH_SIZE; 491689f4e5bSRuchika Gupta break; 492689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 493689f4e5bSRuchika Gupta sign_sz = TEE_SHA384_HASH_SIZE; 494689f4e5bSRuchika Gupta break; 495689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 496689f4e5bSRuchika Gupta sign_sz = TEE_SHA512_HASH_SIZE; 497689f4e5bSRuchika Gupta break; 498689f4e5bSRuchika Gupta default: 499689f4e5bSRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 500689f4e5bSRuchika Gupta } 501689f4e5bSRuchika Gupta 502689f4e5bSRuchika Gupta if (in_size < sign_sz) 503689f4e5bSRuchika Gupta return PKCS11_CKR_SIGNATURE_LEN_RANGE; 504689f4e5bSRuchika Gupta 505689f4e5bSRuchika Gupta return PKCS11_CKR_OK; 506689f4e5bSRuchika Gupta } 507689f4e5bSRuchika Gupta 508512cbf1dSJens Wiklander /* 509512cbf1dSJens Wiklander * step_sym_cipher - processing symmetric (and related) cipher operation step 510512cbf1dSJens Wiklander * 511512cbf1dSJens Wiklander * @session - current session 512512cbf1dSJens Wiklander * @function - processing function (encrypt, decrypt, sign, ...) 513512cbf1dSJens Wiklander * @step - step ID in the processing (oneshot, update, final) 514512cbf1dSJens Wiklander * @ptype - invocation parameter types 515512cbf1dSJens Wiklander * @params - invocation parameter references 516512cbf1dSJens Wiklander */ 517512cbf1dSJens Wiklander enum pkcs11_rc step_symm_operation(struct pkcs11_session *session, 518512cbf1dSJens Wiklander enum processing_func function, 519512cbf1dSJens Wiklander enum processing_step step, 520512cbf1dSJens Wiklander uint32_t ptypes, TEE_Param *params) 521512cbf1dSJens Wiklander { 522512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 523512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 524512cbf1dSJens Wiklander void *in_buf = NULL; 525512cbf1dSJens Wiklander size_t in_size = 0; 526512cbf1dSJens Wiklander void *out_buf = NULL; 527512cbf1dSJens Wiklander uint32_t out_size = 0; 528512cbf1dSJens Wiklander void *in2_buf = NULL; 529512cbf1dSJens Wiklander uint32_t in2_size = 0; 530512cbf1dSJens Wiklander bool output_data = false; 531512cbf1dSJens Wiklander struct active_processing *proc = session->processing; 532512cbf1dSJens Wiklander 533512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 534512cbf1dSJens Wiklander in_buf = params[1].memref.buffer; 535512cbf1dSJens Wiklander in_size = params[1].memref.size; 536512cbf1dSJens Wiklander if (in_size && !in_buf) 537512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 538512cbf1dSJens Wiklander } 539512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) { 540512cbf1dSJens Wiklander in2_buf = params[2].memref.buffer; 541512cbf1dSJens Wiklander in2_size = params[2].memref.size; 542512cbf1dSJens Wiklander if (in2_size && !in2_buf) 543512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 544512cbf1dSJens Wiklander } 545512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 546512cbf1dSJens Wiklander out_buf = params[2].memref.buffer; 547512cbf1dSJens Wiklander out_size = params[2].memref.size; 548512cbf1dSJens Wiklander if (out_size && !out_buf) 549512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 550512cbf1dSJens Wiklander } 551512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 552512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 553512cbf1dSJens Wiklander 554512cbf1dSJens Wiklander switch (step) { 555512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_ONESHOT: 556512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_UPDATE: 557512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_FINAL: 558512cbf1dSJens Wiklander break; 559512cbf1dSJens Wiklander default: 560512cbf1dSJens Wiklander return PKCS11_CKR_GENERAL_ERROR; 561512cbf1dSJens Wiklander } 562512cbf1dSJens Wiklander 563512cbf1dSJens Wiklander if (step != PKCS11_FUNC_STEP_FINAL) { 564512cbf1dSJens Wiklander rc = input_data_size_is_valid(proc, function, in_size); 565512cbf1dSJens Wiklander if (rc) 566512cbf1dSJens Wiklander return rc; 567512cbf1dSJens Wiklander } 568512cbf1dSJens Wiklander 569512cbf1dSJens Wiklander /* 570512cbf1dSJens Wiklander * Feed active operation with data 571512cbf1dSJens Wiklander */ 572512cbf1dSJens Wiklander switch (proc->mecha_type) { 573689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 574689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 575689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 576689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 577689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 578689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 579689f4e5bSRuchika Gupta if (step == PKCS11_FUNC_STEP_FINAL || 580689f4e5bSRuchika Gupta step == PKCS11_FUNC_STEP_ONESHOT) 581689f4e5bSRuchika Gupta break; 582689f4e5bSRuchika Gupta 583689f4e5bSRuchika Gupta if (!in_buf) { 584689f4e5bSRuchika Gupta DMSG("No input data"); 585689f4e5bSRuchika Gupta return PKCS11_CKR_ARGUMENTS_BAD; 586689f4e5bSRuchika Gupta } 587689f4e5bSRuchika Gupta 588689f4e5bSRuchika Gupta switch (function) { 589689f4e5bSRuchika Gupta case PKCS11_FUNCTION_SIGN: 590689f4e5bSRuchika Gupta case PKCS11_FUNCTION_VERIFY: 591689f4e5bSRuchika Gupta TEE_MACUpdate(proc->tee_op_handle, in_buf, in_size); 592689f4e5bSRuchika Gupta rc = PKCS11_CKR_OK; 593689f4e5bSRuchika Gupta break; 594689f4e5bSRuchika Gupta default: 595689f4e5bSRuchika Gupta TEE_Panic(function); 596689f4e5bSRuchika Gupta break; 597689f4e5bSRuchika Gupta } 598689f4e5bSRuchika Gupta break; 599689f4e5bSRuchika Gupta 600512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 601512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 602512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 603512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 604512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 605512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_FINAL || 606512cbf1dSJens Wiklander step == PKCS11_FUNC_STEP_ONESHOT) 607512cbf1dSJens Wiklander break; 608512cbf1dSJens Wiklander 609512cbf1dSJens Wiklander if (!in_buf) { 610512cbf1dSJens Wiklander EMSG("No input data"); 611512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 612512cbf1dSJens Wiklander } 613512cbf1dSJens Wiklander 614512cbf1dSJens Wiklander switch (function) { 615512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 616512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 617512cbf1dSJens Wiklander res = TEE_CipherUpdate(proc->tee_op_handle, 618512cbf1dSJens Wiklander in_buf, in_size, 619512cbf1dSJens Wiklander out_buf, &out_size); 620512cbf1dSJens Wiklander output_data = true; 621512cbf1dSJens Wiklander rc = tee2pkcs_error(res); 622512cbf1dSJens Wiklander break; 623512cbf1dSJens Wiklander default: 624512cbf1dSJens Wiklander TEE_Panic(function); 625512cbf1dSJens Wiklander break; 626512cbf1dSJens Wiklander } 627512cbf1dSJens Wiklander break; 628512cbf1dSJens Wiklander 629512cbf1dSJens Wiklander default: 630512cbf1dSJens Wiklander TEE_Panic(proc->mecha_type); 631512cbf1dSJens Wiklander break; 632512cbf1dSJens Wiklander } 633512cbf1dSJens Wiklander 634512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_UPDATE) 635512cbf1dSJens Wiklander goto out; 636512cbf1dSJens Wiklander 637512cbf1dSJens Wiklander /* 638512cbf1dSJens Wiklander * Finalize (PKCS11_FUNC_STEP_ONESHOT/_FINAL) operation 639512cbf1dSJens Wiklander */ 640512cbf1dSJens Wiklander switch (session->processing->mecha_type) { 641689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 642689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 643689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 644689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 645689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 646689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 647689f4e5bSRuchika Gupta switch (function) { 648689f4e5bSRuchika Gupta case PKCS11_FUNCTION_SIGN: 649689f4e5bSRuchika Gupta res = TEE_MACComputeFinal(proc->tee_op_handle, 650689f4e5bSRuchika Gupta in_buf, in_size, out_buf, 651689f4e5bSRuchika Gupta &out_size); 652689f4e5bSRuchika Gupta output_data = true; 653689f4e5bSRuchika Gupta rc = tee2pkcs_error(res); 654689f4e5bSRuchika Gupta break; 655689f4e5bSRuchika Gupta case PKCS11_FUNCTION_VERIFY: 656689f4e5bSRuchika Gupta rc = input_sign_size_is_valid(proc, in2_size); 657689f4e5bSRuchika Gupta if (rc) 658689f4e5bSRuchika Gupta return rc; 659689f4e5bSRuchika Gupta res = TEE_MACCompareFinal(proc->tee_op_handle, 660689f4e5bSRuchika Gupta in_buf, in_size, in2_buf, 661689f4e5bSRuchika Gupta in2_size); 662689f4e5bSRuchika Gupta rc = tee2pkcs_error(res); 663689f4e5bSRuchika Gupta break; 664689f4e5bSRuchika Gupta default: 665689f4e5bSRuchika Gupta TEE_Panic(function); 666689f4e5bSRuchika Gupta break; 667689f4e5bSRuchika Gupta } 668*2158ea6cSRuchika Gupta 669689f4e5bSRuchika Gupta break; 670689f4e5bSRuchika Gupta 671512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 672512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 673512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 674512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 675512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 676512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_ONESHOT && !in_buf) { 677512cbf1dSJens Wiklander EMSG("No input data"); 678512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 679512cbf1dSJens Wiklander } 680512cbf1dSJens Wiklander 681512cbf1dSJens Wiklander switch (function) { 682512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 683512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 684512cbf1dSJens Wiklander res = TEE_CipherDoFinal(proc->tee_op_handle, 685512cbf1dSJens Wiklander in_buf, in_size, 686512cbf1dSJens Wiklander out_buf, &out_size); 687512cbf1dSJens Wiklander output_data = true; 688512cbf1dSJens Wiklander rc = tee2pkcs_error(res); 689512cbf1dSJens Wiklander break; 690512cbf1dSJens Wiklander default: 691512cbf1dSJens Wiklander TEE_Panic(function); 692512cbf1dSJens Wiklander break; 693512cbf1dSJens Wiklander } 694512cbf1dSJens Wiklander break; 695512cbf1dSJens Wiklander default: 696512cbf1dSJens Wiklander TEE_Panic(proc->mecha_type); 697512cbf1dSJens Wiklander break; 698512cbf1dSJens Wiklander } 699512cbf1dSJens Wiklander 700512cbf1dSJens Wiklander out: 701512cbf1dSJens Wiklander if (output_data && 702512cbf1dSJens Wiklander (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) { 703512cbf1dSJens Wiklander switch (TEE_PARAM_TYPE_GET(ptypes, 2)) { 704512cbf1dSJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 705512cbf1dSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 706512cbf1dSJens Wiklander params[2].memref.size = out_size; 707512cbf1dSJens Wiklander break; 708512cbf1dSJens Wiklander default: 709512cbf1dSJens Wiklander rc = PKCS11_CKR_ARGUMENTS_BAD; 710512cbf1dSJens Wiklander break; 711512cbf1dSJens Wiklander } 712512cbf1dSJens Wiklander } 713512cbf1dSJens Wiklander 714512cbf1dSJens Wiklander return rc; 715512cbf1dSJens Wiklander } 716