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 135512cbf1dSJens Wiklander static enum pkcs11_rc 136512cbf1dSJens Wiklander allocate_tee_operation(struct pkcs11_session *session, 137512cbf1dSJens Wiklander enum processing_func function, 138512cbf1dSJens Wiklander struct pkcs11_attribute_head *params, 139512cbf1dSJens Wiklander struct pkcs11_object *obj) 140512cbf1dSJens Wiklander { 141512cbf1dSJens Wiklander uint32_t size = (uint32_t)get_object_key_bit_size(obj); 142*460ba621SRuchika Gupta uint32_t key_size = size / 8; 143512cbf1dSJens Wiklander uint32_t algo = 0; 144512cbf1dSJens Wiklander uint32_t mode = 0; 145*460ba621SRuchika Gupta uint32_t max_key_size = 0; 146*460ba621SRuchika Gupta uint32_t min_key_size = 0; 147512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 148512cbf1dSJens Wiklander 149512cbf1dSJens Wiklander assert(session->processing->tee_op_handle == TEE_HANDLE_NULL); 150512cbf1dSJens Wiklander 151512cbf1dSJens Wiklander if (pkcs2tee_algorithm(&algo, params)) 152512cbf1dSJens Wiklander return PKCS11_CKR_FUNCTION_FAILED; 153512cbf1dSJens Wiklander 154512cbf1dSJens Wiklander /* Sign/Verify with AES or generic key relate to TEE MAC operation */ 155689f4e5bSRuchika Gupta switch (params->id) { 156689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 157689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 158689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 159689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 160689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 161689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 162*460ba621SRuchika Gupta mechanism_supported_key_sizes(params->id, 163*460ba621SRuchika Gupta &min_key_size, 164*460ba621SRuchika Gupta &max_key_size); 165*460ba621SRuchika Gupta if (key_size < min_key_size) 166*460ba621SRuchika Gupta return PKCS11_CKR_KEY_SIZE_RANGE; 167689f4e5bSRuchika Gupta mode = TEE_MODE_MAC; 168689f4e5bSRuchika Gupta break; 169689f4e5bSRuchika Gupta default: 170512cbf1dSJens Wiklander pkcs2tee_mode(&mode, function); 171689f4e5bSRuchika Gupta break; 172689f4e5bSRuchika Gupta } 173512cbf1dSJens Wiklander 174512cbf1dSJens Wiklander res = TEE_AllocateOperation(&session->processing->tee_op_handle, 175512cbf1dSJens Wiklander algo, mode, size); 176512cbf1dSJens Wiklander if (res) 177512cbf1dSJens Wiklander EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32, 178512cbf1dSJens Wiklander algo, mode, size); 179512cbf1dSJens Wiklander 180512cbf1dSJens Wiklander if (res == TEE_ERROR_NOT_SUPPORTED) 181512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_INVALID; 182512cbf1dSJens Wiklander 183512cbf1dSJens Wiklander return tee2pkcs_error(res); 184512cbf1dSJens Wiklander } 185512cbf1dSJens Wiklander 186512cbf1dSJens Wiklander static enum pkcs11_rc load_tee_key(struct pkcs11_session *session, 187de94d6f8SRuchika Gupta struct pkcs11_object *obj, 188de94d6f8SRuchika Gupta struct pkcs11_attribute_head *proc_params) 189512cbf1dSJens Wiklander { 190512cbf1dSJens Wiklander TEE_Attribute tee_attr = { }; 191512cbf1dSJens Wiklander size_t object_size = 0; 192512cbf1dSJens Wiklander uint32_t tee_key_type = 0; 193de94d6f8SRuchika Gupta enum pkcs11_key_type key_type = 0; 194512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 195512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 196512cbf1dSJens Wiklander 197512cbf1dSJens Wiklander if (obj->key_handle != TEE_HANDLE_NULL) { 198512cbf1dSJens Wiklander /* Key was already loaded and fits current need */ 199512cbf1dSJens Wiklander goto key_ready; 200512cbf1dSJens Wiklander } 201512cbf1dSJens Wiklander 202512cbf1dSJens Wiklander if (!pkcs2tee_load_attr(&tee_attr, TEE_ATTR_SECRET_VALUE, 203512cbf1dSJens Wiklander obj, PKCS11_CKA_VALUE)) { 204512cbf1dSJens Wiklander EMSG("No secret found"); 205512cbf1dSJens Wiklander return PKCS11_CKR_FUNCTION_FAILED; 206512cbf1dSJens Wiklander } 207512cbf1dSJens Wiklander 208de94d6f8SRuchika Gupta switch (proc_params->id) { 209de94d6f8SRuchika Gupta case PKCS11_CKM_MD5_HMAC: 210de94d6f8SRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 211de94d6f8SRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 212de94d6f8SRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 213de94d6f8SRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 214de94d6f8SRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 215de94d6f8SRuchika Gupta key_type = get_key_type(obj->attributes); 216de94d6f8SRuchika Gupta /* 217de94d6f8SRuchika Gupta * If Object Key type is PKCS11_CKK_GENERIC_SECRET, 218de94d6f8SRuchika Gupta * determine the tee_key_type using the 219de94d6f8SRuchika Gupta * mechanism instead of object key_type. 220de94d6f8SRuchika Gupta */ 221de94d6f8SRuchika Gupta if (key_type == PKCS11_CKK_GENERIC_SECRET) 222de94d6f8SRuchika Gupta rc = pkcsmech2tee_key_type(&tee_key_type, 223de94d6f8SRuchika Gupta proc_params->id); 224de94d6f8SRuchika Gupta else 225512cbf1dSJens Wiklander rc = pkcs2tee_key_type(&tee_key_type, obj); 226de94d6f8SRuchika Gupta 227de94d6f8SRuchika Gupta break; 228de94d6f8SRuchika Gupta default: 229de94d6f8SRuchika Gupta /* 230de94d6f8SRuchika Gupta * For all other mechanisms, use object key_type 231de94d6f8SRuchika Gupta * to determine the corresponding tee_key_type 232de94d6f8SRuchika Gupta */ 233de94d6f8SRuchika Gupta rc = pkcs2tee_key_type(&tee_key_type, obj); 234de94d6f8SRuchika Gupta break; 235de94d6f8SRuchika Gupta } 236de94d6f8SRuchika Gupta 237512cbf1dSJens Wiklander if (rc) 238512cbf1dSJens Wiklander return rc; 239512cbf1dSJens Wiklander 240512cbf1dSJens Wiklander object_size = get_object_key_bit_size(obj); 241512cbf1dSJens Wiklander if (!object_size) 242512cbf1dSJens Wiklander return PKCS11_CKR_GENERAL_ERROR; 243512cbf1dSJens Wiklander 244512cbf1dSJens Wiklander res = TEE_AllocateTransientObject(tee_key_type, object_size, 245512cbf1dSJens Wiklander &obj->key_handle); 246512cbf1dSJens Wiklander if (res) { 247512cbf1dSJens Wiklander DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 248512cbf1dSJens Wiklander return tee2pkcs_error(res); 249512cbf1dSJens Wiklander } 250512cbf1dSJens Wiklander 251512cbf1dSJens Wiklander res = TEE_PopulateTransientObject(obj->key_handle, &tee_attr, 1); 252512cbf1dSJens Wiklander if (res) { 253512cbf1dSJens Wiklander DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res); 254512cbf1dSJens Wiklander goto error; 255512cbf1dSJens Wiklander } 256512cbf1dSJens Wiklander 257512cbf1dSJens Wiklander key_ready: 258512cbf1dSJens Wiklander res = TEE_SetOperationKey(session->processing->tee_op_handle, 259512cbf1dSJens Wiklander obj->key_handle); 260512cbf1dSJens Wiklander if (res) { 261512cbf1dSJens Wiklander DMSG("TEE_SetOperationKey failed, %#"PRIx32, res); 262512cbf1dSJens Wiklander goto error; 263512cbf1dSJens Wiklander } 264512cbf1dSJens Wiklander 265512cbf1dSJens Wiklander return PKCS11_CKR_OK; 266512cbf1dSJens Wiklander 267512cbf1dSJens Wiklander error: 268512cbf1dSJens Wiklander TEE_FreeTransientObject(obj->key_handle); 269512cbf1dSJens Wiklander obj->key_handle = TEE_HANDLE_NULL; 270512cbf1dSJens Wiklander 271512cbf1dSJens Wiklander return tee2pkcs_error(res); 272512cbf1dSJens Wiklander } 273512cbf1dSJens Wiklander 274512cbf1dSJens Wiklander static enum pkcs11_rc 275512cbf1dSJens Wiklander init_tee_operation(struct pkcs11_session *session, 276512cbf1dSJens Wiklander struct pkcs11_attribute_head *proc_params) 277512cbf1dSJens Wiklander { 278512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 279512cbf1dSJens Wiklander 280512cbf1dSJens Wiklander switch (proc_params->id) { 281689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 282689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 283689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 284689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 285689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 286689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 287689f4e5bSRuchika Gupta if (proc_params->size) 288689f4e5bSRuchika Gupta return PKCS11_CKR_MECHANISM_PARAM_INVALID; 289689f4e5bSRuchika Gupta 290689f4e5bSRuchika Gupta TEE_MACInit(session->processing->tee_op_handle, NULL, 0); 291689f4e5bSRuchika Gupta rc = PKCS11_CKR_OK; 292689f4e5bSRuchika Gupta break; 293512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 294512cbf1dSJens Wiklander if (proc_params->size) 295512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_PARAM_INVALID; 296512cbf1dSJens Wiklander 297512cbf1dSJens Wiklander TEE_CipherInit(session->processing->tee_op_handle, NULL, 0); 298512cbf1dSJens Wiklander rc = PKCS11_CKR_OK; 299512cbf1dSJens Wiklander break; 300512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 301512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 302512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 303512cbf1dSJens Wiklander if (proc_params->size != 16) 304512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_PARAM_INVALID; 305512cbf1dSJens Wiklander 306512cbf1dSJens Wiklander TEE_CipherInit(session->processing->tee_op_handle, 307512cbf1dSJens Wiklander proc_params->data, 16); 308512cbf1dSJens Wiklander rc = PKCS11_CKR_OK; 309512cbf1dSJens Wiklander break; 310512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 311512cbf1dSJens Wiklander rc = tee_init_ctr_operation(session->processing, 312512cbf1dSJens Wiklander proc_params->data, 313512cbf1dSJens Wiklander proc_params->size); 314512cbf1dSJens Wiklander break; 315512cbf1dSJens Wiklander default: 316512cbf1dSJens Wiklander TEE_Panic(proc_params->id); 317512cbf1dSJens Wiklander break; 318512cbf1dSJens Wiklander } 319512cbf1dSJens Wiklander 320512cbf1dSJens Wiklander return rc; 321512cbf1dSJens Wiklander } 322512cbf1dSJens Wiklander 323512cbf1dSJens Wiklander enum pkcs11_rc init_symm_operation(struct pkcs11_session *session, 324512cbf1dSJens Wiklander enum processing_func function, 325512cbf1dSJens Wiklander struct pkcs11_attribute_head *proc_params, 326512cbf1dSJens Wiklander struct pkcs11_object *obj) 327512cbf1dSJens Wiklander { 328512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 329512cbf1dSJens Wiklander 330512cbf1dSJens Wiklander assert(processing_is_tee_symm(proc_params->id)); 331512cbf1dSJens Wiklander 332512cbf1dSJens Wiklander rc = allocate_tee_operation(session, function, proc_params, obj); 333512cbf1dSJens Wiklander if (rc) 334512cbf1dSJens Wiklander return rc; 335512cbf1dSJens Wiklander 336de94d6f8SRuchika Gupta rc = load_tee_key(session, obj, proc_params); 337512cbf1dSJens Wiklander if (rc) 338512cbf1dSJens Wiklander return rc; 339512cbf1dSJens Wiklander 340512cbf1dSJens Wiklander return init_tee_operation(session, proc_params); 341512cbf1dSJens Wiklander } 342512cbf1dSJens Wiklander 343512cbf1dSJens Wiklander /* Validate input buffer size as per PKCS#11 constraints */ 344512cbf1dSJens Wiklander static enum pkcs11_rc input_data_size_is_valid(struct active_processing *proc, 345512cbf1dSJens Wiklander enum processing_func function, 346512cbf1dSJens Wiklander size_t in_size) 347512cbf1dSJens Wiklander { 348512cbf1dSJens Wiklander switch (proc->mecha_type) { 349512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 350512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 351512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_ENCRYPT && 352512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 353512cbf1dSJens Wiklander return PKCS11_CKR_DATA_LEN_RANGE; 354512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 355512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 356512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 357512cbf1dSJens Wiklander break; 358512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 359512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 360512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 361512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 362512cbf1dSJens Wiklander break; 363512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 364512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_ENCRYPT && 365512cbf1dSJens Wiklander in_size < TEE_AES_BLOCK_SIZE) 366512cbf1dSJens Wiklander return PKCS11_CKR_DATA_LEN_RANGE; 367512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 368512cbf1dSJens Wiklander in_size < TEE_AES_BLOCK_SIZE) 369512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 370512cbf1dSJens Wiklander break; 371512cbf1dSJens Wiklander default: 372512cbf1dSJens Wiklander break; 373512cbf1dSJens Wiklander } 374512cbf1dSJens Wiklander 375512cbf1dSJens Wiklander return PKCS11_CKR_OK; 376512cbf1dSJens Wiklander } 377512cbf1dSJens Wiklander 378689f4e5bSRuchika Gupta /* Validate input buffer size as per PKCS#11 constraints */ 379689f4e5bSRuchika Gupta static enum pkcs11_rc input_sign_size_is_valid(struct active_processing *proc, 380689f4e5bSRuchika Gupta size_t in_size) 381689f4e5bSRuchika Gupta { 382689f4e5bSRuchika Gupta size_t sign_sz = 0; 383689f4e5bSRuchika Gupta 384689f4e5bSRuchika Gupta switch (proc->mecha_type) { 385689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 386689f4e5bSRuchika Gupta sign_sz = TEE_MD5_HASH_SIZE; 387689f4e5bSRuchika Gupta break; 388689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 389689f4e5bSRuchika Gupta sign_sz = TEE_SHA1_HASH_SIZE; 390689f4e5bSRuchika Gupta break; 391689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 392689f4e5bSRuchika Gupta sign_sz = TEE_SHA224_HASH_SIZE; 393689f4e5bSRuchika Gupta break; 394689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 395689f4e5bSRuchika Gupta sign_sz = TEE_SHA256_HASH_SIZE; 396689f4e5bSRuchika Gupta break; 397689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 398689f4e5bSRuchika Gupta sign_sz = TEE_SHA384_HASH_SIZE; 399689f4e5bSRuchika Gupta break; 400689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 401689f4e5bSRuchika Gupta sign_sz = TEE_SHA512_HASH_SIZE; 402689f4e5bSRuchika Gupta break; 403689f4e5bSRuchika Gupta default: 404689f4e5bSRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 405689f4e5bSRuchika Gupta } 406689f4e5bSRuchika Gupta 407689f4e5bSRuchika Gupta if (in_size < sign_sz) 408689f4e5bSRuchika Gupta return PKCS11_CKR_SIGNATURE_LEN_RANGE; 409689f4e5bSRuchika Gupta 410689f4e5bSRuchika Gupta return PKCS11_CKR_OK; 411689f4e5bSRuchika Gupta } 412689f4e5bSRuchika Gupta 413512cbf1dSJens Wiklander /* 414512cbf1dSJens Wiklander * step_sym_cipher - processing symmetric (and related) cipher operation step 415512cbf1dSJens Wiklander * 416512cbf1dSJens Wiklander * @session - current session 417512cbf1dSJens Wiklander * @function - processing function (encrypt, decrypt, sign, ...) 418512cbf1dSJens Wiklander * @step - step ID in the processing (oneshot, update, final) 419512cbf1dSJens Wiklander * @ptype - invocation parameter types 420512cbf1dSJens Wiklander * @params - invocation parameter references 421512cbf1dSJens Wiklander */ 422512cbf1dSJens Wiklander enum pkcs11_rc step_symm_operation(struct pkcs11_session *session, 423512cbf1dSJens Wiklander enum processing_func function, 424512cbf1dSJens Wiklander enum processing_step step, 425512cbf1dSJens Wiklander uint32_t ptypes, TEE_Param *params) 426512cbf1dSJens Wiklander { 427512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 428512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 429512cbf1dSJens Wiklander void *in_buf = NULL; 430512cbf1dSJens Wiklander size_t in_size = 0; 431512cbf1dSJens Wiklander void *out_buf = NULL; 432512cbf1dSJens Wiklander uint32_t out_size = 0; 433512cbf1dSJens Wiklander void *in2_buf = NULL; 434512cbf1dSJens Wiklander uint32_t in2_size = 0; 435512cbf1dSJens Wiklander bool output_data = false; 436512cbf1dSJens Wiklander struct active_processing *proc = session->processing; 437512cbf1dSJens Wiklander 438512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 439512cbf1dSJens Wiklander in_buf = params[1].memref.buffer; 440512cbf1dSJens Wiklander in_size = params[1].memref.size; 441512cbf1dSJens Wiklander if (in_size && !in_buf) 442512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 443512cbf1dSJens Wiklander } 444512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) { 445512cbf1dSJens Wiklander in2_buf = params[2].memref.buffer; 446512cbf1dSJens Wiklander in2_size = params[2].memref.size; 447512cbf1dSJens Wiklander if (in2_size && !in2_buf) 448512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 449512cbf1dSJens Wiklander } 450512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 451512cbf1dSJens Wiklander out_buf = params[2].memref.buffer; 452512cbf1dSJens Wiklander out_size = params[2].memref.size; 453512cbf1dSJens Wiklander if (out_size && !out_buf) 454512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 455512cbf1dSJens Wiklander } 456512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 457512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 458512cbf1dSJens Wiklander 459512cbf1dSJens Wiklander switch (step) { 460512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_ONESHOT: 461512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_UPDATE: 462512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_FINAL: 463512cbf1dSJens Wiklander break; 464512cbf1dSJens Wiklander default: 465512cbf1dSJens Wiklander return PKCS11_CKR_GENERAL_ERROR; 466512cbf1dSJens Wiklander } 467512cbf1dSJens Wiklander 468512cbf1dSJens Wiklander if (step != PKCS11_FUNC_STEP_FINAL) { 469512cbf1dSJens Wiklander rc = input_data_size_is_valid(proc, function, in_size); 470512cbf1dSJens Wiklander if (rc) 471512cbf1dSJens Wiklander return rc; 472512cbf1dSJens Wiklander } 473512cbf1dSJens Wiklander 474512cbf1dSJens Wiklander /* 475512cbf1dSJens Wiklander * Feed active operation with data 476512cbf1dSJens Wiklander */ 477512cbf1dSJens Wiklander switch (proc->mecha_type) { 478689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 479689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 480689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 481689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 482689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 483689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 484689f4e5bSRuchika Gupta if (step == PKCS11_FUNC_STEP_FINAL || 485689f4e5bSRuchika Gupta step == PKCS11_FUNC_STEP_ONESHOT) 486689f4e5bSRuchika Gupta break; 487689f4e5bSRuchika Gupta 488689f4e5bSRuchika Gupta if (!in_buf) { 489689f4e5bSRuchika Gupta DMSG("No input data"); 490689f4e5bSRuchika Gupta return PKCS11_CKR_ARGUMENTS_BAD; 491689f4e5bSRuchika Gupta } 492689f4e5bSRuchika Gupta 493689f4e5bSRuchika Gupta switch (function) { 494689f4e5bSRuchika Gupta case PKCS11_FUNCTION_SIGN: 495689f4e5bSRuchika Gupta case PKCS11_FUNCTION_VERIFY: 496689f4e5bSRuchika Gupta TEE_MACUpdate(proc->tee_op_handle, in_buf, in_size); 497689f4e5bSRuchika Gupta rc = PKCS11_CKR_OK; 498689f4e5bSRuchika Gupta break; 499689f4e5bSRuchika Gupta default: 500689f4e5bSRuchika Gupta TEE_Panic(function); 501689f4e5bSRuchika Gupta break; 502689f4e5bSRuchika Gupta } 503689f4e5bSRuchika Gupta break; 504689f4e5bSRuchika Gupta 505512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 506512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 507512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 508512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 509512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 510512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_FINAL || 511512cbf1dSJens Wiklander step == PKCS11_FUNC_STEP_ONESHOT) 512512cbf1dSJens Wiklander break; 513512cbf1dSJens Wiklander 514512cbf1dSJens Wiklander if (!in_buf) { 515512cbf1dSJens Wiklander EMSG("No input data"); 516512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 517512cbf1dSJens Wiklander } 518512cbf1dSJens Wiklander 519512cbf1dSJens Wiklander switch (function) { 520512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 521512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 522512cbf1dSJens Wiklander res = TEE_CipherUpdate(proc->tee_op_handle, 523512cbf1dSJens Wiklander in_buf, in_size, 524512cbf1dSJens Wiklander out_buf, &out_size); 525512cbf1dSJens Wiklander output_data = true; 526512cbf1dSJens Wiklander rc = tee2pkcs_error(res); 527512cbf1dSJens Wiklander break; 528512cbf1dSJens Wiklander default: 529512cbf1dSJens Wiklander TEE_Panic(function); 530512cbf1dSJens Wiklander break; 531512cbf1dSJens Wiklander } 532512cbf1dSJens Wiklander break; 533512cbf1dSJens Wiklander 534512cbf1dSJens Wiklander default: 535512cbf1dSJens Wiklander TEE_Panic(proc->mecha_type); 536512cbf1dSJens Wiklander break; 537512cbf1dSJens Wiklander } 538512cbf1dSJens Wiklander 539512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_UPDATE) 540512cbf1dSJens Wiklander goto out; 541512cbf1dSJens Wiklander 542512cbf1dSJens Wiklander /* 543512cbf1dSJens Wiklander * Finalize (PKCS11_FUNC_STEP_ONESHOT/_FINAL) operation 544512cbf1dSJens Wiklander */ 545512cbf1dSJens Wiklander switch (session->processing->mecha_type) { 546689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 547689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 548689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 549689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 550689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 551689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 552689f4e5bSRuchika Gupta switch (function) { 553689f4e5bSRuchika Gupta case PKCS11_FUNCTION_SIGN: 554689f4e5bSRuchika Gupta res = TEE_MACComputeFinal(proc->tee_op_handle, 555689f4e5bSRuchika Gupta in_buf, in_size, out_buf, 556689f4e5bSRuchika Gupta &out_size); 557689f4e5bSRuchika Gupta output_data = true; 558689f4e5bSRuchika Gupta rc = tee2pkcs_error(res); 559689f4e5bSRuchika Gupta break; 560689f4e5bSRuchika Gupta case PKCS11_FUNCTION_VERIFY: 561689f4e5bSRuchika Gupta rc = input_sign_size_is_valid(proc, in2_size); 562689f4e5bSRuchika Gupta if (rc) 563689f4e5bSRuchika Gupta return rc; 564689f4e5bSRuchika Gupta res = TEE_MACCompareFinal(proc->tee_op_handle, 565689f4e5bSRuchika Gupta in_buf, in_size, in2_buf, 566689f4e5bSRuchika Gupta in2_size); 567689f4e5bSRuchika Gupta rc = tee2pkcs_error(res); 568689f4e5bSRuchika Gupta break; 569689f4e5bSRuchika Gupta default: 570689f4e5bSRuchika Gupta TEE_Panic(function); 571689f4e5bSRuchika Gupta break; 572689f4e5bSRuchika Gupta } 573689f4e5bSRuchika Gupta break; 574689f4e5bSRuchika Gupta 575512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 576512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 577512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 578512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 579512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 580512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_ONESHOT && !in_buf) { 581512cbf1dSJens Wiklander EMSG("No input data"); 582512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 583512cbf1dSJens Wiklander } 584512cbf1dSJens Wiklander 585512cbf1dSJens Wiklander switch (function) { 586512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 587512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 588512cbf1dSJens Wiklander res = TEE_CipherDoFinal(proc->tee_op_handle, 589512cbf1dSJens Wiklander in_buf, in_size, 590512cbf1dSJens Wiklander out_buf, &out_size); 591512cbf1dSJens Wiklander output_data = true; 592512cbf1dSJens Wiklander rc = tee2pkcs_error(res); 593512cbf1dSJens Wiklander break; 594512cbf1dSJens Wiklander default: 595512cbf1dSJens Wiklander TEE_Panic(function); 596512cbf1dSJens Wiklander break; 597512cbf1dSJens Wiklander } 598512cbf1dSJens Wiklander break; 599512cbf1dSJens Wiklander default: 600512cbf1dSJens Wiklander TEE_Panic(proc->mecha_type); 601512cbf1dSJens Wiklander break; 602512cbf1dSJens Wiklander } 603512cbf1dSJens Wiklander 604512cbf1dSJens Wiklander out: 605512cbf1dSJens Wiklander if (output_data && 606512cbf1dSJens Wiklander (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) { 607512cbf1dSJens Wiklander switch (TEE_PARAM_TYPE_GET(ptypes, 2)) { 608512cbf1dSJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 609512cbf1dSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 610512cbf1dSJens Wiklander params[2].memref.size = out_size; 611512cbf1dSJens Wiklander break; 612512cbf1dSJens Wiklander default: 613512cbf1dSJens Wiklander rc = PKCS11_CKR_ARGUMENTS_BAD; 614512cbf1dSJens Wiklander break; 615512cbf1dSJens Wiklander } 616512cbf1dSJens Wiklander } 617512cbf1dSJens Wiklander 618512cbf1dSJens Wiklander return rc; 619512cbf1dSJens Wiklander } 620