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 2348799892SRuchika Gupta struct input_data_ref { 2448799892SRuchika Gupta size_t size; 2548799892SRuchika Gupta void *data; 2648799892SRuchika Gupta }; 2748799892SRuchika Gupta 28512cbf1dSJens Wiklander bool processing_is_tee_symm(enum pkcs11_mechanism_id proc_id) 29512cbf1dSJens Wiklander { 30512cbf1dSJens Wiklander switch (proc_id) { 31689f4e5bSRuchika Gupta /* Authentication */ 32689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 33689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 34689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 35689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 36689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 37689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 386f6d5e75SVictor Chong /* Ciphering */ 39512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 40512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 41512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 42512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 43512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 4448799892SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 4548799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 46512cbf1dSJens Wiklander return true; 47512cbf1dSJens Wiklander default: 48512cbf1dSJens Wiklander return false; 49512cbf1dSJens Wiklander } 50512cbf1dSJens Wiklander } 51512cbf1dSJens Wiklander 52512cbf1dSJens Wiklander static enum pkcs11_rc 53512cbf1dSJens Wiklander pkcs2tee_algorithm(uint32_t *tee_id, struct pkcs11_attribute_head *proc_params) 54512cbf1dSJens Wiklander { 55512cbf1dSJens Wiklander static const struct { 56512cbf1dSJens Wiklander enum pkcs11_mechanism_id mech_id; 57512cbf1dSJens Wiklander uint32_t tee_id; 58512cbf1dSJens Wiklander } pkcs2tee_algo[] = { 59512cbf1dSJens Wiklander /* AES flavors */ 60512cbf1dSJens Wiklander { PKCS11_CKM_AES_ECB, TEE_ALG_AES_ECB_NOPAD }, 61512cbf1dSJens Wiklander { PKCS11_CKM_AES_CBC, TEE_ALG_AES_CBC_NOPAD }, 62512cbf1dSJens Wiklander { PKCS11_CKM_AES_CBC_PAD, TEE_ALG_AES_CBC_NOPAD }, 6348799892SRuchika Gupta { PKCS11_CKM_AES_ECB_ENCRYPT_DATA, TEE_ALG_AES_ECB_NOPAD }, 6448799892SRuchika Gupta { PKCS11_CKM_AES_CBC_ENCRYPT_DATA, TEE_ALG_AES_CBC_NOPAD }, 65512cbf1dSJens Wiklander { PKCS11_CKM_AES_CTR, TEE_ALG_AES_CTR }, 66512cbf1dSJens Wiklander { PKCS11_CKM_AES_CTS, TEE_ALG_AES_CTS }, 67689f4e5bSRuchika Gupta /* HMAC flavors */ 68689f4e5bSRuchika Gupta { PKCS11_CKM_MD5_HMAC, TEE_ALG_HMAC_MD5 }, 69689f4e5bSRuchika Gupta { PKCS11_CKM_SHA_1_HMAC, TEE_ALG_HMAC_SHA1 }, 70689f4e5bSRuchika Gupta { PKCS11_CKM_SHA224_HMAC, TEE_ALG_HMAC_SHA224 }, 71689f4e5bSRuchika Gupta { PKCS11_CKM_SHA256_HMAC, TEE_ALG_HMAC_SHA256 }, 72689f4e5bSRuchika Gupta { PKCS11_CKM_SHA384_HMAC, TEE_ALG_HMAC_SHA384 }, 73689f4e5bSRuchika Gupta { PKCS11_CKM_SHA512_HMAC, TEE_ALG_HMAC_SHA512 }, 74512cbf1dSJens Wiklander }; 75512cbf1dSJens Wiklander size_t n = 0; 76512cbf1dSJens Wiklander 77512cbf1dSJens Wiklander for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) { 78512cbf1dSJens Wiklander if (proc_params->id == pkcs2tee_algo[n].mech_id) { 79512cbf1dSJens Wiklander *tee_id = pkcs2tee_algo[n].tee_id; 80512cbf1dSJens Wiklander return PKCS11_CKR_OK; 81512cbf1dSJens Wiklander } 82512cbf1dSJens Wiklander } 83512cbf1dSJens Wiklander 84512cbf1dSJens Wiklander return PKCS11_RV_NOT_IMPLEMENTED; 85512cbf1dSJens Wiklander } 86512cbf1dSJens Wiklander 87512cbf1dSJens Wiklander static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type, 88512cbf1dSJens Wiklander struct pkcs11_object *obj) 89512cbf1dSJens Wiklander { 90512cbf1dSJens Wiklander static const struct { 91512cbf1dSJens Wiklander enum pkcs11_key_type key_type; 92512cbf1dSJens Wiklander uint32_t tee_id; 93512cbf1dSJens Wiklander } pkcs2tee_key_type[] = { 94512cbf1dSJens Wiklander { PKCS11_CKK_AES, TEE_TYPE_AES }, 95512cbf1dSJens Wiklander { PKCS11_CKK_GENERIC_SECRET, TEE_TYPE_GENERIC_SECRET }, 96512cbf1dSJens Wiklander { PKCS11_CKK_MD5_HMAC, TEE_TYPE_HMAC_MD5 }, 97512cbf1dSJens Wiklander { PKCS11_CKK_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 }, 98512cbf1dSJens Wiklander { PKCS11_CKK_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 }, 99512cbf1dSJens Wiklander { PKCS11_CKK_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 }, 100512cbf1dSJens Wiklander { PKCS11_CKK_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 }, 101512cbf1dSJens Wiklander { PKCS11_CKK_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 }, 102512cbf1dSJens Wiklander }; 103512cbf1dSJens Wiklander size_t n = 0; 104512cbf1dSJens Wiklander enum pkcs11_key_type key_type = get_key_type(obj->attributes); 105512cbf1dSJens Wiklander 106512cbf1dSJens Wiklander assert(get_class(obj->attributes) == PKCS11_CKO_SECRET_KEY); 107512cbf1dSJens Wiklander 108512cbf1dSJens Wiklander for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) { 109512cbf1dSJens Wiklander if (pkcs2tee_key_type[n].key_type == key_type) { 110512cbf1dSJens Wiklander *tee_type = pkcs2tee_key_type[n].tee_id; 111512cbf1dSJens Wiklander return PKCS11_CKR_OK; 112512cbf1dSJens Wiklander } 113512cbf1dSJens Wiklander } 114512cbf1dSJens Wiklander 115512cbf1dSJens Wiklander return PKCS11_RV_NOT_FOUND; 116512cbf1dSJens Wiklander } 117512cbf1dSJens Wiklander 118de94d6f8SRuchika Gupta static enum pkcs11_rc pkcsmech2tee_key_type(uint32_t *tee_type, 119de94d6f8SRuchika Gupta enum pkcs11_mechanism_id mech_id) 120de94d6f8SRuchika Gupta { 121de94d6f8SRuchika Gupta static const struct { 122de94d6f8SRuchika Gupta enum pkcs11_mechanism_id mech; 123de94d6f8SRuchika Gupta uint32_t tee_id; 124de94d6f8SRuchika Gupta } pkcs2tee_key_type[] = { 125de94d6f8SRuchika Gupta { PKCS11_CKM_MD5_HMAC, TEE_TYPE_HMAC_MD5 }, 126de94d6f8SRuchika Gupta { PKCS11_CKM_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 }, 127de94d6f8SRuchika Gupta { PKCS11_CKM_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 }, 128de94d6f8SRuchika Gupta { PKCS11_CKM_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 }, 129de94d6f8SRuchika Gupta { PKCS11_CKM_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 }, 130de94d6f8SRuchika Gupta { PKCS11_CKM_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 }, 131de94d6f8SRuchika Gupta }; 132de94d6f8SRuchika Gupta size_t n = 0; 133de94d6f8SRuchika Gupta 134de94d6f8SRuchika Gupta for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) { 135de94d6f8SRuchika Gupta if (pkcs2tee_key_type[n].mech == mech_id) { 136de94d6f8SRuchika Gupta *tee_type = pkcs2tee_key_type[n].tee_id; 137de94d6f8SRuchika Gupta return PKCS11_CKR_OK; 138de94d6f8SRuchika Gupta } 139de94d6f8SRuchika Gupta } 140de94d6f8SRuchika Gupta 141de94d6f8SRuchika Gupta return PKCS11_RV_NOT_FOUND; 142de94d6f8SRuchika Gupta } 143de94d6f8SRuchika Gupta 1442158ea6cSRuchika Gupta static enum pkcs11_rc hmac_to_tee_hash(uint32_t *algo, 1452158ea6cSRuchika Gupta enum pkcs11_mechanism_id mech_id) 1462158ea6cSRuchika Gupta { 1472158ea6cSRuchika Gupta static const struct { 1482158ea6cSRuchika Gupta enum pkcs11_mechanism_id mech; 1492158ea6cSRuchika Gupta uint32_t tee_id; 1502158ea6cSRuchika Gupta } hmac_hash[] = { 1512158ea6cSRuchika Gupta { PKCS11_CKM_MD5_HMAC, TEE_ALG_MD5 }, 1522158ea6cSRuchika Gupta { PKCS11_CKM_SHA_1_HMAC, TEE_ALG_SHA1 }, 1532158ea6cSRuchika Gupta { PKCS11_CKM_SHA224_HMAC, TEE_ALG_SHA224 }, 1542158ea6cSRuchika Gupta { PKCS11_CKM_SHA256_HMAC, TEE_ALG_SHA256 }, 1552158ea6cSRuchika Gupta { PKCS11_CKM_SHA384_HMAC, TEE_ALG_SHA384 }, 1562158ea6cSRuchika Gupta { PKCS11_CKM_SHA512_HMAC, TEE_ALG_SHA512 }, 1572158ea6cSRuchika Gupta }; 1582158ea6cSRuchika Gupta size_t n = 0; 1592158ea6cSRuchika Gupta 1602158ea6cSRuchika Gupta for (n = 0; n < ARRAY_SIZE(hmac_hash); n++) { 1612158ea6cSRuchika Gupta if (hmac_hash[n].mech == mech_id) { 1622158ea6cSRuchika Gupta *algo = hmac_hash[n].tee_id; 1632158ea6cSRuchika Gupta return PKCS11_CKR_OK; 1642158ea6cSRuchika Gupta } 1652158ea6cSRuchika Gupta } 1662158ea6cSRuchika Gupta 1672158ea6cSRuchika Gupta return PKCS11_RV_NOT_FOUND; 1682158ea6cSRuchika Gupta } 1692158ea6cSRuchika Gupta 170512cbf1dSJens Wiklander static enum pkcs11_rc 171512cbf1dSJens Wiklander allocate_tee_operation(struct pkcs11_session *session, 172512cbf1dSJens Wiklander enum processing_func function, 173512cbf1dSJens Wiklander struct pkcs11_attribute_head *params, 174512cbf1dSJens Wiklander struct pkcs11_object *obj) 175512cbf1dSJens Wiklander { 176512cbf1dSJens Wiklander uint32_t size = (uint32_t)get_object_key_bit_size(obj); 177460ba621SRuchika Gupta uint32_t key_size = size / 8; 178512cbf1dSJens Wiklander uint32_t algo = 0; 179512cbf1dSJens Wiklander uint32_t mode = 0; 180460ba621SRuchika Gupta uint32_t max_key_size = 0; 181460ba621SRuchika Gupta uint32_t min_key_size = 0; 182512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 183512cbf1dSJens Wiklander 184512cbf1dSJens Wiklander assert(session->processing->tee_op_handle == TEE_HANDLE_NULL); 185512cbf1dSJens Wiklander 186512cbf1dSJens Wiklander if (pkcs2tee_algorithm(&algo, params)) 187512cbf1dSJens Wiklander return PKCS11_CKR_FUNCTION_FAILED; 188512cbf1dSJens Wiklander 189512cbf1dSJens Wiklander /* Sign/Verify with AES or generic key relate to TEE MAC operation */ 190689f4e5bSRuchika Gupta switch (params->id) { 191689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 192689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 193689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 194689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 195689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 196689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 1972d0cd829SRuchika Gupta mechanism_supported_key_sizes_bytes(params->id, &min_key_size, 198460ba621SRuchika Gupta &max_key_size); 199460ba621SRuchika Gupta if (key_size < min_key_size) 200460ba621SRuchika Gupta return PKCS11_CKR_KEY_SIZE_RANGE; 2012158ea6cSRuchika Gupta 2022158ea6cSRuchika Gupta /* 2032158ea6cSRuchika Gupta * If size of generic key is greater than the size 2042158ea6cSRuchika Gupta * supported by TEE API, this is not considered an 2052158ea6cSRuchika Gupta * error. When loading TEE key, we will hash the key 2062158ea6cSRuchika Gupta * to generate the appropriate key for HMAC operation. 2072158ea6cSRuchika Gupta * This key size will not be greater than the 2082158ea6cSRuchika Gupta * max_key_size. So we can use max_key_size for 2092158ea6cSRuchika Gupta * TEE_AllocateOperation(). 2102158ea6cSRuchika Gupta */ 2112158ea6cSRuchika Gupta if (key_size > max_key_size) 2122158ea6cSRuchika Gupta size = max_key_size * 8; 2132158ea6cSRuchika Gupta 214689f4e5bSRuchika Gupta mode = TEE_MODE_MAC; 215689f4e5bSRuchika Gupta break; 216689f4e5bSRuchika Gupta default: 217512cbf1dSJens Wiklander pkcs2tee_mode(&mode, function); 218689f4e5bSRuchika Gupta break; 219689f4e5bSRuchika Gupta } 220512cbf1dSJens Wiklander 221512cbf1dSJens Wiklander res = TEE_AllocateOperation(&session->processing->tee_op_handle, 222512cbf1dSJens Wiklander algo, mode, size); 223512cbf1dSJens Wiklander if (res) 224512cbf1dSJens Wiklander EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32, 225512cbf1dSJens Wiklander algo, mode, size); 226512cbf1dSJens Wiklander 227512cbf1dSJens Wiklander if (res == TEE_ERROR_NOT_SUPPORTED) 228512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_INVALID; 229512cbf1dSJens Wiklander 230512cbf1dSJens Wiklander return tee2pkcs_error(res); 231512cbf1dSJens Wiklander } 232512cbf1dSJens Wiklander 2332158ea6cSRuchika Gupta static enum pkcs11_rc hash_secret_helper(enum pkcs11_mechanism_id mech_id, 2342158ea6cSRuchika Gupta struct pkcs11_object *obj, 2352158ea6cSRuchika Gupta TEE_Attribute *tee_attr, 2362158ea6cSRuchika Gupta void **ctx, 2372158ea6cSRuchika Gupta size_t *object_size_bits) 2382158ea6cSRuchika Gupta { 2392158ea6cSRuchika Gupta uint32_t algo = 0; 2402158ea6cSRuchika Gupta void *hash_ptr = NULL; 2412158ea6cSRuchika Gupta uint32_t hash_size = 0; 2422158ea6cSRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK; 2432158ea6cSRuchika Gupta 2442158ea6cSRuchika Gupta rc = hmac_to_tee_hash(&algo, mech_id); 2452158ea6cSRuchika Gupta if (rc) 2462158ea6cSRuchika Gupta return rc; 2472158ea6cSRuchika Gupta 2482158ea6cSRuchika Gupta hash_size = TEE_ALG_GET_DIGEST_SIZE(algo); 2492158ea6cSRuchika Gupta hash_ptr = TEE_Malloc(hash_size, 0); 2502158ea6cSRuchika Gupta if (!hash_ptr) 2512158ea6cSRuchika Gupta return PKCS11_CKR_DEVICE_MEMORY; 2522158ea6cSRuchika Gupta 2532158ea6cSRuchika Gupta rc = pkcs2tee_load_hashed_attr(tee_attr, TEE_ATTR_SECRET_VALUE, obj, 2542158ea6cSRuchika Gupta PKCS11_CKA_VALUE, algo, hash_ptr, 2552158ea6cSRuchika Gupta &hash_size); 2562158ea6cSRuchika Gupta if (rc) { 2572158ea6cSRuchika Gupta EMSG("No secret/hash error"); 2582158ea6cSRuchika Gupta TEE_Free(hash_ptr); 2592158ea6cSRuchika Gupta return rc; 2602158ea6cSRuchika Gupta } 2612158ea6cSRuchika Gupta 2622158ea6cSRuchika Gupta *ctx = hash_ptr; 2632158ea6cSRuchika Gupta 2642158ea6cSRuchika Gupta *object_size_bits = hash_size * 8; 2652158ea6cSRuchika Gupta 2662158ea6cSRuchika Gupta return PKCS11_CKR_OK; 2672158ea6cSRuchika Gupta } 2682158ea6cSRuchika Gupta 269512cbf1dSJens Wiklander static enum pkcs11_rc load_tee_key(struct pkcs11_session *session, 270de94d6f8SRuchika Gupta struct pkcs11_object *obj, 271de94d6f8SRuchika Gupta struct pkcs11_attribute_head *proc_params) 272512cbf1dSJens Wiklander { 273512cbf1dSJens Wiklander TEE_Attribute tee_attr = { }; 274512cbf1dSJens Wiklander size_t object_size = 0; 275512cbf1dSJens Wiklander uint32_t tee_key_type = 0; 276de94d6f8SRuchika Gupta enum pkcs11_key_type key_type = 0; 277512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 278512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 2792158ea6cSRuchika Gupta uint32_t max_key_size = 0; 2802158ea6cSRuchika Gupta uint32_t min_key_size = 0; 281512cbf1dSJens Wiklander 282512cbf1dSJens Wiklander if (obj->key_handle != TEE_HANDLE_NULL) { 283512cbf1dSJens Wiklander /* Key was already loaded and fits current need */ 284512cbf1dSJens Wiklander goto key_ready; 285512cbf1dSJens Wiklander } 286512cbf1dSJens Wiklander 2872158ea6cSRuchika Gupta object_size = get_object_key_bit_size(obj); 2882158ea6cSRuchika Gupta if (!object_size) 2892158ea6cSRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 290512cbf1dSJens Wiklander 291de94d6f8SRuchika Gupta switch (proc_params->id) { 292de94d6f8SRuchika Gupta case PKCS11_CKM_MD5_HMAC: 293de94d6f8SRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 294de94d6f8SRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 295de94d6f8SRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 296de94d6f8SRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 297de94d6f8SRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 298de94d6f8SRuchika Gupta key_type = get_key_type(obj->attributes); 299de94d6f8SRuchika Gupta /* 300de94d6f8SRuchika Gupta * If Object Key type is PKCS11_CKK_GENERIC_SECRET, 301de94d6f8SRuchika Gupta * determine the tee_key_type using the 302de94d6f8SRuchika Gupta * mechanism instead of object key_type. 303de94d6f8SRuchika Gupta */ 304de94d6f8SRuchika Gupta if (key_type == PKCS11_CKK_GENERIC_SECRET) 305de94d6f8SRuchika Gupta rc = pkcsmech2tee_key_type(&tee_key_type, 306de94d6f8SRuchika Gupta proc_params->id); 307de94d6f8SRuchika Gupta else 308512cbf1dSJens Wiklander rc = pkcs2tee_key_type(&tee_key_type, obj); 309de94d6f8SRuchika Gupta 310512cbf1dSJens Wiklander if (rc) 311512cbf1dSJens Wiklander return rc; 312512cbf1dSJens Wiklander 3132d0cd829SRuchika Gupta mechanism_supported_key_sizes_bytes(proc_params->id, 3142158ea6cSRuchika Gupta &min_key_size, 3152158ea6cSRuchika Gupta &max_key_size); 3162158ea6cSRuchika Gupta 3172158ea6cSRuchika Gupta if ((object_size / 8) > max_key_size) { 3182158ea6cSRuchika Gupta rc = hash_secret_helper(proc_params->id, obj, &tee_attr, 3192158ea6cSRuchika Gupta &session->processing->extra_ctx, 3202158ea6cSRuchika Gupta &object_size); 3212158ea6cSRuchika Gupta if (rc) 3222158ea6cSRuchika Gupta return rc; 3232158ea6cSRuchika Gupta } else { 3242158ea6cSRuchika Gupta if (!pkcs2tee_load_attr(&tee_attr, 3252158ea6cSRuchika Gupta TEE_ATTR_SECRET_VALUE, 3262158ea6cSRuchika Gupta obj, 3272158ea6cSRuchika Gupta PKCS11_CKA_VALUE)) { 3282158ea6cSRuchika Gupta EMSG("No secret found"); 3292158ea6cSRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED; 3302158ea6cSRuchika Gupta } 3312158ea6cSRuchika Gupta } 3322158ea6cSRuchika Gupta break; 3332158ea6cSRuchika Gupta 3342158ea6cSRuchika Gupta default: 3352158ea6cSRuchika Gupta rc = pkcs2tee_key_type(&tee_key_type, obj); 3362158ea6cSRuchika Gupta if (rc) 3372158ea6cSRuchika Gupta return rc; 3382158ea6cSRuchika Gupta 3392158ea6cSRuchika Gupta if (!pkcs2tee_load_attr(&tee_attr, TEE_ATTR_SECRET_VALUE, 3402158ea6cSRuchika Gupta obj, PKCS11_CKA_VALUE)) { 3412158ea6cSRuchika Gupta EMSG("No secret found"); 3422158ea6cSRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED; 3432158ea6cSRuchika Gupta } 3442158ea6cSRuchika Gupta break; 3452158ea6cSRuchika Gupta } 346512cbf1dSJens Wiklander 347512cbf1dSJens Wiklander res = TEE_AllocateTransientObject(tee_key_type, object_size, 348512cbf1dSJens Wiklander &obj->key_handle); 349512cbf1dSJens Wiklander if (res) { 350512cbf1dSJens Wiklander DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 351512cbf1dSJens Wiklander return tee2pkcs_error(res); 352512cbf1dSJens Wiklander } 353512cbf1dSJens Wiklander 354512cbf1dSJens Wiklander res = TEE_PopulateTransientObject(obj->key_handle, &tee_attr, 1); 355512cbf1dSJens Wiklander if (res) { 356512cbf1dSJens Wiklander DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res); 357512cbf1dSJens Wiklander goto error; 358512cbf1dSJens Wiklander } 359512cbf1dSJens Wiklander 360512cbf1dSJens Wiklander key_ready: 361512cbf1dSJens Wiklander res = TEE_SetOperationKey(session->processing->tee_op_handle, 362512cbf1dSJens Wiklander obj->key_handle); 363512cbf1dSJens Wiklander if (res) { 364512cbf1dSJens Wiklander DMSG("TEE_SetOperationKey failed, %#"PRIx32, res); 365512cbf1dSJens Wiklander goto error; 366512cbf1dSJens Wiklander } 367512cbf1dSJens Wiklander 368512cbf1dSJens Wiklander return PKCS11_CKR_OK; 369512cbf1dSJens Wiklander 370512cbf1dSJens Wiklander error: 371512cbf1dSJens Wiklander TEE_FreeTransientObject(obj->key_handle); 372512cbf1dSJens Wiklander obj->key_handle = TEE_HANDLE_NULL; 373512cbf1dSJens Wiklander 374512cbf1dSJens Wiklander return tee2pkcs_error(res); 375512cbf1dSJens Wiklander } 376512cbf1dSJens Wiklander 377512cbf1dSJens Wiklander static enum pkcs11_rc 37848799892SRuchika Gupta tee_init_derive_symm(struct active_processing *processing, 37948799892SRuchika Gupta struct pkcs11_attribute_head *proc_params) 38048799892SRuchika Gupta { 38148799892SRuchika Gupta struct serialargs args = { }; 38248799892SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK; 38348799892SRuchika Gupta struct input_data_ref *param = NULL; 38448799892SRuchika Gupta void *iv = NULL; 38548799892SRuchika Gupta 38648799892SRuchika Gupta if (!proc_params) 38748799892SRuchika Gupta return PKCS11_CKR_ARGUMENTS_BAD; 38848799892SRuchika Gupta 38948799892SRuchika Gupta param = TEE_Malloc(sizeof(struct input_data_ref), TEE_MALLOC_FILL_ZERO); 39048799892SRuchika Gupta if (!param) 39148799892SRuchika Gupta return PKCS11_CKR_DEVICE_MEMORY; 39248799892SRuchika Gupta 39348799892SRuchika Gupta serialargs_init(&args, proc_params->data, proc_params->size); 39448799892SRuchika Gupta 39548799892SRuchika Gupta switch (proc_params->id) { 39648799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 39748799892SRuchika Gupta rc = serialargs_get_ptr(&args, &iv, 16); 39848799892SRuchika Gupta if (rc) 39948799892SRuchika Gupta goto err; 40048799892SRuchika Gupta break; 40148799892SRuchika Gupta default: 40248799892SRuchika Gupta break; 40348799892SRuchika Gupta } 40448799892SRuchika Gupta 40548799892SRuchika Gupta rc = serialargs_get(&args, ¶m->size, sizeof(uint32_t)); 40648799892SRuchika Gupta if (rc) 40748799892SRuchika Gupta goto err; 40848799892SRuchika Gupta 40948799892SRuchika Gupta rc = serialargs_get_ptr(&args, ¶m->data, param->size); 41048799892SRuchika Gupta if (rc) 41148799892SRuchika Gupta goto err; 41248799892SRuchika Gupta 41348799892SRuchika Gupta if (serialargs_remaining_bytes(&args)) { 41448799892SRuchika Gupta rc = PKCS11_CKR_ARGUMENTS_BAD; 41548799892SRuchika Gupta goto err; 41648799892SRuchika Gupta } 41748799892SRuchika Gupta 41848799892SRuchika Gupta processing->extra_ctx = param; 41948799892SRuchika Gupta 42048799892SRuchika Gupta switch (proc_params->id) { 42148799892SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 42248799892SRuchika Gupta if (param->size % TEE_AES_BLOCK_SIZE) { 42348799892SRuchika Gupta rc = PKCS11_CKR_DATA_LEN_RANGE; 42448799892SRuchika Gupta goto err; 42548799892SRuchika Gupta } 42648799892SRuchika Gupta TEE_CipherInit(processing->tee_op_handle, NULL, 0); 42748799892SRuchika Gupta break; 42848799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 42948799892SRuchika Gupta if (param->size % TEE_AES_BLOCK_SIZE) { 43048799892SRuchika Gupta rc = PKCS11_CKR_DATA_LEN_RANGE; 43148799892SRuchika Gupta goto err; 43248799892SRuchika Gupta } 43348799892SRuchika Gupta TEE_CipherInit(processing->tee_op_handle, iv, 16); 43448799892SRuchika Gupta break; 43548799892SRuchika Gupta default: 43648799892SRuchika Gupta TEE_Panic(proc_params->id); 43748799892SRuchika Gupta break; 43848799892SRuchika Gupta } 43948799892SRuchika Gupta 44048799892SRuchika Gupta return PKCS11_CKR_OK; 44148799892SRuchika Gupta 44248799892SRuchika Gupta err: 44348799892SRuchika Gupta processing->extra_ctx = NULL; 44448799892SRuchika Gupta TEE_Free(param); 44548799892SRuchika Gupta return rc; 44648799892SRuchika Gupta } 44748799892SRuchika Gupta 44848799892SRuchika Gupta static enum pkcs11_rc 449512cbf1dSJens Wiklander init_tee_operation(struct pkcs11_session *session, 450512cbf1dSJens Wiklander struct pkcs11_attribute_head *proc_params) 451512cbf1dSJens Wiklander { 452512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 453512cbf1dSJens Wiklander 454512cbf1dSJens Wiklander switch (proc_params->id) { 455689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 456689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 457689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 458689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 459689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 460689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 461689f4e5bSRuchika Gupta if (proc_params->size) 462689f4e5bSRuchika Gupta return PKCS11_CKR_MECHANISM_PARAM_INVALID; 463689f4e5bSRuchika Gupta 464689f4e5bSRuchika Gupta TEE_MACInit(session->processing->tee_op_handle, NULL, 0); 465689f4e5bSRuchika Gupta rc = PKCS11_CKR_OK; 466689f4e5bSRuchika Gupta break; 467512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 468512cbf1dSJens Wiklander if (proc_params->size) 469512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_PARAM_INVALID; 470512cbf1dSJens Wiklander 471512cbf1dSJens Wiklander TEE_CipherInit(session->processing->tee_op_handle, NULL, 0); 472512cbf1dSJens Wiklander rc = PKCS11_CKR_OK; 473512cbf1dSJens Wiklander break; 474512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 475512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 476512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 477512cbf1dSJens Wiklander if (proc_params->size != 16) 478512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_PARAM_INVALID; 479512cbf1dSJens Wiklander 480512cbf1dSJens Wiklander TEE_CipherInit(session->processing->tee_op_handle, 481512cbf1dSJens Wiklander proc_params->data, 16); 482512cbf1dSJens Wiklander rc = PKCS11_CKR_OK; 483512cbf1dSJens Wiklander break; 484512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 485512cbf1dSJens Wiklander rc = tee_init_ctr_operation(session->processing, 486512cbf1dSJens Wiklander proc_params->data, 487512cbf1dSJens Wiklander proc_params->size); 488512cbf1dSJens Wiklander break; 48948799892SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 49048799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 49148799892SRuchika Gupta rc = tee_init_derive_symm(session->processing, proc_params); 49248799892SRuchika Gupta break; 493512cbf1dSJens Wiklander default: 494512cbf1dSJens Wiklander TEE_Panic(proc_params->id); 495512cbf1dSJens Wiklander break; 496512cbf1dSJens Wiklander } 497512cbf1dSJens Wiklander 498512cbf1dSJens Wiklander return rc; 499512cbf1dSJens Wiklander } 500512cbf1dSJens Wiklander 501512cbf1dSJens Wiklander enum pkcs11_rc init_symm_operation(struct pkcs11_session *session, 502512cbf1dSJens Wiklander enum processing_func function, 503512cbf1dSJens Wiklander struct pkcs11_attribute_head *proc_params, 504512cbf1dSJens Wiklander struct pkcs11_object *obj) 505512cbf1dSJens Wiklander { 506512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 507512cbf1dSJens Wiklander 508512cbf1dSJens Wiklander assert(processing_is_tee_symm(proc_params->id)); 509512cbf1dSJens Wiklander 510512cbf1dSJens Wiklander rc = allocate_tee_operation(session, function, proc_params, obj); 511512cbf1dSJens Wiklander if (rc) 512512cbf1dSJens Wiklander return rc; 513512cbf1dSJens Wiklander 514de94d6f8SRuchika Gupta rc = load_tee_key(session, obj, proc_params); 515512cbf1dSJens Wiklander if (rc) 516512cbf1dSJens Wiklander return rc; 517512cbf1dSJens Wiklander 518512cbf1dSJens Wiklander return init_tee_operation(session, proc_params); 519512cbf1dSJens Wiklander } 520512cbf1dSJens Wiklander 521512cbf1dSJens Wiklander /* Validate input buffer size as per PKCS#11 constraints */ 522512cbf1dSJens Wiklander static enum pkcs11_rc input_data_size_is_valid(struct active_processing *proc, 523512cbf1dSJens Wiklander enum processing_func function, 524512cbf1dSJens Wiklander size_t in_size) 525512cbf1dSJens Wiklander { 526512cbf1dSJens Wiklander switch (proc->mecha_type) { 527512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 528512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 529512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_ENCRYPT && 530512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 531512cbf1dSJens Wiklander return PKCS11_CKR_DATA_LEN_RANGE; 532512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 533512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 534512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 535512cbf1dSJens Wiklander break; 536512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 537512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 538512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 539512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 540512cbf1dSJens Wiklander break; 541512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 542512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_ENCRYPT && 543512cbf1dSJens Wiklander in_size < TEE_AES_BLOCK_SIZE) 544512cbf1dSJens Wiklander return PKCS11_CKR_DATA_LEN_RANGE; 545512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 546512cbf1dSJens Wiklander in_size < TEE_AES_BLOCK_SIZE) 547512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 548512cbf1dSJens Wiklander break; 549512cbf1dSJens Wiklander default: 550512cbf1dSJens Wiklander break; 551512cbf1dSJens Wiklander } 552512cbf1dSJens Wiklander 553512cbf1dSJens Wiklander return PKCS11_CKR_OK; 554512cbf1dSJens Wiklander } 555512cbf1dSJens Wiklander 556689f4e5bSRuchika Gupta /* Validate input buffer size as per PKCS#11 constraints */ 557689f4e5bSRuchika Gupta static enum pkcs11_rc input_sign_size_is_valid(struct active_processing *proc, 558689f4e5bSRuchika Gupta size_t in_size) 559689f4e5bSRuchika Gupta { 560689f4e5bSRuchika Gupta size_t sign_sz = 0; 561689f4e5bSRuchika Gupta 562689f4e5bSRuchika Gupta switch (proc->mecha_type) { 563689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 564689f4e5bSRuchika Gupta sign_sz = TEE_MD5_HASH_SIZE; 565689f4e5bSRuchika Gupta break; 566689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 567689f4e5bSRuchika Gupta sign_sz = TEE_SHA1_HASH_SIZE; 568689f4e5bSRuchika Gupta break; 569689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 570689f4e5bSRuchika Gupta sign_sz = TEE_SHA224_HASH_SIZE; 571689f4e5bSRuchika Gupta break; 572689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 573689f4e5bSRuchika Gupta sign_sz = TEE_SHA256_HASH_SIZE; 574689f4e5bSRuchika Gupta break; 575689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 576689f4e5bSRuchika Gupta sign_sz = TEE_SHA384_HASH_SIZE; 577689f4e5bSRuchika Gupta break; 578689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 579689f4e5bSRuchika Gupta sign_sz = TEE_SHA512_HASH_SIZE; 580689f4e5bSRuchika Gupta break; 581689f4e5bSRuchika Gupta default: 582689f4e5bSRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 583689f4e5bSRuchika Gupta } 584689f4e5bSRuchika Gupta 585*42765f82SVictor Chong if (in_size != sign_sz) 586689f4e5bSRuchika Gupta return PKCS11_CKR_SIGNATURE_LEN_RANGE; 587689f4e5bSRuchika Gupta 588689f4e5bSRuchika Gupta return PKCS11_CKR_OK; 589689f4e5bSRuchika Gupta } 590689f4e5bSRuchika Gupta 591512cbf1dSJens Wiklander /* 592512cbf1dSJens Wiklander * step_sym_cipher - processing symmetric (and related) cipher operation step 593512cbf1dSJens Wiklander * 594512cbf1dSJens Wiklander * @session - current session 595512cbf1dSJens Wiklander * @function - processing function (encrypt, decrypt, sign, ...) 596512cbf1dSJens Wiklander * @step - step ID in the processing (oneshot, update, final) 597512cbf1dSJens Wiklander * @ptype - invocation parameter types 598512cbf1dSJens Wiklander * @params - invocation parameter references 599512cbf1dSJens Wiklander */ 600512cbf1dSJens Wiklander enum pkcs11_rc step_symm_operation(struct pkcs11_session *session, 601512cbf1dSJens Wiklander enum processing_func function, 602512cbf1dSJens Wiklander enum processing_step step, 603512cbf1dSJens Wiklander uint32_t ptypes, TEE_Param *params) 604512cbf1dSJens Wiklander { 605512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 606512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 607512cbf1dSJens Wiklander void *in_buf = NULL; 608512cbf1dSJens Wiklander size_t in_size = 0; 609512cbf1dSJens Wiklander void *out_buf = NULL; 610512cbf1dSJens Wiklander uint32_t out_size = 0; 611512cbf1dSJens Wiklander void *in2_buf = NULL; 612512cbf1dSJens Wiklander uint32_t in2_size = 0; 613512cbf1dSJens Wiklander bool output_data = false; 614512cbf1dSJens Wiklander struct active_processing *proc = session->processing; 615512cbf1dSJens Wiklander 616512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 617512cbf1dSJens Wiklander in_buf = params[1].memref.buffer; 618512cbf1dSJens Wiklander in_size = params[1].memref.size; 619512cbf1dSJens Wiklander if (in_size && !in_buf) 620512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 621512cbf1dSJens Wiklander } 622512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) { 623512cbf1dSJens Wiklander in2_buf = params[2].memref.buffer; 624512cbf1dSJens Wiklander in2_size = params[2].memref.size; 625512cbf1dSJens Wiklander if (in2_size && !in2_buf) 626512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 627512cbf1dSJens Wiklander } 628512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 629512cbf1dSJens Wiklander out_buf = params[2].memref.buffer; 630512cbf1dSJens Wiklander out_size = params[2].memref.size; 631512cbf1dSJens Wiklander if (out_size && !out_buf) 632512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 633512cbf1dSJens Wiklander } 634512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 635512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 636512cbf1dSJens Wiklander 637512cbf1dSJens Wiklander switch (step) { 638512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_ONESHOT: 639512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_UPDATE: 640512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_FINAL: 641512cbf1dSJens Wiklander break; 642512cbf1dSJens Wiklander default: 643512cbf1dSJens Wiklander return PKCS11_CKR_GENERAL_ERROR; 644512cbf1dSJens Wiklander } 645512cbf1dSJens Wiklander 646512cbf1dSJens Wiklander if (step != PKCS11_FUNC_STEP_FINAL) { 647512cbf1dSJens Wiklander rc = input_data_size_is_valid(proc, function, in_size); 648512cbf1dSJens Wiklander if (rc) 649512cbf1dSJens Wiklander return rc; 650512cbf1dSJens Wiklander } 651512cbf1dSJens Wiklander 652512cbf1dSJens Wiklander /* 653512cbf1dSJens Wiklander * Feed active operation with data 654512cbf1dSJens Wiklander */ 655512cbf1dSJens Wiklander switch (proc->mecha_type) { 656689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 657689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 658689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 659689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 660689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 661689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 662689f4e5bSRuchika Gupta if (step == PKCS11_FUNC_STEP_FINAL || 663689f4e5bSRuchika Gupta step == PKCS11_FUNC_STEP_ONESHOT) 664689f4e5bSRuchika Gupta break; 665689f4e5bSRuchika Gupta 666689f4e5bSRuchika Gupta if (!in_buf) { 667689f4e5bSRuchika Gupta DMSG("No input data"); 668689f4e5bSRuchika Gupta return PKCS11_CKR_ARGUMENTS_BAD; 669689f4e5bSRuchika Gupta } 670689f4e5bSRuchika Gupta 671689f4e5bSRuchika Gupta switch (function) { 672689f4e5bSRuchika Gupta case PKCS11_FUNCTION_SIGN: 673689f4e5bSRuchika Gupta case PKCS11_FUNCTION_VERIFY: 674689f4e5bSRuchika Gupta TEE_MACUpdate(proc->tee_op_handle, in_buf, in_size); 675689f4e5bSRuchika Gupta rc = PKCS11_CKR_OK; 676689f4e5bSRuchika Gupta break; 677689f4e5bSRuchika Gupta default: 678689f4e5bSRuchika Gupta TEE_Panic(function); 679689f4e5bSRuchika Gupta break; 680689f4e5bSRuchika Gupta } 681689f4e5bSRuchika Gupta break; 682689f4e5bSRuchika Gupta 683512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 684512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 685512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 686512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 687512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 688512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_FINAL || 689512cbf1dSJens Wiklander step == PKCS11_FUNC_STEP_ONESHOT) 690512cbf1dSJens Wiklander break; 691512cbf1dSJens Wiklander 692512cbf1dSJens Wiklander if (!in_buf) { 693512cbf1dSJens Wiklander EMSG("No input data"); 694512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 695512cbf1dSJens Wiklander } 696512cbf1dSJens Wiklander 697512cbf1dSJens Wiklander switch (function) { 698512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 699512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 700512cbf1dSJens Wiklander res = TEE_CipherUpdate(proc->tee_op_handle, 701512cbf1dSJens Wiklander in_buf, in_size, 702512cbf1dSJens Wiklander out_buf, &out_size); 703512cbf1dSJens Wiklander output_data = true; 704512cbf1dSJens Wiklander rc = tee2pkcs_error(res); 705512cbf1dSJens Wiklander break; 706512cbf1dSJens Wiklander default: 707512cbf1dSJens Wiklander TEE_Panic(function); 708512cbf1dSJens Wiklander break; 709512cbf1dSJens Wiklander } 710512cbf1dSJens Wiklander break; 711512cbf1dSJens Wiklander 712512cbf1dSJens Wiklander default: 713512cbf1dSJens Wiklander TEE_Panic(proc->mecha_type); 714512cbf1dSJens Wiklander break; 715512cbf1dSJens Wiklander } 716512cbf1dSJens Wiklander 717512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_UPDATE) 718512cbf1dSJens Wiklander goto out; 719512cbf1dSJens Wiklander 720512cbf1dSJens Wiklander /* 721512cbf1dSJens Wiklander * Finalize (PKCS11_FUNC_STEP_ONESHOT/_FINAL) operation 722512cbf1dSJens Wiklander */ 723512cbf1dSJens Wiklander switch (session->processing->mecha_type) { 724689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 725689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 726689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 727689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 728689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 729689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 730689f4e5bSRuchika Gupta switch (function) { 731689f4e5bSRuchika Gupta case PKCS11_FUNCTION_SIGN: 732689f4e5bSRuchika Gupta res = TEE_MACComputeFinal(proc->tee_op_handle, 733689f4e5bSRuchika Gupta in_buf, in_size, out_buf, 734689f4e5bSRuchika Gupta &out_size); 735689f4e5bSRuchika Gupta output_data = true; 736689f4e5bSRuchika Gupta rc = tee2pkcs_error(res); 737689f4e5bSRuchika Gupta break; 738689f4e5bSRuchika Gupta case PKCS11_FUNCTION_VERIFY: 739689f4e5bSRuchika Gupta rc = input_sign_size_is_valid(proc, in2_size); 740689f4e5bSRuchika Gupta if (rc) 741689f4e5bSRuchika Gupta return rc; 742689f4e5bSRuchika Gupta res = TEE_MACCompareFinal(proc->tee_op_handle, 743689f4e5bSRuchika Gupta in_buf, in_size, in2_buf, 744689f4e5bSRuchika Gupta in2_size); 745689f4e5bSRuchika Gupta rc = tee2pkcs_error(res); 746689f4e5bSRuchika Gupta break; 747689f4e5bSRuchika Gupta default: 748689f4e5bSRuchika Gupta TEE_Panic(function); 749689f4e5bSRuchika Gupta break; 750689f4e5bSRuchika Gupta } 7512158ea6cSRuchika Gupta 752689f4e5bSRuchika Gupta break; 753689f4e5bSRuchika Gupta 754512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 755512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 756512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 757512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 758512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 759512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_ONESHOT && !in_buf) { 760512cbf1dSJens Wiklander EMSG("No input data"); 761512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 762512cbf1dSJens Wiklander } 763512cbf1dSJens Wiklander 764512cbf1dSJens Wiklander switch (function) { 765512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 766512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 767512cbf1dSJens Wiklander res = TEE_CipherDoFinal(proc->tee_op_handle, 768512cbf1dSJens Wiklander in_buf, in_size, 769512cbf1dSJens Wiklander out_buf, &out_size); 770512cbf1dSJens Wiklander output_data = true; 771512cbf1dSJens Wiklander rc = tee2pkcs_error(res); 772512cbf1dSJens Wiklander break; 773512cbf1dSJens Wiklander default: 774512cbf1dSJens Wiklander TEE_Panic(function); 775512cbf1dSJens Wiklander break; 776512cbf1dSJens Wiklander } 777512cbf1dSJens Wiklander break; 778512cbf1dSJens Wiklander default: 779512cbf1dSJens Wiklander TEE_Panic(proc->mecha_type); 780512cbf1dSJens Wiklander break; 781512cbf1dSJens Wiklander } 782512cbf1dSJens Wiklander 783512cbf1dSJens Wiklander out: 784512cbf1dSJens Wiklander if (output_data && 785512cbf1dSJens Wiklander (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) { 786512cbf1dSJens Wiklander switch (TEE_PARAM_TYPE_GET(ptypes, 2)) { 787512cbf1dSJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 788512cbf1dSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 789512cbf1dSJens Wiklander params[2].memref.size = out_size; 790512cbf1dSJens Wiklander break; 791512cbf1dSJens Wiklander default: 792512cbf1dSJens Wiklander rc = PKCS11_CKR_ARGUMENTS_BAD; 793512cbf1dSJens Wiklander break; 794512cbf1dSJens Wiklander } 795512cbf1dSJens Wiklander } 796512cbf1dSJens Wiklander 797512cbf1dSJens Wiklander return rc; 798512cbf1dSJens Wiklander } 79948799892SRuchika Gupta 80048799892SRuchika Gupta enum pkcs11_rc derive_key_by_symm_enc(struct pkcs11_session *session, 8018c499324SRuchika Gupta void **out_buf, uint32_t *out_size) 80248799892SRuchika Gupta { 80348799892SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 80448799892SRuchika Gupta TEE_Result res = TEE_ERROR_GENERIC; 80548799892SRuchika Gupta struct active_processing *proc = session->processing; 80648799892SRuchika Gupta struct input_data_ref *input = proc->extra_ctx; 80748799892SRuchika Gupta void *in_buf = NULL; 80848799892SRuchika Gupta uint32_t in_size = 0; 80948799892SRuchika Gupta 8108c499324SRuchika Gupta switch (proc->mecha_type) { 8118c499324SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 8128c499324SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 81348799892SRuchika Gupta if (!proc->extra_ctx) 81448799892SRuchika Gupta return PKCS11_CKR_ARGUMENTS_BAD; 81548799892SRuchika Gupta 81648799892SRuchika Gupta in_buf = input->data; 81748799892SRuchika Gupta in_size = input->size; 81848799892SRuchika Gupta 8198c499324SRuchika Gupta *out_size = in_size; 8208c499324SRuchika Gupta *out_buf = TEE_Malloc(*out_size, 0); 8218c499324SRuchika Gupta if (!*out_buf) 82248799892SRuchika Gupta return PKCS11_CKR_DEVICE_MEMORY; 82348799892SRuchika Gupta 8248c499324SRuchika Gupta res = TEE_CipherDoFinal(proc->tee_op_handle, in_buf, in_size, 8258c499324SRuchika Gupta *out_buf, out_size); 82648799892SRuchika Gupta rc = tee2pkcs_error(res); 82748799892SRuchika Gupta if (rc) 8288c499324SRuchika Gupta TEE_Free(*out_buf); 8298c499324SRuchika Gupta break; 8308c499324SRuchika Gupta default: 8318c499324SRuchika Gupta return PKCS11_CKR_MECHANISM_INVALID; 83248799892SRuchika Gupta } 83348799892SRuchika Gupta 83448799892SRuchika Gupta return rc; 83548799892SRuchika Gupta } 8365f80f270SRuchika Gupta 8375f80f270SRuchika Gupta enum pkcs11_rc wrap_data_by_symm_enc(struct pkcs11_session *session, 8385f80f270SRuchika Gupta void *data, uint32_t data_sz, 8395f80f270SRuchika Gupta void *out_buf, uint32_t *out_sz) 8405f80f270SRuchika Gupta { 8415f80f270SRuchika Gupta TEE_Result res = TEE_ERROR_GENERIC; 8425f80f270SRuchika Gupta struct active_processing *proc = session->processing; 8435f80f270SRuchika Gupta void *in_buf = NULL; 8445f80f270SRuchika Gupta uint32_t align = 0; 8455f80f270SRuchika Gupta uint32_t in_sz = data_sz; 8465f80f270SRuchika Gupta uint32_t tmp_sz = *out_sz; 8475f80f270SRuchika Gupta uint8_t *tmp_buf = out_buf; 8485f80f270SRuchika Gupta 8495f80f270SRuchika Gupta switch (proc->mecha_type) { 8505f80f270SRuchika Gupta case PKCS11_CKM_AES_ECB: 8515f80f270SRuchika Gupta case PKCS11_CKM_AES_CBC: 8525f80f270SRuchika Gupta align = data_sz % TEE_AES_BLOCK_SIZE; 8535f80f270SRuchika Gupta if (align) 8545f80f270SRuchika Gupta in_sz = data_sz + (TEE_AES_BLOCK_SIZE - align); 8555f80f270SRuchika Gupta 8565f80f270SRuchika Gupta if (*out_sz < in_sz) { 8575f80f270SRuchika Gupta *out_sz = in_sz; 8585f80f270SRuchika Gupta return PKCS11_CKR_BUFFER_TOO_SMALL; 8595f80f270SRuchika Gupta } 8605f80f270SRuchika Gupta 8615f80f270SRuchika Gupta if (align) { 8625f80f270SRuchika Gupta if (data_sz > TEE_AES_BLOCK_SIZE) { 8635f80f270SRuchika Gupta in_sz = data_sz - align; 8645f80f270SRuchika Gupta res = TEE_CipherUpdate(proc->tee_op_handle, 8655f80f270SRuchika Gupta data, in_sz, tmp_buf, 8665f80f270SRuchika Gupta &tmp_sz); 8675f80f270SRuchika Gupta if (res) { 8685f80f270SRuchika Gupta assert(res != TEE_ERROR_SHORT_BUFFER); 8695f80f270SRuchika Gupta return tee2pkcs_error(res); 8705f80f270SRuchika Gupta } 8715f80f270SRuchika Gupta tmp_buf += tmp_sz; 8725f80f270SRuchika Gupta tmp_sz = *out_sz - tmp_sz; 8735f80f270SRuchika Gupta } else { 8745f80f270SRuchika Gupta in_sz = 0; 8755f80f270SRuchika Gupta } 8765f80f270SRuchika Gupta 8775f80f270SRuchika Gupta in_buf = TEE_Malloc(TEE_AES_BLOCK_SIZE, 8785f80f270SRuchika Gupta TEE_MALLOC_FILL_ZERO); 8795f80f270SRuchika Gupta if (!in_buf) 8805f80f270SRuchika Gupta return PKCS11_CKR_DEVICE_MEMORY; 8815f80f270SRuchika Gupta 8825f80f270SRuchika Gupta TEE_MemMove(in_buf, (uint8_t *)data + in_sz, align); 8835f80f270SRuchika Gupta in_sz = TEE_AES_BLOCK_SIZE; 8845f80f270SRuchika Gupta } else { 8855f80f270SRuchika Gupta in_buf = data; 8865f80f270SRuchika Gupta in_sz = data_sz; 8875f80f270SRuchika Gupta } 8885f80f270SRuchika Gupta 8895f80f270SRuchika Gupta res = TEE_CipherDoFinal(proc->tee_op_handle, in_buf, in_sz, 8905f80f270SRuchika Gupta tmp_buf, &tmp_sz); 8915f80f270SRuchika Gupta if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) { 8925f80f270SRuchika Gupta *out_sz = tmp_sz; 8935f80f270SRuchika Gupta if (align) 8945f80f270SRuchika Gupta *out_sz += tmp_buf - (uint8_t *)out_buf; 8955f80f270SRuchika Gupta } 8965f80f270SRuchika Gupta 8975f80f270SRuchika Gupta if (align) 8985f80f270SRuchika Gupta TEE_Free(in_buf); 8995f80f270SRuchika Gupta 9005f80f270SRuchika Gupta return tee2pkcs_error(res); 9015f80f270SRuchika Gupta default: 9025f80f270SRuchika Gupta return PKCS11_CKR_MECHANISM_INVALID; 9035f80f270SRuchika Gupta } 9045f80f270SRuchika Gupta 9055f80f270SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 9065f80f270SRuchika Gupta } 9073668310bSRuchika Gupta 9083668310bSRuchika Gupta enum pkcs11_rc unwrap_key_by_symm(struct pkcs11_session *session, void *data, 9093668310bSRuchika Gupta uint32_t data_sz, void **out_buf, 9103668310bSRuchika Gupta uint32_t *out_sz) 9113668310bSRuchika Gupta { 9123668310bSRuchika Gupta TEE_Result res = TEE_ERROR_GENERIC; 9133668310bSRuchika Gupta struct active_processing *proc = session->processing; 9143668310bSRuchika Gupta 9153668310bSRuchika Gupta if (input_data_size_is_valid(proc, PKCS11_FUNCTION_DECRYPT, data_sz)) 9163668310bSRuchika Gupta return PKCS11_CKR_WRAPPED_KEY_LEN_RANGE; 9173668310bSRuchika Gupta 9183668310bSRuchika Gupta switch (proc->mecha_type) { 9193668310bSRuchika Gupta case PKCS11_CKM_AES_ECB: 9203668310bSRuchika Gupta case PKCS11_CKM_AES_CBC: 9213668310bSRuchika Gupta *out_sz = 0; 9223668310bSRuchika Gupta res = TEE_CipherDoFinal(proc->tee_op_handle, data, data_sz, 9233668310bSRuchika Gupta NULL, out_sz); 9243668310bSRuchika Gupta if (res != TEE_ERROR_SHORT_BUFFER) { 9253668310bSRuchika Gupta DMSG("TEE_CipherDoFinal() issue: %#"PRIx32, res); 9263668310bSRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 9273668310bSRuchika Gupta } 9283668310bSRuchika Gupta 9293668310bSRuchika Gupta *out_buf = TEE_Malloc(*out_sz, TEE_MALLOC_FILL_ZERO); 9303668310bSRuchika Gupta if (!*out_buf) 9313668310bSRuchika Gupta return PKCS11_CKR_DEVICE_MEMORY; 9323668310bSRuchika Gupta 9333668310bSRuchika Gupta res = TEE_CipherDoFinal(proc->tee_op_handle, data, data_sz, 9343668310bSRuchika Gupta *out_buf, out_sz); 9353668310bSRuchika Gupta if (tee2pkcs_error(res)) { 9363668310bSRuchika Gupta TEE_Free(*out_buf); 9373668310bSRuchika Gupta *out_buf = NULL; 9383668310bSRuchika Gupta return PKCS11_CKR_WRAPPED_KEY_INVALID; 9393668310bSRuchika Gupta } 9403668310bSRuchika Gupta break; 9413668310bSRuchika Gupta default: 9423668310bSRuchika Gupta return PKCS11_CKR_MECHANISM_INVALID; 9433668310bSRuchika Gupta } 9443668310bSRuchika Gupta 9453668310bSRuchika Gupta return PKCS11_CKR_OK; 9463668310bSRuchika Gupta } 947