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: 38*70b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 39*70b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 40*70b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 41*70b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 42*70b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 43*70b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 446f6d5e75SVictor Chong /* Ciphering */ 45512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 46512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 47512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 48512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 49512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 5048799892SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 5148799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 52512cbf1dSJens Wiklander return true; 53512cbf1dSJens Wiklander default: 54512cbf1dSJens Wiklander return false; 55512cbf1dSJens Wiklander } 56512cbf1dSJens Wiklander } 57512cbf1dSJens Wiklander 58512cbf1dSJens Wiklander static enum pkcs11_rc 59512cbf1dSJens Wiklander pkcs2tee_algorithm(uint32_t *tee_id, struct pkcs11_attribute_head *proc_params) 60512cbf1dSJens Wiklander { 61512cbf1dSJens Wiklander static const struct { 62512cbf1dSJens Wiklander enum pkcs11_mechanism_id mech_id; 63512cbf1dSJens Wiklander uint32_t tee_id; 64512cbf1dSJens Wiklander } pkcs2tee_algo[] = { 65512cbf1dSJens Wiklander /* AES flavors */ 66512cbf1dSJens Wiklander { PKCS11_CKM_AES_ECB, TEE_ALG_AES_ECB_NOPAD }, 67512cbf1dSJens Wiklander { PKCS11_CKM_AES_CBC, TEE_ALG_AES_CBC_NOPAD }, 68512cbf1dSJens Wiklander { PKCS11_CKM_AES_CBC_PAD, TEE_ALG_AES_CBC_NOPAD }, 6948799892SRuchika Gupta { PKCS11_CKM_AES_ECB_ENCRYPT_DATA, TEE_ALG_AES_ECB_NOPAD }, 7048799892SRuchika Gupta { PKCS11_CKM_AES_CBC_ENCRYPT_DATA, TEE_ALG_AES_CBC_NOPAD }, 71512cbf1dSJens Wiklander { PKCS11_CKM_AES_CTR, TEE_ALG_AES_CTR }, 72512cbf1dSJens Wiklander { PKCS11_CKM_AES_CTS, TEE_ALG_AES_CTS }, 73689f4e5bSRuchika Gupta /* HMAC flavors */ 74689f4e5bSRuchika Gupta { PKCS11_CKM_MD5_HMAC, TEE_ALG_HMAC_MD5 }, 75689f4e5bSRuchika Gupta { PKCS11_CKM_SHA_1_HMAC, TEE_ALG_HMAC_SHA1 }, 76689f4e5bSRuchika Gupta { PKCS11_CKM_SHA224_HMAC, TEE_ALG_HMAC_SHA224 }, 77689f4e5bSRuchika Gupta { PKCS11_CKM_SHA256_HMAC, TEE_ALG_HMAC_SHA256 }, 78689f4e5bSRuchika Gupta { PKCS11_CKM_SHA384_HMAC, TEE_ALG_HMAC_SHA384 }, 79689f4e5bSRuchika Gupta { PKCS11_CKM_SHA512_HMAC, TEE_ALG_HMAC_SHA512 }, 80*70b6683bSVictor Chong { PKCS11_CKM_MD5_HMAC_GENERAL, TEE_ALG_HMAC_MD5 }, 81*70b6683bSVictor Chong { PKCS11_CKM_SHA_1_HMAC_GENERAL, TEE_ALG_HMAC_SHA1 }, 82*70b6683bSVictor Chong { PKCS11_CKM_SHA224_HMAC_GENERAL, TEE_ALG_HMAC_SHA224 }, 83*70b6683bSVictor Chong { PKCS11_CKM_SHA256_HMAC_GENERAL, TEE_ALG_HMAC_SHA256 }, 84*70b6683bSVictor Chong { PKCS11_CKM_SHA384_HMAC_GENERAL, TEE_ALG_HMAC_SHA384 }, 85*70b6683bSVictor Chong { PKCS11_CKM_SHA512_HMAC_GENERAL, TEE_ALG_HMAC_SHA512 }, 86512cbf1dSJens Wiklander }; 87512cbf1dSJens Wiklander size_t n = 0; 88512cbf1dSJens Wiklander 89512cbf1dSJens Wiklander for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) { 90512cbf1dSJens Wiklander if (proc_params->id == pkcs2tee_algo[n].mech_id) { 91512cbf1dSJens Wiklander *tee_id = pkcs2tee_algo[n].tee_id; 92512cbf1dSJens Wiklander return PKCS11_CKR_OK; 93512cbf1dSJens Wiklander } 94512cbf1dSJens Wiklander } 95512cbf1dSJens Wiklander 96512cbf1dSJens Wiklander return PKCS11_RV_NOT_IMPLEMENTED; 97512cbf1dSJens Wiklander } 98512cbf1dSJens Wiklander 99512cbf1dSJens Wiklander static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type, 100512cbf1dSJens Wiklander struct pkcs11_object *obj) 101512cbf1dSJens Wiklander { 102512cbf1dSJens Wiklander static const struct { 103512cbf1dSJens Wiklander enum pkcs11_key_type key_type; 104512cbf1dSJens Wiklander uint32_t tee_id; 105512cbf1dSJens Wiklander } pkcs2tee_key_type[] = { 106512cbf1dSJens Wiklander { PKCS11_CKK_AES, TEE_TYPE_AES }, 107512cbf1dSJens Wiklander { PKCS11_CKK_GENERIC_SECRET, TEE_TYPE_GENERIC_SECRET }, 108512cbf1dSJens Wiklander { PKCS11_CKK_MD5_HMAC, TEE_TYPE_HMAC_MD5 }, 109512cbf1dSJens Wiklander { PKCS11_CKK_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 }, 110512cbf1dSJens Wiklander { PKCS11_CKK_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 }, 111512cbf1dSJens Wiklander { PKCS11_CKK_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 }, 112512cbf1dSJens Wiklander { PKCS11_CKK_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 }, 113512cbf1dSJens Wiklander { PKCS11_CKK_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 }, 114512cbf1dSJens Wiklander }; 115512cbf1dSJens Wiklander size_t n = 0; 116512cbf1dSJens Wiklander enum pkcs11_key_type key_type = get_key_type(obj->attributes); 117512cbf1dSJens Wiklander 118512cbf1dSJens Wiklander assert(get_class(obj->attributes) == PKCS11_CKO_SECRET_KEY); 119512cbf1dSJens Wiklander 120512cbf1dSJens Wiklander for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) { 121512cbf1dSJens Wiklander if (pkcs2tee_key_type[n].key_type == key_type) { 122512cbf1dSJens Wiklander *tee_type = pkcs2tee_key_type[n].tee_id; 123512cbf1dSJens Wiklander return PKCS11_CKR_OK; 124512cbf1dSJens Wiklander } 125512cbf1dSJens Wiklander } 126512cbf1dSJens Wiklander 127512cbf1dSJens Wiklander return PKCS11_RV_NOT_FOUND; 128512cbf1dSJens Wiklander } 129512cbf1dSJens Wiklander 130de94d6f8SRuchika Gupta static enum pkcs11_rc pkcsmech2tee_key_type(uint32_t *tee_type, 131de94d6f8SRuchika Gupta enum pkcs11_mechanism_id mech_id) 132de94d6f8SRuchika Gupta { 133de94d6f8SRuchika Gupta static const struct { 134de94d6f8SRuchika Gupta enum pkcs11_mechanism_id mech; 135de94d6f8SRuchika Gupta uint32_t tee_id; 136de94d6f8SRuchika Gupta } pkcs2tee_key_type[] = { 137de94d6f8SRuchika Gupta { PKCS11_CKM_MD5_HMAC, TEE_TYPE_HMAC_MD5 }, 138de94d6f8SRuchika Gupta { PKCS11_CKM_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 }, 139de94d6f8SRuchika Gupta { PKCS11_CKM_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 }, 140de94d6f8SRuchika Gupta { PKCS11_CKM_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 }, 141de94d6f8SRuchika Gupta { PKCS11_CKM_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 }, 142de94d6f8SRuchika Gupta { PKCS11_CKM_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 }, 143*70b6683bSVictor Chong { PKCS11_CKM_MD5_HMAC_GENERAL, TEE_TYPE_HMAC_MD5 }, 144*70b6683bSVictor Chong { PKCS11_CKM_SHA_1_HMAC_GENERAL, TEE_TYPE_HMAC_SHA1 }, 145*70b6683bSVictor Chong { PKCS11_CKM_SHA224_HMAC_GENERAL, TEE_TYPE_HMAC_SHA224 }, 146*70b6683bSVictor Chong { PKCS11_CKM_SHA256_HMAC_GENERAL, TEE_TYPE_HMAC_SHA256 }, 147*70b6683bSVictor Chong { PKCS11_CKM_SHA384_HMAC_GENERAL, TEE_TYPE_HMAC_SHA384 }, 148*70b6683bSVictor Chong { PKCS11_CKM_SHA512_HMAC_GENERAL, TEE_TYPE_HMAC_SHA512 }, 149de94d6f8SRuchika Gupta }; 150de94d6f8SRuchika Gupta size_t n = 0; 151de94d6f8SRuchika Gupta 152de94d6f8SRuchika Gupta for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) { 153de94d6f8SRuchika Gupta if (pkcs2tee_key_type[n].mech == mech_id) { 154de94d6f8SRuchika Gupta *tee_type = pkcs2tee_key_type[n].tee_id; 155de94d6f8SRuchika Gupta return PKCS11_CKR_OK; 156de94d6f8SRuchika Gupta } 157de94d6f8SRuchika Gupta } 158de94d6f8SRuchika Gupta 159de94d6f8SRuchika Gupta return PKCS11_RV_NOT_FOUND; 160de94d6f8SRuchika Gupta } 161de94d6f8SRuchika Gupta 1622158ea6cSRuchika Gupta static enum pkcs11_rc hmac_to_tee_hash(uint32_t *algo, 1632158ea6cSRuchika Gupta enum pkcs11_mechanism_id mech_id) 1642158ea6cSRuchika Gupta { 1652158ea6cSRuchika Gupta static const struct { 1662158ea6cSRuchika Gupta enum pkcs11_mechanism_id mech; 1672158ea6cSRuchika Gupta uint32_t tee_id; 1682158ea6cSRuchika Gupta } hmac_hash[] = { 1692158ea6cSRuchika Gupta { PKCS11_CKM_MD5_HMAC, TEE_ALG_MD5 }, 1702158ea6cSRuchika Gupta { PKCS11_CKM_SHA_1_HMAC, TEE_ALG_SHA1 }, 1712158ea6cSRuchika Gupta { PKCS11_CKM_SHA224_HMAC, TEE_ALG_SHA224 }, 1722158ea6cSRuchika Gupta { PKCS11_CKM_SHA256_HMAC, TEE_ALG_SHA256 }, 1732158ea6cSRuchika Gupta { PKCS11_CKM_SHA384_HMAC, TEE_ALG_SHA384 }, 1742158ea6cSRuchika Gupta { PKCS11_CKM_SHA512_HMAC, TEE_ALG_SHA512 }, 175*70b6683bSVictor Chong { PKCS11_CKM_MD5_HMAC_GENERAL, TEE_ALG_MD5 }, 176*70b6683bSVictor Chong { PKCS11_CKM_SHA_1_HMAC_GENERAL, TEE_ALG_SHA1 }, 177*70b6683bSVictor Chong { PKCS11_CKM_SHA224_HMAC_GENERAL, TEE_ALG_SHA224 }, 178*70b6683bSVictor Chong { PKCS11_CKM_SHA256_HMAC_GENERAL, TEE_ALG_SHA256 }, 179*70b6683bSVictor Chong { PKCS11_CKM_SHA384_HMAC_GENERAL, TEE_ALG_SHA384 }, 180*70b6683bSVictor Chong { PKCS11_CKM_SHA512_HMAC_GENERAL, TEE_ALG_SHA512 }, 1812158ea6cSRuchika Gupta }; 1822158ea6cSRuchika Gupta size_t n = 0; 1832158ea6cSRuchika Gupta 1842158ea6cSRuchika Gupta for (n = 0; n < ARRAY_SIZE(hmac_hash); n++) { 1852158ea6cSRuchika Gupta if (hmac_hash[n].mech == mech_id) { 1862158ea6cSRuchika Gupta *algo = hmac_hash[n].tee_id; 1872158ea6cSRuchika Gupta return PKCS11_CKR_OK; 1882158ea6cSRuchika Gupta } 1892158ea6cSRuchika Gupta } 1902158ea6cSRuchika Gupta 1912158ea6cSRuchika Gupta return PKCS11_RV_NOT_FOUND; 1922158ea6cSRuchika Gupta } 1932158ea6cSRuchika Gupta 194512cbf1dSJens Wiklander static enum pkcs11_rc 195512cbf1dSJens Wiklander allocate_tee_operation(struct pkcs11_session *session, 196512cbf1dSJens Wiklander enum processing_func function, 197512cbf1dSJens Wiklander struct pkcs11_attribute_head *params, 198512cbf1dSJens Wiklander struct pkcs11_object *obj) 199512cbf1dSJens Wiklander { 200512cbf1dSJens Wiklander uint32_t size = (uint32_t)get_object_key_bit_size(obj); 201460ba621SRuchika Gupta uint32_t key_size = size / 8; 202512cbf1dSJens Wiklander uint32_t algo = 0; 203512cbf1dSJens Wiklander uint32_t mode = 0; 204460ba621SRuchika Gupta uint32_t max_key_size = 0; 205460ba621SRuchika Gupta uint32_t min_key_size = 0; 206512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 207512cbf1dSJens Wiklander 208512cbf1dSJens Wiklander assert(session->processing->tee_op_handle == TEE_HANDLE_NULL); 209512cbf1dSJens Wiklander 210512cbf1dSJens Wiklander if (pkcs2tee_algorithm(&algo, params)) 211512cbf1dSJens Wiklander return PKCS11_CKR_FUNCTION_FAILED; 212512cbf1dSJens Wiklander 213512cbf1dSJens Wiklander /* Sign/Verify with AES or generic key relate to TEE MAC operation */ 214689f4e5bSRuchika Gupta switch (params->id) { 215689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 216689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 217689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 218689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 219689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 220689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 221*70b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 222*70b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 223*70b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 224*70b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 225*70b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 226*70b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 2272d0cd829SRuchika Gupta mechanism_supported_key_sizes_bytes(params->id, &min_key_size, 228460ba621SRuchika Gupta &max_key_size); 229460ba621SRuchika Gupta if (key_size < min_key_size) 230460ba621SRuchika Gupta return PKCS11_CKR_KEY_SIZE_RANGE; 2312158ea6cSRuchika Gupta 2322158ea6cSRuchika Gupta /* 2332158ea6cSRuchika Gupta * If size of generic key is greater than the size 2342158ea6cSRuchika Gupta * supported by TEE API, this is not considered an 2352158ea6cSRuchika Gupta * error. When loading TEE key, we will hash the key 2362158ea6cSRuchika Gupta * to generate the appropriate key for HMAC operation. 2372158ea6cSRuchika Gupta * This key size will not be greater than the 2382158ea6cSRuchika Gupta * max_key_size. So we can use max_key_size for 2392158ea6cSRuchika Gupta * TEE_AllocateOperation(). 2402158ea6cSRuchika Gupta */ 2412158ea6cSRuchika Gupta if (key_size > max_key_size) 2422158ea6cSRuchika Gupta size = max_key_size * 8; 2432158ea6cSRuchika Gupta 244689f4e5bSRuchika Gupta mode = TEE_MODE_MAC; 245689f4e5bSRuchika Gupta break; 246689f4e5bSRuchika Gupta default: 247512cbf1dSJens Wiklander pkcs2tee_mode(&mode, function); 248689f4e5bSRuchika Gupta break; 249689f4e5bSRuchika Gupta } 250512cbf1dSJens Wiklander 251512cbf1dSJens Wiklander res = TEE_AllocateOperation(&session->processing->tee_op_handle, 252512cbf1dSJens Wiklander algo, mode, size); 253512cbf1dSJens Wiklander if (res) 254512cbf1dSJens Wiklander EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32, 255512cbf1dSJens Wiklander algo, mode, size); 256512cbf1dSJens Wiklander 257512cbf1dSJens Wiklander if (res == TEE_ERROR_NOT_SUPPORTED) 258512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_INVALID; 259512cbf1dSJens Wiklander 260512cbf1dSJens Wiklander return tee2pkcs_error(res); 261512cbf1dSJens Wiklander } 262512cbf1dSJens Wiklander 2632158ea6cSRuchika Gupta static enum pkcs11_rc hash_secret_helper(enum pkcs11_mechanism_id mech_id, 2642158ea6cSRuchika Gupta struct pkcs11_object *obj, 2652158ea6cSRuchika Gupta TEE_Attribute *tee_attr, 2662158ea6cSRuchika Gupta void **ctx, 2672158ea6cSRuchika Gupta size_t *object_size_bits) 2682158ea6cSRuchika Gupta { 2692158ea6cSRuchika Gupta uint32_t algo = 0; 2702158ea6cSRuchika Gupta void *hash_ptr = NULL; 2712158ea6cSRuchika Gupta uint32_t hash_size = 0; 2722158ea6cSRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK; 2732158ea6cSRuchika Gupta 2742158ea6cSRuchika Gupta rc = hmac_to_tee_hash(&algo, mech_id); 2752158ea6cSRuchika Gupta if (rc) 2762158ea6cSRuchika Gupta return rc; 2772158ea6cSRuchika Gupta 2782158ea6cSRuchika Gupta hash_size = TEE_ALG_GET_DIGEST_SIZE(algo); 2792158ea6cSRuchika Gupta hash_ptr = TEE_Malloc(hash_size, 0); 2802158ea6cSRuchika Gupta if (!hash_ptr) 2812158ea6cSRuchika Gupta return PKCS11_CKR_DEVICE_MEMORY; 2822158ea6cSRuchika Gupta 2832158ea6cSRuchika Gupta rc = pkcs2tee_load_hashed_attr(tee_attr, TEE_ATTR_SECRET_VALUE, obj, 2842158ea6cSRuchika Gupta PKCS11_CKA_VALUE, algo, hash_ptr, 2852158ea6cSRuchika Gupta &hash_size); 2862158ea6cSRuchika Gupta if (rc) { 2872158ea6cSRuchika Gupta EMSG("No secret/hash error"); 2882158ea6cSRuchika Gupta TEE_Free(hash_ptr); 2892158ea6cSRuchika Gupta return rc; 2902158ea6cSRuchika Gupta } 2912158ea6cSRuchika Gupta 2922158ea6cSRuchika Gupta *ctx = hash_ptr; 2932158ea6cSRuchika Gupta 2942158ea6cSRuchika Gupta *object_size_bits = hash_size * 8; 2952158ea6cSRuchika Gupta 2962158ea6cSRuchika Gupta return PKCS11_CKR_OK; 2972158ea6cSRuchika Gupta } 2982158ea6cSRuchika Gupta 299512cbf1dSJens Wiklander static enum pkcs11_rc load_tee_key(struct pkcs11_session *session, 300de94d6f8SRuchika Gupta struct pkcs11_object *obj, 301de94d6f8SRuchika Gupta struct pkcs11_attribute_head *proc_params) 302512cbf1dSJens Wiklander { 303512cbf1dSJens Wiklander TEE_Attribute tee_attr = { }; 304512cbf1dSJens Wiklander size_t object_size = 0; 305512cbf1dSJens Wiklander uint32_t tee_key_type = 0; 306de94d6f8SRuchika Gupta enum pkcs11_key_type key_type = 0; 307512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 308512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 3092158ea6cSRuchika Gupta uint32_t max_key_size = 0; 3102158ea6cSRuchika Gupta uint32_t min_key_size = 0; 311512cbf1dSJens Wiklander 312512cbf1dSJens Wiklander if (obj->key_handle != TEE_HANDLE_NULL) { 313512cbf1dSJens Wiklander /* Key was already loaded and fits current need */ 314512cbf1dSJens Wiklander goto key_ready; 315512cbf1dSJens Wiklander } 316512cbf1dSJens Wiklander 3172158ea6cSRuchika Gupta object_size = get_object_key_bit_size(obj); 3182158ea6cSRuchika Gupta if (!object_size) 3192158ea6cSRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 320512cbf1dSJens Wiklander 321de94d6f8SRuchika Gupta switch (proc_params->id) { 322de94d6f8SRuchika Gupta case PKCS11_CKM_MD5_HMAC: 323de94d6f8SRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 324de94d6f8SRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 325de94d6f8SRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 326de94d6f8SRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 327de94d6f8SRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 328*70b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 329*70b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 330*70b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 331*70b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 332*70b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 333*70b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 334de94d6f8SRuchika Gupta key_type = get_key_type(obj->attributes); 335de94d6f8SRuchika Gupta /* 336de94d6f8SRuchika Gupta * If Object Key type is PKCS11_CKK_GENERIC_SECRET, 337de94d6f8SRuchika Gupta * determine the tee_key_type using the 338de94d6f8SRuchika Gupta * mechanism instead of object key_type. 339de94d6f8SRuchika Gupta */ 340de94d6f8SRuchika Gupta if (key_type == PKCS11_CKK_GENERIC_SECRET) 341de94d6f8SRuchika Gupta rc = pkcsmech2tee_key_type(&tee_key_type, 342de94d6f8SRuchika Gupta proc_params->id); 343de94d6f8SRuchika Gupta else 344512cbf1dSJens Wiklander rc = pkcs2tee_key_type(&tee_key_type, obj); 345de94d6f8SRuchika Gupta 346512cbf1dSJens Wiklander if (rc) 347512cbf1dSJens Wiklander return rc; 348512cbf1dSJens Wiklander 3492d0cd829SRuchika Gupta mechanism_supported_key_sizes_bytes(proc_params->id, 3502158ea6cSRuchika Gupta &min_key_size, 3512158ea6cSRuchika Gupta &max_key_size); 3522158ea6cSRuchika Gupta 3532158ea6cSRuchika Gupta if ((object_size / 8) > max_key_size) { 3542158ea6cSRuchika Gupta rc = hash_secret_helper(proc_params->id, obj, &tee_attr, 3552158ea6cSRuchika Gupta &session->processing->extra_ctx, 3562158ea6cSRuchika Gupta &object_size); 3572158ea6cSRuchika Gupta if (rc) 3582158ea6cSRuchika Gupta return rc; 3592158ea6cSRuchika Gupta } else { 3602158ea6cSRuchika Gupta if (!pkcs2tee_load_attr(&tee_attr, 3612158ea6cSRuchika Gupta TEE_ATTR_SECRET_VALUE, 3622158ea6cSRuchika Gupta obj, 3632158ea6cSRuchika Gupta PKCS11_CKA_VALUE)) { 3642158ea6cSRuchika Gupta EMSG("No secret found"); 3652158ea6cSRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED; 3662158ea6cSRuchika Gupta } 3672158ea6cSRuchika Gupta } 3682158ea6cSRuchika Gupta break; 3692158ea6cSRuchika Gupta 3702158ea6cSRuchika Gupta default: 3712158ea6cSRuchika Gupta rc = pkcs2tee_key_type(&tee_key_type, obj); 3722158ea6cSRuchika Gupta if (rc) 3732158ea6cSRuchika Gupta return rc; 3742158ea6cSRuchika Gupta 3752158ea6cSRuchika Gupta if (!pkcs2tee_load_attr(&tee_attr, TEE_ATTR_SECRET_VALUE, 3762158ea6cSRuchika Gupta obj, PKCS11_CKA_VALUE)) { 3772158ea6cSRuchika Gupta EMSG("No secret found"); 3782158ea6cSRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED; 3792158ea6cSRuchika Gupta } 3802158ea6cSRuchika Gupta break; 3812158ea6cSRuchika Gupta } 382512cbf1dSJens Wiklander 383512cbf1dSJens Wiklander res = TEE_AllocateTransientObject(tee_key_type, object_size, 384512cbf1dSJens Wiklander &obj->key_handle); 385512cbf1dSJens Wiklander if (res) { 386512cbf1dSJens Wiklander DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 387512cbf1dSJens Wiklander return tee2pkcs_error(res); 388512cbf1dSJens Wiklander } 389512cbf1dSJens Wiklander 390512cbf1dSJens Wiklander res = TEE_PopulateTransientObject(obj->key_handle, &tee_attr, 1); 391512cbf1dSJens Wiklander if (res) { 392512cbf1dSJens Wiklander DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res); 393512cbf1dSJens Wiklander goto error; 394512cbf1dSJens Wiklander } 395512cbf1dSJens Wiklander 396512cbf1dSJens Wiklander key_ready: 397512cbf1dSJens Wiklander res = TEE_SetOperationKey(session->processing->tee_op_handle, 398512cbf1dSJens Wiklander obj->key_handle); 399512cbf1dSJens Wiklander if (res) { 400512cbf1dSJens Wiklander DMSG("TEE_SetOperationKey failed, %#"PRIx32, res); 401512cbf1dSJens Wiklander goto error; 402512cbf1dSJens Wiklander } 403512cbf1dSJens Wiklander 404512cbf1dSJens Wiklander return PKCS11_CKR_OK; 405512cbf1dSJens Wiklander 406512cbf1dSJens Wiklander error: 407512cbf1dSJens Wiklander TEE_FreeTransientObject(obj->key_handle); 408512cbf1dSJens Wiklander obj->key_handle = TEE_HANDLE_NULL; 409512cbf1dSJens Wiklander 410512cbf1dSJens Wiklander return tee2pkcs_error(res); 411512cbf1dSJens Wiklander } 412512cbf1dSJens Wiklander 413512cbf1dSJens Wiklander static enum pkcs11_rc 41448799892SRuchika Gupta tee_init_derive_symm(struct active_processing *processing, 41548799892SRuchika Gupta struct pkcs11_attribute_head *proc_params) 41648799892SRuchika Gupta { 41748799892SRuchika Gupta struct serialargs args = { }; 41848799892SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK; 41948799892SRuchika Gupta struct input_data_ref *param = NULL; 42048799892SRuchika Gupta void *iv = NULL; 42148799892SRuchika Gupta 42248799892SRuchika Gupta if (!proc_params) 42348799892SRuchika Gupta return PKCS11_CKR_ARGUMENTS_BAD; 42448799892SRuchika Gupta 42548799892SRuchika Gupta param = TEE_Malloc(sizeof(struct input_data_ref), TEE_MALLOC_FILL_ZERO); 42648799892SRuchika Gupta if (!param) 42748799892SRuchika Gupta return PKCS11_CKR_DEVICE_MEMORY; 42848799892SRuchika Gupta 42948799892SRuchika Gupta serialargs_init(&args, proc_params->data, proc_params->size); 43048799892SRuchika Gupta 43148799892SRuchika Gupta switch (proc_params->id) { 43248799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 43348799892SRuchika Gupta rc = serialargs_get_ptr(&args, &iv, 16); 43448799892SRuchika Gupta if (rc) 43548799892SRuchika Gupta goto err; 43648799892SRuchika Gupta break; 43748799892SRuchika Gupta default: 43848799892SRuchika Gupta break; 43948799892SRuchika Gupta } 44048799892SRuchika Gupta 44148799892SRuchika Gupta rc = serialargs_get(&args, ¶m->size, sizeof(uint32_t)); 44248799892SRuchika Gupta if (rc) 44348799892SRuchika Gupta goto err; 44448799892SRuchika Gupta 44548799892SRuchika Gupta rc = serialargs_get_ptr(&args, ¶m->data, param->size); 44648799892SRuchika Gupta if (rc) 44748799892SRuchika Gupta goto err; 44848799892SRuchika Gupta 44948799892SRuchika Gupta if (serialargs_remaining_bytes(&args)) { 45048799892SRuchika Gupta rc = PKCS11_CKR_ARGUMENTS_BAD; 45148799892SRuchika Gupta goto err; 45248799892SRuchika Gupta } 45348799892SRuchika Gupta 45448799892SRuchika Gupta processing->extra_ctx = param; 45548799892SRuchika Gupta 45648799892SRuchika Gupta switch (proc_params->id) { 45748799892SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 45848799892SRuchika Gupta if (param->size % TEE_AES_BLOCK_SIZE) { 45948799892SRuchika Gupta rc = PKCS11_CKR_DATA_LEN_RANGE; 46048799892SRuchika Gupta goto err; 46148799892SRuchika Gupta } 46248799892SRuchika Gupta TEE_CipherInit(processing->tee_op_handle, NULL, 0); 46348799892SRuchika Gupta break; 46448799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 46548799892SRuchika Gupta if (param->size % TEE_AES_BLOCK_SIZE) { 46648799892SRuchika Gupta rc = PKCS11_CKR_DATA_LEN_RANGE; 46748799892SRuchika Gupta goto err; 46848799892SRuchika Gupta } 46948799892SRuchika Gupta TEE_CipherInit(processing->tee_op_handle, iv, 16); 47048799892SRuchika Gupta break; 47148799892SRuchika Gupta default: 47248799892SRuchika Gupta TEE_Panic(proc_params->id); 47348799892SRuchika Gupta break; 47448799892SRuchika Gupta } 47548799892SRuchika Gupta 47648799892SRuchika Gupta return PKCS11_CKR_OK; 47748799892SRuchika Gupta 47848799892SRuchika Gupta err: 47948799892SRuchika Gupta processing->extra_ctx = NULL; 48048799892SRuchika Gupta TEE_Free(param); 48148799892SRuchika Gupta return rc; 48248799892SRuchika Gupta } 48348799892SRuchika Gupta 48448799892SRuchika Gupta static enum pkcs11_rc 485*70b6683bSVictor Chong input_hmac_len_is_valid(struct pkcs11_attribute_head *proc_params, 486*70b6683bSVictor Chong uint32_t hmac_len) 487*70b6683bSVictor Chong { 488*70b6683bSVictor Chong uint32_t sign_sz = 0; 489*70b6683bSVictor Chong 490*70b6683bSVictor Chong switch (proc_params->id) { 491*70b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 492*70b6683bSVictor Chong sign_sz = TEE_MD5_HASH_SIZE; 493*70b6683bSVictor Chong break; 494*70b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 495*70b6683bSVictor Chong sign_sz = TEE_SHA1_HASH_SIZE; 496*70b6683bSVictor Chong break; 497*70b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 498*70b6683bSVictor Chong sign_sz = TEE_SHA224_HASH_SIZE; 499*70b6683bSVictor Chong break; 500*70b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 501*70b6683bSVictor Chong sign_sz = TEE_SHA256_HASH_SIZE; 502*70b6683bSVictor Chong break; 503*70b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 504*70b6683bSVictor Chong sign_sz = TEE_SHA384_HASH_SIZE; 505*70b6683bSVictor Chong break; 506*70b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 507*70b6683bSVictor Chong sign_sz = TEE_SHA512_HASH_SIZE; 508*70b6683bSVictor Chong break; 509*70b6683bSVictor Chong default: 510*70b6683bSVictor Chong return PKCS11_CKR_MECHANISM_INVALID; 511*70b6683bSVictor Chong } 512*70b6683bSVictor Chong 513*70b6683bSVictor Chong if (!hmac_len || hmac_len > sign_sz) 514*70b6683bSVictor Chong return PKCS11_CKR_SIGNATURE_LEN_RANGE; 515*70b6683bSVictor Chong 516*70b6683bSVictor Chong return PKCS11_CKR_OK; 517*70b6683bSVictor Chong } 518*70b6683bSVictor Chong 519*70b6683bSVictor Chong static enum pkcs11_rc 520512cbf1dSJens Wiklander init_tee_operation(struct pkcs11_session *session, 521512cbf1dSJens Wiklander struct pkcs11_attribute_head *proc_params) 522512cbf1dSJens Wiklander { 523512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 524*70b6683bSVictor Chong uint32_t *pkcs11_data = NULL; 525512cbf1dSJens Wiklander 526512cbf1dSJens Wiklander switch (proc_params->id) { 527689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 528689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 529689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 530689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 531689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 532689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 533689f4e5bSRuchika Gupta if (proc_params->size) 534689f4e5bSRuchika Gupta return PKCS11_CKR_MECHANISM_PARAM_INVALID; 535689f4e5bSRuchika Gupta 536689f4e5bSRuchika Gupta TEE_MACInit(session->processing->tee_op_handle, NULL, 0); 537689f4e5bSRuchika Gupta rc = PKCS11_CKR_OK; 538689f4e5bSRuchika Gupta break; 539*70b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 540*70b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 541*70b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 542*70b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 543*70b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 544*70b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 545*70b6683bSVictor Chong if (proc_params->size != sizeof(uint32_t)) 546*70b6683bSVictor Chong return PKCS11_CKR_MECHANISM_PARAM_INVALID; 547*70b6683bSVictor Chong 548*70b6683bSVictor Chong pkcs11_data = TEE_Malloc(sizeof(uint32_t), 549*70b6683bSVictor Chong TEE_MALLOC_FILL_ZERO); 550*70b6683bSVictor Chong if (!pkcs11_data) 551*70b6683bSVictor Chong return PKCS11_CKR_DEVICE_MEMORY; 552*70b6683bSVictor Chong 553*70b6683bSVictor Chong TEE_MemMove(pkcs11_data, proc_params->data, sizeof(uint32_t)); 554*70b6683bSVictor Chong 555*70b6683bSVictor Chong rc = input_hmac_len_is_valid(proc_params, *pkcs11_data); 556*70b6683bSVictor Chong if (rc) { 557*70b6683bSVictor Chong TEE_Free(pkcs11_data); 558*70b6683bSVictor Chong return rc; 559*70b6683bSVictor Chong } 560*70b6683bSVictor Chong 561*70b6683bSVictor Chong session->processing->extra_ctx = (void *)pkcs11_data; 562*70b6683bSVictor Chong 563*70b6683bSVictor Chong TEE_MACInit(session->processing->tee_op_handle, NULL, 0); 564*70b6683bSVictor Chong rc = PKCS11_CKR_OK; 565*70b6683bSVictor Chong break; 566512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 567512cbf1dSJens Wiklander if (proc_params->size) 568512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_PARAM_INVALID; 569512cbf1dSJens Wiklander 570512cbf1dSJens Wiklander TEE_CipherInit(session->processing->tee_op_handle, NULL, 0); 571512cbf1dSJens Wiklander rc = PKCS11_CKR_OK; 572512cbf1dSJens Wiklander break; 573512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 574512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 575512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 576512cbf1dSJens Wiklander if (proc_params->size != 16) 577512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_PARAM_INVALID; 578512cbf1dSJens Wiklander 579512cbf1dSJens Wiklander TEE_CipherInit(session->processing->tee_op_handle, 580512cbf1dSJens Wiklander proc_params->data, 16); 581512cbf1dSJens Wiklander rc = PKCS11_CKR_OK; 582512cbf1dSJens Wiklander break; 583512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 584512cbf1dSJens Wiklander rc = tee_init_ctr_operation(session->processing, 585512cbf1dSJens Wiklander proc_params->data, 586512cbf1dSJens Wiklander proc_params->size); 587512cbf1dSJens Wiklander break; 58848799892SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 58948799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 59048799892SRuchika Gupta rc = tee_init_derive_symm(session->processing, proc_params); 59148799892SRuchika Gupta break; 592512cbf1dSJens Wiklander default: 593512cbf1dSJens Wiklander TEE_Panic(proc_params->id); 594512cbf1dSJens Wiklander break; 595512cbf1dSJens Wiklander } 596512cbf1dSJens Wiklander 597512cbf1dSJens Wiklander return rc; 598512cbf1dSJens Wiklander } 599512cbf1dSJens Wiklander 600512cbf1dSJens Wiklander enum pkcs11_rc init_symm_operation(struct pkcs11_session *session, 601512cbf1dSJens Wiklander enum processing_func function, 602512cbf1dSJens Wiklander struct pkcs11_attribute_head *proc_params, 603512cbf1dSJens Wiklander struct pkcs11_object *obj) 604512cbf1dSJens Wiklander { 605512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 606512cbf1dSJens Wiklander 607512cbf1dSJens Wiklander assert(processing_is_tee_symm(proc_params->id)); 608512cbf1dSJens Wiklander 609512cbf1dSJens Wiklander rc = allocate_tee_operation(session, function, proc_params, obj); 610512cbf1dSJens Wiklander if (rc) 611512cbf1dSJens Wiklander return rc; 612512cbf1dSJens Wiklander 613de94d6f8SRuchika Gupta rc = load_tee_key(session, obj, proc_params); 614512cbf1dSJens Wiklander if (rc) 615512cbf1dSJens Wiklander return rc; 616512cbf1dSJens Wiklander 617512cbf1dSJens Wiklander return init_tee_operation(session, proc_params); 618512cbf1dSJens Wiklander } 619512cbf1dSJens Wiklander 620512cbf1dSJens Wiklander /* Validate input buffer size as per PKCS#11 constraints */ 621512cbf1dSJens Wiklander static enum pkcs11_rc input_data_size_is_valid(struct active_processing *proc, 622512cbf1dSJens Wiklander enum processing_func function, 623512cbf1dSJens Wiklander size_t in_size) 624512cbf1dSJens Wiklander { 625512cbf1dSJens Wiklander switch (proc->mecha_type) { 626512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 627512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 628512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_ENCRYPT && 629512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 630512cbf1dSJens Wiklander return PKCS11_CKR_DATA_LEN_RANGE; 631512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 632512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 633512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 634512cbf1dSJens Wiklander break; 635512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 636512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 637512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 638512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 639512cbf1dSJens Wiklander break; 640512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 641512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_ENCRYPT && 642512cbf1dSJens Wiklander in_size < TEE_AES_BLOCK_SIZE) 643512cbf1dSJens Wiklander return PKCS11_CKR_DATA_LEN_RANGE; 644512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 645512cbf1dSJens Wiklander in_size < TEE_AES_BLOCK_SIZE) 646512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 647512cbf1dSJens Wiklander break; 648512cbf1dSJens Wiklander default: 649512cbf1dSJens Wiklander break; 650512cbf1dSJens Wiklander } 651512cbf1dSJens Wiklander 652512cbf1dSJens Wiklander return PKCS11_CKR_OK; 653512cbf1dSJens Wiklander } 654512cbf1dSJens Wiklander 655689f4e5bSRuchika Gupta /* Validate input buffer size as per PKCS#11 constraints */ 656689f4e5bSRuchika Gupta static enum pkcs11_rc input_sign_size_is_valid(struct active_processing *proc, 657689f4e5bSRuchika Gupta size_t in_size) 658689f4e5bSRuchika Gupta { 659689f4e5bSRuchika Gupta size_t sign_sz = 0; 660689f4e5bSRuchika Gupta 661689f4e5bSRuchika Gupta switch (proc->mecha_type) { 662689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 663689f4e5bSRuchika Gupta sign_sz = TEE_MD5_HASH_SIZE; 664689f4e5bSRuchika Gupta break; 665689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 666689f4e5bSRuchika Gupta sign_sz = TEE_SHA1_HASH_SIZE; 667689f4e5bSRuchika Gupta break; 668689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 669689f4e5bSRuchika Gupta sign_sz = TEE_SHA224_HASH_SIZE; 670689f4e5bSRuchika Gupta break; 671689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 672689f4e5bSRuchika Gupta sign_sz = TEE_SHA256_HASH_SIZE; 673689f4e5bSRuchika Gupta break; 674689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 675689f4e5bSRuchika Gupta sign_sz = TEE_SHA384_HASH_SIZE; 676689f4e5bSRuchika Gupta break; 677689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 678689f4e5bSRuchika Gupta sign_sz = TEE_SHA512_HASH_SIZE; 679689f4e5bSRuchika Gupta break; 680689f4e5bSRuchika Gupta default: 681689f4e5bSRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 682689f4e5bSRuchika Gupta } 683689f4e5bSRuchika Gupta 68442765f82SVictor Chong if (in_size != sign_sz) 685689f4e5bSRuchika Gupta return PKCS11_CKR_SIGNATURE_LEN_RANGE; 686689f4e5bSRuchika Gupta 687689f4e5bSRuchika Gupta return PKCS11_CKR_OK; 688689f4e5bSRuchika Gupta } 689689f4e5bSRuchika Gupta 690512cbf1dSJens Wiklander /* 691512cbf1dSJens Wiklander * step_sym_cipher - processing symmetric (and related) cipher operation step 692512cbf1dSJens Wiklander * 693512cbf1dSJens Wiklander * @session - current session 694512cbf1dSJens Wiklander * @function - processing function (encrypt, decrypt, sign, ...) 695512cbf1dSJens Wiklander * @step - step ID in the processing (oneshot, update, final) 696512cbf1dSJens Wiklander * @ptype - invocation parameter types 697512cbf1dSJens Wiklander * @params - invocation parameter references 698512cbf1dSJens Wiklander */ 699512cbf1dSJens Wiklander enum pkcs11_rc step_symm_operation(struct pkcs11_session *session, 700512cbf1dSJens Wiklander enum processing_func function, 701512cbf1dSJens Wiklander enum processing_step step, 702512cbf1dSJens Wiklander uint32_t ptypes, TEE_Param *params) 703512cbf1dSJens Wiklander { 704512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 705512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 706512cbf1dSJens Wiklander void *in_buf = NULL; 707512cbf1dSJens Wiklander size_t in_size = 0; 708512cbf1dSJens Wiklander void *out_buf = NULL; 709512cbf1dSJens Wiklander uint32_t out_size = 0; 710512cbf1dSJens Wiklander void *in2_buf = NULL; 711512cbf1dSJens Wiklander uint32_t in2_size = 0; 712512cbf1dSJens Wiklander bool output_data = false; 713512cbf1dSJens Wiklander struct active_processing *proc = session->processing; 714*70b6683bSVictor Chong uint32_t hmac_len = 0; 715*70b6683bSVictor Chong uint8_t computed_mac[TEE_MAX_HASH_SIZE] = { 0 }; 716*70b6683bSVictor Chong uint32_t computed_mac_size = TEE_MAX_HASH_SIZE; 717512cbf1dSJens Wiklander 718512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 719512cbf1dSJens Wiklander in_buf = params[1].memref.buffer; 720512cbf1dSJens Wiklander in_size = params[1].memref.size; 721512cbf1dSJens Wiklander if (in_size && !in_buf) 722512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 723512cbf1dSJens Wiklander } 724512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) { 725512cbf1dSJens Wiklander in2_buf = params[2].memref.buffer; 726512cbf1dSJens Wiklander in2_size = params[2].memref.size; 727512cbf1dSJens Wiklander if (in2_size && !in2_buf) 728512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 729512cbf1dSJens Wiklander } 730512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 731512cbf1dSJens Wiklander out_buf = params[2].memref.buffer; 732512cbf1dSJens Wiklander out_size = params[2].memref.size; 733512cbf1dSJens Wiklander if (out_size && !out_buf) 734512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 735512cbf1dSJens Wiklander } 736512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 737512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 738512cbf1dSJens Wiklander 739512cbf1dSJens Wiklander switch (step) { 740512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_ONESHOT: 741512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_UPDATE: 742512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_FINAL: 743512cbf1dSJens Wiklander break; 744512cbf1dSJens Wiklander default: 745512cbf1dSJens Wiklander return PKCS11_CKR_GENERAL_ERROR; 746512cbf1dSJens Wiklander } 747512cbf1dSJens Wiklander 748512cbf1dSJens Wiklander if (step != PKCS11_FUNC_STEP_FINAL) { 749512cbf1dSJens Wiklander rc = input_data_size_is_valid(proc, function, in_size); 750512cbf1dSJens Wiklander if (rc) 751512cbf1dSJens Wiklander return rc; 752512cbf1dSJens Wiklander } 753512cbf1dSJens Wiklander 754512cbf1dSJens Wiklander /* 755512cbf1dSJens Wiklander * Feed active operation with data 756512cbf1dSJens Wiklander */ 757512cbf1dSJens Wiklander switch (proc->mecha_type) { 758689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 759689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 760689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 761689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 762689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 763689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 764*70b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 765*70b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 766*70b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 767*70b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 768*70b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 769*70b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 770689f4e5bSRuchika Gupta if (step == PKCS11_FUNC_STEP_FINAL || 771689f4e5bSRuchika Gupta step == PKCS11_FUNC_STEP_ONESHOT) 772689f4e5bSRuchika Gupta break; 773689f4e5bSRuchika Gupta 774689f4e5bSRuchika Gupta if (!in_buf) { 775689f4e5bSRuchika Gupta DMSG("No input data"); 776689f4e5bSRuchika Gupta return PKCS11_CKR_ARGUMENTS_BAD; 777689f4e5bSRuchika Gupta } 778689f4e5bSRuchika Gupta 779689f4e5bSRuchika Gupta switch (function) { 780689f4e5bSRuchika Gupta case PKCS11_FUNCTION_SIGN: 781689f4e5bSRuchika Gupta case PKCS11_FUNCTION_VERIFY: 782689f4e5bSRuchika Gupta TEE_MACUpdate(proc->tee_op_handle, in_buf, in_size); 783689f4e5bSRuchika Gupta rc = PKCS11_CKR_OK; 784689f4e5bSRuchika Gupta break; 785689f4e5bSRuchika Gupta default: 786689f4e5bSRuchika Gupta TEE_Panic(function); 787689f4e5bSRuchika Gupta break; 788689f4e5bSRuchika Gupta } 789689f4e5bSRuchika Gupta break; 790689f4e5bSRuchika Gupta 791512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 792512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 793512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 794512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 795512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 796512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_FINAL || 797512cbf1dSJens Wiklander step == PKCS11_FUNC_STEP_ONESHOT) 798512cbf1dSJens Wiklander break; 799512cbf1dSJens Wiklander 800512cbf1dSJens Wiklander if (!in_buf) { 801512cbf1dSJens Wiklander EMSG("No input data"); 802512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 803512cbf1dSJens Wiklander } 804512cbf1dSJens Wiklander 805512cbf1dSJens Wiklander switch (function) { 806512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 807512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 808512cbf1dSJens Wiklander res = TEE_CipherUpdate(proc->tee_op_handle, 809512cbf1dSJens Wiklander in_buf, in_size, 810512cbf1dSJens Wiklander out_buf, &out_size); 811512cbf1dSJens Wiklander output_data = true; 812512cbf1dSJens Wiklander rc = tee2pkcs_error(res); 813512cbf1dSJens Wiklander break; 814512cbf1dSJens Wiklander default: 815512cbf1dSJens Wiklander TEE_Panic(function); 816512cbf1dSJens Wiklander break; 817512cbf1dSJens Wiklander } 818512cbf1dSJens Wiklander break; 819512cbf1dSJens Wiklander 820512cbf1dSJens Wiklander default: 821512cbf1dSJens Wiklander TEE_Panic(proc->mecha_type); 822512cbf1dSJens Wiklander break; 823512cbf1dSJens Wiklander } 824512cbf1dSJens Wiklander 825512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_UPDATE) 826512cbf1dSJens Wiklander goto out; 827512cbf1dSJens Wiklander 828512cbf1dSJens Wiklander /* 829512cbf1dSJens Wiklander * Finalize (PKCS11_FUNC_STEP_ONESHOT/_FINAL) operation 830512cbf1dSJens Wiklander */ 831512cbf1dSJens Wiklander switch (session->processing->mecha_type) { 832689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 833689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 834689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 835689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 836689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 837689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 838689f4e5bSRuchika Gupta switch (function) { 839689f4e5bSRuchika Gupta case PKCS11_FUNCTION_SIGN: 840689f4e5bSRuchika Gupta res = TEE_MACComputeFinal(proc->tee_op_handle, 841689f4e5bSRuchika Gupta in_buf, in_size, out_buf, 842689f4e5bSRuchika Gupta &out_size); 843689f4e5bSRuchika Gupta output_data = true; 844689f4e5bSRuchika Gupta rc = tee2pkcs_error(res); 845689f4e5bSRuchika Gupta break; 846689f4e5bSRuchika Gupta case PKCS11_FUNCTION_VERIFY: 847689f4e5bSRuchika Gupta rc = input_sign_size_is_valid(proc, in2_size); 848689f4e5bSRuchika Gupta if (rc) 849689f4e5bSRuchika Gupta return rc; 850689f4e5bSRuchika Gupta res = TEE_MACCompareFinal(proc->tee_op_handle, 851689f4e5bSRuchika Gupta in_buf, in_size, in2_buf, 852689f4e5bSRuchika Gupta in2_size); 853689f4e5bSRuchika Gupta rc = tee2pkcs_error(res); 854689f4e5bSRuchika Gupta break; 855689f4e5bSRuchika Gupta default: 856689f4e5bSRuchika Gupta TEE_Panic(function); 857689f4e5bSRuchika Gupta break; 858689f4e5bSRuchika Gupta } 8592158ea6cSRuchika Gupta 860689f4e5bSRuchika Gupta break; 861689f4e5bSRuchika Gupta 862*70b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 863*70b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 864*70b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 865*70b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 866*70b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 867*70b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 868*70b6683bSVictor Chong assert(session->processing->extra_ctx); 869*70b6683bSVictor Chong hmac_len = *(uint32_t *)session->processing->extra_ctx; 870*70b6683bSVictor Chong 871*70b6683bSVictor Chong switch (function) { 872*70b6683bSVictor Chong case PKCS11_FUNCTION_SIGN: 873*70b6683bSVictor Chong if (out_size < hmac_len) { 874*70b6683bSVictor Chong /* inform client of required size */ 875*70b6683bSVictor Chong out_size = hmac_len; 876*70b6683bSVictor Chong output_data = true; 877*70b6683bSVictor Chong rc = PKCS11_CKR_BUFFER_TOO_SMALL; 878*70b6683bSVictor Chong goto out; 879*70b6683bSVictor Chong } 880*70b6683bSVictor Chong 881*70b6683bSVictor Chong res = TEE_MACComputeFinal(proc->tee_op_handle, 882*70b6683bSVictor Chong in_buf, in_size, 883*70b6683bSVictor Chong computed_mac, 884*70b6683bSVictor Chong &computed_mac_size); 885*70b6683bSVictor Chong if (res == TEE_SUCCESS) { 886*70b6683bSVictor Chong /* truncate to hmac_len */ 887*70b6683bSVictor Chong TEE_MemMove(out_buf, computed_mac, hmac_len); 888*70b6683bSVictor Chong output_data = true; 889*70b6683bSVictor Chong } 890*70b6683bSVictor Chong 891*70b6683bSVictor Chong /* inform client of required size */ 892*70b6683bSVictor Chong out_size = hmac_len; 893*70b6683bSVictor Chong rc = tee2pkcs_error(res); 894*70b6683bSVictor Chong break; 895*70b6683bSVictor Chong case PKCS11_FUNCTION_VERIFY: 896*70b6683bSVictor Chong /* must compute full MAC before comparing partial */ 897*70b6683bSVictor Chong res = TEE_MACComputeFinal(proc->tee_op_handle, in_buf, 898*70b6683bSVictor Chong in_size, computed_mac, 899*70b6683bSVictor Chong &computed_mac_size); 900*70b6683bSVictor Chong 901*70b6683bSVictor Chong if (!in2_size || in2_size > computed_mac_size) { 902*70b6683bSVictor Chong EMSG("Invalid signature size: %"PRIu32, 903*70b6683bSVictor Chong in2_size); 904*70b6683bSVictor Chong return PKCS11_CKR_SIGNATURE_LEN_RANGE; 905*70b6683bSVictor Chong } 906*70b6683bSVictor Chong 907*70b6683bSVictor Chong if (res == TEE_SUCCESS) { 908*70b6683bSVictor Chong /* 909*70b6683bSVictor Chong * Only the first in2_size bytes of the 910*70b6683bSVictor Chong * signature to be verified is passed in from 911*70b6683bSVictor Chong * caller 912*70b6683bSVictor Chong */ 913*70b6683bSVictor Chong if (TEE_MemCompare(in2_buf, computed_mac, 914*70b6683bSVictor Chong in2_size)) { 915*70b6683bSVictor Chong res = TEE_ERROR_MAC_INVALID; 916*70b6683bSVictor Chong } 917*70b6683bSVictor Chong } 918*70b6683bSVictor Chong 919*70b6683bSVictor Chong rc = tee2pkcs_error(res); 920*70b6683bSVictor Chong break; 921*70b6683bSVictor Chong default: 922*70b6683bSVictor Chong TEE_Panic(function); 923*70b6683bSVictor Chong break; 924*70b6683bSVictor Chong } 925*70b6683bSVictor Chong 926*70b6683bSVictor Chong break; 927*70b6683bSVictor Chong 928512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 929512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 930512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 931512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 932512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 933512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_ONESHOT && !in_buf) { 934512cbf1dSJens Wiklander EMSG("No input data"); 935512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 936512cbf1dSJens Wiklander } 937512cbf1dSJens Wiklander 938512cbf1dSJens Wiklander switch (function) { 939512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 940512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 941512cbf1dSJens Wiklander res = TEE_CipherDoFinal(proc->tee_op_handle, 942512cbf1dSJens Wiklander in_buf, in_size, 943512cbf1dSJens Wiklander out_buf, &out_size); 944512cbf1dSJens Wiklander output_data = true; 945512cbf1dSJens Wiklander rc = tee2pkcs_error(res); 946512cbf1dSJens Wiklander break; 947512cbf1dSJens Wiklander default: 948512cbf1dSJens Wiklander TEE_Panic(function); 949512cbf1dSJens Wiklander break; 950512cbf1dSJens Wiklander } 951512cbf1dSJens Wiklander break; 952512cbf1dSJens Wiklander default: 953512cbf1dSJens Wiklander TEE_Panic(proc->mecha_type); 954512cbf1dSJens Wiklander break; 955512cbf1dSJens Wiklander } 956512cbf1dSJens Wiklander 957512cbf1dSJens Wiklander out: 958512cbf1dSJens Wiklander if (output_data && 959512cbf1dSJens Wiklander (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) { 960512cbf1dSJens Wiklander switch (TEE_PARAM_TYPE_GET(ptypes, 2)) { 961512cbf1dSJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 962512cbf1dSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 963512cbf1dSJens Wiklander params[2].memref.size = out_size; 964512cbf1dSJens Wiklander break; 965512cbf1dSJens Wiklander default: 966512cbf1dSJens Wiklander rc = PKCS11_CKR_ARGUMENTS_BAD; 967512cbf1dSJens Wiklander break; 968512cbf1dSJens Wiklander } 969512cbf1dSJens Wiklander } 970512cbf1dSJens Wiklander 971512cbf1dSJens Wiklander return rc; 972512cbf1dSJens Wiklander } 97348799892SRuchika Gupta 97448799892SRuchika Gupta enum pkcs11_rc derive_key_by_symm_enc(struct pkcs11_session *session, 9758c499324SRuchika Gupta void **out_buf, uint32_t *out_size) 97648799892SRuchika Gupta { 97748799892SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 97848799892SRuchika Gupta TEE_Result res = TEE_ERROR_GENERIC; 97948799892SRuchika Gupta struct active_processing *proc = session->processing; 98048799892SRuchika Gupta struct input_data_ref *input = proc->extra_ctx; 98148799892SRuchika Gupta void *in_buf = NULL; 98248799892SRuchika Gupta uint32_t in_size = 0; 98348799892SRuchika Gupta 9848c499324SRuchika Gupta switch (proc->mecha_type) { 9858c499324SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 9868c499324SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 98748799892SRuchika Gupta if (!proc->extra_ctx) 98848799892SRuchika Gupta return PKCS11_CKR_ARGUMENTS_BAD; 98948799892SRuchika Gupta 99048799892SRuchika Gupta in_buf = input->data; 99148799892SRuchika Gupta in_size = input->size; 99248799892SRuchika Gupta 9938c499324SRuchika Gupta *out_size = in_size; 9948c499324SRuchika Gupta *out_buf = TEE_Malloc(*out_size, 0); 9958c499324SRuchika Gupta if (!*out_buf) 99648799892SRuchika Gupta return PKCS11_CKR_DEVICE_MEMORY; 99748799892SRuchika Gupta 9988c499324SRuchika Gupta res = TEE_CipherDoFinal(proc->tee_op_handle, in_buf, in_size, 9998c499324SRuchika Gupta *out_buf, out_size); 100048799892SRuchika Gupta rc = tee2pkcs_error(res); 100148799892SRuchika Gupta if (rc) 10028c499324SRuchika Gupta TEE_Free(*out_buf); 10038c499324SRuchika Gupta break; 10048c499324SRuchika Gupta default: 10058c499324SRuchika Gupta return PKCS11_CKR_MECHANISM_INVALID; 100648799892SRuchika Gupta } 100748799892SRuchika Gupta 100848799892SRuchika Gupta return rc; 100948799892SRuchika Gupta } 10105f80f270SRuchika Gupta 10115f80f270SRuchika Gupta enum pkcs11_rc wrap_data_by_symm_enc(struct pkcs11_session *session, 10125f80f270SRuchika Gupta void *data, uint32_t data_sz, 10135f80f270SRuchika Gupta void *out_buf, uint32_t *out_sz) 10145f80f270SRuchika Gupta { 10155f80f270SRuchika Gupta TEE_Result res = TEE_ERROR_GENERIC; 10165f80f270SRuchika Gupta struct active_processing *proc = session->processing; 10175f80f270SRuchika Gupta void *in_buf = NULL; 10185f80f270SRuchika Gupta uint32_t align = 0; 10195f80f270SRuchika Gupta uint32_t in_sz = data_sz; 10205f80f270SRuchika Gupta uint32_t tmp_sz = *out_sz; 10215f80f270SRuchika Gupta uint8_t *tmp_buf = out_buf; 10225f80f270SRuchika Gupta 10235f80f270SRuchika Gupta switch (proc->mecha_type) { 10245f80f270SRuchika Gupta case PKCS11_CKM_AES_ECB: 10255f80f270SRuchika Gupta case PKCS11_CKM_AES_CBC: 10265f80f270SRuchika Gupta align = data_sz % TEE_AES_BLOCK_SIZE; 10275f80f270SRuchika Gupta if (align) 10285f80f270SRuchika Gupta in_sz = data_sz + (TEE_AES_BLOCK_SIZE - align); 10295f80f270SRuchika Gupta 10305f80f270SRuchika Gupta if (*out_sz < in_sz) { 10315f80f270SRuchika Gupta *out_sz = in_sz; 10325f80f270SRuchika Gupta return PKCS11_CKR_BUFFER_TOO_SMALL; 10335f80f270SRuchika Gupta } 10345f80f270SRuchika Gupta 10355f80f270SRuchika Gupta if (align) { 10365f80f270SRuchika Gupta if (data_sz > TEE_AES_BLOCK_SIZE) { 10375f80f270SRuchika Gupta in_sz = data_sz - align; 10385f80f270SRuchika Gupta res = TEE_CipherUpdate(proc->tee_op_handle, 10395f80f270SRuchika Gupta data, in_sz, tmp_buf, 10405f80f270SRuchika Gupta &tmp_sz); 10415f80f270SRuchika Gupta if (res) { 10425f80f270SRuchika Gupta assert(res != TEE_ERROR_SHORT_BUFFER); 10435f80f270SRuchika Gupta return tee2pkcs_error(res); 10445f80f270SRuchika Gupta } 10455f80f270SRuchika Gupta tmp_buf += tmp_sz; 10465f80f270SRuchika Gupta tmp_sz = *out_sz - tmp_sz; 10475f80f270SRuchika Gupta } else { 10485f80f270SRuchika Gupta in_sz = 0; 10495f80f270SRuchika Gupta } 10505f80f270SRuchika Gupta 10515f80f270SRuchika Gupta in_buf = TEE_Malloc(TEE_AES_BLOCK_SIZE, 10525f80f270SRuchika Gupta TEE_MALLOC_FILL_ZERO); 10535f80f270SRuchika Gupta if (!in_buf) 10545f80f270SRuchika Gupta return PKCS11_CKR_DEVICE_MEMORY; 10555f80f270SRuchika Gupta 10565f80f270SRuchika Gupta TEE_MemMove(in_buf, (uint8_t *)data + in_sz, align); 10575f80f270SRuchika Gupta in_sz = TEE_AES_BLOCK_SIZE; 10585f80f270SRuchika Gupta } else { 10595f80f270SRuchika Gupta in_buf = data; 10605f80f270SRuchika Gupta in_sz = data_sz; 10615f80f270SRuchika Gupta } 10625f80f270SRuchika Gupta 10635f80f270SRuchika Gupta res = TEE_CipherDoFinal(proc->tee_op_handle, in_buf, in_sz, 10645f80f270SRuchika Gupta tmp_buf, &tmp_sz); 10655f80f270SRuchika Gupta if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) { 10665f80f270SRuchika Gupta *out_sz = tmp_sz; 10675f80f270SRuchika Gupta if (align) 10685f80f270SRuchika Gupta *out_sz += tmp_buf - (uint8_t *)out_buf; 10695f80f270SRuchika Gupta } 10705f80f270SRuchika Gupta 10715f80f270SRuchika Gupta if (align) 10725f80f270SRuchika Gupta TEE_Free(in_buf); 10735f80f270SRuchika Gupta 10745f80f270SRuchika Gupta return tee2pkcs_error(res); 10755f80f270SRuchika Gupta default: 10765f80f270SRuchika Gupta return PKCS11_CKR_MECHANISM_INVALID; 10775f80f270SRuchika Gupta } 10785f80f270SRuchika Gupta 10795f80f270SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 10805f80f270SRuchika Gupta } 10813668310bSRuchika Gupta 10823668310bSRuchika Gupta enum pkcs11_rc unwrap_key_by_symm(struct pkcs11_session *session, void *data, 10833668310bSRuchika Gupta uint32_t data_sz, void **out_buf, 10843668310bSRuchika Gupta uint32_t *out_sz) 10853668310bSRuchika Gupta { 10863668310bSRuchika Gupta TEE_Result res = TEE_ERROR_GENERIC; 10873668310bSRuchika Gupta struct active_processing *proc = session->processing; 10883668310bSRuchika Gupta 10893668310bSRuchika Gupta if (input_data_size_is_valid(proc, PKCS11_FUNCTION_DECRYPT, data_sz)) 10903668310bSRuchika Gupta return PKCS11_CKR_WRAPPED_KEY_LEN_RANGE; 10913668310bSRuchika Gupta 10923668310bSRuchika Gupta switch (proc->mecha_type) { 10933668310bSRuchika Gupta case PKCS11_CKM_AES_ECB: 10943668310bSRuchika Gupta case PKCS11_CKM_AES_CBC: 10953668310bSRuchika Gupta *out_sz = 0; 10963668310bSRuchika Gupta res = TEE_CipherDoFinal(proc->tee_op_handle, data, data_sz, 10973668310bSRuchika Gupta NULL, out_sz); 10983668310bSRuchika Gupta if (res != TEE_ERROR_SHORT_BUFFER) { 10993668310bSRuchika Gupta DMSG("TEE_CipherDoFinal() issue: %#"PRIx32, res); 11003668310bSRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 11013668310bSRuchika Gupta } 11023668310bSRuchika Gupta 11033668310bSRuchika Gupta *out_buf = TEE_Malloc(*out_sz, TEE_MALLOC_FILL_ZERO); 11043668310bSRuchika Gupta if (!*out_buf) 11053668310bSRuchika Gupta return PKCS11_CKR_DEVICE_MEMORY; 11063668310bSRuchika Gupta 11073668310bSRuchika Gupta res = TEE_CipherDoFinal(proc->tee_op_handle, data, data_sz, 11083668310bSRuchika Gupta *out_buf, out_sz); 11093668310bSRuchika Gupta if (tee2pkcs_error(res)) { 11103668310bSRuchika Gupta TEE_Free(*out_buf); 11113668310bSRuchika Gupta *out_buf = NULL; 11123668310bSRuchika Gupta return PKCS11_CKR_WRAPPED_KEY_INVALID; 11133668310bSRuchika Gupta } 11143668310bSRuchika Gupta break; 11153668310bSRuchika Gupta default: 11163668310bSRuchika Gupta return PKCS11_CKR_MECHANISM_INVALID; 11173668310bSRuchika Gupta } 11183668310bSRuchika Gupta 11193668310bSRuchika Gupta return PKCS11_CKR_OK; 11203668310bSRuchika Gupta } 1121