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 */ 320ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC: 33689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 34689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 35689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 36689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 37689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 38689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 390ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC_GENERAL: 4070b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 4170b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 4270b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 4370b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 4470b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 4570b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 466f6d5e75SVictor Chong /* Ciphering */ 47512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 48512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 49512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 50512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 51*63778faaSEtienne Carriere case PKCS11_CKM_AES_GCM: 5248799892SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 5348799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 54512cbf1dSJens Wiklander return true; 55512cbf1dSJens Wiklander default: 56512cbf1dSJens Wiklander return false; 57512cbf1dSJens Wiklander } 58512cbf1dSJens Wiklander } 59512cbf1dSJens Wiklander 60512cbf1dSJens Wiklander static enum pkcs11_rc 61512cbf1dSJens Wiklander pkcs2tee_algorithm(uint32_t *tee_id, struct pkcs11_attribute_head *proc_params) 62512cbf1dSJens Wiklander { 63512cbf1dSJens Wiklander static const struct { 64512cbf1dSJens Wiklander enum pkcs11_mechanism_id mech_id; 65512cbf1dSJens Wiklander uint32_t tee_id; 66512cbf1dSJens Wiklander } pkcs2tee_algo[] = { 67512cbf1dSJens Wiklander /* AES flavors */ 68512cbf1dSJens Wiklander { PKCS11_CKM_AES_ECB, TEE_ALG_AES_ECB_NOPAD }, 69512cbf1dSJens Wiklander { PKCS11_CKM_AES_CBC, TEE_ALG_AES_CBC_NOPAD }, 7048799892SRuchika Gupta { PKCS11_CKM_AES_ECB_ENCRYPT_DATA, TEE_ALG_AES_ECB_NOPAD }, 7148799892SRuchika Gupta { PKCS11_CKM_AES_CBC_ENCRYPT_DATA, TEE_ALG_AES_CBC_NOPAD }, 72512cbf1dSJens Wiklander { PKCS11_CKM_AES_CTR, TEE_ALG_AES_CTR }, 73512cbf1dSJens Wiklander { PKCS11_CKM_AES_CTS, TEE_ALG_AES_CTS }, 74*63778faaSEtienne Carriere { PKCS11_CKM_AES_GCM, TEE_ALG_AES_GCM }, 750ef6b144SVictor Chong { PKCS11_CKM_AES_CMAC, TEE_ALG_AES_CMAC }, 760ef6b144SVictor Chong { PKCS11_CKM_AES_CMAC_GENERAL, TEE_ALG_AES_CMAC }, 77689f4e5bSRuchika Gupta /* HMAC flavors */ 78689f4e5bSRuchika Gupta { PKCS11_CKM_MD5_HMAC, TEE_ALG_HMAC_MD5 }, 79689f4e5bSRuchika Gupta { PKCS11_CKM_SHA_1_HMAC, TEE_ALG_HMAC_SHA1 }, 80689f4e5bSRuchika Gupta { PKCS11_CKM_SHA224_HMAC, TEE_ALG_HMAC_SHA224 }, 81689f4e5bSRuchika Gupta { PKCS11_CKM_SHA256_HMAC, TEE_ALG_HMAC_SHA256 }, 82689f4e5bSRuchika Gupta { PKCS11_CKM_SHA384_HMAC, TEE_ALG_HMAC_SHA384 }, 83689f4e5bSRuchika Gupta { PKCS11_CKM_SHA512_HMAC, TEE_ALG_HMAC_SHA512 }, 8470b6683bSVictor Chong { PKCS11_CKM_MD5_HMAC_GENERAL, TEE_ALG_HMAC_MD5 }, 8570b6683bSVictor Chong { PKCS11_CKM_SHA_1_HMAC_GENERAL, TEE_ALG_HMAC_SHA1 }, 8670b6683bSVictor Chong { PKCS11_CKM_SHA224_HMAC_GENERAL, TEE_ALG_HMAC_SHA224 }, 8770b6683bSVictor Chong { PKCS11_CKM_SHA256_HMAC_GENERAL, TEE_ALG_HMAC_SHA256 }, 8870b6683bSVictor Chong { PKCS11_CKM_SHA384_HMAC_GENERAL, TEE_ALG_HMAC_SHA384 }, 8970b6683bSVictor Chong { PKCS11_CKM_SHA512_HMAC_GENERAL, TEE_ALG_HMAC_SHA512 }, 90512cbf1dSJens Wiklander }; 91512cbf1dSJens Wiklander size_t n = 0; 92512cbf1dSJens Wiklander 93512cbf1dSJens Wiklander for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) { 94512cbf1dSJens Wiklander if (proc_params->id == pkcs2tee_algo[n].mech_id) { 95512cbf1dSJens Wiklander *tee_id = pkcs2tee_algo[n].tee_id; 96512cbf1dSJens Wiklander return PKCS11_CKR_OK; 97512cbf1dSJens Wiklander } 98512cbf1dSJens Wiklander } 99512cbf1dSJens Wiklander 100512cbf1dSJens Wiklander return PKCS11_RV_NOT_IMPLEMENTED; 101512cbf1dSJens Wiklander } 102512cbf1dSJens Wiklander 103512cbf1dSJens Wiklander static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type, 104512cbf1dSJens Wiklander struct pkcs11_object *obj) 105512cbf1dSJens Wiklander { 106512cbf1dSJens Wiklander static const struct { 107512cbf1dSJens Wiklander enum pkcs11_key_type key_type; 108512cbf1dSJens Wiklander uint32_t tee_id; 109512cbf1dSJens Wiklander } pkcs2tee_key_type[] = { 110512cbf1dSJens Wiklander { PKCS11_CKK_AES, TEE_TYPE_AES }, 111512cbf1dSJens Wiklander { PKCS11_CKK_GENERIC_SECRET, TEE_TYPE_GENERIC_SECRET }, 112512cbf1dSJens Wiklander { PKCS11_CKK_MD5_HMAC, TEE_TYPE_HMAC_MD5 }, 113512cbf1dSJens Wiklander { PKCS11_CKK_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 }, 114512cbf1dSJens Wiklander { PKCS11_CKK_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 }, 115512cbf1dSJens Wiklander { PKCS11_CKK_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 }, 116512cbf1dSJens Wiklander { PKCS11_CKK_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 }, 117512cbf1dSJens Wiklander { PKCS11_CKK_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 }, 118512cbf1dSJens Wiklander }; 119512cbf1dSJens Wiklander size_t n = 0; 120512cbf1dSJens Wiklander enum pkcs11_key_type key_type = get_key_type(obj->attributes); 121512cbf1dSJens Wiklander 122512cbf1dSJens Wiklander assert(get_class(obj->attributes) == PKCS11_CKO_SECRET_KEY); 123512cbf1dSJens Wiklander 124512cbf1dSJens Wiklander for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) { 125512cbf1dSJens Wiklander if (pkcs2tee_key_type[n].key_type == key_type) { 126512cbf1dSJens Wiklander *tee_type = pkcs2tee_key_type[n].tee_id; 127512cbf1dSJens Wiklander return PKCS11_CKR_OK; 128512cbf1dSJens Wiklander } 129512cbf1dSJens Wiklander } 130512cbf1dSJens Wiklander 131512cbf1dSJens Wiklander return PKCS11_RV_NOT_FOUND; 132512cbf1dSJens Wiklander } 133512cbf1dSJens Wiklander 134de94d6f8SRuchika Gupta static enum pkcs11_rc pkcsmech2tee_key_type(uint32_t *tee_type, 135de94d6f8SRuchika Gupta enum pkcs11_mechanism_id mech_id) 136de94d6f8SRuchika Gupta { 137de94d6f8SRuchika Gupta static const struct { 138de94d6f8SRuchika Gupta enum pkcs11_mechanism_id mech; 139de94d6f8SRuchika Gupta uint32_t tee_id; 140de94d6f8SRuchika Gupta } pkcs2tee_key_type[] = { 141de94d6f8SRuchika Gupta { PKCS11_CKM_MD5_HMAC, TEE_TYPE_HMAC_MD5 }, 142de94d6f8SRuchika Gupta { PKCS11_CKM_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 }, 143de94d6f8SRuchika Gupta { PKCS11_CKM_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 }, 144de94d6f8SRuchika Gupta { PKCS11_CKM_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 }, 145de94d6f8SRuchika Gupta { PKCS11_CKM_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 }, 146de94d6f8SRuchika Gupta { PKCS11_CKM_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 }, 14770b6683bSVictor Chong { PKCS11_CKM_MD5_HMAC_GENERAL, TEE_TYPE_HMAC_MD5 }, 14870b6683bSVictor Chong { PKCS11_CKM_SHA_1_HMAC_GENERAL, TEE_TYPE_HMAC_SHA1 }, 14970b6683bSVictor Chong { PKCS11_CKM_SHA224_HMAC_GENERAL, TEE_TYPE_HMAC_SHA224 }, 15070b6683bSVictor Chong { PKCS11_CKM_SHA256_HMAC_GENERAL, TEE_TYPE_HMAC_SHA256 }, 15170b6683bSVictor Chong { PKCS11_CKM_SHA384_HMAC_GENERAL, TEE_TYPE_HMAC_SHA384 }, 15270b6683bSVictor Chong { PKCS11_CKM_SHA512_HMAC_GENERAL, TEE_TYPE_HMAC_SHA512 }, 153de94d6f8SRuchika Gupta }; 154de94d6f8SRuchika Gupta size_t n = 0; 155de94d6f8SRuchika Gupta 156de94d6f8SRuchika Gupta for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) { 157de94d6f8SRuchika Gupta if (pkcs2tee_key_type[n].mech == mech_id) { 158de94d6f8SRuchika Gupta *tee_type = pkcs2tee_key_type[n].tee_id; 159de94d6f8SRuchika Gupta return PKCS11_CKR_OK; 160de94d6f8SRuchika Gupta } 161de94d6f8SRuchika Gupta } 162de94d6f8SRuchika Gupta 163de94d6f8SRuchika Gupta return PKCS11_RV_NOT_FOUND; 164de94d6f8SRuchika Gupta } 165de94d6f8SRuchika Gupta 1662158ea6cSRuchika Gupta static enum pkcs11_rc hmac_to_tee_hash(uint32_t *algo, 1672158ea6cSRuchika Gupta enum pkcs11_mechanism_id mech_id) 1682158ea6cSRuchika Gupta { 1692158ea6cSRuchika Gupta static const struct { 1702158ea6cSRuchika Gupta enum pkcs11_mechanism_id mech; 1712158ea6cSRuchika Gupta uint32_t tee_id; 1722158ea6cSRuchika Gupta } hmac_hash[] = { 1732158ea6cSRuchika Gupta { PKCS11_CKM_MD5_HMAC, TEE_ALG_MD5 }, 1742158ea6cSRuchika Gupta { PKCS11_CKM_SHA_1_HMAC, TEE_ALG_SHA1 }, 1752158ea6cSRuchika Gupta { PKCS11_CKM_SHA224_HMAC, TEE_ALG_SHA224 }, 1762158ea6cSRuchika Gupta { PKCS11_CKM_SHA256_HMAC, TEE_ALG_SHA256 }, 1772158ea6cSRuchika Gupta { PKCS11_CKM_SHA384_HMAC, TEE_ALG_SHA384 }, 1782158ea6cSRuchika Gupta { PKCS11_CKM_SHA512_HMAC, TEE_ALG_SHA512 }, 17970b6683bSVictor Chong { PKCS11_CKM_MD5_HMAC_GENERAL, TEE_ALG_MD5 }, 18070b6683bSVictor Chong { PKCS11_CKM_SHA_1_HMAC_GENERAL, TEE_ALG_SHA1 }, 18170b6683bSVictor Chong { PKCS11_CKM_SHA224_HMAC_GENERAL, TEE_ALG_SHA224 }, 18270b6683bSVictor Chong { PKCS11_CKM_SHA256_HMAC_GENERAL, TEE_ALG_SHA256 }, 18370b6683bSVictor Chong { PKCS11_CKM_SHA384_HMAC_GENERAL, TEE_ALG_SHA384 }, 18470b6683bSVictor Chong { PKCS11_CKM_SHA512_HMAC_GENERAL, TEE_ALG_SHA512 }, 1852158ea6cSRuchika Gupta }; 1862158ea6cSRuchika Gupta size_t n = 0; 1872158ea6cSRuchika Gupta 1882158ea6cSRuchika Gupta for (n = 0; n < ARRAY_SIZE(hmac_hash); n++) { 1892158ea6cSRuchika Gupta if (hmac_hash[n].mech == mech_id) { 1902158ea6cSRuchika Gupta *algo = hmac_hash[n].tee_id; 1912158ea6cSRuchika Gupta return PKCS11_CKR_OK; 1922158ea6cSRuchika Gupta } 1932158ea6cSRuchika Gupta } 1942158ea6cSRuchika Gupta 1952158ea6cSRuchika Gupta return PKCS11_RV_NOT_FOUND; 1962158ea6cSRuchika Gupta } 1972158ea6cSRuchika Gupta 198512cbf1dSJens Wiklander static enum pkcs11_rc 199512cbf1dSJens Wiklander allocate_tee_operation(struct pkcs11_session *session, 200512cbf1dSJens Wiklander enum processing_func function, 201512cbf1dSJens Wiklander struct pkcs11_attribute_head *params, 202512cbf1dSJens Wiklander struct pkcs11_object *obj) 203512cbf1dSJens Wiklander { 204512cbf1dSJens Wiklander uint32_t size = (uint32_t)get_object_key_bit_size(obj); 205460ba621SRuchika Gupta uint32_t key_size = size / 8; 206512cbf1dSJens Wiklander uint32_t algo = 0; 207512cbf1dSJens Wiklander uint32_t mode = 0; 208460ba621SRuchika Gupta uint32_t max_key_size = 0; 209460ba621SRuchika Gupta uint32_t min_key_size = 0; 210512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 211512cbf1dSJens Wiklander 212*63778faaSEtienne Carriere assert(session->processing->tee_op_handle == TEE_HANDLE_NULL && 213*63778faaSEtienne Carriere session->processing->tee_op_handle2 == TEE_HANDLE_NULL); 214512cbf1dSJens Wiklander 215512cbf1dSJens Wiklander if (pkcs2tee_algorithm(&algo, params)) 216512cbf1dSJens Wiklander return PKCS11_CKR_FUNCTION_FAILED; 217512cbf1dSJens Wiklander 218512cbf1dSJens Wiklander /* Sign/Verify with AES or generic key relate to TEE MAC operation */ 219689f4e5bSRuchika Gupta switch (params->id) { 220689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 221689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 222689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 223689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 224689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 225689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 22670b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 22770b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 22870b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 22970b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 23070b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 23170b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 2322d0cd829SRuchika Gupta mechanism_supported_key_sizes_bytes(params->id, &min_key_size, 233460ba621SRuchika Gupta &max_key_size); 234460ba621SRuchika Gupta if (key_size < min_key_size) 235460ba621SRuchika Gupta return PKCS11_CKR_KEY_SIZE_RANGE; 2362158ea6cSRuchika Gupta 2372158ea6cSRuchika Gupta /* 2382158ea6cSRuchika Gupta * If size of generic key is greater than the size 2392158ea6cSRuchika Gupta * supported by TEE API, this is not considered an 2402158ea6cSRuchika Gupta * error. When loading TEE key, we will hash the key 2412158ea6cSRuchika Gupta * to generate the appropriate key for HMAC operation. 2422158ea6cSRuchika Gupta * This key size will not be greater than the 2432158ea6cSRuchika Gupta * max_key_size. So we can use max_key_size for 2442158ea6cSRuchika Gupta * TEE_AllocateOperation(). 2452158ea6cSRuchika Gupta */ 2462158ea6cSRuchika Gupta if (key_size > max_key_size) 2472158ea6cSRuchika Gupta size = max_key_size * 8; 2482158ea6cSRuchika Gupta 249689f4e5bSRuchika Gupta mode = TEE_MODE_MAC; 250689f4e5bSRuchika Gupta break; 2510ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC: 2520ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC_GENERAL: 2530ef6b144SVictor Chong mode = TEE_MODE_MAC; 2540ef6b144SVictor Chong break; 255689f4e5bSRuchika Gupta default: 256512cbf1dSJens Wiklander pkcs2tee_mode(&mode, function); 257689f4e5bSRuchika Gupta break; 258689f4e5bSRuchika Gupta } 259512cbf1dSJens Wiklander 260512cbf1dSJens Wiklander res = TEE_AllocateOperation(&session->processing->tee_op_handle, 261512cbf1dSJens Wiklander algo, mode, size); 262512cbf1dSJens Wiklander if (res) 263512cbf1dSJens Wiklander EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32, 264512cbf1dSJens Wiklander algo, mode, size); 265512cbf1dSJens Wiklander 266512cbf1dSJens Wiklander if (res == TEE_ERROR_NOT_SUPPORTED) 267512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_INVALID; 268512cbf1dSJens Wiklander 269*63778faaSEtienne Carriere if (res == TEE_SUCCESS || params->id == PKCS11_CKM_AES_GCM) { 270*63778faaSEtienne Carriere /* 271*63778faaSEtienne Carriere * Allocate a 2nd operation handler to save the operation state 272*63778faaSEtienne Carriere * on AES GCM one-shot processing that queries the output 273*63778faaSEtienne Carriere * buffer size. This is needed as we will need to reset and 274*63778faaSEtienne Carriere * re-init the TEE operation once we report the expected output 275*63778faaSEtienne Carriere * buffer size to client that we call again the AE processing 276*63778faaSEtienne Carriere * function. 277*63778faaSEtienne Carriere */ 278*63778faaSEtienne Carriere TEE_OperationHandle *hdl = &session->processing->tee_op_handle2; 279*63778faaSEtienne Carriere 280*63778faaSEtienne Carriere res = TEE_AllocateOperation(hdl, algo, mode, size); 281*63778faaSEtienne Carriere } 282*63778faaSEtienne Carriere 283512cbf1dSJens Wiklander return tee2pkcs_error(res); 284512cbf1dSJens Wiklander } 285512cbf1dSJens Wiklander 2862158ea6cSRuchika Gupta static enum pkcs11_rc hash_secret_helper(enum pkcs11_mechanism_id mech_id, 2872158ea6cSRuchika Gupta struct pkcs11_object *obj, 2882158ea6cSRuchika Gupta TEE_Attribute *tee_attr, 2892158ea6cSRuchika Gupta void **ctx, 2902158ea6cSRuchika Gupta size_t *object_size_bits) 2912158ea6cSRuchika Gupta { 2922158ea6cSRuchika Gupta uint32_t algo = 0; 2932158ea6cSRuchika Gupta void *hash_ptr = NULL; 2942158ea6cSRuchika Gupta uint32_t hash_size = 0; 2952158ea6cSRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK; 2962158ea6cSRuchika Gupta 2972158ea6cSRuchika Gupta rc = hmac_to_tee_hash(&algo, mech_id); 2982158ea6cSRuchika Gupta if (rc) 2992158ea6cSRuchika Gupta return rc; 3002158ea6cSRuchika Gupta 3012158ea6cSRuchika Gupta hash_size = TEE_ALG_GET_DIGEST_SIZE(algo); 3022158ea6cSRuchika Gupta hash_ptr = TEE_Malloc(hash_size, 0); 3032158ea6cSRuchika Gupta if (!hash_ptr) 3042158ea6cSRuchika Gupta return PKCS11_CKR_DEVICE_MEMORY; 3052158ea6cSRuchika Gupta 3062158ea6cSRuchika Gupta rc = pkcs2tee_load_hashed_attr(tee_attr, TEE_ATTR_SECRET_VALUE, obj, 3072158ea6cSRuchika Gupta PKCS11_CKA_VALUE, algo, hash_ptr, 3082158ea6cSRuchika Gupta &hash_size); 3092158ea6cSRuchika Gupta if (rc) { 3102158ea6cSRuchika Gupta EMSG("No secret/hash error"); 3112158ea6cSRuchika Gupta TEE_Free(hash_ptr); 3122158ea6cSRuchika Gupta return rc; 3132158ea6cSRuchika Gupta } 3142158ea6cSRuchika Gupta 3152158ea6cSRuchika Gupta *ctx = hash_ptr; 3162158ea6cSRuchika Gupta 3172158ea6cSRuchika Gupta *object_size_bits = hash_size * 8; 3182158ea6cSRuchika Gupta 3192158ea6cSRuchika Gupta return PKCS11_CKR_OK; 3202158ea6cSRuchika Gupta } 3212158ea6cSRuchika Gupta 322512cbf1dSJens Wiklander static enum pkcs11_rc load_tee_key(struct pkcs11_session *session, 323de94d6f8SRuchika Gupta struct pkcs11_object *obj, 324de94d6f8SRuchika Gupta struct pkcs11_attribute_head *proc_params) 325512cbf1dSJens Wiklander { 326512cbf1dSJens Wiklander TEE_Attribute tee_attr = { }; 327512cbf1dSJens Wiklander size_t object_size = 0; 328512cbf1dSJens Wiklander uint32_t tee_key_type = 0; 329de94d6f8SRuchika Gupta enum pkcs11_key_type key_type = 0; 330512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 331512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 3322158ea6cSRuchika Gupta uint32_t max_key_size = 0; 3332158ea6cSRuchika Gupta uint32_t min_key_size = 0; 334512cbf1dSJens Wiklander 335512cbf1dSJens Wiklander if (obj->key_handle != TEE_HANDLE_NULL) { 336512cbf1dSJens Wiklander /* Key was already loaded and fits current need */ 337512cbf1dSJens Wiklander goto key_ready; 338512cbf1dSJens Wiklander } 339512cbf1dSJens Wiklander 3402158ea6cSRuchika Gupta object_size = get_object_key_bit_size(obj); 3412158ea6cSRuchika Gupta if (!object_size) 3422158ea6cSRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 343512cbf1dSJens Wiklander 344de94d6f8SRuchika Gupta switch (proc_params->id) { 345de94d6f8SRuchika Gupta case PKCS11_CKM_MD5_HMAC: 346de94d6f8SRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 347de94d6f8SRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 348de94d6f8SRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 349de94d6f8SRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 350de94d6f8SRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 35170b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 35270b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 35370b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 35470b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 35570b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 35670b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 357de94d6f8SRuchika Gupta key_type = get_key_type(obj->attributes); 358de94d6f8SRuchika Gupta /* 359de94d6f8SRuchika Gupta * If Object Key type is PKCS11_CKK_GENERIC_SECRET, 360de94d6f8SRuchika Gupta * determine the tee_key_type using the 361de94d6f8SRuchika Gupta * mechanism instead of object key_type. 362de94d6f8SRuchika Gupta */ 363de94d6f8SRuchika Gupta if (key_type == PKCS11_CKK_GENERIC_SECRET) 364de94d6f8SRuchika Gupta rc = pkcsmech2tee_key_type(&tee_key_type, 365de94d6f8SRuchika Gupta proc_params->id); 366de94d6f8SRuchika Gupta else 367512cbf1dSJens Wiklander rc = pkcs2tee_key_type(&tee_key_type, obj); 368de94d6f8SRuchika Gupta 369512cbf1dSJens Wiklander if (rc) 370512cbf1dSJens Wiklander return rc; 371512cbf1dSJens Wiklander 3722d0cd829SRuchika Gupta mechanism_supported_key_sizes_bytes(proc_params->id, 3732158ea6cSRuchika Gupta &min_key_size, 3742158ea6cSRuchika Gupta &max_key_size); 3752158ea6cSRuchika Gupta 3762158ea6cSRuchika Gupta if ((object_size / 8) > max_key_size) { 3772158ea6cSRuchika Gupta rc = hash_secret_helper(proc_params->id, obj, &tee_attr, 3782158ea6cSRuchika Gupta &session->processing->extra_ctx, 3792158ea6cSRuchika Gupta &object_size); 3802158ea6cSRuchika Gupta if (rc) 3812158ea6cSRuchika Gupta return rc; 3822158ea6cSRuchika Gupta } else { 3832158ea6cSRuchika Gupta if (!pkcs2tee_load_attr(&tee_attr, 3842158ea6cSRuchika Gupta TEE_ATTR_SECRET_VALUE, 3852158ea6cSRuchika Gupta obj, 3862158ea6cSRuchika Gupta PKCS11_CKA_VALUE)) { 3872158ea6cSRuchika Gupta EMSG("No secret found"); 3882158ea6cSRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED; 3892158ea6cSRuchika Gupta } 3902158ea6cSRuchika Gupta } 3912158ea6cSRuchika Gupta break; 3922158ea6cSRuchika Gupta 3932158ea6cSRuchika Gupta default: 3942158ea6cSRuchika Gupta rc = pkcs2tee_key_type(&tee_key_type, obj); 3952158ea6cSRuchika Gupta if (rc) 3962158ea6cSRuchika Gupta return rc; 3972158ea6cSRuchika Gupta 3982158ea6cSRuchika Gupta if (!pkcs2tee_load_attr(&tee_attr, TEE_ATTR_SECRET_VALUE, 3992158ea6cSRuchika Gupta obj, PKCS11_CKA_VALUE)) { 4002158ea6cSRuchika Gupta EMSG("No secret found"); 4012158ea6cSRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED; 4022158ea6cSRuchika Gupta } 4032158ea6cSRuchika Gupta break; 4042158ea6cSRuchika Gupta } 405512cbf1dSJens Wiklander 406512cbf1dSJens Wiklander res = TEE_AllocateTransientObject(tee_key_type, object_size, 407512cbf1dSJens Wiklander &obj->key_handle); 408512cbf1dSJens Wiklander if (res) { 409512cbf1dSJens Wiklander DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 410512cbf1dSJens Wiklander return tee2pkcs_error(res); 411512cbf1dSJens Wiklander } 412512cbf1dSJens Wiklander 413512cbf1dSJens Wiklander res = TEE_PopulateTransientObject(obj->key_handle, &tee_attr, 1); 414512cbf1dSJens Wiklander if (res) { 415512cbf1dSJens Wiklander DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res); 416512cbf1dSJens Wiklander goto error; 417512cbf1dSJens Wiklander } 418512cbf1dSJens Wiklander 419512cbf1dSJens Wiklander key_ready: 420512cbf1dSJens Wiklander res = TEE_SetOperationKey(session->processing->tee_op_handle, 421512cbf1dSJens Wiklander obj->key_handle); 422512cbf1dSJens Wiklander if (res) { 423512cbf1dSJens Wiklander DMSG("TEE_SetOperationKey failed, %#"PRIx32, res); 424512cbf1dSJens Wiklander goto error; 425512cbf1dSJens Wiklander } 426512cbf1dSJens Wiklander 427512cbf1dSJens Wiklander return PKCS11_CKR_OK; 428512cbf1dSJens Wiklander 429512cbf1dSJens Wiklander error: 430512cbf1dSJens Wiklander TEE_FreeTransientObject(obj->key_handle); 431512cbf1dSJens Wiklander obj->key_handle = TEE_HANDLE_NULL; 432512cbf1dSJens Wiklander 433512cbf1dSJens Wiklander return tee2pkcs_error(res); 434512cbf1dSJens Wiklander } 435512cbf1dSJens Wiklander 436512cbf1dSJens Wiklander static enum pkcs11_rc 43748799892SRuchika Gupta tee_init_derive_symm(struct active_processing *processing, 43848799892SRuchika Gupta struct pkcs11_attribute_head *proc_params) 43948799892SRuchika Gupta { 44048799892SRuchika Gupta struct serialargs args = { }; 44148799892SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK; 44248799892SRuchika Gupta struct input_data_ref *param = NULL; 44348799892SRuchika Gupta void *iv = NULL; 44448799892SRuchika Gupta 44548799892SRuchika Gupta if (!proc_params) 44648799892SRuchika Gupta return PKCS11_CKR_ARGUMENTS_BAD; 44748799892SRuchika Gupta 44848799892SRuchika Gupta param = TEE_Malloc(sizeof(struct input_data_ref), TEE_MALLOC_FILL_ZERO); 44948799892SRuchika Gupta if (!param) 45048799892SRuchika Gupta return PKCS11_CKR_DEVICE_MEMORY; 45148799892SRuchika Gupta 45248799892SRuchika Gupta serialargs_init(&args, proc_params->data, proc_params->size); 45348799892SRuchika Gupta 45448799892SRuchika Gupta switch (proc_params->id) { 45548799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 45648799892SRuchika Gupta rc = serialargs_get_ptr(&args, &iv, 16); 45748799892SRuchika Gupta if (rc) 45848799892SRuchika Gupta goto err; 45948799892SRuchika Gupta break; 46048799892SRuchika Gupta default: 46148799892SRuchika Gupta break; 46248799892SRuchika Gupta } 46348799892SRuchika Gupta 46448799892SRuchika Gupta rc = serialargs_get(&args, ¶m->size, sizeof(uint32_t)); 46548799892SRuchika Gupta if (rc) 46648799892SRuchika Gupta goto err; 46748799892SRuchika Gupta 46848799892SRuchika Gupta rc = serialargs_get_ptr(&args, ¶m->data, param->size); 46948799892SRuchika Gupta if (rc) 47048799892SRuchika Gupta goto err; 47148799892SRuchika Gupta 47248799892SRuchika Gupta if (serialargs_remaining_bytes(&args)) { 47348799892SRuchika Gupta rc = PKCS11_CKR_ARGUMENTS_BAD; 47448799892SRuchika Gupta goto err; 47548799892SRuchika Gupta } 47648799892SRuchika Gupta 47748799892SRuchika Gupta processing->extra_ctx = param; 47848799892SRuchika Gupta 47948799892SRuchika Gupta switch (proc_params->id) { 48048799892SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 48148799892SRuchika Gupta if (param->size % TEE_AES_BLOCK_SIZE) { 48248799892SRuchika Gupta rc = PKCS11_CKR_DATA_LEN_RANGE; 48348799892SRuchika Gupta goto err; 48448799892SRuchika Gupta } 48548799892SRuchika Gupta TEE_CipherInit(processing->tee_op_handle, NULL, 0); 48648799892SRuchika Gupta break; 48748799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 48848799892SRuchika Gupta if (param->size % TEE_AES_BLOCK_SIZE) { 48948799892SRuchika Gupta rc = PKCS11_CKR_DATA_LEN_RANGE; 49048799892SRuchika Gupta goto err; 49148799892SRuchika Gupta } 49248799892SRuchika Gupta TEE_CipherInit(processing->tee_op_handle, iv, 16); 49348799892SRuchika Gupta break; 49448799892SRuchika Gupta default: 49548799892SRuchika Gupta TEE_Panic(proc_params->id); 49648799892SRuchika Gupta break; 49748799892SRuchika Gupta } 49848799892SRuchika Gupta 49948799892SRuchika Gupta return PKCS11_CKR_OK; 50048799892SRuchika Gupta 50148799892SRuchika Gupta err: 50248799892SRuchika Gupta processing->extra_ctx = NULL; 50348799892SRuchika Gupta TEE_Free(param); 50448799892SRuchika Gupta return rc; 50548799892SRuchika Gupta } 50648799892SRuchika Gupta 50748799892SRuchika Gupta static enum pkcs11_rc 50870b6683bSVictor Chong input_hmac_len_is_valid(struct pkcs11_attribute_head *proc_params, 50970b6683bSVictor Chong uint32_t hmac_len) 51070b6683bSVictor Chong { 51170b6683bSVictor Chong uint32_t sign_sz = 0; 51270b6683bSVictor Chong 51370b6683bSVictor Chong switch (proc_params->id) { 51470b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 51570b6683bSVictor Chong sign_sz = TEE_MD5_HASH_SIZE; 51670b6683bSVictor Chong break; 51770b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 51870b6683bSVictor Chong sign_sz = TEE_SHA1_HASH_SIZE; 51970b6683bSVictor Chong break; 52070b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 52170b6683bSVictor Chong sign_sz = TEE_SHA224_HASH_SIZE; 52270b6683bSVictor Chong break; 52370b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 52470b6683bSVictor Chong sign_sz = TEE_SHA256_HASH_SIZE; 52570b6683bSVictor Chong break; 52670b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 52770b6683bSVictor Chong sign_sz = TEE_SHA384_HASH_SIZE; 52870b6683bSVictor Chong break; 52970b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 53070b6683bSVictor Chong sign_sz = TEE_SHA512_HASH_SIZE; 53170b6683bSVictor Chong break; 5320ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC_GENERAL: 5330ef6b144SVictor Chong sign_sz = TEE_AES_BLOCK_SIZE; 5340ef6b144SVictor Chong break; 53570b6683bSVictor Chong default: 53670b6683bSVictor Chong return PKCS11_CKR_MECHANISM_INVALID; 53770b6683bSVictor Chong } 53870b6683bSVictor Chong 53970b6683bSVictor Chong if (!hmac_len || hmac_len > sign_sz) 54070b6683bSVictor Chong return PKCS11_CKR_SIGNATURE_LEN_RANGE; 54170b6683bSVictor Chong 54270b6683bSVictor Chong return PKCS11_CKR_OK; 54370b6683bSVictor Chong } 54470b6683bSVictor Chong 54570b6683bSVictor Chong static enum pkcs11_rc 546512cbf1dSJens Wiklander init_tee_operation(struct pkcs11_session *session, 547512cbf1dSJens Wiklander struct pkcs11_attribute_head *proc_params) 548512cbf1dSJens Wiklander { 549512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 55070b6683bSVictor Chong uint32_t *pkcs11_data = NULL; 551512cbf1dSJens Wiklander 552512cbf1dSJens Wiklander switch (proc_params->id) { 5530ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC: 554689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 555689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 556689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 557689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 558689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 559689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 560689f4e5bSRuchika Gupta if (proc_params->size) 561689f4e5bSRuchika Gupta return PKCS11_CKR_MECHANISM_PARAM_INVALID; 562689f4e5bSRuchika Gupta 563689f4e5bSRuchika Gupta TEE_MACInit(session->processing->tee_op_handle, NULL, 0); 564689f4e5bSRuchika Gupta rc = PKCS11_CKR_OK; 565689f4e5bSRuchika Gupta break; 5660ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC_GENERAL: 56770b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 56870b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 56970b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 57070b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 57170b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 57270b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 57370b6683bSVictor Chong if (proc_params->size != sizeof(uint32_t)) 57470b6683bSVictor Chong return PKCS11_CKR_MECHANISM_PARAM_INVALID; 57570b6683bSVictor Chong 57670b6683bSVictor Chong pkcs11_data = TEE_Malloc(sizeof(uint32_t), 57770b6683bSVictor Chong TEE_MALLOC_FILL_ZERO); 57870b6683bSVictor Chong if (!pkcs11_data) 57970b6683bSVictor Chong return PKCS11_CKR_DEVICE_MEMORY; 58070b6683bSVictor Chong 58170b6683bSVictor Chong TEE_MemMove(pkcs11_data, proc_params->data, sizeof(uint32_t)); 58270b6683bSVictor Chong 58370b6683bSVictor Chong rc = input_hmac_len_is_valid(proc_params, *pkcs11_data); 58470b6683bSVictor Chong if (rc) { 58570b6683bSVictor Chong TEE_Free(pkcs11_data); 58670b6683bSVictor Chong return rc; 58770b6683bSVictor Chong } 58870b6683bSVictor Chong 58970b6683bSVictor Chong session->processing->extra_ctx = (void *)pkcs11_data; 59070b6683bSVictor Chong 59170b6683bSVictor Chong TEE_MACInit(session->processing->tee_op_handle, NULL, 0); 59270b6683bSVictor Chong rc = PKCS11_CKR_OK; 59370b6683bSVictor Chong break; 594512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 595512cbf1dSJens Wiklander if (proc_params->size) 596512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_PARAM_INVALID; 597512cbf1dSJens Wiklander 598512cbf1dSJens Wiklander TEE_CipherInit(session->processing->tee_op_handle, NULL, 0); 599512cbf1dSJens Wiklander rc = PKCS11_CKR_OK; 600512cbf1dSJens Wiklander break; 601512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 602512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 603512cbf1dSJens Wiklander if (proc_params->size != 16) 604512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_PARAM_INVALID; 605512cbf1dSJens Wiklander 606512cbf1dSJens Wiklander TEE_CipherInit(session->processing->tee_op_handle, 607512cbf1dSJens Wiklander proc_params->data, 16); 608512cbf1dSJens Wiklander rc = PKCS11_CKR_OK; 609512cbf1dSJens Wiklander break; 610512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 611512cbf1dSJens Wiklander rc = tee_init_ctr_operation(session->processing, 612512cbf1dSJens Wiklander proc_params->data, 613512cbf1dSJens Wiklander proc_params->size); 614512cbf1dSJens Wiklander break; 615*63778faaSEtienne Carriere case PKCS11_CKM_AES_GCM: 616*63778faaSEtienne Carriere rc = tee_init_gcm_operation(session, 617*63778faaSEtienne Carriere proc_params->data, 618*63778faaSEtienne Carriere proc_params->size); 619*63778faaSEtienne Carriere break; 62048799892SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 62148799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 62248799892SRuchika Gupta rc = tee_init_derive_symm(session->processing, proc_params); 62348799892SRuchika Gupta break; 624512cbf1dSJens Wiklander default: 625512cbf1dSJens Wiklander TEE_Panic(proc_params->id); 626512cbf1dSJens Wiklander break; 627512cbf1dSJens Wiklander } 628512cbf1dSJens Wiklander 629512cbf1dSJens Wiklander return rc; 630512cbf1dSJens Wiklander } 631512cbf1dSJens Wiklander 632512cbf1dSJens Wiklander enum pkcs11_rc init_symm_operation(struct pkcs11_session *session, 633512cbf1dSJens Wiklander enum processing_func function, 634512cbf1dSJens Wiklander struct pkcs11_attribute_head *proc_params, 635512cbf1dSJens Wiklander struct pkcs11_object *obj) 636512cbf1dSJens Wiklander { 637512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 638512cbf1dSJens Wiklander 639512cbf1dSJens Wiklander assert(processing_is_tee_symm(proc_params->id)); 640512cbf1dSJens Wiklander 641512cbf1dSJens Wiklander rc = allocate_tee_operation(session, function, proc_params, obj); 642512cbf1dSJens Wiklander if (rc) 643512cbf1dSJens Wiklander return rc; 644512cbf1dSJens Wiklander 645de94d6f8SRuchika Gupta rc = load_tee_key(session, obj, proc_params); 646512cbf1dSJens Wiklander if (rc) 647512cbf1dSJens Wiklander return rc; 648512cbf1dSJens Wiklander 649909efccbSEtienne Carriere rc = init_tee_operation(session, proc_params); 650909efccbSEtienne Carriere if (!rc) 651909efccbSEtienne Carriere session->processing->mecha_type = proc_params->id; 652909efccbSEtienne Carriere 653909efccbSEtienne Carriere return rc; 654512cbf1dSJens Wiklander } 655512cbf1dSJens Wiklander 656512cbf1dSJens Wiklander /* Validate input buffer size as per PKCS#11 constraints */ 657512cbf1dSJens Wiklander static enum pkcs11_rc input_data_size_is_valid(struct active_processing *proc, 658512cbf1dSJens Wiklander enum processing_func function, 659512cbf1dSJens Wiklander size_t in_size) 660512cbf1dSJens Wiklander { 661512cbf1dSJens Wiklander switch (proc->mecha_type) { 662512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 663512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 664512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_ENCRYPT && 665512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 666512cbf1dSJens Wiklander return PKCS11_CKR_DATA_LEN_RANGE; 667512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 668512cbf1dSJens Wiklander in_size % TEE_AES_BLOCK_SIZE) 669512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 670512cbf1dSJens Wiklander break; 671512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 672512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_ENCRYPT && 673512cbf1dSJens Wiklander in_size < TEE_AES_BLOCK_SIZE) 674512cbf1dSJens Wiklander return PKCS11_CKR_DATA_LEN_RANGE; 675512cbf1dSJens Wiklander if (function == PKCS11_FUNCTION_DECRYPT && 676512cbf1dSJens Wiklander in_size < TEE_AES_BLOCK_SIZE) 677512cbf1dSJens Wiklander return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 678512cbf1dSJens Wiklander break; 679512cbf1dSJens Wiklander default: 680512cbf1dSJens Wiklander break; 681512cbf1dSJens Wiklander } 682512cbf1dSJens Wiklander 683512cbf1dSJens Wiklander return PKCS11_CKR_OK; 684512cbf1dSJens Wiklander } 685512cbf1dSJens Wiklander 686689f4e5bSRuchika Gupta /* Validate input buffer size as per PKCS#11 constraints */ 687689f4e5bSRuchika Gupta static enum pkcs11_rc input_sign_size_is_valid(struct active_processing *proc, 688689f4e5bSRuchika Gupta size_t in_size) 689689f4e5bSRuchika Gupta { 690689f4e5bSRuchika Gupta size_t sign_sz = 0; 691689f4e5bSRuchika Gupta 692689f4e5bSRuchika Gupta switch (proc->mecha_type) { 693689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 694689f4e5bSRuchika Gupta sign_sz = TEE_MD5_HASH_SIZE; 695689f4e5bSRuchika Gupta break; 696689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 697689f4e5bSRuchika Gupta sign_sz = TEE_SHA1_HASH_SIZE; 698689f4e5bSRuchika Gupta break; 699689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 700689f4e5bSRuchika Gupta sign_sz = TEE_SHA224_HASH_SIZE; 701689f4e5bSRuchika Gupta break; 702689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 703689f4e5bSRuchika Gupta sign_sz = TEE_SHA256_HASH_SIZE; 704689f4e5bSRuchika Gupta break; 705689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 706689f4e5bSRuchika Gupta sign_sz = TEE_SHA384_HASH_SIZE; 707689f4e5bSRuchika Gupta break; 708689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 709689f4e5bSRuchika Gupta sign_sz = TEE_SHA512_HASH_SIZE; 710689f4e5bSRuchika Gupta break; 7110ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC: 7120ef6b144SVictor Chong sign_sz = TEE_AES_BLOCK_SIZE; 7130ef6b144SVictor Chong break; 714689f4e5bSRuchika Gupta default: 715689f4e5bSRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 716689f4e5bSRuchika Gupta } 717689f4e5bSRuchika Gupta 71842765f82SVictor Chong if (in_size != sign_sz) 719689f4e5bSRuchika Gupta return PKCS11_CKR_SIGNATURE_LEN_RANGE; 720689f4e5bSRuchika Gupta 721689f4e5bSRuchika Gupta return PKCS11_CKR_OK; 722689f4e5bSRuchika Gupta } 723689f4e5bSRuchika Gupta 724512cbf1dSJens Wiklander /* 725512cbf1dSJens Wiklander * step_sym_cipher - processing symmetric (and related) cipher operation step 726512cbf1dSJens Wiklander * 727512cbf1dSJens Wiklander * @session - current session 728512cbf1dSJens Wiklander * @function - processing function (encrypt, decrypt, sign, ...) 729512cbf1dSJens Wiklander * @step - step ID in the processing (oneshot, update, final) 730512cbf1dSJens Wiklander * @ptype - invocation parameter types 731512cbf1dSJens Wiklander * @params - invocation parameter references 732512cbf1dSJens Wiklander */ 733512cbf1dSJens Wiklander enum pkcs11_rc step_symm_operation(struct pkcs11_session *session, 734512cbf1dSJens Wiklander enum processing_func function, 735512cbf1dSJens Wiklander enum processing_step step, 736512cbf1dSJens Wiklander uint32_t ptypes, TEE_Param *params) 737512cbf1dSJens Wiklander { 738512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 739512cbf1dSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 740512cbf1dSJens Wiklander void *in_buf = NULL; 741512cbf1dSJens Wiklander size_t in_size = 0; 742512cbf1dSJens Wiklander void *out_buf = NULL; 743c7f1b4f7SJens Wiklander size_t out_size = 0; 744512cbf1dSJens Wiklander void *in2_buf = NULL; 745512cbf1dSJens Wiklander uint32_t in2_size = 0; 746512cbf1dSJens Wiklander bool output_data = false; 747512cbf1dSJens Wiklander struct active_processing *proc = session->processing; 74870b6683bSVictor Chong uint32_t hmac_len = 0; 74970b6683bSVictor Chong uint8_t computed_mac[TEE_MAX_HASH_SIZE] = { 0 }; 750c7f1b4f7SJens Wiklander size_t computed_mac_size = TEE_MAX_HASH_SIZE; 751*63778faaSEtienne Carriere size_t ae_out_size = 0; 752512cbf1dSJens Wiklander 753512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 754512cbf1dSJens Wiklander in_buf = params[1].memref.buffer; 755512cbf1dSJens Wiklander in_size = params[1].memref.size; 756512cbf1dSJens Wiklander if (in_size && !in_buf) 757512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 758512cbf1dSJens Wiklander } 759512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) { 760512cbf1dSJens Wiklander in2_buf = params[2].memref.buffer; 761512cbf1dSJens Wiklander in2_size = params[2].memref.size; 762512cbf1dSJens Wiklander if (in2_size && !in2_buf) 763512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 764512cbf1dSJens Wiklander } 765512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 766512cbf1dSJens Wiklander out_buf = params[2].memref.buffer; 767512cbf1dSJens Wiklander out_size = params[2].memref.size; 768*63778faaSEtienne Carriere ae_out_size = out_size; 769512cbf1dSJens Wiklander if (out_size && !out_buf) 770512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 771512cbf1dSJens Wiklander } 772512cbf1dSJens Wiklander if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 773512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 774512cbf1dSJens Wiklander 775512cbf1dSJens Wiklander switch (step) { 776512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_ONESHOT: 777512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_UPDATE: 778512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_FINAL: 779512cbf1dSJens Wiklander break; 780512cbf1dSJens Wiklander default: 781512cbf1dSJens Wiklander return PKCS11_CKR_GENERAL_ERROR; 782512cbf1dSJens Wiklander } 783512cbf1dSJens Wiklander 784512cbf1dSJens Wiklander if (step != PKCS11_FUNC_STEP_FINAL) { 785512cbf1dSJens Wiklander rc = input_data_size_is_valid(proc, function, in_size); 786512cbf1dSJens Wiklander if (rc) 787512cbf1dSJens Wiklander return rc; 788512cbf1dSJens Wiklander } 789512cbf1dSJens Wiklander 790512cbf1dSJens Wiklander /* 791512cbf1dSJens Wiklander * Feed active operation with data 792512cbf1dSJens Wiklander */ 793512cbf1dSJens Wiklander switch (proc->mecha_type) { 7940ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC: 795689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 796689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 797689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 798689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 799689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 800689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 8010ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC_GENERAL: 80270b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 80370b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 80470b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 80570b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 80670b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 80770b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 808689f4e5bSRuchika Gupta if (step == PKCS11_FUNC_STEP_FINAL || 809689f4e5bSRuchika Gupta step == PKCS11_FUNC_STEP_ONESHOT) 810689f4e5bSRuchika Gupta break; 811689f4e5bSRuchika Gupta 812689f4e5bSRuchika Gupta if (!in_buf) { 813689f4e5bSRuchika Gupta DMSG("No input data"); 814689f4e5bSRuchika Gupta return PKCS11_CKR_ARGUMENTS_BAD; 815689f4e5bSRuchika Gupta } 816689f4e5bSRuchika Gupta 817689f4e5bSRuchika Gupta switch (function) { 818689f4e5bSRuchika Gupta case PKCS11_FUNCTION_SIGN: 819689f4e5bSRuchika Gupta case PKCS11_FUNCTION_VERIFY: 820689f4e5bSRuchika Gupta TEE_MACUpdate(proc->tee_op_handle, in_buf, in_size); 821689f4e5bSRuchika Gupta rc = PKCS11_CKR_OK; 822689f4e5bSRuchika Gupta break; 823689f4e5bSRuchika Gupta default: 824689f4e5bSRuchika Gupta TEE_Panic(function); 825689f4e5bSRuchika Gupta break; 826689f4e5bSRuchika Gupta } 827689f4e5bSRuchika Gupta break; 828689f4e5bSRuchika Gupta 829512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 830512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 831512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 832512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 833512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_FINAL || 834512cbf1dSJens Wiklander step == PKCS11_FUNC_STEP_ONESHOT) 835512cbf1dSJens Wiklander break; 836512cbf1dSJens Wiklander 837512cbf1dSJens Wiklander if (!in_buf) { 838512cbf1dSJens Wiklander EMSG("No input data"); 839512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 840512cbf1dSJens Wiklander } 841512cbf1dSJens Wiklander 842512cbf1dSJens Wiklander switch (function) { 843512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 844512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 845512cbf1dSJens Wiklander res = TEE_CipherUpdate(proc->tee_op_handle, 846512cbf1dSJens Wiklander in_buf, in_size, 847512cbf1dSJens Wiklander out_buf, &out_size); 848512cbf1dSJens Wiklander output_data = true; 849512cbf1dSJens Wiklander rc = tee2pkcs_error(res); 850512cbf1dSJens Wiklander break; 851512cbf1dSJens Wiklander default: 852512cbf1dSJens Wiklander TEE_Panic(function); 853512cbf1dSJens Wiklander break; 854512cbf1dSJens Wiklander } 855512cbf1dSJens Wiklander break; 856*63778faaSEtienne Carriere case PKCS11_CKM_AES_GCM: 857*63778faaSEtienne Carriere if (step == PKCS11_FUNC_STEP_FINAL) 858*63778faaSEtienne Carriere break; 859512cbf1dSJens Wiklander 860*63778faaSEtienne Carriere switch (function) { 861*63778faaSEtienne Carriere case PKCS11_FUNCTION_ENCRYPT: 862*63778faaSEtienne Carriere res = TEE_AEUpdate(proc->tee_op_handle, 863*63778faaSEtienne Carriere in_buf, in_size, out_buf, &out_size); 864*63778faaSEtienne Carriere 865*63778faaSEtienne Carriere output_data = true; 866*63778faaSEtienne Carriere rc = tee2pkcs_error(res); 867*63778faaSEtienne Carriere if (rc && rc != PKCS11_CKR_BUFFER_TOO_SMALL) 868*63778faaSEtienne Carriere return rc; 869*63778faaSEtienne Carriere if (step == PKCS11_FUNC_STEP_ONESHOT) { 870*63778faaSEtienne Carriere if (rc == PKCS11_CKR_BUFFER_TOO_SMALL) { 871*63778faaSEtienne Carriere /* Return output data size incl. tag*/ 872*63778faaSEtienne Carriere out_size += 16; 873*63778faaSEtienne Carriere goto out; 874*63778faaSEtienne Carriere } 875*63778faaSEtienne Carriere out_buf = (char *)out_buf + out_size; 876*63778faaSEtienne Carriere /* Remaining space for the tag data */ 877*63778faaSEtienne Carriere ae_out_size -= out_size; 878*63778faaSEtienne Carriere } 879*63778faaSEtienne Carriere break; 880*63778faaSEtienne Carriere case PKCS11_FUNCTION_DECRYPT: 881*63778faaSEtienne Carriere rc = tee_ae_decrypt_update(session, in_buf, in_size); 882*63778faaSEtienne Carriere assert(rc != PKCS11_CKR_BUFFER_TOO_SMALL); 883*63778faaSEtienne Carriere if (rc) 884*63778faaSEtienne Carriere return rc; 885*63778faaSEtienne Carriere /* Do not output decrypted data until tag is verified */ 886*63778faaSEtienne Carriere out_size = 0; 887*63778faaSEtienne Carriere output_data = true; 888*63778faaSEtienne Carriere break; 889*63778faaSEtienne Carriere default: 890*63778faaSEtienne Carriere TEE_Panic(function); 891*63778faaSEtienne Carriere break; 892*63778faaSEtienne Carriere } 893*63778faaSEtienne Carriere break; 894512cbf1dSJens Wiklander default: 895512cbf1dSJens Wiklander TEE_Panic(proc->mecha_type); 896512cbf1dSJens Wiklander break; 897512cbf1dSJens Wiklander } 898512cbf1dSJens Wiklander 899512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_UPDATE) 900512cbf1dSJens Wiklander goto out; 901512cbf1dSJens Wiklander 902512cbf1dSJens Wiklander /* 903512cbf1dSJens Wiklander * Finalize (PKCS11_FUNC_STEP_ONESHOT/_FINAL) operation 904512cbf1dSJens Wiklander */ 905512cbf1dSJens Wiklander switch (session->processing->mecha_type) { 9060ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC: 907689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 908689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 909689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 910689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 911689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 912689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 913689f4e5bSRuchika Gupta switch (function) { 914689f4e5bSRuchika Gupta case PKCS11_FUNCTION_SIGN: 915689f4e5bSRuchika Gupta res = TEE_MACComputeFinal(proc->tee_op_handle, 916689f4e5bSRuchika Gupta in_buf, in_size, out_buf, 917689f4e5bSRuchika Gupta &out_size); 918689f4e5bSRuchika Gupta output_data = true; 919689f4e5bSRuchika Gupta rc = tee2pkcs_error(res); 920689f4e5bSRuchika Gupta break; 921689f4e5bSRuchika Gupta case PKCS11_FUNCTION_VERIFY: 922689f4e5bSRuchika Gupta rc = input_sign_size_is_valid(proc, in2_size); 923689f4e5bSRuchika Gupta if (rc) 924689f4e5bSRuchika Gupta return rc; 925689f4e5bSRuchika Gupta res = TEE_MACCompareFinal(proc->tee_op_handle, 926689f4e5bSRuchika Gupta in_buf, in_size, in2_buf, 927689f4e5bSRuchika Gupta in2_size); 928689f4e5bSRuchika Gupta rc = tee2pkcs_error(res); 929689f4e5bSRuchika Gupta break; 930689f4e5bSRuchika Gupta default: 931689f4e5bSRuchika Gupta TEE_Panic(function); 932689f4e5bSRuchika Gupta break; 933689f4e5bSRuchika Gupta } 9342158ea6cSRuchika Gupta 935689f4e5bSRuchika Gupta break; 936689f4e5bSRuchika Gupta 9370ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC_GENERAL: 93870b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 93970b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 94070b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 94170b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 94270b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 94370b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 94470b6683bSVictor Chong assert(session->processing->extra_ctx); 94570b6683bSVictor Chong hmac_len = *(uint32_t *)session->processing->extra_ctx; 94670b6683bSVictor Chong 94770b6683bSVictor Chong switch (function) { 94870b6683bSVictor Chong case PKCS11_FUNCTION_SIGN: 94970b6683bSVictor Chong if (out_size < hmac_len) { 95070b6683bSVictor Chong /* inform client of required size */ 95170b6683bSVictor Chong out_size = hmac_len; 95270b6683bSVictor Chong output_data = true; 95370b6683bSVictor Chong rc = PKCS11_CKR_BUFFER_TOO_SMALL; 95470b6683bSVictor Chong goto out; 95570b6683bSVictor Chong } 95670b6683bSVictor Chong 95770b6683bSVictor Chong res = TEE_MACComputeFinal(proc->tee_op_handle, 95870b6683bSVictor Chong in_buf, in_size, 95970b6683bSVictor Chong computed_mac, 96070b6683bSVictor Chong &computed_mac_size); 96170b6683bSVictor Chong if (res == TEE_SUCCESS) { 96270b6683bSVictor Chong /* truncate to hmac_len */ 96370b6683bSVictor Chong TEE_MemMove(out_buf, computed_mac, hmac_len); 96470b6683bSVictor Chong output_data = true; 96570b6683bSVictor Chong } 96670b6683bSVictor Chong 96770b6683bSVictor Chong /* inform client of required size */ 96870b6683bSVictor Chong out_size = hmac_len; 96970b6683bSVictor Chong rc = tee2pkcs_error(res); 97070b6683bSVictor Chong break; 97170b6683bSVictor Chong case PKCS11_FUNCTION_VERIFY: 97270b6683bSVictor Chong /* must compute full MAC before comparing partial */ 97370b6683bSVictor Chong res = TEE_MACComputeFinal(proc->tee_op_handle, in_buf, 97470b6683bSVictor Chong in_size, computed_mac, 97570b6683bSVictor Chong &computed_mac_size); 97670b6683bSVictor Chong 97770b6683bSVictor Chong if (!in2_size || in2_size > computed_mac_size) { 97870b6683bSVictor Chong EMSG("Invalid signature size: %"PRIu32, 97970b6683bSVictor Chong in2_size); 98070b6683bSVictor Chong return PKCS11_CKR_SIGNATURE_LEN_RANGE; 98170b6683bSVictor Chong } 98270b6683bSVictor Chong 98370b6683bSVictor Chong if (res == TEE_SUCCESS) { 98470b6683bSVictor Chong /* 98570b6683bSVictor Chong * Only the first in2_size bytes of the 98670b6683bSVictor Chong * signature to be verified is passed in from 98770b6683bSVictor Chong * caller 98870b6683bSVictor Chong */ 98970b6683bSVictor Chong if (TEE_MemCompare(in2_buf, computed_mac, 99070b6683bSVictor Chong in2_size)) { 99170b6683bSVictor Chong res = TEE_ERROR_MAC_INVALID; 99270b6683bSVictor Chong } 99370b6683bSVictor Chong } 99470b6683bSVictor Chong 99570b6683bSVictor Chong rc = tee2pkcs_error(res); 99670b6683bSVictor Chong break; 99770b6683bSVictor Chong default: 99870b6683bSVictor Chong TEE_Panic(function); 99970b6683bSVictor Chong break; 100070b6683bSVictor Chong } 100170b6683bSVictor Chong 100270b6683bSVictor Chong break; 100370b6683bSVictor Chong 1004512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 1005512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 1006512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 1007512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 1008512cbf1dSJens Wiklander if (step == PKCS11_FUNC_STEP_ONESHOT && !in_buf) { 1009512cbf1dSJens Wiklander EMSG("No input data"); 1010512cbf1dSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 1011512cbf1dSJens Wiklander } 1012512cbf1dSJens Wiklander 1013512cbf1dSJens Wiklander switch (function) { 1014512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 1015512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 1016512cbf1dSJens Wiklander res = TEE_CipherDoFinal(proc->tee_op_handle, 1017512cbf1dSJens Wiklander in_buf, in_size, 1018512cbf1dSJens Wiklander out_buf, &out_size); 1019512cbf1dSJens Wiklander output_data = true; 1020512cbf1dSJens Wiklander rc = tee2pkcs_error(res); 1021512cbf1dSJens Wiklander break; 1022512cbf1dSJens Wiklander default: 1023512cbf1dSJens Wiklander TEE_Panic(function); 1024512cbf1dSJens Wiklander break; 1025512cbf1dSJens Wiklander } 1026512cbf1dSJens Wiklander break; 1027*63778faaSEtienne Carriere case PKCS11_CKM_AES_GCM: 1028*63778faaSEtienne Carriere switch (function) { 1029*63778faaSEtienne Carriere case PKCS11_FUNCTION_ENCRYPT: 1030*63778faaSEtienne Carriere rc = tee_ae_encrypt_final(session, out_buf, 1031*63778faaSEtienne Carriere &ae_out_size); 1032*63778faaSEtienne Carriere output_data = true; 1033*63778faaSEtienne Carriere if (step == PKCS11_FUNC_STEP_ONESHOT) 1034*63778faaSEtienne Carriere out_size += ae_out_size; 1035*63778faaSEtienne Carriere else 1036*63778faaSEtienne Carriere out_size = ae_out_size; 1037*63778faaSEtienne Carriere break; 1038*63778faaSEtienne Carriere case PKCS11_FUNCTION_DECRYPT: 1039*63778faaSEtienne Carriere /* Now we're ready to reveal data */ 1040*63778faaSEtienne Carriere out_size = ae_out_size; 1041*63778faaSEtienne Carriere rc = tee_ae_decrypt_final(session, out_buf, &out_size); 1042*63778faaSEtienne Carriere output_data = true; 1043*63778faaSEtienne Carriere break; 1044*63778faaSEtienne Carriere default: 1045*63778faaSEtienne Carriere TEE_Panic(function); 1046*63778faaSEtienne Carriere break; 1047*63778faaSEtienne Carriere } 1048*63778faaSEtienne Carriere 1049*63778faaSEtienne Carriere if (step == PKCS11_FUNC_STEP_ONESHOT && 1050*63778faaSEtienne Carriere rc == PKCS11_CKR_BUFFER_TOO_SMALL) { 1051*63778faaSEtienne Carriere enum pkcs11_rc rc2 = PKCS11_CKR_OK; 1052*63778faaSEtienne Carriere 1053*63778faaSEtienne Carriere /* 1054*63778faaSEtienne Carriere * Change operation state to its initial state 1055*63778faaSEtienne Carriere * as client will likely request again the 1056*63778faaSEtienne Carriere * one-shot processing but possibly with 1057*63778faaSEtienne Carriere * different input data. 1058*63778faaSEtienne Carriere */ 1059*63778faaSEtienne Carriere rc2 = tee_ae_reinit_gcm_operation(session); 1060*63778faaSEtienne Carriere if (rc2) 1061*63778faaSEtienne Carriere return rc2; 1062*63778faaSEtienne Carriere } 1063*63778faaSEtienne Carriere break; 1064512cbf1dSJens Wiklander default: 1065512cbf1dSJens Wiklander TEE_Panic(proc->mecha_type); 1066512cbf1dSJens Wiklander break; 1067512cbf1dSJens Wiklander } 1068512cbf1dSJens Wiklander 1069512cbf1dSJens Wiklander out: 1070512cbf1dSJens Wiklander if (output_data && 1071512cbf1dSJens Wiklander (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) { 1072512cbf1dSJens Wiklander switch (TEE_PARAM_TYPE_GET(ptypes, 2)) { 1073512cbf1dSJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 1074512cbf1dSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 1075512cbf1dSJens Wiklander params[2].memref.size = out_size; 1076512cbf1dSJens Wiklander break; 1077512cbf1dSJens Wiklander default: 1078512cbf1dSJens Wiklander rc = PKCS11_CKR_ARGUMENTS_BAD; 1079512cbf1dSJens Wiklander break; 1080512cbf1dSJens Wiklander } 1081512cbf1dSJens Wiklander } 1082512cbf1dSJens Wiklander 1083512cbf1dSJens Wiklander return rc; 1084512cbf1dSJens Wiklander } 108548799892SRuchika Gupta 108648799892SRuchika Gupta enum pkcs11_rc derive_key_by_symm_enc(struct pkcs11_session *session, 10878c499324SRuchika Gupta void **out_buf, uint32_t *out_size) 108848799892SRuchika Gupta { 108948799892SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 109048799892SRuchika Gupta TEE_Result res = TEE_ERROR_GENERIC; 109148799892SRuchika Gupta struct active_processing *proc = session->processing; 109248799892SRuchika Gupta struct input_data_ref *input = proc->extra_ctx; 109348799892SRuchika Gupta void *in_buf = NULL; 1094a5ea52c2SElvira Khabirova void *dest_buf = NULL; 109548799892SRuchika Gupta uint32_t in_size = 0; 1096c7f1b4f7SJens Wiklander size_t tmp_sz = 0; 109748799892SRuchika Gupta 10988c499324SRuchika Gupta switch (proc->mecha_type) { 10998c499324SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 11008c499324SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 110148799892SRuchika Gupta if (!proc->extra_ctx) 110248799892SRuchika Gupta return PKCS11_CKR_ARGUMENTS_BAD; 110348799892SRuchika Gupta 110448799892SRuchika Gupta in_buf = input->data; 110548799892SRuchika Gupta in_size = input->size; 110648799892SRuchika Gupta 11078c499324SRuchika Gupta *out_size = in_size; 1108a5ea52c2SElvira Khabirova dest_buf = TEE_Malloc(*out_size, 0); 1109a5ea52c2SElvira Khabirova if (!dest_buf) 111048799892SRuchika Gupta return PKCS11_CKR_DEVICE_MEMORY; 111148799892SRuchika Gupta 1112c7f1b4f7SJens Wiklander tmp_sz = *out_size; 11138c499324SRuchika Gupta res = TEE_CipherDoFinal(proc->tee_op_handle, in_buf, in_size, 1114c7f1b4f7SJens Wiklander dest_buf, &tmp_sz); 1115c7f1b4f7SJens Wiklander *out_size = tmp_sz; 111648799892SRuchika Gupta rc = tee2pkcs_error(res); 1117a5ea52c2SElvira Khabirova if (rc) { 1118a5ea52c2SElvira Khabirova TEE_Free(dest_buf); 1119a5ea52c2SElvira Khabirova return rc; 1120a5ea52c2SElvira Khabirova } 1121a5ea52c2SElvira Khabirova 1122a5ea52c2SElvira Khabirova *out_buf = dest_buf; 11238c499324SRuchika Gupta break; 11248c499324SRuchika Gupta default: 11258c499324SRuchika Gupta return PKCS11_CKR_MECHANISM_INVALID; 112648799892SRuchika Gupta } 112748799892SRuchika Gupta 112848799892SRuchika Gupta return rc; 112948799892SRuchika Gupta } 11305f80f270SRuchika Gupta 11315f80f270SRuchika Gupta enum pkcs11_rc wrap_data_by_symm_enc(struct pkcs11_session *session, 11325f80f270SRuchika Gupta void *data, uint32_t data_sz, 11335f80f270SRuchika Gupta void *out_buf, uint32_t *out_sz) 11345f80f270SRuchika Gupta { 11355f80f270SRuchika Gupta TEE_Result res = TEE_ERROR_GENERIC; 11365f80f270SRuchika Gupta struct active_processing *proc = session->processing; 11375f80f270SRuchika Gupta void *in_buf = NULL; 11385f80f270SRuchika Gupta uint32_t align = 0; 11395f80f270SRuchika Gupta uint32_t in_sz = data_sz; 1140c7f1b4f7SJens Wiklander size_t tmp_sz = *out_sz; 11415f80f270SRuchika Gupta uint8_t *tmp_buf = out_buf; 11425f80f270SRuchika Gupta 11435f80f270SRuchika Gupta switch (proc->mecha_type) { 11445f80f270SRuchika Gupta case PKCS11_CKM_AES_ECB: 11455f80f270SRuchika Gupta case PKCS11_CKM_AES_CBC: 11465f80f270SRuchika Gupta align = data_sz % TEE_AES_BLOCK_SIZE; 11475f80f270SRuchika Gupta if (align) 11485f80f270SRuchika Gupta in_sz = data_sz + (TEE_AES_BLOCK_SIZE - align); 11495f80f270SRuchika Gupta 11505f80f270SRuchika Gupta if (*out_sz < in_sz) { 11515f80f270SRuchika Gupta *out_sz = in_sz; 11525f80f270SRuchika Gupta return PKCS11_CKR_BUFFER_TOO_SMALL; 11535f80f270SRuchika Gupta } 11545f80f270SRuchika Gupta 11555f80f270SRuchika Gupta if (align) { 11565f80f270SRuchika Gupta if (data_sz > TEE_AES_BLOCK_SIZE) { 11575f80f270SRuchika Gupta in_sz = data_sz - align; 11585f80f270SRuchika Gupta res = TEE_CipherUpdate(proc->tee_op_handle, 11595f80f270SRuchika Gupta data, in_sz, tmp_buf, 11605f80f270SRuchika Gupta &tmp_sz); 11615f80f270SRuchika Gupta if (res) { 11625f80f270SRuchika Gupta assert(res != TEE_ERROR_SHORT_BUFFER); 11635f80f270SRuchika Gupta return tee2pkcs_error(res); 11645f80f270SRuchika Gupta } 11655f80f270SRuchika Gupta tmp_buf += tmp_sz; 11665f80f270SRuchika Gupta tmp_sz = *out_sz - tmp_sz; 11675f80f270SRuchika Gupta } else { 11685f80f270SRuchika Gupta in_sz = 0; 11695f80f270SRuchika Gupta } 11705f80f270SRuchika Gupta 11715f80f270SRuchika Gupta in_buf = TEE_Malloc(TEE_AES_BLOCK_SIZE, 11725f80f270SRuchika Gupta TEE_MALLOC_FILL_ZERO); 11735f80f270SRuchika Gupta if (!in_buf) 11745f80f270SRuchika Gupta return PKCS11_CKR_DEVICE_MEMORY; 11755f80f270SRuchika Gupta 11765f80f270SRuchika Gupta TEE_MemMove(in_buf, (uint8_t *)data + in_sz, align); 11775f80f270SRuchika Gupta in_sz = TEE_AES_BLOCK_SIZE; 11785f80f270SRuchika Gupta } else { 11795f80f270SRuchika Gupta in_buf = data; 11805f80f270SRuchika Gupta in_sz = data_sz; 11815f80f270SRuchika Gupta } 11825f80f270SRuchika Gupta 11835f80f270SRuchika Gupta res = TEE_CipherDoFinal(proc->tee_op_handle, in_buf, in_sz, 11845f80f270SRuchika Gupta tmp_buf, &tmp_sz); 11855f80f270SRuchika Gupta if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) { 11865f80f270SRuchika Gupta *out_sz = tmp_sz; 11875f80f270SRuchika Gupta if (align) 11885f80f270SRuchika Gupta *out_sz += tmp_buf - (uint8_t *)out_buf; 11895f80f270SRuchika Gupta } 11905f80f270SRuchika Gupta 11915f80f270SRuchika Gupta if (align) 11925f80f270SRuchika Gupta TEE_Free(in_buf); 11935f80f270SRuchika Gupta 11945f80f270SRuchika Gupta return tee2pkcs_error(res); 11955f80f270SRuchika Gupta default: 11965f80f270SRuchika Gupta return PKCS11_CKR_MECHANISM_INVALID; 11975f80f270SRuchika Gupta } 11985f80f270SRuchika Gupta 11995f80f270SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 12005f80f270SRuchika Gupta } 12013668310bSRuchika Gupta 12023668310bSRuchika Gupta enum pkcs11_rc unwrap_key_by_symm(struct pkcs11_session *session, void *data, 12033668310bSRuchika Gupta uint32_t data_sz, void **out_buf, 12043668310bSRuchika Gupta uint32_t *out_sz) 12053668310bSRuchika Gupta { 12063668310bSRuchika Gupta TEE_Result res = TEE_ERROR_GENERIC; 12073668310bSRuchika Gupta struct active_processing *proc = session->processing; 1208c7f1b4f7SJens Wiklander size_t tmp_sz = 0; 12093668310bSRuchika Gupta 12103668310bSRuchika Gupta if (input_data_size_is_valid(proc, PKCS11_FUNCTION_DECRYPT, data_sz)) 12113668310bSRuchika Gupta return PKCS11_CKR_WRAPPED_KEY_LEN_RANGE; 12123668310bSRuchika Gupta 12133668310bSRuchika Gupta switch (proc->mecha_type) { 12143668310bSRuchika Gupta case PKCS11_CKM_AES_ECB: 12153668310bSRuchika Gupta case PKCS11_CKM_AES_CBC: 12163668310bSRuchika Gupta *out_sz = 0; 12173668310bSRuchika Gupta res = TEE_CipherDoFinal(proc->tee_op_handle, data, data_sz, 1218c7f1b4f7SJens Wiklander NULL, &tmp_sz); 1219c7f1b4f7SJens Wiklander *out_sz = tmp_sz; 12203668310bSRuchika Gupta if (res != TEE_ERROR_SHORT_BUFFER) { 12213668310bSRuchika Gupta DMSG("TEE_CipherDoFinal() issue: %#"PRIx32, res); 12223668310bSRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 12233668310bSRuchika Gupta } 12243668310bSRuchika Gupta 12253668310bSRuchika Gupta *out_buf = TEE_Malloc(*out_sz, TEE_MALLOC_FILL_ZERO); 12263668310bSRuchika Gupta if (!*out_buf) 12273668310bSRuchika Gupta return PKCS11_CKR_DEVICE_MEMORY; 12283668310bSRuchika Gupta 12293668310bSRuchika Gupta res = TEE_CipherDoFinal(proc->tee_op_handle, data, data_sz, 1230c7f1b4f7SJens Wiklander *out_buf, &tmp_sz); 1231c7f1b4f7SJens Wiklander *out_sz = tmp_sz; 12323668310bSRuchika Gupta if (tee2pkcs_error(res)) { 12333668310bSRuchika Gupta TEE_Free(*out_buf); 12343668310bSRuchika Gupta *out_buf = NULL; 12353668310bSRuchika Gupta return PKCS11_CKR_WRAPPED_KEY_INVALID; 12363668310bSRuchika Gupta } 12373668310bSRuchika Gupta break; 12383668310bSRuchika Gupta default: 12393668310bSRuchika Gupta return PKCS11_CKR_MECHANISM_INVALID; 12403668310bSRuchika Gupta } 12413668310bSRuchika Gupta 12423668310bSRuchika Gupta return PKCS11_CKR_OK; 12433668310bSRuchika Gupta } 1244