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) { 26*689f4e5bSRuchika Gupta /* Authentication */ 27*689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 28*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 29*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 30*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 31*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 32*689f4e5bSRuchika 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 }, 58*689f4e5bSRuchika Gupta /* HMAC flavors */ 59*689f4e5bSRuchika Gupta { PKCS11_CKM_MD5_HMAC, TEE_ALG_HMAC_MD5 }, 60*689f4e5bSRuchika Gupta { PKCS11_CKM_SHA_1_HMAC, TEE_ALG_HMAC_SHA1 }, 61*689f4e5bSRuchika Gupta { PKCS11_CKM_SHA224_HMAC, TEE_ALG_HMAC_SHA224 }, 62*689f4e5bSRuchika Gupta { PKCS11_CKM_SHA256_HMAC, TEE_ALG_HMAC_SHA256 }, 63*689f4e5bSRuchika Gupta { PKCS11_CKM_SHA384_HMAC, TEE_ALG_HMAC_SHA384 }, 64*689f4e5bSRuchika 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 109512cbf1dSJens Wiklander static enum pkcs11_rc 110512cbf1dSJens Wiklander allocate_tee_operation(struct pkcs11_session *session, 111512cbf1dSJens Wiklander enum processing_func function, 112512cbf1dSJens Wiklander struct pkcs11_attribute_head *params, 113512cbf1dSJens Wiklander struct pkcs11_object *obj) 114512cbf1dSJens Wiklander { 115512cbf1dSJens Wiklander uint32_t size = (uint32_t)get_object_key_bit_size(obj); 116512cbf1dSJens Wiklander uint32_t algo = 0; 117512cbf1dSJens Wiklander uint32_t mode = 0; 118512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 119512cbf1dSJens Wiklander 120512cbf1dSJens Wiklander assert(session->processing->tee_op_handle == TEE_HANDLE_NULL); 121512cbf1dSJens Wiklander 122512cbf1dSJens Wiklander if (pkcs2tee_algorithm(&algo, params)) 123512cbf1dSJens Wiklander return PKCS11_CKR_FUNCTION_FAILED; 124512cbf1dSJens Wiklander 125512cbf1dSJens Wiklander /* Sign/Verify with AES or generic key relate to TEE MAC operation */ 126*689f4e5bSRuchika Gupta switch (params->id) { 127*689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 128*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 129*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 130*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 131*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 132*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 133*689f4e5bSRuchika Gupta mode = TEE_MODE_MAC; 134*689f4e5bSRuchika Gupta break; 135*689f4e5bSRuchika Gupta default: 136512cbf1dSJens Wiklander pkcs2tee_mode(&mode, function); 137*689f4e5bSRuchika Gupta break; 138*689f4e5bSRuchika Gupta } 139512cbf1dSJens Wiklander 140512cbf1dSJens Wiklander res = TEE_AllocateOperation(&session->processing->tee_op_handle, 141512cbf1dSJens Wiklander algo, mode, size); 142512cbf1dSJens Wiklander if (res) 143512cbf1dSJens Wiklander EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32, 144512cbf1dSJens Wiklander algo, mode, size); 145512cbf1dSJens Wiklander 146512cbf1dSJens Wiklander if (res == TEE_ERROR_NOT_SUPPORTED) 147512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_INVALID; 148512cbf1dSJens Wiklander 149512cbf1dSJens Wiklander return tee2pkcs_error(res); 150512cbf1dSJens Wiklander } 151512cbf1dSJens Wiklander 152512cbf1dSJens Wiklander static enum pkcs11_rc load_tee_key(struct pkcs11_session *session, 153512cbf1dSJens Wiklander struct pkcs11_object *obj) 154512cbf1dSJens Wiklander { 155512cbf1dSJens Wiklander TEE_Attribute tee_attr = { }; 156512cbf1dSJens Wiklander size_t object_size = 0; 157512cbf1dSJens Wiklander uint32_t tee_key_type = 0; 158512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 159512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 160512cbf1dSJens Wiklander 161512cbf1dSJens Wiklander if (obj->key_handle != TEE_HANDLE_NULL) { 162512cbf1dSJens Wiklander /* Key was already loaded and fits current need */ 163512cbf1dSJens Wiklander goto key_ready; 164512cbf1dSJens Wiklander } 165512cbf1dSJens Wiklander 166512cbf1dSJens Wiklander if (!pkcs2tee_load_attr(&tee_attr, TEE_ATTR_SECRET_VALUE, 167512cbf1dSJens Wiklander obj, PKCS11_CKA_VALUE)) { 168512cbf1dSJens Wiklander EMSG("No secret found"); 169512cbf1dSJens Wiklander return PKCS11_CKR_FUNCTION_FAILED; 170512cbf1dSJens Wiklander } 171512cbf1dSJens Wiklander 172512cbf1dSJens Wiklander rc = pkcs2tee_key_type(&tee_key_type, obj); 173512cbf1dSJens Wiklander if (rc) 174512cbf1dSJens Wiklander return rc; 175512cbf1dSJens Wiklander 176512cbf1dSJens Wiklander object_size = get_object_key_bit_size(obj); 177512cbf1dSJens Wiklander if (!object_size) 178512cbf1dSJens Wiklander return PKCS11_CKR_GENERAL_ERROR; 179512cbf1dSJens Wiklander 180512cbf1dSJens Wiklander res = TEE_AllocateTransientObject(tee_key_type, object_size, 181512cbf1dSJens Wiklander &obj->key_handle); 182512cbf1dSJens Wiklander if (res) { 183512cbf1dSJens Wiklander DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 184512cbf1dSJens Wiklander return tee2pkcs_error(res); 185512cbf1dSJens Wiklander } 186512cbf1dSJens Wiklander 187512cbf1dSJens Wiklander res = TEE_PopulateTransientObject(obj->key_handle, &tee_attr, 1); 188512cbf1dSJens Wiklander if (res) { 189512cbf1dSJens Wiklander DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res); 190512cbf1dSJens Wiklander goto error; 191512cbf1dSJens Wiklander } 192512cbf1dSJens Wiklander 193512cbf1dSJens Wiklander key_ready: 194512cbf1dSJens Wiklander res = TEE_SetOperationKey(session->processing->tee_op_handle, 195512cbf1dSJens Wiklander obj->key_handle); 196512cbf1dSJens Wiklander if (res) { 197512cbf1dSJens Wiklander DMSG("TEE_SetOperationKey failed, %#"PRIx32, res); 198512cbf1dSJens Wiklander goto error; 199512cbf1dSJens Wiklander } 200512cbf1dSJens Wiklander 201512cbf1dSJens Wiklander return PKCS11_CKR_OK; 202512cbf1dSJens Wiklander 203512cbf1dSJens Wiklander error: 204512cbf1dSJens Wiklander TEE_FreeTransientObject(obj->key_handle); 205512cbf1dSJens Wiklander obj->key_handle = TEE_HANDLE_NULL; 206512cbf1dSJens Wiklander 207512cbf1dSJens Wiklander return tee2pkcs_error(res); 208512cbf1dSJens Wiklander } 209512cbf1dSJens Wiklander 210512cbf1dSJens Wiklander static enum pkcs11_rc 211512cbf1dSJens Wiklander init_tee_operation(struct pkcs11_session *session, 212512cbf1dSJens Wiklander struct pkcs11_attribute_head *proc_params) 213512cbf1dSJens Wiklander { 214512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 215512cbf1dSJens Wiklander 216512cbf1dSJens Wiklander switch (proc_params->id) { 217*689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 218*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 219*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 220*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 221*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 222*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 223*689f4e5bSRuchika Gupta if (proc_params->size) 224*689f4e5bSRuchika Gupta return PKCS11_CKR_MECHANISM_PARAM_INVALID; 225*689f4e5bSRuchika Gupta 226*689f4e5bSRuchika Gupta TEE_MACInit(session->processing->tee_op_handle, NULL, 0); 227*689f4e5bSRuchika Gupta rc = PKCS11_CKR_OK; 228*689f4e5bSRuchika Gupta break; 229512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 230512cbf1dSJens Wiklander if (proc_params->size) 231512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_PARAM_INVALID; 232512cbf1dSJens Wiklander 233512cbf1dSJens Wiklander TEE_CipherInit(session->processing->tee_op_handle, NULL, 0); 234512cbf1dSJens Wiklander rc = PKCS11_CKR_OK; 235512cbf1dSJens Wiklander break; 236512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 237512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 238512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 239512cbf1dSJens Wiklander if (proc_params->size != 16) 240512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_PARAM_INVALID; 241512cbf1dSJens Wiklander 242512cbf1dSJens Wiklander TEE_CipherInit(session->processing->tee_op_handle, 243512cbf1dSJens Wiklander proc_params->data, 16); 244512cbf1dSJens Wiklander rc = PKCS11_CKR_OK; 245512cbf1dSJens Wiklander break; 246512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 247512cbf1dSJens Wiklander rc = tee_init_ctr_operation(session->processing, 248512cbf1dSJens Wiklander proc_params->data, 249512cbf1dSJens Wiklander proc_params->size); 250512cbf1dSJens Wiklander break; 251512cbf1dSJens Wiklander default: 252512cbf1dSJens Wiklander TEE_Panic(proc_params->id); 253512cbf1dSJens Wiklander break; 254512cbf1dSJens Wiklander } 255512cbf1dSJens Wiklander 256512cbf1dSJens Wiklander return rc; 257512cbf1dSJens Wiklander } 258512cbf1dSJens Wiklander 259512cbf1dSJens Wiklander enum pkcs11_rc init_symm_operation(struct pkcs11_session *session, 260512cbf1dSJens Wiklander enum processing_func function, 261512cbf1dSJens Wiklander struct pkcs11_attribute_head *proc_params, 262512cbf1dSJens Wiklander struct pkcs11_object *obj) 263512cbf1dSJens Wiklander { 264512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 265512cbf1dSJens Wiklander 266512cbf1dSJens Wiklander assert(processing_is_tee_symm(proc_params->id)); 267512cbf1dSJens Wiklander 268512cbf1dSJens Wiklander rc = allocate_tee_operation(session, function, proc_params, obj); 269512cbf1dSJens Wiklander if (rc) 270512cbf1dSJens Wiklander return rc; 271512cbf1dSJens Wiklander 272512cbf1dSJens Wiklander rc = load_tee_key(session, obj); 273512cbf1dSJens Wiklander if (rc) 274512cbf1dSJens Wiklander return rc; 275512cbf1dSJens Wiklander 276512cbf1dSJens Wiklander return init_tee_operation(session, proc_params); 277512cbf1dSJens Wiklander } 278512cbf1dSJens Wiklander 279512cbf1dSJens Wiklander /* Validate input buffer size as per PKCS#11 constraints */ 280512cbf1dSJens Wiklander static enum pkcs11_rc input_data_size_is_valid(struct active_processing *proc, 281512cbf1dSJens Wiklander enum processing_func function, 282512cbf1dSJens Wiklander size_t in_size) 283512cbf1dSJens Wiklander { 284512cbf1dSJens Wiklander switch (proc->mecha_type) { 285512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 286512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 287512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_ENCRYPT && 288512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 289512cbf1dSJens Wiklander return PKCS11_CKR_DATA_LEN_RANGE; 290512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 291512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 292512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 293512cbf1dSJens Wiklander break; 294512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 295512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 296512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 297512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 298512cbf1dSJens Wiklander break; 299512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 300512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_ENCRYPT && 301512cbf1dSJens Wiklander in_size < TEE_AES_BLOCK_SIZE) 302512cbf1dSJens Wiklander return PKCS11_CKR_DATA_LEN_RANGE; 303512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 304512cbf1dSJens Wiklander in_size < TEE_AES_BLOCK_SIZE) 305512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 306512cbf1dSJens Wiklander break; 307512cbf1dSJens Wiklander default: 308512cbf1dSJens Wiklander break; 309512cbf1dSJens Wiklander } 310512cbf1dSJens Wiklander 311512cbf1dSJens Wiklander return PKCS11_CKR_OK; 312512cbf1dSJens Wiklander } 313512cbf1dSJens Wiklander 314*689f4e5bSRuchika Gupta /* Validate input buffer size as per PKCS#11 constraints */ 315*689f4e5bSRuchika Gupta static enum pkcs11_rc input_sign_size_is_valid(struct active_processing *proc, 316*689f4e5bSRuchika Gupta size_t in_size) 317*689f4e5bSRuchika Gupta { 318*689f4e5bSRuchika Gupta size_t sign_sz = 0; 319*689f4e5bSRuchika Gupta 320*689f4e5bSRuchika Gupta switch (proc->mecha_type) { 321*689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 322*689f4e5bSRuchika Gupta sign_sz = TEE_MD5_HASH_SIZE; 323*689f4e5bSRuchika Gupta break; 324*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 325*689f4e5bSRuchika Gupta sign_sz = TEE_SHA1_HASH_SIZE; 326*689f4e5bSRuchika Gupta break; 327*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 328*689f4e5bSRuchika Gupta sign_sz = TEE_SHA224_HASH_SIZE; 329*689f4e5bSRuchika Gupta break; 330*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 331*689f4e5bSRuchika Gupta sign_sz = TEE_SHA256_HASH_SIZE; 332*689f4e5bSRuchika Gupta break; 333*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 334*689f4e5bSRuchika Gupta sign_sz = TEE_SHA384_HASH_SIZE; 335*689f4e5bSRuchika Gupta break; 336*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 337*689f4e5bSRuchika Gupta sign_sz = TEE_SHA512_HASH_SIZE; 338*689f4e5bSRuchika Gupta break; 339*689f4e5bSRuchika Gupta default: 340*689f4e5bSRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 341*689f4e5bSRuchika Gupta } 342*689f4e5bSRuchika Gupta 343*689f4e5bSRuchika Gupta if (in_size < sign_sz) 344*689f4e5bSRuchika Gupta return PKCS11_CKR_SIGNATURE_LEN_RANGE; 345*689f4e5bSRuchika Gupta 346*689f4e5bSRuchika Gupta return PKCS11_CKR_OK; 347*689f4e5bSRuchika Gupta } 348*689f4e5bSRuchika Gupta 349512cbf1dSJens Wiklander /* 350512cbf1dSJens Wiklander * step_sym_cipher - processing symmetric (and related) cipher operation step 351512cbf1dSJens Wiklander * 352512cbf1dSJens Wiklander * @session - current session 353512cbf1dSJens Wiklander * @function - processing function (encrypt, decrypt, sign, ...) 354512cbf1dSJens Wiklander * @step - step ID in the processing (oneshot, update, final) 355512cbf1dSJens Wiklander * @ptype - invocation parameter types 356512cbf1dSJens Wiklander * @params - invocation parameter references 357512cbf1dSJens Wiklander */ 358512cbf1dSJens Wiklander enum pkcs11_rc step_symm_operation(struct pkcs11_session *session, 359512cbf1dSJens Wiklander enum processing_func function, 360512cbf1dSJens Wiklander enum processing_step step, 361512cbf1dSJens Wiklander uint32_t ptypes, TEE_Param *params) 362512cbf1dSJens Wiklander { 363512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 364512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 365512cbf1dSJens Wiklander void *in_buf = NULL; 366512cbf1dSJens Wiklander size_t in_size = 0; 367512cbf1dSJens Wiklander void *out_buf = NULL; 368512cbf1dSJens Wiklander uint32_t out_size = 0; 369512cbf1dSJens Wiklander void *in2_buf = NULL; 370512cbf1dSJens Wiklander uint32_t in2_size = 0; 371512cbf1dSJens Wiklander bool output_data = false; 372512cbf1dSJens Wiklander struct active_processing *proc = session->processing; 373512cbf1dSJens Wiklander 374512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 375512cbf1dSJens Wiklander in_buf = params[1].memref.buffer; 376512cbf1dSJens Wiklander in_size = params[1].memref.size; 377512cbf1dSJens Wiklander if (in_size && !in_buf) 378512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 379512cbf1dSJens Wiklander } 380512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) { 381512cbf1dSJens Wiklander in2_buf = params[2].memref.buffer; 382512cbf1dSJens Wiklander in2_size = params[2].memref.size; 383512cbf1dSJens Wiklander if (in2_size && !in2_buf) 384512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 385512cbf1dSJens Wiklander } 386512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 387512cbf1dSJens Wiklander out_buf = params[2].memref.buffer; 388512cbf1dSJens Wiklander out_size = params[2].memref.size; 389512cbf1dSJens Wiklander if (out_size && !out_buf) 390512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 391512cbf1dSJens Wiklander } 392512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 393512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 394512cbf1dSJens Wiklander 395512cbf1dSJens Wiklander switch (step) { 396512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_ONESHOT: 397512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_UPDATE: 398512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_FINAL: 399512cbf1dSJens Wiklander break; 400512cbf1dSJens Wiklander default: 401512cbf1dSJens Wiklander return PKCS11_CKR_GENERAL_ERROR; 402512cbf1dSJens Wiklander } 403512cbf1dSJens Wiklander 404512cbf1dSJens Wiklander if (step != PKCS11_FUNC_STEP_FINAL) { 405512cbf1dSJens Wiklander rc = input_data_size_is_valid(proc, function, in_size); 406512cbf1dSJens Wiklander if (rc) 407512cbf1dSJens Wiklander return rc; 408512cbf1dSJens Wiklander } 409512cbf1dSJens Wiklander 410512cbf1dSJens Wiklander /* 411512cbf1dSJens Wiklander * Feed active operation with data 412512cbf1dSJens Wiklander */ 413512cbf1dSJens Wiklander switch (proc->mecha_type) { 414*689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 415*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 416*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 417*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 418*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 419*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 420*689f4e5bSRuchika Gupta if (step == PKCS11_FUNC_STEP_FINAL || 421*689f4e5bSRuchika Gupta step == PKCS11_FUNC_STEP_ONESHOT) 422*689f4e5bSRuchika Gupta break; 423*689f4e5bSRuchika Gupta 424*689f4e5bSRuchika Gupta if (!in_buf) { 425*689f4e5bSRuchika Gupta DMSG("No input data"); 426*689f4e5bSRuchika Gupta return PKCS11_CKR_ARGUMENTS_BAD; 427*689f4e5bSRuchika Gupta } 428*689f4e5bSRuchika Gupta 429*689f4e5bSRuchika Gupta switch (function) { 430*689f4e5bSRuchika Gupta case PKCS11_FUNCTION_SIGN: 431*689f4e5bSRuchika Gupta case PKCS11_FUNCTION_VERIFY: 432*689f4e5bSRuchika Gupta TEE_MACUpdate(proc->tee_op_handle, in_buf, in_size); 433*689f4e5bSRuchika Gupta rc = PKCS11_CKR_OK; 434*689f4e5bSRuchika Gupta break; 435*689f4e5bSRuchika Gupta default: 436*689f4e5bSRuchika Gupta TEE_Panic(function); 437*689f4e5bSRuchika Gupta break; 438*689f4e5bSRuchika Gupta } 439*689f4e5bSRuchika Gupta break; 440*689f4e5bSRuchika Gupta 441512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 442512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 443512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 444512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 445512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 446512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_FINAL || 447512cbf1dSJens Wiklander step == PKCS11_FUNC_STEP_ONESHOT) 448512cbf1dSJens Wiklander break; 449512cbf1dSJens Wiklander 450512cbf1dSJens Wiklander if (!in_buf) { 451512cbf1dSJens Wiklander EMSG("No input data"); 452512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 453512cbf1dSJens Wiklander } 454512cbf1dSJens Wiklander 455512cbf1dSJens Wiklander switch (function) { 456512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 457512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 458512cbf1dSJens Wiklander res = TEE_CipherUpdate(proc->tee_op_handle, 459512cbf1dSJens Wiklander in_buf, in_size, 460512cbf1dSJens Wiklander out_buf, &out_size); 461512cbf1dSJens Wiklander output_data = true; 462512cbf1dSJens Wiklander rc = tee2pkcs_error(res); 463512cbf1dSJens Wiklander break; 464512cbf1dSJens Wiklander default: 465512cbf1dSJens Wiklander TEE_Panic(function); 466512cbf1dSJens Wiklander break; 467512cbf1dSJens Wiklander } 468512cbf1dSJens Wiklander break; 469512cbf1dSJens Wiklander 470512cbf1dSJens Wiklander default: 471512cbf1dSJens Wiklander TEE_Panic(proc->mecha_type); 472512cbf1dSJens Wiklander break; 473512cbf1dSJens Wiklander } 474512cbf1dSJens Wiklander 475512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_UPDATE) 476512cbf1dSJens Wiklander goto out; 477512cbf1dSJens Wiklander 478512cbf1dSJens Wiklander /* 479512cbf1dSJens Wiklander * Finalize (PKCS11_FUNC_STEP_ONESHOT/_FINAL) operation 480512cbf1dSJens Wiklander */ 481512cbf1dSJens Wiklander switch (session->processing->mecha_type) { 482*689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 483*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 484*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 485*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 486*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 487*689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 488*689f4e5bSRuchika Gupta switch (function) { 489*689f4e5bSRuchika Gupta case PKCS11_FUNCTION_SIGN: 490*689f4e5bSRuchika Gupta res = TEE_MACComputeFinal(proc->tee_op_handle, 491*689f4e5bSRuchika Gupta in_buf, in_size, out_buf, 492*689f4e5bSRuchika Gupta &out_size); 493*689f4e5bSRuchika Gupta output_data = true; 494*689f4e5bSRuchika Gupta rc = tee2pkcs_error(res); 495*689f4e5bSRuchika Gupta break; 496*689f4e5bSRuchika Gupta case PKCS11_FUNCTION_VERIFY: 497*689f4e5bSRuchika Gupta rc = input_sign_size_is_valid(proc, in2_size); 498*689f4e5bSRuchika Gupta if (rc) 499*689f4e5bSRuchika Gupta return rc; 500*689f4e5bSRuchika Gupta res = TEE_MACCompareFinal(proc->tee_op_handle, 501*689f4e5bSRuchika Gupta in_buf, in_size, in2_buf, 502*689f4e5bSRuchika Gupta in2_size); 503*689f4e5bSRuchika Gupta rc = tee2pkcs_error(res); 504*689f4e5bSRuchika Gupta break; 505*689f4e5bSRuchika Gupta default: 506*689f4e5bSRuchika Gupta TEE_Panic(function); 507*689f4e5bSRuchika Gupta break; 508*689f4e5bSRuchika Gupta } 509*689f4e5bSRuchika Gupta break; 510*689f4e5bSRuchika Gupta 511512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 512512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 513512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 514512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 515512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 516512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_ONESHOT && !in_buf) { 517512cbf1dSJens Wiklander EMSG("No input data"); 518512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 519512cbf1dSJens Wiklander } 520512cbf1dSJens Wiklander 521512cbf1dSJens Wiklander switch (function) { 522512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 523512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 524512cbf1dSJens Wiklander res = TEE_CipherDoFinal(proc->tee_op_handle, 525512cbf1dSJens Wiklander in_buf, in_size, 526512cbf1dSJens Wiklander out_buf, &out_size); 527512cbf1dSJens Wiklander output_data = true; 528512cbf1dSJens Wiklander rc = tee2pkcs_error(res); 529512cbf1dSJens Wiklander break; 530512cbf1dSJens Wiklander default: 531512cbf1dSJens Wiklander TEE_Panic(function); 532512cbf1dSJens Wiklander break; 533512cbf1dSJens Wiklander } 534512cbf1dSJens Wiklander break; 535512cbf1dSJens Wiklander default: 536512cbf1dSJens Wiklander TEE_Panic(proc->mecha_type); 537512cbf1dSJens Wiklander break; 538512cbf1dSJens Wiklander } 539512cbf1dSJens Wiklander 540512cbf1dSJens Wiklander out: 541512cbf1dSJens Wiklander if (output_data && 542512cbf1dSJens Wiklander (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) { 543512cbf1dSJens Wiklander switch (TEE_PARAM_TYPE_GET(ptypes, 2)) { 544512cbf1dSJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 545512cbf1dSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 546512cbf1dSJens Wiklander params[2].memref.size = out_size; 547512cbf1dSJens Wiklander break; 548512cbf1dSJens Wiklander default: 549512cbf1dSJens Wiklander rc = PKCS11_CKR_ARGUMENTS_BAD; 550512cbf1dSJens Wiklander break; 551512cbf1dSJens Wiklander } 552512cbf1dSJens Wiklander } 553512cbf1dSJens Wiklander 554512cbf1dSJens Wiklander return rc; 555512cbf1dSJens Wiklander } 556