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 109*de94d6f8SRuchika Gupta static enum pkcs11_rc pkcsmech2tee_key_type(uint32_t *tee_type, 110*de94d6f8SRuchika Gupta enum pkcs11_mechanism_id mech_id) 111*de94d6f8SRuchika Gupta { 112*de94d6f8SRuchika Gupta static const struct { 113*de94d6f8SRuchika Gupta enum pkcs11_mechanism_id mech; 114*de94d6f8SRuchika Gupta uint32_t tee_id; 115*de94d6f8SRuchika Gupta } pkcs2tee_key_type[] = { 116*de94d6f8SRuchika Gupta { PKCS11_CKM_MD5_HMAC, TEE_TYPE_HMAC_MD5 }, 117*de94d6f8SRuchika Gupta { PKCS11_CKM_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 }, 118*de94d6f8SRuchika Gupta { PKCS11_CKM_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 }, 119*de94d6f8SRuchika Gupta { PKCS11_CKM_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 }, 120*de94d6f8SRuchika Gupta { PKCS11_CKM_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 }, 121*de94d6f8SRuchika Gupta { PKCS11_CKM_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 }, 122*de94d6f8SRuchika Gupta }; 123*de94d6f8SRuchika Gupta size_t n = 0; 124*de94d6f8SRuchika Gupta 125*de94d6f8SRuchika Gupta for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) { 126*de94d6f8SRuchika Gupta if (pkcs2tee_key_type[n].mech == mech_id) { 127*de94d6f8SRuchika Gupta *tee_type = pkcs2tee_key_type[n].tee_id; 128*de94d6f8SRuchika Gupta return PKCS11_CKR_OK; 129*de94d6f8SRuchika Gupta } 130*de94d6f8SRuchika Gupta } 131*de94d6f8SRuchika Gupta 132*de94d6f8SRuchika Gupta return PKCS11_RV_NOT_FOUND; 133*de94d6f8SRuchika Gupta } 134*de94d6f8SRuchika 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); 142512cbf1dSJens Wiklander uint32_t algo = 0; 143512cbf1dSJens Wiklander uint32_t mode = 0; 144512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 145512cbf1dSJens Wiklander 146512cbf1dSJens Wiklander assert(session->processing->tee_op_handle == TEE_HANDLE_NULL); 147512cbf1dSJens Wiklander 148512cbf1dSJens Wiklander if (pkcs2tee_algorithm(&algo, params)) 149512cbf1dSJens Wiklander return PKCS11_CKR_FUNCTION_FAILED; 150512cbf1dSJens Wiklander 151512cbf1dSJens Wiklander /* Sign/Verify with AES or generic key relate to TEE MAC operation */ 152689f4e5bSRuchika Gupta switch (params->id) { 153689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 154689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 155689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 156689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 157689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 158689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 159689f4e5bSRuchika Gupta mode = TEE_MODE_MAC; 160689f4e5bSRuchika Gupta break; 161689f4e5bSRuchika Gupta default: 162512cbf1dSJens Wiklander pkcs2tee_mode(&mode, function); 163689f4e5bSRuchika Gupta break; 164689f4e5bSRuchika Gupta } 165512cbf1dSJens Wiklander 166512cbf1dSJens Wiklander res = TEE_AllocateOperation(&session->processing->tee_op_handle, 167512cbf1dSJens Wiklander algo, mode, size); 168512cbf1dSJens Wiklander if (res) 169512cbf1dSJens Wiklander EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32, 170512cbf1dSJens Wiklander algo, mode, size); 171512cbf1dSJens Wiklander 172512cbf1dSJens Wiklander if (res == TEE_ERROR_NOT_SUPPORTED) 173512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_INVALID; 174512cbf1dSJens Wiklander 175512cbf1dSJens Wiklander return tee2pkcs_error(res); 176512cbf1dSJens Wiklander } 177512cbf1dSJens Wiklander 178512cbf1dSJens Wiklander static enum pkcs11_rc load_tee_key(struct pkcs11_session *session, 179*de94d6f8SRuchika Gupta struct pkcs11_object *obj, 180*de94d6f8SRuchika Gupta struct pkcs11_attribute_head *proc_params) 181512cbf1dSJens Wiklander { 182512cbf1dSJens Wiklander TEE_Attribute tee_attr = { }; 183512cbf1dSJens Wiklander size_t object_size = 0; 184512cbf1dSJens Wiklander uint32_t tee_key_type = 0; 185*de94d6f8SRuchika Gupta enum pkcs11_key_type key_type = 0; 186512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 187512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 188512cbf1dSJens Wiklander 189512cbf1dSJens Wiklander if (obj->key_handle != TEE_HANDLE_NULL) { 190512cbf1dSJens Wiklander /* Key was already loaded and fits current need */ 191512cbf1dSJens Wiklander goto key_ready; 192512cbf1dSJens Wiklander } 193512cbf1dSJens Wiklander 194512cbf1dSJens Wiklander if (!pkcs2tee_load_attr(&tee_attr, TEE_ATTR_SECRET_VALUE, 195512cbf1dSJens Wiklander obj, PKCS11_CKA_VALUE)) { 196512cbf1dSJens Wiklander EMSG("No secret found"); 197512cbf1dSJens Wiklander return PKCS11_CKR_FUNCTION_FAILED; 198512cbf1dSJens Wiklander } 199512cbf1dSJens Wiklander 200*de94d6f8SRuchika Gupta switch (proc_params->id) { 201*de94d6f8SRuchika Gupta case PKCS11_CKM_MD5_HMAC: 202*de94d6f8SRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 203*de94d6f8SRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 204*de94d6f8SRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 205*de94d6f8SRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 206*de94d6f8SRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 207*de94d6f8SRuchika Gupta key_type = get_key_type(obj->attributes); 208*de94d6f8SRuchika Gupta /* 209*de94d6f8SRuchika Gupta * If Object Key type is PKCS11_CKK_GENERIC_SECRET, 210*de94d6f8SRuchika Gupta * determine the tee_key_type using the 211*de94d6f8SRuchika Gupta * mechanism instead of object key_type. 212*de94d6f8SRuchika Gupta */ 213*de94d6f8SRuchika Gupta if (key_type == PKCS11_CKK_GENERIC_SECRET) 214*de94d6f8SRuchika Gupta rc = pkcsmech2tee_key_type(&tee_key_type, 215*de94d6f8SRuchika Gupta proc_params->id); 216*de94d6f8SRuchika Gupta else 217512cbf1dSJens Wiklander rc = pkcs2tee_key_type(&tee_key_type, obj); 218*de94d6f8SRuchika Gupta 219*de94d6f8SRuchika Gupta break; 220*de94d6f8SRuchika Gupta default: 221*de94d6f8SRuchika Gupta /* 222*de94d6f8SRuchika Gupta * For all other mechanisms, use object key_type 223*de94d6f8SRuchika Gupta * to determine the corresponding tee_key_type 224*de94d6f8SRuchika Gupta */ 225*de94d6f8SRuchika Gupta rc = pkcs2tee_key_type(&tee_key_type, obj); 226*de94d6f8SRuchika Gupta break; 227*de94d6f8SRuchika Gupta } 228*de94d6f8SRuchika Gupta 229512cbf1dSJens Wiklander if (rc) 230512cbf1dSJens Wiklander return rc; 231512cbf1dSJens Wiklander 232512cbf1dSJens Wiklander object_size = get_object_key_bit_size(obj); 233512cbf1dSJens Wiklander if (!object_size) 234512cbf1dSJens Wiklander return PKCS11_CKR_GENERAL_ERROR; 235512cbf1dSJens Wiklander 236512cbf1dSJens Wiklander res = TEE_AllocateTransientObject(tee_key_type, object_size, 237512cbf1dSJens Wiklander &obj->key_handle); 238512cbf1dSJens Wiklander if (res) { 239512cbf1dSJens Wiklander DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 240512cbf1dSJens Wiklander return tee2pkcs_error(res); 241512cbf1dSJens Wiklander } 242512cbf1dSJens Wiklander 243512cbf1dSJens Wiklander res = TEE_PopulateTransientObject(obj->key_handle, &tee_attr, 1); 244512cbf1dSJens Wiklander if (res) { 245512cbf1dSJens Wiklander DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res); 246512cbf1dSJens Wiklander goto error; 247512cbf1dSJens Wiklander } 248512cbf1dSJens Wiklander 249512cbf1dSJens Wiklander key_ready: 250512cbf1dSJens Wiklander res = TEE_SetOperationKey(session->processing->tee_op_handle, 251512cbf1dSJens Wiklander obj->key_handle); 252512cbf1dSJens Wiklander if (res) { 253512cbf1dSJens Wiklander DMSG("TEE_SetOperationKey failed, %#"PRIx32, res); 254512cbf1dSJens Wiklander goto error; 255512cbf1dSJens Wiklander } 256512cbf1dSJens Wiklander 257512cbf1dSJens Wiklander return PKCS11_CKR_OK; 258512cbf1dSJens Wiklander 259512cbf1dSJens Wiklander error: 260512cbf1dSJens Wiklander TEE_FreeTransientObject(obj->key_handle); 261512cbf1dSJens Wiklander obj->key_handle = TEE_HANDLE_NULL; 262512cbf1dSJens Wiklander 263512cbf1dSJens Wiklander return tee2pkcs_error(res); 264512cbf1dSJens Wiklander } 265512cbf1dSJens Wiklander 266512cbf1dSJens Wiklander static enum pkcs11_rc 267512cbf1dSJens Wiklander init_tee_operation(struct pkcs11_session *session, 268512cbf1dSJens Wiklander struct pkcs11_attribute_head *proc_params) 269512cbf1dSJens Wiklander { 270512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 271512cbf1dSJens Wiklander 272512cbf1dSJens Wiklander switch (proc_params->id) { 273689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 274689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 275689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 276689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 277689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 278689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 279689f4e5bSRuchika Gupta if (proc_params->size) 280689f4e5bSRuchika Gupta return PKCS11_CKR_MECHANISM_PARAM_INVALID; 281689f4e5bSRuchika Gupta 282689f4e5bSRuchika Gupta TEE_MACInit(session->processing->tee_op_handle, NULL, 0); 283689f4e5bSRuchika Gupta rc = PKCS11_CKR_OK; 284689f4e5bSRuchika Gupta break; 285512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 286512cbf1dSJens Wiklander if (proc_params->size) 287512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_PARAM_INVALID; 288512cbf1dSJens Wiklander 289512cbf1dSJens Wiklander TEE_CipherInit(session->processing->tee_op_handle, NULL, 0); 290512cbf1dSJens Wiklander rc = PKCS11_CKR_OK; 291512cbf1dSJens Wiklander break; 292512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 293512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 294512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 295512cbf1dSJens Wiklander if (proc_params->size != 16) 296512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_PARAM_INVALID; 297512cbf1dSJens Wiklander 298512cbf1dSJens Wiklander TEE_CipherInit(session->processing->tee_op_handle, 299512cbf1dSJens Wiklander proc_params->data, 16); 300512cbf1dSJens Wiklander rc = PKCS11_CKR_OK; 301512cbf1dSJens Wiklander break; 302512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 303512cbf1dSJens Wiklander rc = tee_init_ctr_operation(session->processing, 304512cbf1dSJens Wiklander proc_params->data, 305512cbf1dSJens Wiklander proc_params->size); 306512cbf1dSJens Wiklander break; 307512cbf1dSJens Wiklander default: 308512cbf1dSJens Wiklander TEE_Panic(proc_params->id); 309512cbf1dSJens Wiklander break; 310512cbf1dSJens Wiklander } 311512cbf1dSJens Wiklander 312512cbf1dSJens Wiklander return rc; 313512cbf1dSJens Wiklander } 314512cbf1dSJens Wiklander 315512cbf1dSJens Wiklander enum pkcs11_rc init_symm_operation(struct pkcs11_session *session, 316512cbf1dSJens Wiklander enum processing_func function, 317512cbf1dSJens Wiklander struct pkcs11_attribute_head *proc_params, 318512cbf1dSJens Wiklander struct pkcs11_object *obj) 319512cbf1dSJens Wiklander { 320512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 321512cbf1dSJens Wiklander 322512cbf1dSJens Wiklander assert(processing_is_tee_symm(proc_params->id)); 323512cbf1dSJens Wiklander 324512cbf1dSJens Wiklander rc = allocate_tee_operation(session, function, proc_params, obj); 325512cbf1dSJens Wiklander if (rc) 326512cbf1dSJens Wiklander return rc; 327512cbf1dSJens Wiklander 328*de94d6f8SRuchika Gupta rc = load_tee_key(session, obj, proc_params); 329512cbf1dSJens Wiklander if (rc) 330512cbf1dSJens Wiklander return rc; 331512cbf1dSJens Wiklander 332512cbf1dSJens Wiklander return init_tee_operation(session, proc_params); 333512cbf1dSJens Wiklander } 334512cbf1dSJens Wiklander 335512cbf1dSJens Wiklander /* Validate input buffer size as per PKCS#11 constraints */ 336512cbf1dSJens Wiklander static enum pkcs11_rc input_data_size_is_valid(struct active_processing *proc, 337512cbf1dSJens Wiklander enum processing_func function, 338512cbf1dSJens Wiklander size_t in_size) 339512cbf1dSJens Wiklander { 340512cbf1dSJens Wiklander switch (proc->mecha_type) { 341512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 342512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 343512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_ENCRYPT && 344512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 345512cbf1dSJens Wiklander return PKCS11_CKR_DATA_LEN_RANGE; 346512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 347512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 348512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 349512cbf1dSJens Wiklander break; 350512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 351512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 352512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 353512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 354512cbf1dSJens Wiklander break; 355512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 356512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_ENCRYPT && 357512cbf1dSJens Wiklander in_size < TEE_AES_BLOCK_SIZE) 358512cbf1dSJens Wiklander return PKCS11_CKR_DATA_LEN_RANGE; 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 default: 364512cbf1dSJens Wiklander break; 365512cbf1dSJens Wiklander } 366512cbf1dSJens Wiklander 367512cbf1dSJens Wiklander return PKCS11_CKR_OK; 368512cbf1dSJens Wiklander } 369512cbf1dSJens Wiklander 370689f4e5bSRuchika Gupta /* Validate input buffer size as per PKCS#11 constraints */ 371689f4e5bSRuchika Gupta static enum pkcs11_rc input_sign_size_is_valid(struct active_processing *proc, 372689f4e5bSRuchika Gupta size_t in_size) 373689f4e5bSRuchika Gupta { 374689f4e5bSRuchika Gupta size_t sign_sz = 0; 375689f4e5bSRuchika Gupta 376689f4e5bSRuchika Gupta switch (proc->mecha_type) { 377689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 378689f4e5bSRuchika Gupta sign_sz = TEE_MD5_HASH_SIZE; 379689f4e5bSRuchika Gupta break; 380689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 381689f4e5bSRuchika Gupta sign_sz = TEE_SHA1_HASH_SIZE; 382689f4e5bSRuchika Gupta break; 383689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 384689f4e5bSRuchika Gupta sign_sz = TEE_SHA224_HASH_SIZE; 385689f4e5bSRuchika Gupta break; 386689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 387689f4e5bSRuchika Gupta sign_sz = TEE_SHA256_HASH_SIZE; 388689f4e5bSRuchika Gupta break; 389689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 390689f4e5bSRuchika Gupta sign_sz = TEE_SHA384_HASH_SIZE; 391689f4e5bSRuchika Gupta break; 392689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 393689f4e5bSRuchika Gupta sign_sz = TEE_SHA512_HASH_SIZE; 394689f4e5bSRuchika Gupta break; 395689f4e5bSRuchika Gupta default: 396689f4e5bSRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 397689f4e5bSRuchika Gupta } 398689f4e5bSRuchika Gupta 399689f4e5bSRuchika Gupta if (in_size < sign_sz) 400689f4e5bSRuchika Gupta return PKCS11_CKR_SIGNATURE_LEN_RANGE; 401689f4e5bSRuchika Gupta 402689f4e5bSRuchika Gupta return PKCS11_CKR_OK; 403689f4e5bSRuchika Gupta } 404689f4e5bSRuchika Gupta 405512cbf1dSJens Wiklander /* 406512cbf1dSJens Wiklander * step_sym_cipher - processing symmetric (and related) cipher operation step 407512cbf1dSJens Wiklander * 408512cbf1dSJens Wiklander * @session - current session 409512cbf1dSJens Wiklander * @function - processing function (encrypt, decrypt, sign, ...) 410512cbf1dSJens Wiklander * @step - step ID in the processing (oneshot, update, final) 411512cbf1dSJens Wiklander * @ptype - invocation parameter types 412512cbf1dSJens Wiklander * @params - invocation parameter references 413512cbf1dSJens Wiklander */ 414512cbf1dSJens Wiklander enum pkcs11_rc step_symm_operation(struct pkcs11_session *session, 415512cbf1dSJens Wiklander enum processing_func function, 416512cbf1dSJens Wiklander enum processing_step step, 417512cbf1dSJens Wiklander uint32_t ptypes, TEE_Param *params) 418512cbf1dSJens Wiklander { 419512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 420512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 421512cbf1dSJens Wiklander void *in_buf = NULL; 422512cbf1dSJens Wiklander size_t in_size = 0; 423512cbf1dSJens Wiklander void *out_buf = NULL; 424512cbf1dSJens Wiklander uint32_t out_size = 0; 425512cbf1dSJens Wiklander void *in2_buf = NULL; 426512cbf1dSJens Wiklander uint32_t in2_size = 0; 427512cbf1dSJens Wiklander bool output_data = false; 428512cbf1dSJens Wiklander struct active_processing *proc = session->processing; 429512cbf1dSJens Wiklander 430512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 431512cbf1dSJens Wiklander in_buf = params[1].memref.buffer; 432512cbf1dSJens Wiklander in_size = params[1].memref.size; 433512cbf1dSJens Wiklander if (in_size && !in_buf) 434512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 435512cbf1dSJens Wiklander } 436512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) { 437512cbf1dSJens Wiklander in2_buf = params[2].memref.buffer; 438512cbf1dSJens Wiklander in2_size = params[2].memref.size; 439512cbf1dSJens Wiklander if (in2_size && !in2_buf) 440512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 441512cbf1dSJens Wiklander } 442512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 443512cbf1dSJens Wiklander out_buf = params[2].memref.buffer; 444512cbf1dSJens Wiklander out_size = params[2].memref.size; 445512cbf1dSJens Wiklander if (out_size && !out_buf) 446512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 447512cbf1dSJens Wiklander } 448512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 449512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 450512cbf1dSJens Wiklander 451512cbf1dSJens Wiklander switch (step) { 452512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_ONESHOT: 453512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_UPDATE: 454512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_FINAL: 455512cbf1dSJens Wiklander break; 456512cbf1dSJens Wiklander default: 457512cbf1dSJens Wiklander return PKCS11_CKR_GENERAL_ERROR; 458512cbf1dSJens Wiklander } 459512cbf1dSJens Wiklander 460512cbf1dSJens Wiklander if (step != PKCS11_FUNC_STEP_FINAL) { 461512cbf1dSJens Wiklander rc = input_data_size_is_valid(proc, function, in_size); 462512cbf1dSJens Wiklander if (rc) 463512cbf1dSJens Wiklander return rc; 464512cbf1dSJens Wiklander } 465512cbf1dSJens Wiklander 466512cbf1dSJens Wiklander /* 467512cbf1dSJens Wiklander * Feed active operation with data 468512cbf1dSJens Wiklander */ 469512cbf1dSJens Wiklander switch (proc->mecha_type) { 470689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 471689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 472689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 473689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 474689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 475689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 476689f4e5bSRuchika Gupta if (step == PKCS11_FUNC_STEP_FINAL || 477689f4e5bSRuchika Gupta step == PKCS11_FUNC_STEP_ONESHOT) 478689f4e5bSRuchika Gupta break; 479689f4e5bSRuchika Gupta 480689f4e5bSRuchika Gupta if (!in_buf) { 481689f4e5bSRuchika Gupta DMSG("No input data"); 482689f4e5bSRuchika Gupta return PKCS11_CKR_ARGUMENTS_BAD; 483689f4e5bSRuchika Gupta } 484689f4e5bSRuchika Gupta 485689f4e5bSRuchika Gupta switch (function) { 486689f4e5bSRuchika Gupta case PKCS11_FUNCTION_SIGN: 487689f4e5bSRuchika Gupta case PKCS11_FUNCTION_VERIFY: 488689f4e5bSRuchika Gupta TEE_MACUpdate(proc->tee_op_handle, in_buf, in_size); 489689f4e5bSRuchika Gupta rc = PKCS11_CKR_OK; 490689f4e5bSRuchika Gupta break; 491689f4e5bSRuchika Gupta default: 492689f4e5bSRuchika Gupta TEE_Panic(function); 493689f4e5bSRuchika Gupta break; 494689f4e5bSRuchika Gupta } 495689f4e5bSRuchika Gupta break; 496689f4e5bSRuchika Gupta 497512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 498512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 499512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 500512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 501512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 502512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_FINAL || 503512cbf1dSJens Wiklander step == PKCS11_FUNC_STEP_ONESHOT) 504512cbf1dSJens Wiklander break; 505512cbf1dSJens Wiklander 506512cbf1dSJens Wiklander if (!in_buf) { 507512cbf1dSJens Wiklander EMSG("No input data"); 508512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 509512cbf1dSJens Wiklander } 510512cbf1dSJens Wiklander 511512cbf1dSJens Wiklander switch (function) { 512512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 513512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 514512cbf1dSJens Wiklander res = TEE_CipherUpdate(proc->tee_op_handle, 515512cbf1dSJens Wiklander in_buf, in_size, 516512cbf1dSJens Wiklander out_buf, &out_size); 517512cbf1dSJens Wiklander output_data = true; 518512cbf1dSJens Wiklander rc = tee2pkcs_error(res); 519512cbf1dSJens Wiklander break; 520512cbf1dSJens Wiklander default: 521512cbf1dSJens Wiklander TEE_Panic(function); 522512cbf1dSJens Wiklander break; 523512cbf1dSJens Wiklander } 524512cbf1dSJens Wiklander break; 525512cbf1dSJens Wiklander 526512cbf1dSJens Wiklander default: 527512cbf1dSJens Wiklander TEE_Panic(proc->mecha_type); 528512cbf1dSJens Wiklander break; 529512cbf1dSJens Wiklander } 530512cbf1dSJens Wiklander 531512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_UPDATE) 532512cbf1dSJens Wiklander goto out; 533512cbf1dSJens Wiklander 534512cbf1dSJens Wiklander /* 535512cbf1dSJens Wiklander * Finalize (PKCS11_FUNC_STEP_ONESHOT/_FINAL) operation 536512cbf1dSJens Wiklander */ 537512cbf1dSJens Wiklander switch (session->processing->mecha_type) { 538689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 539689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 540689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 541689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 542689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 543689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 544689f4e5bSRuchika Gupta switch (function) { 545689f4e5bSRuchika Gupta case PKCS11_FUNCTION_SIGN: 546689f4e5bSRuchika Gupta res = TEE_MACComputeFinal(proc->tee_op_handle, 547689f4e5bSRuchika Gupta in_buf, in_size, out_buf, 548689f4e5bSRuchika Gupta &out_size); 549689f4e5bSRuchika Gupta output_data = true; 550689f4e5bSRuchika Gupta rc = tee2pkcs_error(res); 551689f4e5bSRuchika Gupta break; 552689f4e5bSRuchika Gupta case PKCS11_FUNCTION_VERIFY: 553689f4e5bSRuchika Gupta rc = input_sign_size_is_valid(proc, in2_size); 554689f4e5bSRuchika Gupta if (rc) 555689f4e5bSRuchika Gupta return rc; 556689f4e5bSRuchika Gupta res = TEE_MACCompareFinal(proc->tee_op_handle, 557689f4e5bSRuchika Gupta in_buf, in_size, in2_buf, 558689f4e5bSRuchika Gupta in2_size); 559689f4e5bSRuchika Gupta rc = tee2pkcs_error(res); 560689f4e5bSRuchika Gupta break; 561689f4e5bSRuchika Gupta default: 562689f4e5bSRuchika Gupta TEE_Panic(function); 563689f4e5bSRuchika Gupta break; 564689f4e5bSRuchika Gupta } 565689f4e5bSRuchika Gupta break; 566689f4e5bSRuchika Gupta 567512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 568512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 569512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 570512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 571512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 572512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_ONESHOT && !in_buf) { 573512cbf1dSJens Wiklander EMSG("No input data"); 574512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 575512cbf1dSJens Wiklander } 576512cbf1dSJens Wiklander 577512cbf1dSJens Wiklander switch (function) { 578512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 579512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 580512cbf1dSJens Wiklander res = TEE_CipherDoFinal(proc->tee_op_handle, 581512cbf1dSJens Wiklander in_buf, in_size, 582512cbf1dSJens Wiklander out_buf, &out_size); 583512cbf1dSJens Wiklander output_data = true; 584512cbf1dSJens Wiklander rc = tee2pkcs_error(res); 585512cbf1dSJens Wiklander break; 586512cbf1dSJens Wiklander default: 587512cbf1dSJens Wiklander TEE_Panic(function); 588512cbf1dSJens Wiklander break; 589512cbf1dSJens Wiklander } 590512cbf1dSJens Wiklander break; 591512cbf1dSJens Wiklander default: 592512cbf1dSJens Wiklander TEE_Panic(proc->mecha_type); 593512cbf1dSJens Wiklander break; 594512cbf1dSJens Wiklander } 595512cbf1dSJens Wiklander 596512cbf1dSJens Wiklander out: 597512cbf1dSJens Wiklander if (output_data && 598512cbf1dSJens Wiklander (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) { 599512cbf1dSJens Wiklander switch (TEE_PARAM_TYPE_GET(ptypes, 2)) { 600512cbf1dSJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 601512cbf1dSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 602512cbf1dSJens Wiklander params[2].memref.size = out_size; 603512cbf1dSJens Wiklander break; 604512cbf1dSJens Wiklander default: 605512cbf1dSJens Wiklander rc = PKCS11_CKR_ARGUMENTS_BAD; 606512cbf1dSJens Wiklander break; 607512cbf1dSJens Wiklander } 608512cbf1dSJens Wiklander } 609512cbf1dSJens Wiklander 610512cbf1dSJens Wiklander return rc; 611512cbf1dSJens Wiklander } 612