163f89caaSJens Wiklander // SPDX-License-Identifier: BSD-2-Clause 263f89caaSJens Wiklander /* 363f89caaSJens Wiklander * Copyright (c) 2017-2020, Linaro Limited 463f89caaSJens Wiklander */ 563f89caaSJens Wiklander 663f89caaSJens Wiklander #include <assert.h> 763f89caaSJens Wiklander #include <inttypes.h> 8*7c243321SVesa Jääskeläinen #include <mbedtls/asn1write.h> 9*7c243321SVesa Jääskeläinen #include <mbedtls/ecp.h> 1045d40bdaSValerii Chubar #include <mbedtls/pk.h> 1163f89caaSJens Wiklander #include <pkcs11_ta.h> 1263f89caaSJens Wiklander #include <stdlib.h> 1363f89caaSJens Wiklander #include <string_ext.h> 1463f89caaSJens Wiklander #include <tee_internal_api_extensions.h> 1563f89caaSJens Wiklander #include <tee_internal_api.h> 166a760c9eSEtienne Carriere #include <trace.h> 1763f89caaSJens Wiklander #include <util.h> 1863f89caaSJens Wiklander 1963f89caaSJens Wiklander #include "attributes.h" 2063f89caaSJens Wiklander #include "handle.h" 2163f89caaSJens Wiklander #include "pkcs11_attributes.h" 2263f89caaSJens Wiklander #include "pkcs11_helpers.h" 2363f89caaSJens Wiklander #include "pkcs11_token.h" 24*7c243321SVesa Jääskeläinen #include "processing.h" 2563f89caaSJens Wiklander #include "sanitize_object.h" 2663f89caaSJens Wiklander #include "serializer.h" 2763f89caaSJens Wiklander #include "token_capabilities.h" 2863f89caaSJens Wiklander 29512cbf1dSJens Wiklander static uint32_t pkcs11_func2ckfm(enum processing_func function) 30512cbf1dSJens Wiklander { 31512cbf1dSJens Wiklander switch (function) { 32512cbf1dSJens Wiklander case PKCS11_FUNCTION_DIGEST: 33512cbf1dSJens Wiklander return PKCS11_CKFM_DIGEST; 34512cbf1dSJens Wiklander case PKCS11_FUNCTION_GENERATE: 35512cbf1dSJens Wiklander return PKCS11_CKFM_GENERATE; 36512cbf1dSJens Wiklander case PKCS11_FUNCTION_GENERATE_PAIR: 37512cbf1dSJens Wiklander return PKCS11_CKFM_GENERATE_KEY_PAIR; 38512cbf1dSJens Wiklander case PKCS11_FUNCTION_DERIVE: 39512cbf1dSJens Wiklander return PKCS11_CKFM_DERIVE; 40512cbf1dSJens Wiklander case PKCS11_FUNCTION_WRAP: 41512cbf1dSJens Wiklander return PKCS11_CKFM_WRAP; 42512cbf1dSJens Wiklander case PKCS11_FUNCTION_UNWRAP: 43512cbf1dSJens Wiklander return PKCS11_CKFM_UNWRAP; 44512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 45512cbf1dSJens Wiklander return PKCS11_CKFM_ENCRYPT; 46512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 47512cbf1dSJens Wiklander return PKCS11_CKFM_DECRYPT; 48512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN: 49512cbf1dSJens Wiklander return PKCS11_CKFM_SIGN; 50512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY: 51512cbf1dSJens Wiklander return PKCS11_CKFM_VERIFY; 52512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN_RECOVER: 53512cbf1dSJens Wiklander return PKCS11_CKFM_SIGN_RECOVER; 54512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY_RECOVER: 55512cbf1dSJens Wiklander return PKCS11_CKFM_VERIFY_RECOVER; 56512cbf1dSJens Wiklander default: 57512cbf1dSJens Wiklander return 0; 58512cbf1dSJens Wiklander } 59512cbf1dSJens Wiklander } 60512cbf1dSJens Wiklander 61512cbf1dSJens Wiklander enum pkcs11_rc 62512cbf1dSJens Wiklander check_mechanism_against_processing(struct pkcs11_session *session, 63512cbf1dSJens Wiklander enum pkcs11_mechanism_id mechanism_type, 64512cbf1dSJens Wiklander enum processing_func function, 65512cbf1dSJens Wiklander enum processing_step step) 66512cbf1dSJens Wiklander { 67512cbf1dSJens Wiklander bool allowed = false; 68512cbf1dSJens Wiklander 69512cbf1dSJens Wiklander switch (step) { 70512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_INIT: 71512cbf1dSJens Wiklander switch (function) { 72512cbf1dSJens Wiklander case PKCS11_FUNCTION_IMPORT: 73512cbf1dSJens Wiklander case PKCS11_FUNCTION_COPY: 74512cbf1dSJens Wiklander case PKCS11_FUNCTION_MODIFY: 75512cbf1dSJens Wiklander case PKCS11_FUNCTION_DESTROY: 76512cbf1dSJens Wiklander return PKCS11_CKR_OK; 77512cbf1dSJens Wiklander default: 78512cbf1dSJens Wiklander break; 79512cbf1dSJens Wiklander } 80512cbf1dSJens Wiklander /* 81512cbf1dSJens Wiklander * Check that the returned PKCS11_CKFM_* flag from 82512cbf1dSJens Wiklander * pkcs11_func2ckfm() is among the ones from 83512cbf1dSJens Wiklander * mechanism_supported_flags(). 84512cbf1dSJens Wiklander */ 85512cbf1dSJens Wiklander allowed = mechanism_supported_flags(mechanism_type) & 86512cbf1dSJens Wiklander pkcs11_func2ckfm(function); 87512cbf1dSJens Wiklander break; 88512cbf1dSJens Wiklander 89512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_ONESHOT: 900460a039SRuchika Gupta if (session->processing->always_authen && 910460a039SRuchika Gupta !session->processing->relogged) 920460a039SRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 930460a039SRuchika Gupta 942364aa69SRuchika Gupta if (session->processing->step == PKCS11_FUNC_STEP_UPDATE || 952364aa69SRuchika Gupta session->processing->step == PKCS11_FUNC_STEP_FINAL) { 962364aa69SRuchika Gupta EMSG("Cannot perform one-shot on active processing"); 970460a039SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE; 980460a039SRuchika Gupta } 990460a039SRuchika Gupta 1000460a039SRuchika Gupta allowed = true; 1010460a039SRuchika Gupta break; 1020460a039SRuchika Gupta 103512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_UPDATE: 104512cbf1dSJens Wiklander if (session->processing->always_authen && 105512cbf1dSJens Wiklander !session->processing->relogged) 106512cbf1dSJens Wiklander return PKCS11_CKR_USER_NOT_LOGGED_IN; 107512cbf1dSJens Wiklander 1082364aa69SRuchika Gupta if (session->processing->step == PKCS11_FUNC_STEP_ONESHOT || 1092364aa69SRuchika Gupta session->processing->step == PKCS11_FUNC_STEP_FINAL) { 1102364aa69SRuchika Gupta EMSG("Cannot perform update on finalized processing"); 1112364aa69SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE; 1122364aa69SRuchika Gupta } 1132364aa69SRuchika Gupta 114512cbf1dSJens Wiklander allowed = !mechanism_is_one_shot_only(mechanism_type); 115512cbf1dSJens Wiklander break; 116512cbf1dSJens Wiklander 1179e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE_KEY: 1189e91a619SVesa Jääskeläinen assert(function == PKCS11_FUNCTION_DIGEST); 1199e91a619SVesa Jääskeläinen 1209e91a619SVesa Jääskeläinen if (session->processing->always_authen && 1219e91a619SVesa Jääskeläinen !session->processing->relogged) 1229e91a619SVesa Jääskeläinen return PKCS11_CKR_USER_NOT_LOGGED_IN; 1239e91a619SVesa Jääskeläinen 1249e91a619SVesa Jääskeläinen allowed = true; 1259e91a619SVesa Jääskeläinen break; 1269e91a619SVesa Jääskeläinen 127512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_FINAL: 128512cbf1dSJens Wiklander if (session->processing->always_authen && 129512cbf1dSJens Wiklander !session->processing->relogged) 130512cbf1dSJens Wiklander return PKCS11_CKR_USER_NOT_LOGGED_IN; 131512cbf1dSJens Wiklander 1322364aa69SRuchika Gupta if (session->processing->step == PKCS11_FUNC_STEP_ONESHOT) { 1332364aa69SRuchika Gupta EMSG("Cannot perform final on oneshot processing"); 1342364aa69SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE; 1352364aa69SRuchika Gupta } 136512cbf1dSJens Wiklander return PKCS11_CKR_OK; 137512cbf1dSJens Wiklander 138512cbf1dSJens Wiklander default: 139512cbf1dSJens Wiklander TEE_Panic(step); 140512cbf1dSJens Wiklander break; 141512cbf1dSJens Wiklander } 142512cbf1dSJens Wiklander 143512cbf1dSJens Wiklander if (!allowed) { 144512cbf1dSJens Wiklander EMSG("Processing %#x/%s not permitted (%u/%u)", 145512cbf1dSJens Wiklander (unsigned int)mechanism_type, id2str_proc(mechanism_type), 146512cbf1dSJens Wiklander function, step); 147df705578SRuchika Gupta return PKCS11_CKR_MECHANISM_INVALID; 148512cbf1dSJens Wiklander } 149512cbf1dSJens Wiklander 150512cbf1dSJens Wiklander return PKCS11_CKR_OK; 151512cbf1dSJens Wiklander } 152512cbf1dSJens Wiklander 15363f89caaSJens Wiklander /* 15463f89caaSJens Wiklander * Object default boolean attributes as per PKCS#11 15563f89caaSJens Wiklander */ 15663f89caaSJens Wiklander static uint8_t *pkcs11_object_default_boolprop(uint32_t attribute) 15763f89caaSJens Wiklander { 15863f89caaSJens Wiklander static const uint8_t bool_true = 1; 15963f89caaSJens Wiklander static const uint8_t bool_false; 16063f89caaSJens Wiklander 16163f89caaSJens Wiklander switch (attribute) { 16263f89caaSJens Wiklander /* As per PKCS#11 default value */ 16363f89caaSJens Wiklander case PKCS11_CKA_MODIFIABLE: 16463f89caaSJens Wiklander case PKCS11_CKA_COPYABLE: 16563f89caaSJens Wiklander case PKCS11_CKA_DESTROYABLE: 16663f89caaSJens Wiklander return (uint8_t *)&bool_true; 16763f89caaSJens Wiklander case PKCS11_CKA_TOKEN: 16863f89caaSJens Wiklander case PKCS11_CKA_PRIVATE: 16939fc24faSEtienne Carriere case PKCS11_CKA_WRAP_WITH_TRUSTED: 17039fc24faSEtienne Carriere case PKCS11_CKA_ALWAYS_AUTHENTICATE: 17163f89caaSJens Wiklander case PKCS11_CKA_SENSITIVE: 17263f89caaSJens Wiklander return (uint8_t *)&bool_false; 17363f89caaSJens Wiklander /* Token specific default value */ 17463f89caaSJens Wiklander case PKCS11_CKA_SIGN: 17563f89caaSJens Wiklander case PKCS11_CKA_VERIFY: 17663f89caaSJens Wiklander case PKCS11_CKA_DERIVE: 17763f89caaSJens Wiklander case PKCS11_CKA_ENCRYPT: 17863f89caaSJens Wiklander case PKCS11_CKA_DECRYPT: 17963f89caaSJens Wiklander case PKCS11_CKA_SIGN_RECOVER: 18063f89caaSJens Wiklander case PKCS11_CKA_VERIFY_RECOVER: 18163f89caaSJens Wiklander case PKCS11_CKA_WRAP: 18263f89caaSJens Wiklander case PKCS11_CKA_UNWRAP: 18363f89caaSJens Wiklander case PKCS11_CKA_EXTRACTABLE: 18463f89caaSJens Wiklander case PKCS11_CKA_TRUSTED: 18563f89caaSJens Wiklander return (uint8_t *)&bool_false; 18663f89caaSJens Wiklander default: 18763f89caaSJens Wiklander DMSG("No default for boolprop attribute %#"PRIx32, attribute); 18863f89caaSJens Wiklander return NULL; 18963f89caaSJens Wiklander } 19063f89caaSJens Wiklander } 19163f89caaSJens Wiklander 19263f89caaSJens Wiklander /* 19363f89caaSJens Wiklander * Object expects several boolean attributes to be set to a default value 19463f89caaSJens Wiklander * or to a validate client configuration value. This function append the input 19563f89caaSJens Wiklander * attribute (id/size/value) in the serialized object. 19663f89caaSJens Wiklander */ 19763f89caaSJens Wiklander static enum pkcs11_rc pkcs11_import_object_boolprop(struct obj_attrs **out, 19863f89caaSJens Wiklander struct obj_attrs *templ, 19963f89caaSJens Wiklander uint32_t attribute) 20063f89caaSJens Wiklander { 20163f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 20263f89caaSJens Wiklander uint8_t bbool = 0; 20363f89caaSJens Wiklander uint32_t size = sizeof(uint8_t); 20463f89caaSJens Wiklander void *attr = NULL; 20563f89caaSJens Wiklander 20663f89caaSJens Wiklander rc = get_attribute(templ, attribute, &bbool, &size); 20763f89caaSJens Wiklander if (rc) { 20863f89caaSJens Wiklander if (rc != PKCS11_RV_NOT_FOUND) 20963f89caaSJens Wiklander return rc; 21063f89caaSJens Wiklander attr = pkcs11_object_default_boolprop(attribute); 21163f89caaSJens Wiklander if (!attr) 21263f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCOMPLETE; 21363f89caaSJens Wiklander } else { 21463f89caaSJens Wiklander attr = &bbool; 21563f89caaSJens Wiklander } 21663f89caaSJens Wiklander 21763f89caaSJens Wiklander /* Boolean attributes are 1byte in the ABI, no alignment issue */ 21863f89caaSJens Wiklander return add_attribute(out, attribute, attr, sizeof(uint8_t)); 21963f89caaSJens Wiklander } 22063f89caaSJens Wiklander 22163f89caaSJens Wiklander static enum pkcs11_rc set_mandatory_boolprops(struct obj_attrs **out, 22263f89caaSJens Wiklander struct obj_attrs *temp, 22363f89caaSJens Wiklander uint32_t const *bp, 22463f89caaSJens Wiklander size_t bp_count) 22563f89caaSJens Wiklander { 22663f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 22763f89caaSJens Wiklander size_t n = 0; 22863f89caaSJens Wiklander 22963f89caaSJens Wiklander for (n = 0; n < bp_count; n++) { 23063f89caaSJens Wiklander rc = pkcs11_import_object_boolprop(out, temp, bp[n]); 23163f89caaSJens Wiklander if (rc) 23263f89caaSJens Wiklander return rc; 23363f89caaSJens Wiklander } 23463f89caaSJens Wiklander 23563f89caaSJens Wiklander return rc; 23663f89caaSJens Wiklander } 23763f89caaSJens Wiklander 23863f89caaSJens Wiklander static enum pkcs11_rc set_mandatory_attributes(struct obj_attrs **out, 23963f89caaSJens Wiklander struct obj_attrs *temp, 24016df60c7SEtienne Carriere uint32_t const *attrs, 24116df60c7SEtienne Carriere size_t attrs_count) 24263f89caaSJens Wiklander { 24363f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 24463f89caaSJens Wiklander size_t n = 0; 24563f89caaSJens Wiklander 24616df60c7SEtienne Carriere for (n = 0; n < attrs_count; n++) { 24763f89caaSJens Wiklander uint32_t size = 0; 24863f89caaSJens Wiklander void *value = NULL; 24963f89caaSJens Wiklander 25016df60c7SEtienne Carriere if (get_attribute_ptr(temp, attrs[n], &value, &size)) 25163f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCOMPLETE; 25263f89caaSJens Wiklander 25316df60c7SEtienne Carriere rc = add_attribute(out, attrs[n], value, size); 25463f89caaSJens Wiklander if (rc) 25563f89caaSJens Wiklander return rc; 25663f89caaSJens Wiklander } 25763f89caaSJens Wiklander 25863f89caaSJens Wiklander return rc; 25963f89caaSJens Wiklander } 26063f89caaSJens Wiklander 26163f89caaSJens Wiklander static enum pkcs11_rc get_default_value(enum pkcs11_attr_id id, void **value, 26263f89caaSJens Wiklander uint32_t *size) 26363f89caaSJens Wiklander { 26463f89caaSJens Wiklander /* should have been taken care of already */ 26563f89caaSJens Wiklander assert(!pkcs11_attr_is_boolean(id)); 26663f89caaSJens Wiklander 26763f89caaSJens Wiklander /* All other attributes have an empty default value */ 26863f89caaSJens Wiklander *value = NULL; 26963f89caaSJens Wiklander *size = 0; 27063f89caaSJens Wiklander return PKCS11_CKR_OK; 27163f89caaSJens Wiklander } 27263f89caaSJens Wiklander 2734eb88651SRuchika Gupta static enum pkcs11_rc set_optional_attributes_with_def(struct obj_attrs **out, 27463f89caaSJens Wiklander struct obj_attrs *temp, 27516df60c7SEtienne Carriere uint32_t const *attrs, 27616df60c7SEtienne Carriere size_t attrs_count, 2774eb88651SRuchika Gupta bool default_to_null) 27863f89caaSJens Wiklander { 27963f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 28063f89caaSJens Wiklander size_t n = 0; 28163f89caaSJens Wiklander 28216df60c7SEtienne Carriere for (n = 0; n < attrs_count; n++) { 28363f89caaSJens Wiklander uint32_t size = 0; 28463f89caaSJens Wiklander void *value = NULL; 28563f89caaSJens Wiklander 28616df60c7SEtienne Carriere rc = get_attribute_ptr(temp, attrs[n], &value, &size); 2874eb88651SRuchika Gupta if (rc == PKCS11_RV_NOT_FOUND) { 2884eb88651SRuchika Gupta if (default_to_null) { 28916df60c7SEtienne Carriere rc = get_default_value(attrs[n], &value, &size); 2904eb88651SRuchika Gupta } else { 2914eb88651SRuchika Gupta rc = PKCS11_CKR_OK; 2924eb88651SRuchika Gupta continue; 2934eb88651SRuchika Gupta } 2944eb88651SRuchika Gupta } 29563f89caaSJens Wiklander if (rc) 29663f89caaSJens Wiklander return rc; 29763f89caaSJens Wiklander 29816df60c7SEtienne Carriere rc = add_attribute(out, attrs[n], value, size); 29963f89caaSJens Wiklander if (rc) 30063f89caaSJens Wiklander return rc; 30163f89caaSJens Wiklander } 30263f89caaSJens Wiklander 30363f89caaSJens Wiklander return rc; 30463f89caaSJens Wiklander } 30563f89caaSJens Wiklander 3064eb88651SRuchika Gupta static enum pkcs11_rc set_attributes_opt_or_null(struct obj_attrs **out, 3074eb88651SRuchika Gupta struct obj_attrs *temp, 30816df60c7SEtienne Carriere uint32_t const *attrs, 30916df60c7SEtienne Carriere size_t attrs_count) 3104eb88651SRuchika Gupta { 31116df60c7SEtienne Carriere return set_optional_attributes_with_def(out, temp, attrs, attrs_count, 31216df60c7SEtienne Carriere true /* defaults to empty */); 3134eb88651SRuchika Gupta } 3144eb88651SRuchika Gupta 3154eb88651SRuchika Gupta static enum pkcs11_rc set_optional_attributes(struct obj_attrs **out, 3164eb88651SRuchika Gupta struct obj_attrs *temp, 31716df60c7SEtienne Carriere uint32_t const *attrs, 31816df60c7SEtienne Carriere size_t attrs_count) 3194eb88651SRuchika Gupta { 32016df60c7SEtienne Carriere return set_optional_attributes_with_def(out, temp, attrs, attrs_count, 32116df60c7SEtienne Carriere false /* no default value */); 3224eb88651SRuchika Gupta } 3234eb88651SRuchika Gupta 32463f89caaSJens Wiklander /* 32563f89caaSJens Wiklander * Below are listed the mandated or optional expected attributes for 32663f89caaSJens Wiklander * PKCS#11 storage objects. 32763f89caaSJens Wiklander * 32863f89caaSJens Wiklander * Note: boolprops (mandated boolean attributes) PKCS11_CKA_ALWAYS_SENSITIVE, 32963f89caaSJens Wiklander * and PKCS11_CKA_NEVER_EXTRACTABLE are set by the token, not provided 33063f89caaSJens Wiklander * in the client template. 33163f89caaSJens Wiklander */ 33263f89caaSJens Wiklander 33363f89caaSJens Wiklander /* PKCS#11 specification for any object (session/token) of the storage */ 3344eb88651SRuchika Gupta static const uint32_t any_object_boolprops[] = { 33563f89caaSJens Wiklander PKCS11_CKA_TOKEN, PKCS11_CKA_PRIVATE, 33663f89caaSJens Wiklander PKCS11_CKA_MODIFIABLE, PKCS11_CKA_COPYABLE, PKCS11_CKA_DESTROYABLE, 33763f89caaSJens Wiklander }; 33863f89caaSJens Wiklander 3394eb88651SRuchika Gupta static const uint32_t any_object_opt_or_null[] = { 34063f89caaSJens Wiklander PKCS11_CKA_LABEL, 34163f89caaSJens Wiklander }; 34263f89caaSJens Wiklander 3434eb88651SRuchika Gupta /* PKCS#11 specification for raw data object (+any_object_xxx) */ 3444eb88651SRuchika Gupta const uint32_t raw_data_opt_or_null[] = { 34563f89caaSJens Wiklander PKCS11_CKA_OBJECT_ID, PKCS11_CKA_APPLICATION, PKCS11_CKA_VALUE, 34663f89caaSJens Wiklander }; 34763f89caaSJens Wiklander 3484137952dSVesa Jääskeläinen /* PKCS#11 specification for certificate object (+pkcs11_any_object_xxx) */ 3494137952dSVesa Jääskeläinen static const uint32_t pkcs11_certificate_mandated[] = { 3504137952dSVesa Jääskeläinen PKCS11_CKA_CERTIFICATE_TYPE, 3514137952dSVesa Jääskeläinen }; 3524137952dSVesa Jääskeläinen 3534137952dSVesa Jääskeläinen static const uint32_t pkcs11_certificate_boolprops[] = { 3544137952dSVesa Jääskeläinen PKCS11_CKA_TRUSTED, 3554137952dSVesa Jääskeläinen }; 3564137952dSVesa Jääskeläinen 3574137952dSVesa Jääskeläinen static const uint32_t pkcs11_certificate_optional[] = { 3584137952dSVesa Jääskeläinen PKCS11_CKA_CERTIFICATE_CATEGORY, PKCS11_CKA_CHECK_VALUE, 3594137952dSVesa Jääskeläinen PKCS11_CKA_START_DATE, PKCS11_CKA_END_DATE, PKCS11_CKA_PUBLIC_KEY_INFO, 3604137952dSVesa Jääskeläinen }; 3614137952dSVesa Jääskeläinen 3624137952dSVesa Jääskeläinen /* 3634137952dSVesa Jääskeläinen * PKCS#11 specification for X.509 certificate object (+pkcs11_certificate_xxx) 3644137952dSVesa Jääskeläinen */ 3654137952dSVesa Jääskeläinen static const uint32_t pkcs11_x509_certificate_mandated[] = { 3664137952dSVesa Jääskeläinen PKCS11_CKA_SUBJECT, 3674137952dSVesa Jääskeläinen }; 3684137952dSVesa Jääskeläinen 3694137952dSVesa Jääskeläinen static const uint32_t pkcs11_x509_certificate_optional[] = { 3704137952dSVesa Jääskeläinen PKCS11_CKA_ID, PKCS11_CKA_ISSUER, PKCS11_CKA_SERIAL_NUMBER, 3714137952dSVesa Jääskeläinen PKCS11_CKA_VALUE, PKCS11_CKA_URL, 3724137952dSVesa Jääskeläinen PKCS11_CKA_HASH_OF_SUBJECT_PUBLIC_KEY, 3734137952dSVesa Jääskeläinen PKCS11_CKA_HASH_OF_ISSUER_PUBLIC_KEY, 3744137952dSVesa Jääskeläinen PKCS11_CKA_JAVA_MIDP_SECURITY_DOMAIN, PKCS11_CKA_NAME_HASH_ALGORITHM, 3754137952dSVesa Jääskeläinen }; 3764137952dSVesa Jääskeläinen 3774eb88651SRuchika Gupta /* PKCS#11 specification for any key object (+any_object_xxx) */ 3784eb88651SRuchika Gupta static const uint32_t any_key_boolprops[] = { 37963f89caaSJens Wiklander PKCS11_CKA_DERIVE, 38063f89caaSJens Wiklander }; 38163f89caaSJens Wiklander 3824eb88651SRuchika Gupta static const uint32_t any_key_opt_or_null[] = { 38363f89caaSJens Wiklander PKCS11_CKA_ID, 38463f89caaSJens Wiklander PKCS11_CKA_START_DATE, PKCS11_CKA_END_DATE, 3854eb88651SRuchika Gupta }; 3864eb88651SRuchika Gupta 3874eb88651SRuchika Gupta static const uint32_t any_key_optional[] = { 38863f89caaSJens Wiklander PKCS11_CKA_ALLOWED_MECHANISMS, 38963f89caaSJens Wiklander }; 39063f89caaSJens Wiklander 3914eb88651SRuchika Gupta /* PKCS#11 specification for any symmetric key (+any_key_xxx) */ 3924eb88651SRuchika Gupta static const uint32_t symm_key_boolprops[] = { 39363f89caaSJens Wiklander PKCS11_CKA_ENCRYPT, PKCS11_CKA_DECRYPT, 39463f89caaSJens Wiklander PKCS11_CKA_SIGN, PKCS11_CKA_VERIFY, 39563f89caaSJens Wiklander PKCS11_CKA_WRAP, PKCS11_CKA_UNWRAP, 39663f89caaSJens Wiklander PKCS11_CKA_SENSITIVE, PKCS11_CKA_EXTRACTABLE, 39763f89caaSJens Wiklander PKCS11_CKA_WRAP_WITH_TRUSTED, PKCS11_CKA_TRUSTED, 39863f89caaSJens Wiklander }; 39963f89caaSJens Wiklander 4004eb88651SRuchika Gupta static const uint32_t symm_key_opt_or_null[] = { 40163f89caaSJens Wiklander PKCS11_CKA_WRAP_TEMPLATE, PKCS11_CKA_UNWRAP_TEMPLATE, 4020ac5c695SRuchika Gupta PKCS11_CKA_DERIVE_TEMPLATE, PKCS11_CKA_VALUE, 4030ac5c695SRuchika Gupta }; 4040ac5c695SRuchika Gupta 4050ac5c695SRuchika Gupta static const uint32_t symm_key_optional[] = { 4060ac5c695SRuchika Gupta PKCS11_CKA_VALUE_LEN, 40763f89caaSJens Wiklander }; 40863f89caaSJens Wiklander 4094eb88651SRuchika Gupta /* PKCS#11 specification for any asymmetric public key (+any_key_xxx) */ 4104eb88651SRuchika Gupta static const uint32_t public_key_boolprops[] = { 41163f89caaSJens Wiklander PKCS11_CKA_ENCRYPT, PKCS11_CKA_VERIFY, PKCS11_CKA_VERIFY_RECOVER, 41263f89caaSJens Wiklander PKCS11_CKA_WRAP, 41363f89caaSJens Wiklander PKCS11_CKA_TRUSTED, 41463f89caaSJens Wiklander }; 41563f89caaSJens Wiklander 4164eb88651SRuchika Gupta static const uint32_t public_key_mandated[] = { 41763f89caaSJens Wiklander }; 41863f89caaSJens Wiklander 4194eb88651SRuchika Gupta static const uint32_t public_key_opt_or_null[] = { 420edd95148SVesa Jääskeläinen PKCS11_CKA_SUBJECT, PKCS11_CKA_WRAP_TEMPLATE, 421edd95148SVesa Jääskeläinen PKCS11_CKA_PUBLIC_KEY_INFO, 42263f89caaSJens Wiklander }; 42363f89caaSJens Wiklander 4244eb88651SRuchika Gupta /* PKCS#11 specification for any asymmetric private key (+any_key_xxx) */ 4254eb88651SRuchika Gupta static const uint32_t private_key_boolprops[] = { 42663f89caaSJens Wiklander PKCS11_CKA_DECRYPT, PKCS11_CKA_SIGN, PKCS11_CKA_SIGN_RECOVER, 42763f89caaSJens Wiklander PKCS11_CKA_UNWRAP, 42863f89caaSJens Wiklander PKCS11_CKA_SENSITIVE, PKCS11_CKA_EXTRACTABLE, 42963f89caaSJens Wiklander PKCS11_CKA_WRAP_WITH_TRUSTED, PKCS11_CKA_ALWAYS_AUTHENTICATE, 43063f89caaSJens Wiklander }; 43163f89caaSJens Wiklander 4324eb88651SRuchika Gupta static const uint32_t private_key_mandated[] = { 43363f89caaSJens Wiklander }; 43463f89caaSJens Wiklander 4354eb88651SRuchika Gupta static const uint32_t private_key_opt_or_null[] = { 436edd95148SVesa Jääskeläinen PKCS11_CKA_SUBJECT, PKCS11_CKA_UNWRAP_TEMPLATE, 437edd95148SVesa Jääskeläinen PKCS11_CKA_PUBLIC_KEY_INFO, 43863f89caaSJens Wiklander }; 43963f89caaSJens Wiklander 4404eb88651SRuchika Gupta /* PKCS#11 specification for any RSA key (+public/private_key_xxx) */ 4419cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_gen_mand[] = { 44263f89caaSJens Wiklander PKCS11_CKA_MODULUS_BITS, 44363f89caaSJens Wiklander }; 44463f89caaSJens Wiklander 4459cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_create_mand[] = { 44663f89caaSJens Wiklander PKCS11_CKA_MODULUS, PKCS11_CKA_PUBLIC_EXPONENT, 44763f89caaSJens Wiklander }; 44863f89caaSJens Wiklander 4499cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_gen_opt_or_null[] = { 4509cf1afceSVesa Jääskeläinen PKCS11_CKA_PUBLIC_EXPONENT, 4519cf1afceSVesa Jääskeläinen }; 4529cf1afceSVesa Jääskeläinen 4539cf1afceSVesa Jääskeläinen static const uint32_t rsa_priv_key_opt_or_null[] = { 45463f89caaSJens Wiklander PKCS11_CKA_MODULUS, PKCS11_CKA_PUBLIC_EXPONENT, 45563f89caaSJens Wiklander PKCS11_CKA_PRIVATE_EXPONENT, 45663f89caaSJens Wiklander PKCS11_CKA_PRIME_1, PKCS11_CKA_PRIME_2, 45763f89caaSJens Wiklander PKCS11_CKA_EXPONENT_1, PKCS11_CKA_EXPONENT_2, PKCS11_CKA_COEFFICIENT, 45863f89caaSJens Wiklander }; 45963f89caaSJens Wiklander 4604eb88651SRuchika Gupta /* PKCS#11 specification for any EC key (+public/private_key_xxx) */ 4614eb88651SRuchika Gupta static const uint32_t ec_public_key_mandated[] = { 46263f89caaSJens Wiklander PKCS11_CKA_EC_PARAMS, 46363f89caaSJens Wiklander }; 46463f89caaSJens Wiklander 4654eb88651SRuchika Gupta static const uint32_t ec_public_key_opt_or_null[] = { 46663f89caaSJens Wiklander PKCS11_CKA_EC_POINT, 46763f89caaSJens Wiklander }; 46863f89caaSJens Wiklander 4694eb88651SRuchika Gupta static const uint32_t ec_private_key_mandated[] = { 47063f89caaSJens Wiklander }; 47163f89caaSJens Wiklander 4724eb88651SRuchika Gupta static const uint32_t ec_private_key_opt_or_null[] = { 47302b16804SVesa Jääskeläinen PKCS11_CKA_EC_PARAMS, 47463f89caaSJens Wiklander PKCS11_CKA_VALUE, 47563f89caaSJens Wiklander }; 47663f89caaSJens Wiklander 47703e07432SValerii Chubar static const uint32_t eddsa_private_key_opt_or_null[] = { 47803e07432SValerii Chubar PKCS11_CKA_EC_PARAMS, 47903e07432SValerii Chubar PKCS11_CKA_VALUE, 48003e07432SValerii Chubar PKCS11_CKA_EC_POINT, 48103e07432SValerii Chubar }; 48203e07432SValerii Chubar 48363f89caaSJens Wiklander static enum pkcs11_rc create_storage_attributes(struct obj_attrs **out, 48463f89caaSJens Wiklander struct obj_attrs *temp) 48563f89caaSJens Wiklander { 48663f89caaSJens Wiklander enum pkcs11_class_id class = PKCS11_CKO_UNDEFINED_ID; 48763f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 48863f89caaSJens Wiklander 48963f89caaSJens Wiklander rc = init_attributes_head(out); 49063f89caaSJens Wiklander if (rc) 49163f89caaSJens Wiklander return rc; 49263f89caaSJens Wiklander 49363f89caaSJens Wiklander /* Object class is mandatory */ 49463f89caaSJens Wiklander class = get_class(temp); 49563f89caaSJens Wiklander if (class == PKCS11_CKO_UNDEFINED_ID) { 49663f89caaSJens Wiklander EMSG("Class attribute not found"); 49763f89caaSJens Wiklander 49863f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 49963f89caaSJens Wiklander } 50063f89caaSJens Wiklander rc = add_attribute(out, PKCS11_CKA_CLASS, &class, sizeof(uint32_t)); 50163f89caaSJens Wiklander if (rc) 50263f89caaSJens Wiklander return rc; 50363f89caaSJens Wiklander 5044eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, any_object_boolprops, 5054eb88651SRuchika Gupta ARRAY_SIZE(any_object_boolprops)); 50663f89caaSJens Wiklander if (rc) 50763f89caaSJens Wiklander return rc; 50863f89caaSJens Wiklander 5094eb88651SRuchika Gupta return set_attributes_opt_or_null(out, temp, any_object_opt_or_null, 5104eb88651SRuchika Gupta ARRAY_SIZE(any_object_opt_or_null)); 51163f89caaSJens Wiklander } 51263f89caaSJens Wiklander 51363f89caaSJens Wiklander static enum pkcs11_rc create_genkey_attributes(struct obj_attrs **out, 51463f89caaSJens Wiklander struct obj_attrs *temp) 51563f89caaSJens Wiklander { 51663f89caaSJens Wiklander uint32_t type = PKCS11_CKO_UNDEFINED_ID; 51763f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 51863f89caaSJens Wiklander 51963f89caaSJens Wiklander rc = create_storage_attributes(out, temp); 52063f89caaSJens Wiklander if (rc) 52163f89caaSJens Wiklander return rc; 52263f89caaSJens Wiklander 52363f89caaSJens Wiklander type = get_key_type(temp); 52463f89caaSJens Wiklander if (type == PKCS11_CKK_UNDEFINED_ID) { 52563f89caaSJens Wiklander EMSG("Key type attribute not found"); 52663f89caaSJens Wiklander 52763f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 52863f89caaSJens Wiklander } 52963f89caaSJens Wiklander rc = add_attribute(out, PKCS11_CKA_KEY_TYPE, &type, sizeof(uint32_t)); 53063f89caaSJens Wiklander if (rc) 53163f89caaSJens Wiklander return rc; 53263f89caaSJens Wiklander 5334eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, any_key_boolprops, 5344eb88651SRuchika Gupta ARRAY_SIZE(any_key_boolprops)); 53563f89caaSJens Wiklander if (rc) 53663f89caaSJens Wiklander return rc; 53763f89caaSJens Wiklander 5384eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, any_key_opt_or_null, 5394eb88651SRuchika Gupta ARRAY_SIZE(any_key_opt_or_null)); 5404eb88651SRuchika Gupta if (rc) 5414eb88651SRuchika Gupta return rc; 5424eb88651SRuchika Gupta 5434eb88651SRuchika Gupta return set_optional_attributes(out, temp, any_key_optional, 5444eb88651SRuchika Gupta ARRAY_SIZE(any_key_optional)); 5454eb88651SRuchika Gupta 54663f89caaSJens Wiklander } 54763f89caaSJens Wiklander 54863f89caaSJens Wiklander static enum pkcs11_rc create_symm_key_attributes(struct obj_attrs **out, 54963f89caaSJens Wiklander struct obj_attrs *temp) 55063f89caaSJens Wiklander { 55163f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 55263f89caaSJens Wiklander 55363f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_SECRET_KEY); 55463f89caaSJens Wiklander 55563f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 55663f89caaSJens Wiklander if (rc) 55763f89caaSJens Wiklander return rc; 55863f89caaSJens Wiklander 55963f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_SECRET_KEY); 56063f89caaSJens Wiklander 56163f89caaSJens Wiklander switch (get_key_type(*out)) { 56263f89caaSJens Wiklander case PKCS11_CKK_GENERIC_SECRET: 56363f89caaSJens Wiklander case PKCS11_CKK_AES: 56463f89caaSJens Wiklander case PKCS11_CKK_MD5_HMAC: 56563f89caaSJens Wiklander case PKCS11_CKK_SHA_1_HMAC: 56663f89caaSJens Wiklander case PKCS11_CKK_SHA256_HMAC: 56763f89caaSJens Wiklander case PKCS11_CKK_SHA384_HMAC: 56863f89caaSJens Wiklander case PKCS11_CKK_SHA512_HMAC: 56963f89caaSJens Wiklander case PKCS11_CKK_SHA224_HMAC: 57063f89caaSJens Wiklander break; 57163f89caaSJens Wiklander default: 57263f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 57363f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 57463f89caaSJens Wiklander 57563f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 57663f89caaSJens Wiklander } 57763f89caaSJens Wiklander 5784eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, symm_key_boolprops, 5794eb88651SRuchika Gupta ARRAY_SIZE(symm_key_boolprops)); 58063f89caaSJens Wiklander if (rc) 58163f89caaSJens Wiklander return rc; 58263f89caaSJens Wiklander 5830ac5c695SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, symm_key_opt_or_null, 5844eb88651SRuchika Gupta ARRAY_SIZE(symm_key_opt_or_null)); 5850ac5c695SRuchika Gupta if (rc) 5860ac5c695SRuchika Gupta return rc; 5870ac5c695SRuchika Gupta 5880ac5c695SRuchika Gupta return set_optional_attributes(out, temp, symm_key_optional, 5890ac5c695SRuchika Gupta ARRAY_SIZE(symm_key_optional)); 59063f89caaSJens Wiklander } 59163f89caaSJens Wiklander 59263f89caaSJens Wiklander static enum pkcs11_rc create_data_attributes(struct obj_attrs **out, 59363f89caaSJens Wiklander struct obj_attrs *temp) 59463f89caaSJens Wiklander { 59563f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 59663f89caaSJens Wiklander 59763f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_DATA); 59863f89caaSJens Wiklander 59963f89caaSJens Wiklander rc = create_storage_attributes(out, temp); 60063f89caaSJens Wiklander if (rc) 60163f89caaSJens Wiklander return rc; 60263f89caaSJens Wiklander 60363f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_DATA); 60463f89caaSJens Wiklander 6054eb88651SRuchika Gupta return set_attributes_opt_or_null(out, temp, raw_data_opt_or_null, 6064eb88651SRuchika Gupta ARRAY_SIZE(raw_data_opt_or_null)); 60763f89caaSJens Wiklander } 60863f89caaSJens Wiklander 6094137952dSVesa Jääskeläinen static enum pkcs11_rc create_certificate_attributes(struct obj_attrs **out, 6104137952dSVesa Jääskeläinen struct obj_attrs *temp) 6114137952dSVesa Jääskeläinen { 6124137952dSVesa Jääskeläinen uint32_t const *mandated = NULL; 6134137952dSVesa Jääskeläinen uint32_t const *optional = NULL; 6144137952dSVesa Jääskeläinen size_t mandated_count = 0; 6154137952dSVesa Jääskeläinen size_t optional_count = 0; 6164137952dSVesa Jääskeläinen void *attr_value = NULL; 6174137952dSVesa Jääskeläinen uint32_t attr_size = 0; 6184137952dSVesa Jääskeläinen uint32_t default_cert_category = 6194137952dSVesa Jääskeläinen PKCS11_CK_CERTIFICATE_CATEGORY_UNSPECIFIED; 6204137952dSVesa Jääskeläinen uint32_t default_name_hash_alg = PKCS11_CKM_SHA_1; 6214137952dSVesa Jääskeläinen uint32_t cert_category = 0; 6224137952dSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_OK; 6234137952dSVesa Jääskeläinen 6244137952dSVesa Jääskeläinen assert(get_class(temp) == PKCS11_CKO_CERTIFICATE); 6254137952dSVesa Jääskeläinen 6264137952dSVesa Jääskeläinen rc = create_storage_attributes(out, temp); 6274137952dSVesa Jääskeläinen if (rc) 6284137952dSVesa Jääskeläinen return rc; 6294137952dSVesa Jääskeläinen 6304137952dSVesa Jääskeläinen assert(get_class(*out) == PKCS11_CKO_CERTIFICATE); 6314137952dSVesa Jääskeläinen 6324137952dSVesa Jääskeläinen rc = set_mandatory_boolprops(out, temp, pkcs11_certificate_boolprops, 6334137952dSVesa Jääskeläinen ARRAY_SIZE(pkcs11_certificate_boolprops)); 6344137952dSVesa Jääskeläinen if (rc) 6354137952dSVesa Jääskeläinen return rc; 6364137952dSVesa Jääskeläinen 6374137952dSVesa Jääskeläinen rc = set_mandatory_attributes(out, temp, pkcs11_certificate_mandated, 6384137952dSVesa Jääskeläinen ARRAY_SIZE(pkcs11_certificate_mandated)); 6394137952dSVesa Jääskeläinen if (rc) 6404137952dSVesa Jääskeläinen return rc; 6414137952dSVesa Jääskeläinen 6424137952dSVesa Jääskeläinen rc = set_optional_attributes(out, temp, pkcs11_certificate_optional, 6434137952dSVesa Jääskeläinen ARRAY_SIZE(pkcs11_certificate_optional)); 6444137952dSVesa Jääskeläinen if (rc) 6454137952dSVesa Jääskeläinen return rc; 6464137952dSVesa Jääskeläinen 6474137952dSVesa Jääskeläinen switch (get_certificate_type(*out)) { 6484137952dSVesa Jääskeläinen case PKCS11_CKC_X_509: 6494137952dSVesa Jääskeläinen mandated = pkcs11_x509_certificate_mandated; 6504137952dSVesa Jääskeläinen optional = pkcs11_x509_certificate_optional; 6514137952dSVesa Jääskeläinen mandated_count = ARRAY_SIZE(pkcs11_x509_certificate_mandated); 6524137952dSVesa Jääskeläinen optional_count = ARRAY_SIZE(pkcs11_x509_certificate_optional); 6534137952dSVesa Jääskeläinen break; 6544137952dSVesa Jääskeläinen default: 6554137952dSVesa Jääskeläinen EMSG("Invalid certificate type %#"PRIx32"/%s", 6564137952dSVesa Jääskeläinen get_certificate_type(*out), 6574137952dSVesa Jääskeläinen id2str_certificate_type(get_certificate_type(*out))); 6584137952dSVesa Jääskeläinen 6594137952dSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 6604137952dSVesa Jääskeläinen } 6614137952dSVesa Jääskeläinen 6624137952dSVesa Jääskeläinen rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 6634137952dSVesa Jääskeläinen if (rc) 6644137952dSVesa Jääskeläinen return rc; 6654137952dSVesa Jääskeläinen 6664137952dSVesa Jääskeläinen rc = set_optional_attributes(out, temp, optional, optional_count); 6674137952dSVesa Jääskeläinen if (rc) 6684137952dSVesa Jääskeläinen return rc; 6694137952dSVesa Jääskeläinen 6704137952dSVesa Jääskeläinen attr_size = 0; 6714137952dSVesa Jääskeläinen rc = get_attribute_ptr(*out, PKCS11_CKA_CERTIFICATE_CATEGORY, 6724137952dSVesa Jääskeläinen &attr_value, &attr_size); 6734137952dSVesa Jääskeläinen if (rc == PKCS11_CKR_OK && attr_size == sizeof(cert_category)) { 6744137952dSVesa Jääskeläinen /* Sanitize certificate category */ 6754137952dSVesa Jääskeläinen TEE_MemMove(&cert_category, attr_value, sizeof(cert_category)); 6764137952dSVesa Jääskeläinen 6774137952dSVesa Jääskeläinen switch (cert_category) { 6784137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_UNSPECIFIED: 6794137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_TOKEN_USER: 6804137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_AUTHORITY: 6814137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_OTHER_ENTITY: 6824137952dSVesa Jääskeläinen break; 6834137952dSVesa Jääskeläinen default: 6844137952dSVesa Jääskeläinen EMSG("Invalid certificate category %#"PRIx32, 6854137952dSVesa Jääskeläinen cert_category); 6864137952dSVesa Jääskeläinen 6874137952dSVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 6884137952dSVesa Jääskeläinen } 6894137952dSVesa Jääskeläinen } else if (rc == PKCS11_RV_NOT_FOUND) { 6904137952dSVesa Jääskeläinen /* Set default category when missing */ 6914137952dSVesa Jääskeläinen rc = set_attribute(out, PKCS11_CKA_CERTIFICATE_CATEGORY, 6924137952dSVesa Jääskeläinen &default_cert_category, 6934137952dSVesa Jääskeläinen sizeof(default_cert_category)); 6944137952dSVesa Jääskeläinen if (rc) 6954137952dSVesa Jääskeläinen return rc; 6964137952dSVesa Jääskeläinen } else { 6974137952dSVesa Jääskeläinen /* All other cases are errors */ 6984137952dSVesa Jääskeläinen EMSG("Invalid certificate category"); 6994137952dSVesa Jääskeläinen 7004137952dSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 7014137952dSVesa Jääskeläinen } 7024137952dSVesa Jääskeläinen 7034137952dSVesa Jääskeläinen attr_size = 0; 7044137952dSVesa Jääskeläinen rc = get_attribute_ptr(*out, PKCS11_CKA_NAME_HASH_ALGORITHM, NULL, 7054137952dSVesa Jääskeläinen &attr_size); 7064137952dSVesa Jääskeläinen if (rc == PKCS11_CKR_OK && attr_size == sizeof(uint32_t)) { 7074137952dSVesa Jääskeläinen /* We accept any algorithm what caller wanted to specify */ 7084137952dSVesa Jääskeläinen } else if (rc == PKCS11_RV_NOT_FOUND) { 7094137952dSVesa Jääskeläinen /* Set default hash algorithm when missing */ 7104137952dSVesa Jääskeläinen rc = set_attribute(out, PKCS11_CKA_NAME_HASH_ALGORITHM, 7114137952dSVesa Jääskeläinen &default_name_hash_alg, 7124137952dSVesa Jääskeläinen sizeof(default_name_hash_alg)); 7134137952dSVesa Jääskeläinen if (rc) 7144137952dSVesa Jääskeläinen return rc; 7154137952dSVesa Jääskeläinen } else { 7164137952dSVesa Jääskeläinen /* All other cases are errors */ 7174137952dSVesa Jääskeläinen EMSG("Invalid name hash algorithm"); 7184137952dSVesa Jääskeläinen 7194137952dSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 7204137952dSVesa Jääskeläinen } 7214137952dSVesa Jääskeläinen 7224137952dSVesa Jääskeläinen return rc; 7234137952dSVesa Jääskeläinen } 7244137952dSVesa Jääskeläinen 72563f89caaSJens Wiklander static enum pkcs11_rc create_pub_key_attributes(struct obj_attrs **out, 7269cf1afceSVesa Jääskeläinen struct obj_attrs *temp, 7279cf1afceSVesa Jääskeläinen enum processing_func function) 72863f89caaSJens Wiklander { 72963f89caaSJens Wiklander uint32_t const *mandated = NULL; 7309cf1afceSVesa Jääskeläinen uint32_t const *oon = NULL; 73163f89caaSJens Wiklander size_t mandated_count = 0; 7329cf1afceSVesa Jääskeläinen size_t oon_count = 0; 73363f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 73463f89caaSJens Wiklander 73563f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_PUBLIC_KEY); 73663f89caaSJens Wiklander 73763f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 73863f89caaSJens Wiklander if (rc) 73963f89caaSJens Wiklander return rc; 74063f89caaSJens Wiklander 74163f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_PUBLIC_KEY); 74263f89caaSJens Wiklander 7434eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, public_key_boolprops, 7444eb88651SRuchika Gupta ARRAY_SIZE(public_key_boolprops)); 74563f89caaSJens Wiklander if (rc) 74663f89caaSJens Wiklander return rc; 74763f89caaSJens Wiklander 7484eb88651SRuchika Gupta rc = set_mandatory_attributes(out, temp, public_key_mandated, 7494eb88651SRuchika Gupta ARRAY_SIZE(public_key_mandated)); 75063f89caaSJens Wiklander if (rc) 75163f89caaSJens Wiklander return rc; 75263f89caaSJens Wiklander 7534eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, 7544eb88651SRuchika Gupta public_key_opt_or_null, 7554eb88651SRuchika Gupta ARRAY_SIZE(public_key_opt_or_null)); 75663f89caaSJens Wiklander if (rc) 75763f89caaSJens Wiklander return rc; 75863f89caaSJens Wiklander 75963f89caaSJens Wiklander switch (get_key_type(*out)) { 76063f89caaSJens Wiklander case PKCS11_CKK_RSA: 7619cf1afceSVesa Jääskeläinen switch (function) { 7629cf1afceSVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 7639cf1afceSVesa Jääskeläinen mandated = rsa_pub_key_gen_mand; 7649cf1afceSVesa Jääskeläinen oon = rsa_pub_key_gen_opt_or_null; 7659cf1afceSVesa Jääskeläinen mandated_count = ARRAY_SIZE(rsa_pub_key_gen_mand); 7669cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(rsa_pub_key_gen_opt_or_null); 7679cf1afceSVesa Jääskeläinen break; 7689cf1afceSVesa Jääskeläinen case PKCS11_FUNCTION_IMPORT: 7699cf1afceSVesa Jääskeläinen mandated = rsa_pub_key_create_mand; 7709cf1afceSVesa Jääskeläinen mandated_count = ARRAY_SIZE(rsa_pub_key_create_mand); 7719cf1afceSVesa Jääskeläinen break; 7729cf1afceSVesa Jääskeläinen default: 7739cf1afceSVesa Jääskeläinen EMSG("Unsupported function %#"PRIx32"/%s", function, 7749cf1afceSVesa Jääskeläinen id2str_function(function)); 7759cf1afceSVesa Jääskeläinen 7769cf1afceSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 7779cf1afceSVesa Jääskeläinen } 77863f89caaSJens Wiklander break; 77963f89caaSJens Wiklander case PKCS11_CKK_EC: 78003e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 7814eb88651SRuchika Gupta mandated = ec_public_key_mandated; 7829cf1afceSVesa Jääskeläinen oon = ec_public_key_opt_or_null; 7834eb88651SRuchika Gupta mandated_count = ARRAY_SIZE(ec_public_key_mandated); 7849cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(ec_public_key_opt_or_null); 78563f89caaSJens Wiklander break; 78663f89caaSJens Wiklander default: 78763f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 78863f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 78963f89caaSJens Wiklander 79063f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 79163f89caaSJens Wiklander } 79263f89caaSJens Wiklander 79363f89caaSJens Wiklander rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 79463f89caaSJens Wiklander if (rc) 79563f89caaSJens Wiklander return rc; 79663f89caaSJens Wiklander 7979cf1afceSVesa Jääskeläinen return set_attributes_opt_or_null(out, temp, oon, oon_count); 79863f89caaSJens Wiklander } 79963f89caaSJens Wiklander 8005071d7d1SVesa Jääskeläinen static enum pkcs11_rc 8015071d7d1SVesa Jääskeläinen create_pub_key_rsa_generated_attributes(struct obj_attrs **out, 8025071d7d1SVesa Jääskeläinen struct obj_attrs *temp, 8035071d7d1SVesa Jääskeläinen enum processing_func function) 8045071d7d1SVesa Jääskeläinen { 8055071d7d1SVesa Jääskeläinen uint32_t key_bits = 0; 8065071d7d1SVesa Jääskeläinen void *a_ptr = NULL; 8075071d7d1SVesa Jääskeläinen uint32_t a_size = 0; 8085071d7d1SVesa Jääskeläinen 8095071d7d1SVesa Jääskeläinen if (function != PKCS11_FUNCTION_IMPORT) 8105071d7d1SVesa Jääskeläinen return PKCS11_CKR_OK; 8115071d7d1SVesa Jääskeläinen 8125071d7d1SVesa Jääskeläinen /* Calculate CKA_MODULUS_BITS */ 8135071d7d1SVesa Jääskeläinen 8145071d7d1SVesa Jääskeläinen if (get_attribute_ptr(temp, PKCS11_CKA_MODULUS, 8155071d7d1SVesa Jääskeläinen &a_ptr, &a_size) || !a_ptr) { 8165071d7d1SVesa Jääskeläinen EMSG("No CKA_MODULUS attribute found in public key"); 8175071d7d1SVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 8185071d7d1SVesa Jääskeläinen } 8195071d7d1SVesa Jääskeläinen 8205071d7d1SVesa Jääskeläinen key_bits = a_size * 8; 8215071d7d1SVesa Jääskeläinen 8225071d7d1SVesa Jääskeläinen return add_attribute(out, PKCS11_CKA_MODULUS_BITS, &key_bits, 8235071d7d1SVesa Jääskeläinen sizeof(key_bits)); 8245071d7d1SVesa Jääskeläinen } 8255071d7d1SVesa Jääskeläinen 8265071d7d1SVesa Jääskeläinen static enum pkcs11_rc 8275071d7d1SVesa Jääskeläinen create_pub_key_generated_attributes(struct obj_attrs **out, 8285071d7d1SVesa Jääskeläinen struct obj_attrs *temp, 8295071d7d1SVesa Jääskeläinen enum processing_func function) 8305071d7d1SVesa Jääskeläinen { 8315071d7d1SVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_OK; 8325071d7d1SVesa Jääskeläinen 8335071d7d1SVesa Jääskeläinen switch (get_key_type(*out)) { 8345071d7d1SVesa Jääskeläinen case PKCS11_CKK_RSA: 8355071d7d1SVesa Jääskeläinen rc = create_pub_key_rsa_generated_attributes(out, temp, 8365071d7d1SVesa Jääskeläinen function); 8375071d7d1SVesa Jääskeläinen break; 8385071d7d1SVesa Jääskeläinen default: 8395071d7d1SVesa Jääskeläinen /* no-op */ 8405071d7d1SVesa Jääskeläinen break; 8415071d7d1SVesa Jääskeläinen } 8425071d7d1SVesa Jääskeläinen 8435071d7d1SVesa Jääskeläinen return rc; 8445071d7d1SVesa Jääskeläinen } 8455071d7d1SVesa Jääskeläinen 84663f89caaSJens Wiklander static enum pkcs11_rc create_priv_key_attributes(struct obj_attrs **out, 84763f89caaSJens Wiklander struct obj_attrs *temp) 84863f89caaSJens Wiklander { 84963f89caaSJens Wiklander uint32_t const *mandated = NULL; 8509cf1afceSVesa Jääskeläinen uint32_t const *oon = NULL; 85163f89caaSJens Wiklander size_t mandated_count = 0; 8529cf1afceSVesa Jääskeläinen size_t oon_count = 0; 85363f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 85463f89caaSJens Wiklander 85563f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_PRIVATE_KEY); 85663f89caaSJens Wiklander 85763f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 85863f89caaSJens Wiklander if (rc) 85963f89caaSJens Wiklander return rc; 86063f89caaSJens Wiklander 86163f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_PRIVATE_KEY); 86263f89caaSJens Wiklander 8634eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, private_key_boolprops, 8644eb88651SRuchika Gupta ARRAY_SIZE(private_key_boolprops)); 86563f89caaSJens Wiklander if (rc) 86663f89caaSJens Wiklander return rc; 86763f89caaSJens Wiklander 8684eb88651SRuchika Gupta rc = set_mandatory_attributes(out, temp, private_key_mandated, 8694eb88651SRuchika Gupta ARRAY_SIZE(private_key_mandated)); 87063f89caaSJens Wiklander if (rc) 87163f89caaSJens Wiklander return rc; 87263f89caaSJens Wiklander 8734eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, private_key_opt_or_null, 8744eb88651SRuchika Gupta ARRAY_SIZE(private_key_opt_or_null)); 87563f89caaSJens Wiklander if (rc) 87663f89caaSJens Wiklander return rc; 87763f89caaSJens Wiklander 87863f89caaSJens Wiklander switch (get_key_type(*out)) { 87963f89caaSJens Wiklander case PKCS11_CKK_RSA: 8809cf1afceSVesa Jääskeläinen oon = rsa_priv_key_opt_or_null; 8819cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(rsa_priv_key_opt_or_null); 88263f89caaSJens Wiklander break; 88363f89caaSJens Wiklander case PKCS11_CKK_EC: 8844eb88651SRuchika Gupta mandated = ec_private_key_mandated; 8859cf1afceSVesa Jääskeläinen oon = ec_private_key_opt_or_null; 8864eb88651SRuchika Gupta mandated_count = ARRAY_SIZE(ec_private_key_mandated); 8879cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(ec_private_key_opt_or_null); 88863f89caaSJens Wiklander break; 88903e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 89003e07432SValerii Chubar mandated = ec_private_key_mandated; 89103e07432SValerii Chubar oon = eddsa_private_key_opt_or_null; 89203e07432SValerii Chubar mandated_count = ARRAY_SIZE(ec_private_key_mandated); 89303e07432SValerii Chubar oon_count = ARRAY_SIZE(eddsa_private_key_opt_or_null); 89403e07432SValerii Chubar break; 89563f89caaSJens Wiklander default: 89663f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 89763f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 89863f89caaSJens Wiklander 89963f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 90063f89caaSJens Wiklander } 90163f89caaSJens Wiklander 90263f89caaSJens Wiklander rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 90363f89caaSJens Wiklander if (rc) 90463f89caaSJens Wiklander return rc; 90563f89caaSJens Wiklander 9069cf1afceSVesa Jääskeläinen return set_attributes_opt_or_null(out, temp, oon, oon_count); 90763f89caaSJens Wiklander } 90863f89caaSJens Wiklander 909196bcd93SRuchika Gupta static enum pkcs11_rc 910*7c243321SVesa Jääskeläinen create_ec_priv_key_hidden_attributes(struct obj_attrs **out, 911*7c243321SVesa Jääskeläinen struct obj_attrs *temp, 912*7c243321SVesa Jääskeläinen enum processing_func function) 913*7c243321SVesa Jääskeläinen { 914*7c243321SVesa Jääskeläinen struct mbedtls_ecp_keypair key_pair = { }; 915*7c243321SVesa Jääskeläinen mbedtls_ecp_group_id ec_curve = MBEDTLS_ECP_DP_NONE; 916*7c243321SVesa Jääskeläinen size_t buflen = 0; 917*7c243321SVesa Jääskeläinen uint8_t *buf = NULL; 918*7c243321SVesa Jääskeläinen size_t asnbuflen = 0; 919*7c243321SVesa Jääskeläinen uint8_t *asnbuf = NULL; 920*7c243321SVesa Jääskeläinen uint8_t *ptr = NULL; 921*7c243321SVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 922*7c243321SVesa Jääskeläinen int tee_size = 0; 923*7c243321SVesa Jääskeläinen int tee_curve = 0; 924*7c243321SVesa Jääskeläinen void *a_ptr = NULL; 925*7c243321SVesa Jääskeläinen uint32_t a_size = 0; 926*7c243321SVesa Jääskeläinen int ret = 0; 927*7c243321SVesa Jääskeläinen 928*7c243321SVesa Jääskeläinen if (function != PKCS11_FUNCTION_IMPORT) 929*7c243321SVesa Jääskeläinen return PKCS11_CKR_OK; 930*7c243321SVesa Jääskeläinen 931*7c243321SVesa Jääskeläinen /* 932*7c243321SVesa Jääskeläinen * TEE internal API requires that for private key operations there 933*7c243321SVesa Jääskeläinen * needs to be also public key available. 934*7c243321SVesa Jääskeläinen * 935*7c243321SVesa Jääskeläinen * Generate hidden EC point from private key. 936*7c243321SVesa Jääskeläinen */ 937*7c243321SVesa Jääskeläinen 938*7c243321SVesa Jääskeläinen if (get_attribute_ptr(temp, PKCS11_CKA_EC_PARAMS, 939*7c243321SVesa Jääskeläinen &a_ptr, &a_size) || !a_ptr) { 940*7c243321SVesa Jääskeläinen EMSG("No EC_PARAMS attribute found in private key"); 941*7c243321SVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 942*7c243321SVesa Jääskeläinen } 943*7c243321SVesa Jääskeläinen 944*7c243321SVesa Jääskeläinen /* Just valdiate that curve is found */ 945*7c243321SVesa Jääskeläinen tee_size = ec_params2tee_keysize(a_ptr, a_size); 946*7c243321SVesa Jääskeläinen if (!tee_size) { 947*7c243321SVesa Jääskeläinen EMSG("Unsupported EC_PARAMS curve"); 948*7c243321SVesa Jääskeläinen return PKCS11_CKR_CURVE_NOT_SUPPORTED; 949*7c243321SVesa Jääskeläinen } 950*7c243321SVesa Jääskeläinen 951*7c243321SVesa Jääskeläinen tee_curve = ec_params2tee_curve(a_ptr, a_size); 952*7c243321SVesa Jääskeläinen 953*7c243321SVesa Jääskeläinen switch (tee_curve) { 954*7c243321SVesa Jääskeläinen case TEE_ECC_CURVE_NIST_P192: 955*7c243321SVesa Jääskeläinen ec_curve = MBEDTLS_ECP_DP_SECP192R1; 956*7c243321SVesa Jääskeläinen break; 957*7c243321SVesa Jääskeläinen case TEE_ECC_CURVE_NIST_P224: 958*7c243321SVesa Jääskeläinen ec_curve = MBEDTLS_ECP_DP_SECP224R1; 959*7c243321SVesa Jääskeläinen break; 960*7c243321SVesa Jääskeläinen case TEE_ECC_CURVE_NIST_P256: 961*7c243321SVesa Jääskeläinen ec_curve = MBEDTLS_ECP_DP_SECP256R1; 962*7c243321SVesa Jääskeläinen break; 963*7c243321SVesa Jääskeläinen case TEE_ECC_CURVE_NIST_P384: 964*7c243321SVesa Jääskeläinen ec_curve = MBEDTLS_ECP_DP_SECP384R1; 965*7c243321SVesa Jääskeläinen break; 966*7c243321SVesa Jääskeläinen case TEE_ECC_CURVE_NIST_P521: 967*7c243321SVesa Jääskeläinen ec_curve = MBEDTLS_ECP_DP_SECP521R1; 968*7c243321SVesa Jääskeläinen break; 969*7c243321SVesa Jääskeläinen default: 970*7c243321SVesa Jääskeläinen EMSG("Failed to map EC_PARAMS to supported curve"); 971*7c243321SVesa Jääskeläinen return PKCS11_CKR_CURVE_NOT_SUPPORTED; 972*7c243321SVesa Jääskeläinen } 973*7c243321SVesa Jääskeläinen 974*7c243321SVesa Jääskeläinen if (get_attribute_ptr(temp, PKCS11_CKA_VALUE, 975*7c243321SVesa Jääskeläinen &a_ptr, &a_size) || !a_ptr) { 976*7c243321SVesa Jääskeläinen EMSG("No VALUE attribute found in private key"); 977*7c243321SVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 978*7c243321SVesa Jääskeläinen } 979*7c243321SVesa Jääskeläinen 980*7c243321SVesa Jääskeläinen mbedtls_ecp_keypair_init(&key_pair); 981*7c243321SVesa Jääskeläinen 982*7c243321SVesa Jääskeläinen ret = mbedtls_ecp_read_key(ec_curve, &key_pair, a_ptr, a_size); 983*7c243321SVesa Jääskeläinen if (ret) { 984*7c243321SVesa Jääskeläinen EMSG("Failed to parse CKA_VALUE"); 985*7c243321SVesa Jääskeläinen rc = PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 986*7c243321SVesa Jääskeläinen goto out; 987*7c243321SVesa Jääskeläinen } 988*7c243321SVesa Jääskeläinen 989*7c243321SVesa Jääskeläinen ret = mbedtls_ecp_mul(&key_pair.grp, &key_pair.Q, &key_pair.d, 990*7c243321SVesa Jääskeläinen &key_pair.grp.G, NULL, NULL); 991*7c243321SVesa Jääskeläinen if (ret) { 992*7c243321SVesa Jääskeläinen EMSG("Failed to create public key"); 993*7c243321SVesa Jääskeläinen goto out; 994*7c243321SVesa Jääskeläinen } 995*7c243321SVesa Jääskeläinen 996*7c243321SVesa Jääskeläinen ret = mbedtls_ecp_check_privkey(&key_pair.grp, &key_pair.d); 997*7c243321SVesa Jääskeläinen if (ret) { 998*7c243321SVesa Jääskeläinen EMSG("Failed to verify private key"); 999*7c243321SVesa Jääskeläinen goto out; 1000*7c243321SVesa Jääskeläinen } 1001*7c243321SVesa Jääskeläinen 1002*7c243321SVesa Jääskeläinen ret = mbedtls_ecp_check_pubkey(&key_pair.grp, &key_pair.Q); 1003*7c243321SVesa Jääskeläinen if (ret) { 1004*7c243321SVesa Jääskeläinen EMSG("Failed to verify public key"); 1005*7c243321SVesa Jääskeläinen goto out; 1006*7c243321SVesa Jääskeläinen } 1007*7c243321SVesa Jääskeläinen 1008*7c243321SVesa Jääskeläinen ret = mbedtls_ecp_point_write_binary(&key_pair.grp, &key_pair.Q, 1009*7c243321SVesa Jääskeläinen MBEDTLS_ECP_PF_UNCOMPRESSED, 1010*7c243321SVesa Jääskeläinen &buflen, NULL, 0); 1011*7c243321SVesa Jääskeläinen if (ret != MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL) { 1012*7c243321SVesa Jääskeläinen EMSG("Failed to determine size of binary public key"); 1013*7c243321SVesa Jääskeläinen goto out; 1014*7c243321SVesa Jääskeläinen } 1015*7c243321SVesa Jääskeläinen 1016*7c243321SVesa Jääskeläinen buf = TEE_Malloc(buflen, TEE_MALLOC_FILL_ZERO); 1017*7c243321SVesa Jääskeläinen if (!buf) { 1018*7c243321SVesa Jääskeläinen EMSG("Failed to allocate memory for public key"); 1019*7c243321SVesa Jääskeläinen rc = PKCS11_CKR_DEVICE_MEMORY; 1020*7c243321SVesa Jääskeläinen goto out; 1021*7c243321SVesa Jääskeläinen } 1022*7c243321SVesa Jääskeläinen 1023*7c243321SVesa Jääskeläinen asnbuflen = 1 /* octet string */ + 5 /* length */ + buflen; 1024*7c243321SVesa Jääskeläinen 1025*7c243321SVesa Jääskeläinen asnbuf = TEE_Malloc(asnbuflen, TEE_MALLOC_FILL_ZERO); 1026*7c243321SVesa Jääskeläinen if (!asnbuf) { 1027*7c243321SVesa Jääskeläinen EMSG("Failed to allocate memory for public key"); 1028*7c243321SVesa Jääskeläinen rc = PKCS11_CKR_DEVICE_MEMORY; 1029*7c243321SVesa Jääskeläinen goto out; 1030*7c243321SVesa Jääskeläinen } 1031*7c243321SVesa Jääskeläinen 1032*7c243321SVesa Jääskeläinen ret = mbedtls_ecp_point_write_binary(&key_pair.grp, &key_pair.Q, 1033*7c243321SVesa Jääskeläinen MBEDTLS_ECP_PF_UNCOMPRESSED, 1034*7c243321SVesa Jääskeläinen &buflen, buf, buflen); 1035*7c243321SVesa Jääskeläinen if (ret) { 1036*7c243321SVesa Jääskeläinen EMSG("Failed to write binary public key"); 1037*7c243321SVesa Jääskeläinen goto out; 1038*7c243321SVesa Jääskeläinen } 1039*7c243321SVesa Jääskeläinen 1040*7c243321SVesa Jääskeläinen /* Note: ASN.1 writing works backwards */ 1041*7c243321SVesa Jääskeläinen ptr = asnbuf + asnbuflen; 1042*7c243321SVesa Jääskeläinen 1043*7c243321SVesa Jääskeläinen ret = mbedtls_asn1_write_octet_string(&ptr, asnbuf, buf, buflen); 1044*7c243321SVesa Jääskeläinen if (ret < 0) { 1045*7c243321SVesa Jääskeläinen EMSG("Failed to write asn1 public key"); 1046*7c243321SVesa Jääskeläinen goto out; 1047*7c243321SVesa Jääskeläinen } 1048*7c243321SVesa Jääskeläinen 1049*7c243321SVesa Jääskeläinen rc = add_attribute(out, PKCS11_CKA_OPTEE_HIDDEN_EC_POINT, ptr, 1050*7c243321SVesa Jääskeläinen (size_t)ret); 1051*7c243321SVesa Jääskeläinen 1052*7c243321SVesa Jääskeläinen out: 1053*7c243321SVesa Jääskeläinen TEE_Free(asnbuf); 1054*7c243321SVesa Jääskeläinen TEE_Free(buf); 1055*7c243321SVesa Jääskeläinen mbedtls_ecp_keypair_free(&key_pair); 1056*7c243321SVesa Jääskeläinen 1057*7c243321SVesa Jääskeläinen return rc; 1058*7c243321SVesa Jääskeläinen } 1059*7c243321SVesa Jääskeläinen 1060*7c243321SVesa Jääskeläinen static enum pkcs11_rc 1061*7c243321SVesa Jääskeläinen create_priv_key_hidden_attributes(struct obj_attrs **out, 1062*7c243321SVesa Jääskeläinen struct obj_attrs *temp, 1063*7c243321SVesa Jääskeläinen enum processing_func function) 1064*7c243321SVesa Jääskeläinen { 1065*7c243321SVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_OK; 1066*7c243321SVesa Jääskeläinen 1067*7c243321SVesa Jääskeläinen switch (get_key_type(*out)) { 1068*7c243321SVesa Jääskeläinen case PKCS11_CKK_EC: 1069*7c243321SVesa Jääskeläinen rc = create_ec_priv_key_hidden_attributes(out, temp, function); 1070*7c243321SVesa Jääskeläinen break; 1071*7c243321SVesa Jääskeläinen default: 1072*7c243321SVesa Jääskeläinen /* no-op */ 1073*7c243321SVesa Jääskeläinen break; 1074*7c243321SVesa Jääskeläinen } 1075*7c243321SVesa Jääskeläinen 1076*7c243321SVesa Jääskeläinen return rc; 1077*7c243321SVesa Jääskeläinen } 1078*7c243321SVesa Jääskeläinen 1079*7c243321SVesa Jääskeläinen static enum pkcs11_rc 1080196bcd93SRuchika Gupta sanitize_symm_key_attributes(struct obj_attrs **temp, 1081196bcd93SRuchika Gupta enum processing_func function) 1082196bcd93SRuchika Gupta { 1083196bcd93SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK; 1084196bcd93SRuchika Gupta uint32_t a_size = 0; 1085196bcd93SRuchika Gupta 1086196bcd93SRuchika Gupta assert(get_class(*temp) == PKCS11_CKO_SECRET_KEY); 1087196bcd93SRuchika Gupta 1088196bcd93SRuchika Gupta rc = get_attribute_ptr(*temp, PKCS11_CKA_VALUE, NULL, &a_size); 1089196bcd93SRuchika Gupta 1090196bcd93SRuchika Gupta switch (get_key_type(*temp)) { 1091196bcd93SRuchika Gupta case PKCS11_CKK_GENERIC_SECRET: 1092196bcd93SRuchika Gupta case PKCS11_CKK_AES: 1093196bcd93SRuchika Gupta case PKCS11_CKK_MD5_HMAC: 1094196bcd93SRuchika Gupta case PKCS11_CKK_SHA_1_HMAC: 1095196bcd93SRuchika Gupta case PKCS11_CKK_SHA256_HMAC: 1096196bcd93SRuchika Gupta case PKCS11_CKK_SHA384_HMAC: 1097196bcd93SRuchika Gupta case PKCS11_CKK_SHA512_HMAC: 1098196bcd93SRuchika Gupta case PKCS11_CKK_SHA224_HMAC: 1099196bcd93SRuchika Gupta switch (function) { 1100196bcd93SRuchika Gupta case PKCS11_FUNCTION_IMPORT: 1101196bcd93SRuchika Gupta /* CKA_VALUE is a mandatory with C_CreateObject */ 1102196bcd93SRuchika Gupta if (rc || a_size == 0) 1103196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1104196bcd93SRuchika Gupta 1105196bcd93SRuchika Gupta if (get_attribute_ptr(*temp, PKCS11_CKA_VALUE_LEN, NULL, 1106196bcd93SRuchika Gupta NULL) != PKCS11_RV_NOT_FOUND) 1107196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1108196bcd93SRuchika Gupta 1109196bcd93SRuchika Gupta return add_attribute(temp, PKCS11_CKA_VALUE_LEN, 1110196bcd93SRuchika Gupta &a_size, sizeof(uint32_t)); 1111196bcd93SRuchika Gupta case PKCS11_FUNCTION_GENERATE: 1112196bcd93SRuchika Gupta if (rc != PKCS11_RV_NOT_FOUND) 1113196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1114196bcd93SRuchika Gupta break; 1115196bcd93SRuchika Gupta default: 1116196bcd93SRuchika Gupta break; 1117196bcd93SRuchika Gupta } 1118196bcd93SRuchika Gupta break; 1119196bcd93SRuchika Gupta default: 1120196bcd93SRuchika Gupta EMSG("Invalid key type %#"PRIx32"/%s", 1121196bcd93SRuchika Gupta get_key_type(*temp), id2str_key_type(get_key_type(*temp))); 1122196bcd93SRuchika Gupta 1123196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1124196bcd93SRuchika Gupta } 1125196bcd93SRuchika Gupta 1126196bcd93SRuchika Gupta return PKCS11_CKR_OK; 1127196bcd93SRuchika Gupta } 1128196bcd93SRuchika Gupta 112963f89caaSJens Wiklander /* 113063f89caaSJens Wiklander * Create an attribute list for a new object from a template and a parent 113163f89caaSJens Wiklander * object (optional) for an object generation function (generate, copy, 113263f89caaSJens Wiklander * derive...). 113363f89caaSJens Wiklander * 113463f89caaSJens Wiklander * PKCS#11 directives on the supplied template and expected return value: 113563f89caaSJens Wiklander * - template has an invalid attribute ID: ATTRIBUTE_TYPE_INVALID 113663f89caaSJens Wiklander * - template has an invalid value for an attribute: ATTRIBUTE_VALID_INVALID 113763f89caaSJens Wiklander * - template has value for a read-only attribute: ATTRIBUTE_READ_ONLY 113863f89caaSJens Wiklander * - template+default+parent => still miss an attribute: TEMPLATE_INCONSISTENT 113963f89caaSJens Wiklander * 114063f89caaSJens Wiklander * INFO on PKCS11_CMD_COPY_OBJECT: 114163f89caaSJens Wiklander * - parent PKCS11_CKA_COPYIABLE=false => return ACTION_PROHIBITED. 114263f89caaSJens Wiklander * - template can specify PKCS11_CKA_TOKEN, PKCS11_CKA_PRIVATE, 114363f89caaSJens Wiklander * PKCS11_CKA_MODIFIABLE, PKCS11_CKA_DESTROYABLE. 114463f89caaSJens Wiklander * - SENSITIVE can change from false to true, not from true to false. 114563f89caaSJens Wiklander * - LOCAL is the parent LOCAL 114663f89caaSJens Wiklander */ 114763f89caaSJens Wiklander enum pkcs11_rc 114863f89caaSJens Wiklander create_attributes_from_template(struct obj_attrs **out, void *template, 114963f89caaSJens Wiklander size_t template_size, 115048799892SRuchika Gupta struct obj_attrs *parent, 115163f89caaSJens Wiklander enum processing_func function, 11524cfce748SRuchika Gupta enum pkcs11_mechanism_id mecha, 115302b16804SVesa Jääskeläinen enum pkcs11_class_id template_class) 115463f89caaSJens Wiklander { 115563f89caaSJens Wiklander struct obj_attrs *temp = NULL; 115663f89caaSJens Wiklander struct obj_attrs *attrs = NULL; 115763f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 115863f89caaSJens Wiklander uint8_t local = 0; 115963f89caaSJens Wiklander uint8_t always_sensitive = 0; 116063f89caaSJens Wiklander uint8_t never_extract = 0; 1161e3f0cb56SRuchika Gupta uint8_t extractable = 0; 1162fa247a2aSRuchika Gupta uint32_t class = PKCS11_UNDEFINED_ID; 1163fa247a2aSRuchika Gupta uint32_t type = PKCS11_UNDEFINED_ID; 116463f89caaSJens Wiklander uint32_t mechanism_id = PKCS11_CKM_UNDEFINED_ID; 1165e3f0cb56SRuchika Gupta struct obj_attrs *req_attrs = NULL; 1166e3f0cb56SRuchika Gupta uint32_t size = 0; 1167e3f0cb56SRuchika Gupta uint32_t indirect_template = PKCS11_CKA_UNDEFINED_ID; 116863f89caaSJens Wiklander 116963f89caaSJens Wiklander #ifdef DEBUG /* Sanity: check function argument */ 117063f89caaSJens Wiklander trace_attributes_from_api_head("template", template, template_size); 117163f89caaSJens Wiklander switch (function) { 1172fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 1173013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 117463f89caaSJens Wiklander case PKCS11_FUNCTION_IMPORT: 11752d25a9bcSRuchika Gupta case PKCS11_FUNCTION_MODIFY: 117648799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 1177e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 11782d25a9bcSRuchika Gupta case PKCS11_FUNCTION_COPY: 117963f89caaSJens Wiklander break; 118063f89caaSJens Wiklander default: 118163f89caaSJens Wiklander TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 118263f89caaSJens Wiklander } 118363f89caaSJens Wiklander #endif 118463f89caaSJens Wiklander 1185dcad3409SRuchika Gupta /* 1186dcad3409SRuchika Gupta * For PKCS11_FUNCTION_GENERATE, find the class and type 1187dcad3409SRuchika Gupta * based on the mechanism. These will be passed as hint 1188dcad3409SRuchika Gupta * sanitize_client_object() and added in temp if not 1189dcad3409SRuchika Gupta * already present 1190dcad3409SRuchika Gupta */ 1191dcad3409SRuchika Gupta if (function == PKCS11_FUNCTION_GENERATE) { 1192fa247a2aSRuchika Gupta switch (mecha) { 1193fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1194fa247a2aSRuchika Gupta class = PKCS11_CKO_SECRET_KEY; 1195fa247a2aSRuchika Gupta type = PKCS11_CKK_GENERIC_SECRET; 1196fa247a2aSRuchika Gupta break; 1197fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 1198fa247a2aSRuchika Gupta class = PKCS11_CKO_SECRET_KEY; 1199fa247a2aSRuchika Gupta type = PKCS11_CKK_AES; 1200fa247a2aSRuchika Gupta break; 1201fa247a2aSRuchika Gupta default: 1202dcad3409SRuchika Gupta TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 1203fa247a2aSRuchika Gupta } 1204fa247a2aSRuchika Gupta } 1205fa247a2aSRuchika Gupta 12062d25a9bcSRuchika Gupta /* 1207013934d8SVesa Jääskeläinen * For PKCS11_FUNCTION_GENERATE_PAIR, find the class and type 1208013934d8SVesa Jääskeläinen * based on the mechanism. These will be passed as hint 1209013934d8SVesa Jääskeläinen * sanitize_client_object() and added in temp if not 1210013934d8SVesa Jääskeläinen * already present 1211013934d8SVesa Jääskeläinen */ 1212013934d8SVesa Jääskeläinen if (function == PKCS11_FUNCTION_GENERATE_PAIR) { 1213013934d8SVesa Jääskeläinen switch (mecha) { 121403e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: 121503e07432SValerii Chubar class = template_class; 121603e07432SValerii Chubar type = PKCS11_CKK_EDDSA; 121703e07432SValerii Chubar break; 121802b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 121902b16804SVesa Jääskeläinen class = template_class; 122002b16804SVesa Jääskeläinen type = PKCS11_CKK_EC; 122102b16804SVesa Jääskeläinen break; 122286922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 122386922832SVesa Jääskeläinen class = template_class; 122486922832SVesa Jääskeläinen type = PKCS11_CKK_RSA; 122586922832SVesa Jääskeläinen break; 1226013934d8SVesa Jääskeläinen default: 1227013934d8SVesa Jääskeläinen TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 1228013934d8SVesa Jääskeläinen } 1229013934d8SVesa Jääskeläinen } 1230013934d8SVesa Jääskeläinen 1231013934d8SVesa Jääskeläinen /* 12322d25a9bcSRuchika Gupta * Check and remove duplicates if any and create a new temporary 12332d25a9bcSRuchika Gupta * template 12342d25a9bcSRuchika Gupta */ 1235dcad3409SRuchika Gupta rc = sanitize_client_object(&temp, template, template_size, class, 1236dcad3409SRuchika Gupta type); 1237dcad3409SRuchika Gupta if (rc) 1238dcad3409SRuchika Gupta goto out; 1239dcad3409SRuchika Gupta 1240dcad3409SRuchika Gupta /* 12412d25a9bcSRuchika Gupta * For function type modify and copy return the created template 12422d25a9bcSRuchika Gupta * from here. Rest of the code below is for creating objects 12432d25a9bcSRuchika Gupta * or generating keys. 12442d25a9bcSRuchika Gupta */ 12452d25a9bcSRuchika Gupta switch (function) { 12462d25a9bcSRuchika Gupta case PKCS11_FUNCTION_MODIFY: 12472d25a9bcSRuchika Gupta case PKCS11_FUNCTION_COPY: 12482d25a9bcSRuchika Gupta *out = temp; 12492d25a9bcSRuchika Gupta return rc; 1250e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 1251e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 1252e3f0cb56SRuchika Gupta if (function == PKCS11_FUNCTION_UNWRAP) 1253e3f0cb56SRuchika Gupta indirect_template = PKCS11_CKA_UNWRAP_TEMPLATE; 1254e3f0cb56SRuchika Gupta else 1255e3f0cb56SRuchika Gupta indirect_template = PKCS11_CKA_DERIVE_TEMPLATE; 1256e3f0cb56SRuchika Gupta 1257e3f0cb56SRuchika Gupta rc = get_attribute_ptr(parent, indirect_template, 1258e3f0cb56SRuchika Gupta (void *)&req_attrs, &size); 1259e3f0cb56SRuchika Gupta if (rc == PKCS11_CKR_OK && size != 0) { 1260e3f0cb56SRuchika Gupta rc = attributes_match_add_reference(&temp, req_attrs); 1261e3f0cb56SRuchika Gupta if (rc) 1262e3f0cb56SRuchika Gupta goto out; 1263e3f0cb56SRuchika Gupta } 1264e3f0cb56SRuchika Gupta break; 12652d25a9bcSRuchika Gupta default: 12662d25a9bcSRuchika Gupta break; 12672d25a9bcSRuchika Gupta } 12682d25a9bcSRuchika Gupta 12692d25a9bcSRuchika Gupta /* 1270dcad3409SRuchika Gupta * Check if class and type in temp are consistent with the mechanism 1271dcad3409SRuchika Gupta */ 1272fa247a2aSRuchika Gupta switch (mecha) { 1273fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1274fa247a2aSRuchika Gupta if (get_class(temp) != PKCS11_CKO_SECRET_KEY || 1275fa247a2aSRuchika Gupta get_key_type(temp) != PKCS11_CKK_GENERIC_SECRET) { 1276fa247a2aSRuchika Gupta rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 1277fa247a2aSRuchika Gupta goto out; 1278fa247a2aSRuchika Gupta } 1279fa247a2aSRuchika Gupta break; 1280fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 1281fa247a2aSRuchika Gupta if (get_class(temp) != PKCS11_CKO_SECRET_KEY || 1282fa247a2aSRuchika Gupta get_key_type(temp) != PKCS11_CKK_AES) { 1283fa247a2aSRuchika Gupta rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 1284fa247a2aSRuchika Gupta goto out; 1285fa247a2aSRuchika Gupta } 1286fa247a2aSRuchika Gupta break; 128702b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 128802b16804SVesa Jääskeläinen if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && 128902b16804SVesa Jääskeläinen get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || 129002b16804SVesa Jääskeläinen get_key_type(temp) != PKCS11_CKK_EC) { 129102b16804SVesa Jääskeläinen rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 129202b16804SVesa Jääskeläinen goto out; 129302b16804SVesa Jääskeläinen } 129402b16804SVesa Jääskeläinen break; 129503e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: 129603e07432SValerii Chubar if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && 129703e07432SValerii Chubar get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || 129803e07432SValerii Chubar get_key_type(temp) != PKCS11_CKK_EC_EDWARDS) { 129903e07432SValerii Chubar rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 130003e07432SValerii Chubar goto out; 130103e07432SValerii Chubar } 130203e07432SValerii Chubar break; 130386922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 130486922832SVesa Jääskeläinen if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && 130586922832SVesa Jääskeläinen get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || 130686922832SVesa Jääskeläinen get_key_type(temp) != PKCS11_CKK_RSA) { 130786922832SVesa Jääskeläinen rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 130886922832SVesa Jääskeläinen goto out; 130986922832SVesa Jääskeläinen } 131086922832SVesa Jääskeläinen break; 1311fa247a2aSRuchika Gupta default: 1312fa247a2aSRuchika Gupta break; 1313fa247a2aSRuchika Gupta } 131463f89caaSJens Wiklander 131563f89caaSJens Wiklander if (!sanitize_consistent_class_and_type(temp)) { 131663f89caaSJens Wiklander EMSG("Inconsistent class/type"); 131763f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 131863f89caaSJens Wiklander goto out; 131963f89caaSJens Wiklander } 132063f89caaSJens Wiklander 1321e3f0cb56SRuchika Gupta /* 1322e3f0cb56SRuchika Gupta * TBD - Add a check to see if temp contains any attribute which 1323e3f0cb56SRuchika Gupta * is not consistent with the object class or type and return error. 1324e3f0cb56SRuchika Gupta * In current implementation such attributes are ignored and not 1325e3f0cb56SRuchika Gupta * added to final object while PKCS#11 specification expects a 1326e3f0cb56SRuchika Gupta * failure and an error code be returned. 1327e3f0cb56SRuchika Gupta */ 1328e3f0cb56SRuchika Gupta 132963f89caaSJens Wiklander switch (get_class(temp)) { 133063f89caaSJens Wiklander case PKCS11_CKO_DATA: 133163f89caaSJens Wiklander rc = create_data_attributes(&attrs, temp); 133263f89caaSJens Wiklander break; 13334137952dSVesa Jääskeläinen case PKCS11_CKO_CERTIFICATE: 13344137952dSVesa Jääskeläinen rc = create_certificate_attributes(&attrs, temp); 13354137952dSVesa Jääskeläinen break; 133663f89caaSJens Wiklander case PKCS11_CKO_SECRET_KEY: 1337196bcd93SRuchika Gupta rc = sanitize_symm_key_attributes(&temp, function); 1338196bcd93SRuchika Gupta if (rc) 1339196bcd93SRuchika Gupta goto out; 134063f89caaSJens Wiklander rc = create_symm_key_attributes(&attrs, temp); 134163f89caaSJens Wiklander break; 134263f89caaSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 13439cf1afceSVesa Jääskeläinen rc = create_pub_key_attributes(&attrs, temp, function); 13445071d7d1SVesa Jääskeläinen if (rc) 13455071d7d1SVesa Jääskeläinen goto out; 13465071d7d1SVesa Jääskeläinen rc = create_pub_key_generated_attributes(&attrs, temp, 13475071d7d1SVesa Jääskeläinen function); 134863f89caaSJens Wiklander break; 134963f89caaSJens Wiklander case PKCS11_CKO_PRIVATE_KEY: 135063f89caaSJens Wiklander rc = create_priv_key_attributes(&attrs, temp); 1351*7c243321SVesa Jääskeläinen if (rc) 1352*7c243321SVesa Jääskeläinen goto out; 1353*7c243321SVesa Jääskeläinen rc = create_priv_key_hidden_attributes(&attrs, temp, function); 135463f89caaSJens Wiklander break; 135563f89caaSJens Wiklander default: 135663f89caaSJens Wiklander DMSG("Invalid object class %#"PRIx32"/%s", 135763f89caaSJens Wiklander get_class(temp), id2str_class(get_class(temp))); 135863f89caaSJens Wiklander 135963f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 136063f89caaSJens Wiklander break; 136163f89caaSJens Wiklander } 136263f89caaSJens Wiklander if (rc) 136363f89caaSJens Wiklander goto out; 136463f89caaSJens Wiklander 136590c47fe2SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_LOCAL, NULL, NULL) != 1366002f6b93SEtienne Carriere PKCS11_RV_NOT_FOUND) { 1367002f6b93SEtienne Carriere rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 136863f89caaSJens Wiklander goto out; 1369002f6b93SEtienne Carriere } 137063f89caaSJens Wiklander 137190c47fe2SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_KEY_GEN_MECHANISM, NULL, NULL) != 1372002f6b93SEtienne Carriere PKCS11_RV_NOT_FOUND) { 1373002f6b93SEtienne Carriere rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 137463f89caaSJens Wiklander goto out; 1375002f6b93SEtienne Carriere } 137663f89caaSJens Wiklander 137763f89caaSJens Wiklander switch (function) { 1378fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 1379013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 1380fa247a2aSRuchika Gupta local = PKCS11_TRUE; 1381fa247a2aSRuchika Gupta break; 138263f89caaSJens Wiklander case PKCS11_FUNCTION_IMPORT: 138348799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 1384e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 138563f89caaSJens Wiklander default: 138663f89caaSJens Wiklander local = PKCS11_FALSE; 138763f89caaSJens Wiklander break; 138863f89caaSJens Wiklander } 138963f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_LOCAL, &local, sizeof(local)); 139063f89caaSJens Wiklander if (rc) 139163f89caaSJens Wiklander goto out; 139263f89caaSJens Wiklander 139363f89caaSJens Wiklander switch (get_class(attrs)) { 139463f89caaSJens Wiklander case PKCS11_CKO_SECRET_KEY: 139563f89caaSJens Wiklander case PKCS11_CKO_PRIVATE_KEY: 139663f89caaSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 139763f89caaSJens Wiklander always_sensitive = PKCS11_FALSE; 139863f89caaSJens Wiklander never_extract = PKCS11_FALSE; 139963f89caaSJens Wiklander 1400fa247a2aSRuchika Gupta switch (function) { 140148799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 140248799892SRuchika Gupta always_sensitive = 140348799892SRuchika Gupta get_bool(parent, PKCS11_CKA_ALWAYS_SENSITIVE) && 140448799892SRuchika Gupta get_bool(attrs, PKCS11_CKA_SENSITIVE); 140548799892SRuchika Gupta never_extract = 140648799892SRuchika Gupta get_bool(parent, PKCS11_CKA_NEVER_EXTRACTABLE) && 140748799892SRuchika Gupta !get_bool(attrs, PKCS11_CKA_EXTRACTABLE); 140848799892SRuchika Gupta break; 1409e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 1410e3f0cb56SRuchika Gupta always_sensitive = PKCS11_FALSE; 1411e3f0cb56SRuchika Gupta never_extract = PKCS11_FALSE; 1412e3f0cb56SRuchika Gupta extractable = PKCS11_TRUE; 1413e3f0cb56SRuchika Gupta 1414e3f0cb56SRuchika Gupta /* 1415e3f0cb56SRuchika Gupta * Check if template passed by user has CKA_EXTRACTABLE. 1416e3f0cb56SRuchika Gupta * If not, by default value of CKA_EXTRACTABLE is set as 1417e3f0cb56SRuchika Gupta * TRUE. 1418e3f0cb56SRuchika Gupta */ 1419e3f0cb56SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_EXTRACTABLE, 1420e3f0cb56SRuchika Gupta NULL, 1421e3f0cb56SRuchika Gupta NULL) == PKCS11_RV_NOT_FOUND) { 1422e3f0cb56SRuchika Gupta rc = set_attribute(&attrs, 1423e3f0cb56SRuchika Gupta PKCS11_CKA_EXTRACTABLE, 1424e3f0cb56SRuchika Gupta &extractable, 1425e3f0cb56SRuchika Gupta sizeof(extractable)); 1426e3f0cb56SRuchika Gupta if (rc) 1427e3f0cb56SRuchika Gupta goto out; 1428e3f0cb56SRuchika Gupta } 1429e3f0cb56SRuchika Gupta break; 1430fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 1431013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 1432fa247a2aSRuchika Gupta always_sensitive = get_bool(attrs, 1433fa247a2aSRuchika Gupta PKCS11_CKA_SENSITIVE); 1434fa247a2aSRuchika Gupta never_extract = !get_bool(attrs, 1435fa247a2aSRuchika Gupta PKCS11_CKA_EXTRACTABLE); 1436fa247a2aSRuchika Gupta break; 1437fa247a2aSRuchika Gupta default: 1438fa247a2aSRuchika Gupta break; 1439fa247a2aSRuchika Gupta } 1440fa247a2aSRuchika Gupta 144163f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_ALWAYS_SENSITIVE, 144263f89caaSJens Wiklander &always_sensitive, sizeof(always_sensitive)); 144363f89caaSJens Wiklander if (rc) 144463f89caaSJens Wiklander goto out; 144563f89caaSJens Wiklander 144663f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_NEVER_EXTRACTABLE, 144763f89caaSJens Wiklander &never_extract, sizeof(never_extract)); 144863f89caaSJens Wiklander if (rc) 144963f89caaSJens Wiklander goto out; 145063f89caaSJens Wiklander 145163f89caaSJens Wiklander /* Keys mandate attribute PKCS11_CKA_KEY_GEN_MECHANISM */ 1452fa247a2aSRuchika Gupta if (local) 1453fa247a2aSRuchika Gupta mechanism_id = mecha; 1454fa247a2aSRuchika Gupta else 145563f89caaSJens Wiklander mechanism_id = PKCS11_CK_UNAVAILABLE_INFORMATION; 1456fa247a2aSRuchika Gupta 145763f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_KEY_GEN_MECHANISM, 145863f89caaSJens Wiklander &mechanism_id, sizeof(mechanism_id)); 145963f89caaSJens Wiklander if (rc) 146063f89caaSJens Wiklander goto out; 146163f89caaSJens Wiklander break; 146263f89caaSJens Wiklander 146363f89caaSJens Wiklander default: 146463f89caaSJens Wiklander break; 146563f89caaSJens Wiklander } 146663f89caaSJens Wiklander 146763f89caaSJens Wiklander *out = attrs; 146863f89caaSJens Wiklander 146963f89caaSJens Wiklander #ifdef DEBUG 147063f89caaSJens Wiklander trace_attributes("object", attrs); 147163f89caaSJens Wiklander #endif 147263f89caaSJens Wiklander 147363f89caaSJens Wiklander out: 147463f89caaSJens Wiklander TEE_Free(temp); 147563f89caaSJens Wiklander if (rc) 147663f89caaSJens Wiklander TEE_Free(attrs); 147763f89caaSJens Wiklander 147863f89caaSJens Wiklander return rc; 147963f89caaSJens Wiklander } 148063f89caaSJens Wiklander 148163f89caaSJens Wiklander static enum pkcs11_rc check_attrs_misc_integrity(struct obj_attrs *head) 148263f89caaSJens Wiklander { 148363f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_NEVER_EXTRACTABLE) && 148463f89caaSJens Wiklander get_bool(head, PKCS11_CKA_EXTRACTABLE)) { 148563f89caaSJens Wiklander DMSG("Never/Extractable attributes mismatch %d/%d", 148663f89caaSJens Wiklander get_bool(head, PKCS11_CKA_NEVER_EXTRACTABLE), 148763f89caaSJens Wiklander get_bool(head, PKCS11_CKA_EXTRACTABLE)); 148863f89caaSJens Wiklander 148963f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 149063f89caaSJens Wiklander } 149163f89caaSJens Wiklander 149263f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_ALWAYS_SENSITIVE) && 149363f89caaSJens Wiklander !get_bool(head, PKCS11_CKA_SENSITIVE)) { 149463f89caaSJens Wiklander DMSG("Sensitive/always attributes mismatch %d/%d", 149563f89caaSJens Wiklander get_bool(head, PKCS11_CKA_SENSITIVE), 149663f89caaSJens Wiklander get_bool(head, PKCS11_CKA_ALWAYS_SENSITIVE)); 149763f89caaSJens Wiklander 149863f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 149963f89caaSJens Wiklander } 150063f89caaSJens Wiklander 150163f89caaSJens Wiklander return PKCS11_CKR_OK; 150263f89caaSJens Wiklander } 150363f89caaSJens Wiklander 150489735787SRuchika Gupta bool object_is_private(struct obj_attrs *head) 150589735787SRuchika Gupta { 150665fb9092SVesa Jääskeläinen return get_bool(head, PKCS11_CKA_PRIVATE); 150789735787SRuchika Gupta } 150889735787SRuchika Gupta 15092d25a9bcSRuchika Gupta bool object_is_token(struct obj_attrs *head) 15102d25a9bcSRuchika Gupta { 15112d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_TOKEN); 15122d25a9bcSRuchika Gupta } 15132d25a9bcSRuchika Gupta 15142d25a9bcSRuchika Gupta bool object_is_modifiable(struct obj_attrs *head) 15152d25a9bcSRuchika Gupta { 15162d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_MODIFIABLE); 15172d25a9bcSRuchika Gupta } 15182d25a9bcSRuchika Gupta 15192d25a9bcSRuchika Gupta bool object_is_copyable(struct obj_attrs *head) 15202d25a9bcSRuchika Gupta { 15212d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_COPYABLE); 15222d25a9bcSRuchika Gupta } 15232d25a9bcSRuchika Gupta 152463f89caaSJens Wiklander /* 1525512cbf1dSJens Wiklander * Check access to object against authentication to token 1526512cbf1dSJens Wiklander */ 1527512cbf1dSJens Wiklander enum pkcs11_rc check_access_attrs_against_token(struct pkcs11_session *session, 1528512cbf1dSJens Wiklander struct obj_attrs *head) 1529512cbf1dSJens Wiklander { 1530512cbf1dSJens Wiklander bool private = true; 1531512cbf1dSJens Wiklander 1532512cbf1dSJens Wiklander switch (get_class(head)) { 1533512cbf1dSJens Wiklander case PKCS11_CKO_SECRET_KEY: 153465fb9092SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1535512cbf1dSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 1536512cbf1dSJens Wiklander case PKCS11_CKO_DATA: 15374137952dSVesa Jääskeläinen case PKCS11_CKO_CERTIFICATE: 153865fb9092SVesa Jääskeläinen private = object_is_private(head); 1539512cbf1dSJens Wiklander break; 1540512cbf1dSJens Wiklander default: 1541512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1542512cbf1dSJens Wiklander } 1543512cbf1dSJens Wiklander 15445db0fef4SRuchika Gupta if (private && (pkcs11_session_is_public(session) || 15455db0fef4SRuchika Gupta pkcs11_session_is_so(session))) { 15465db0fef4SRuchika Gupta DMSG("Private object access from a public or SO session"); 1547512cbf1dSJens Wiklander 154812f1ba86SRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 1549512cbf1dSJens Wiklander } 1550512cbf1dSJens Wiklander 1551512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1552512cbf1dSJens Wiklander } 1553512cbf1dSJens Wiklander 1554512cbf1dSJens Wiklander /* 155563f89caaSJens Wiklander * Check the attributes of a to-be-created object matches the token state 155663f89caaSJens Wiklander */ 155763f89caaSJens Wiklander enum pkcs11_rc check_created_attrs_against_token(struct pkcs11_session *session, 155863f89caaSJens Wiklander struct obj_attrs *head) 155963f89caaSJens Wiklander { 156063f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 156163f89caaSJens Wiklander 156263f89caaSJens Wiklander rc = check_attrs_misc_integrity(head); 156363f89caaSJens Wiklander if (rc) 156463f89caaSJens Wiklander return rc; 156563f89caaSJens Wiklander 156663f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_TRUSTED) && 156763f89caaSJens Wiklander !pkcs11_session_is_so(session)) { 156863f89caaSJens Wiklander DMSG("Can't create trusted object"); 156963f89caaSJens Wiklander 157063f89caaSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 157163f89caaSJens Wiklander } 157263f89caaSJens Wiklander 157363f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_TOKEN) && 157463f89caaSJens Wiklander !pkcs11_session_is_read_write(session)) { 157563f89caaSJens Wiklander DMSG("Can't create persistent object"); 157663f89caaSJens Wiklander 157763f89caaSJens Wiklander return PKCS11_CKR_SESSION_READ_ONLY; 157863f89caaSJens Wiklander } 157963f89caaSJens Wiklander 158063f89caaSJens Wiklander return PKCS11_CKR_OK; 158163f89caaSJens Wiklander } 158263f89caaSJens Wiklander 158363f89caaSJens Wiklander #define DMSG_BAD_BBOOL(attr, proc, head) \ 158463f89caaSJens Wiklander do { \ 158563f89caaSJens Wiklander uint32_t __maybe_unused _attr = (attr); \ 158663f89caaSJens Wiklander uint8_t __maybe_unused _bvalue = 0; \ 158763f89caaSJens Wiklander enum pkcs11_rc __maybe_unused _rc = PKCS11_CKR_OK; \ 158863f89caaSJens Wiklander \ 158963f89caaSJens Wiklander _rc = get_attribute((head), _attr, &_bvalue, NULL); \ 159063f89caaSJens Wiklander DMSG("%s issue for %s: %sfound, value %"PRIu8, \ 159163f89caaSJens Wiklander id2str_attr(_attr), id2str_proc((proc)), \ 159263f89caaSJens Wiklander _rc ? "not " : "", _bvalue); \ 159363f89caaSJens Wiklander } while (0) 159463f89caaSJens Wiklander 159563f89caaSJens Wiklander static bool __maybe_unused check_attr_bval(uint32_t proc_id __maybe_unused, 159663f89caaSJens Wiklander struct obj_attrs *head, 159763f89caaSJens Wiklander uint32_t attribute, bool val) 159863f89caaSJens Wiklander { 159963f89caaSJens Wiklander uint8_t bbool = 0; 160063f89caaSJens Wiklander uint32_t sz = sizeof(bbool); 160163f89caaSJens Wiklander 160263f89caaSJens Wiklander if (!get_attribute(head, attribute, &bbool, &sz) && !!bbool == val) 160363f89caaSJens Wiklander return true; 160463f89caaSJens Wiklander 160563f89caaSJens Wiklander DMSG_BAD_BBOOL(attribute, proc_id, head); 160663f89caaSJens Wiklander return false; 160763f89caaSJens Wiklander } 160863f89caaSJens Wiklander 160963f89caaSJens Wiklander /* 161063f89caaSJens Wiklander * Check the attributes of a new secret match the processing/mechanism 161163f89caaSJens Wiklander * used to create it. 161263f89caaSJens Wiklander * 161363f89caaSJens Wiklander * @proc_id - PKCS11_CKM_xxx 161463f89caaSJens Wiklander * @head - head of the attributes of the to-be-created object. 161563f89caaSJens Wiklander */ 161663f89caaSJens Wiklander enum pkcs11_rc check_created_attrs_against_processing(uint32_t proc_id, 161763f89caaSJens Wiklander struct obj_attrs *head) 161863f89caaSJens Wiklander { 161963f89caaSJens Wiklander /* 162063f89caaSJens Wiklander * Processings that do not create secrets are not expected to call 162163f89caaSJens Wiklander * this function which would panic. 162263f89caaSJens Wiklander */ 162363f89caaSJens Wiklander switch (proc_id) { 162463f89caaSJens Wiklander case PKCS11_PROCESSING_IMPORT: 1625cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 1626e3f0cb56SRuchika Gupta case PKCS11_CKM_AES_ECB: 1627e3f0cb56SRuchika Gupta case PKCS11_CKM_AES_CBC: 162848799892SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 162948799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 163045d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP: 163163f89caaSJens Wiklander assert(check_attr_bval(proc_id, head, PKCS11_CKA_LOCAL, false)); 163263f89caaSJens Wiklander break; 1633fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1634fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 163503e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: 163602b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 163786922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 1638fa247a2aSRuchika Gupta assert(check_attr_bval(proc_id, head, PKCS11_CKA_LOCAL, true)); 1639fa247a2aSRuchika Gupta break; 164063f89caaSJens Wiklander default: 164163f89caaSJens Wiklander TEE_Panic(proc_id); 164263f89caaSJens Wiklander break; 164363f89caaSJens Wiklander } 164463f89caaSJens Wiklander 1645fa247a2aSRuchika Gupta switch (proc_id) { 1646fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1647fa247a2aSRuchika Gupta assert(get_key_type(head) == PKCS11_CKK_GENERIC_SECRET); 1648fa247a2aSRuchika Gupta break; 1649fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 1650fa247a2aSRuchika Gupta assert(get_key_type(head) == PKCS11_CKK_AES); 1651fa247a2aSRuchika Gupta break; 165203e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: 165303e07432SValerii Chubar assert(get_key_type(head) == PKCS11_CKK_EC_EDWARDS); 165403e07432SValerii Chubar break; 165502b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 165602b16804SVesa Jääskeläinen assert(get_key_type(head) == PKCS11_CKK_EC); 165702b16804SVesa Jääskeläinen break; 165886922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 165986922832SVesa Jääskeläinen assert(get_key_type(head) == PKCS11_CKK_RSA); 166086922832SVesa Jääskeläinen break; 1661fa247a2aSRuchika Gupta case PKCS11_PROCESSING_IMPORT: 1662cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 1663fa247a2aSRuchika Gupta default: 1664fa247a2aSRuchika Gupta break; 1665fa247a2aSRuchika Gupta } 1666fa247a2aSRuchika Gupta 166763f89caaSJens Wiklander return PKCS11_CKR_OK; 166863f89caaSJens Wiklander } 1669512cbf1dSJens Wiklander 16702d0cd829SRuchika Gupta /* Return min and max key size supported for a key_type in bytes */ 1671512cbf1dSJens Wiklander static void get_key_min_max_sizes(enum pkcs11_key_type key_type, 1672512cbf1dSJens Wiklander uint32_t *min_key_size, 1673512cbf1dSJens Wiklander uint32_t *max_key_size) 1674512cbf1dSJens Wiklander { 1675512cbf1dSJens Wiklander enum pkcs11_mechanism_id mechanism = PKCS11_CKM_UNDEFINED_ID; 1676512cbf1dSJens Wiklander 1677512cbf1dSJens Wiklander switch (key_type) { 1678fa247a2aSRuchika Gupta case PKCS11_CKK_GENERIC_SECRET: 1679fa247a2aSRuchika Gupta mechanism = PKCS11_CKM_GENERIC_SECRET_KEY_GEN; 1680fa247a2aSRuchika Gupta break; 1681512cbf1dSJens Wiklander case PKCS11_CKK_AES: 1682512cbf1dSJens Wiklander mechanism = PKCS11_CKM_AES_KEY_GEN; 1683512cbf1dSJens Wiklander break; 16841f45c9cfSRuchika Gupta case PKCS11_CKK_MD5_HMAC: 16851f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_MD5_HMAC; 16861f45c9cfSRuchika Gupta break; 16871f45c9cfSRuchika Gupta case PKCS11_CKK_SHA_1_HMAC: 16881f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA_1_HMAC; 16891f45c9cfSRuchika Gupta break; 16901f45c9cfSRuchika Gupta case PKCS11_CKK_SHA224_HMAC: 16911f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA224_HMAC; 16921f45c9cfSRuchika Gupta break; 1693a339a354SEtienne Carriere case PKCS11_CKK_SHA256_HMAC: 1694a339a354SEtienne Carriere mechanism = PKCS11_CKM_SHA256_HMAC; 1695a339a354SEtienne Carriere break; 16961f45c9cfSRuchika Gupta case PKCS11_CKK_SHA384_HMAC: 16971f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA384_HMAC; 16981f45c9cfSRuchika Gupta break; 16991f45c9cfSRuchika Gupta case PKCS11_CKK_SHA512_HMAC: 17001f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA512_HMAC; 17011f45c9cfSRuchika Gupta break; 1702db28c542SVesa Jääskeläinen case PKCS11_CKK_EC: 1703db28c542SVesa Jääskeläinen mechanism = PKCS11_CKM_EC_KEY_PAIR_GEN; 1704db28c542SVesa Jääskeläinen break; 170503e07432SValerii Chubar case PKCS11_CKK_EDDSA: 170603e07432SValerii Chubar mechanism = PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN; 170703e07432SValerii Chubar break; 170886922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 170986922832SVesa Jääskeläinen mechanism = PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN; 171086922832SVesa Jääskeläinen break; 1711512cbf1dSJens Wiklander default: 1712512cbf1dSJens Wiklander TEE_Panic(key_type); 1713512cbf1dSJens Wiklander break; 1714512cbf1dSJens Wiklander } 1715512cbf1dSJens Wiklander 17162d0cd829SRuchika Gupta mechanism_supported_key_sizes_bytes(mechanism, min_key_size, 1717512cbf1dSJens Wiklander max_key_size); 1718512cbf1dSJens Wiklander } 1719512cbf1dSJens Wiklander 1720512cbf1dSJens Wiklander enum pkcs11_rc check_created_attrs(struct obj_attrs *key1, 1721512cbf1dSJens Wiklander struct obj_attrs *key2) 1722512cbf1dSJens Wiklander { 1723512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 1724512cbf1dSJens Wiklander struct obj_attrs *secret = NULL; 1725013934d8SVesa Jääskeläinen struct obj_attrs *private = NULL; 1726013934d8SVesa Jääskeläinen struct obj_attrs *public = NULL; 1727512cbf1dSJens Wiklander uint32_t max_key_size = 0; 1728512cbf1dSJens Wiklander uint32_t min_key_size = 0; 1729512cbf1dSJens Wiklander uint32_t key_length = 0; 1730512cbf1dSJens Wiklander 1731512cbf1dSJens Wiklander switch (get_class(key1)) { 1732512cbf1dSJens Wiklander case PKCS11_CKO_SECRET_KEY: 1733512cbf1dSJens Wiklander secret = key1; 1734512cbf1dSJens Wiklander break; 1735013934d8SVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 1736013934d8SVesa Jääskeläinen public = key1; 1737013934d8SVesa Jääskeläinen break; 1738013934d8SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1739013934d8SVesa Jääskeläinen private = key1; 1740013934d8SVesa Jääskeläinen break; 1741512cbf1dSJens Wiklander default: 1742512cbf1dSJens Wiklander return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 1743512cbf1dSJens Wiklander } 1744512cbf1dSJens Wiklander 1745013934d8SVesa Jääskeläinen if (key2) { 1746013934d8SVesa Jääskeläinen switch (get_class(key2)) { 1747013934d8SVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 1748013934d8SVesa Jääskeläinen public = key2; 1749013934d8SVesa Jääskeläinen if (private == key1) 1750013934d8SVesa Jääskeläinen break; 1751013934d8SVesa Jääskeläinen 1752013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1753013934d8SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1754013934d8SVesa Jääskeläinen private = key2; 1755013934d8SVesa Jääskeläinen if (public == key1) 1756013934d8SVesa Jääskeläinen break; 1757013934d8SVesa Jääskeläinen 1758013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1759013934d8SVesa Jääskeläinen default: 1760512cbf1dSJens Wiklander return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 1761013934d8SVesa Jääskeläinen } 1762013934d8SVesa Jääskeläinen 1763013934d8SVesa Jääskeläinen if (get_key_type(private) != get_key_type(public)) 1764013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1765013934d8SVesa Jääskeläinen } 1766512cbf1dSJens Wiklander 1767512cbf1dSJens Wiklander if (secret) { 1768512cbf1dSJens Wiklander switch (get_key_type(secret)) { 1769512cbf1dSJens Wiklander case PKCS11_CKK_AES: 1770512cbf1dSJens Wiklander case PKCS11_CKK_GENERIC_SECRET: 1771512cbf1dSJens Wiklander case PKCS11_CKK_MD5_HMAC: 1772512cbf1dSJens Wiklander case PKCS11_CKK_SHA_1_HMAC: 1773512cbf1dSJens Wiklander case PKCS11_CKK_SHA224_HMAC: 1774512cbf1dSJens Wiklander case PKCS11_CKK_SHA256_HMAC: 1775512cbf1dSJens Wiklander case PKCS11_CKK_SHA384_HMAC: 1776512cbf1dSJens Wiklander case PKCS11_CKK_SHA512_HMAC: 1777512cbf1dSJens Wiklander break; 1778512cbf1dSJens Wiklander default: 1779512cbf1dSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1780512cbf1dSJens Wiklander } 1781512cbf1dSJens Wiklander 1782512cbf1dSJens Wiklander /* Get key size */ 1783512cbf1dSJens Wiklander rc = get_u32_attribute(secret, PKCS11_CKA_VALUE_LEN, 1784512cbf1dSJens Wiklander &key_length); 1785512cbf1dSJens Wiklander if (rc) 1786d1d44372SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCOMPLETE; 1787512cbf1dSJens Wiklander } 1788013934d8SVesa Jääskeläinen if (public) { 1789013934d8SVesa Jääskeläinen switch (get_key_type(public)) { 179086922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 179186922832SVesa Jääskeläinen /* Get key size */ 179286922832SVesa Jääskeläinen rc = get_u32_attribute(public, PKCS11_CKA_MODULUS_BITS, 179386922832SVesa Jääskeläinen &key_length); 179486922832SVesa Jääskeläinen if (rc) 179586922832SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 179686922832SVesa Jääskeläinen key_length = ROUNDUP(key_length, 8) / 8; 179786922832SVesa Jääskeläinen break; 179802b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 179903e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 180002b16804SVesa Jääskeläinen break; 1801013934d8SVesa Jääskeläinen default: 1802013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1803013934d8SVesa Jääskeläinen } 1804013934d8SVesa Jääskeläinen } 1805013934d8SVesa Jääskeläinen if (private) { 1806013934d8SVesa Jääskeläinen switch (get_key_type(private)) { 180786922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 180802b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 180903e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 181002b16804SVesa Jääskeläinen break; 1811013934d8SVesa Jääskeläinen default: 1812013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1813013934d8SVesa Jääskeläinen } 1814013934d8SVesa Jääskeläinen } 1815512cbf1dSJens Wiklander 181602b16804SVesa Jääskeläinen /* 181702b16804SVesa Jääskeläinen * Check key size for symmetric keys and RSA keys 181802b16804SVesa Jääskeläinen * EC is bound to domains, no need to check here. 181902b16804SVesa Jääskeläinen */ 182002b16804SVesa Jääskeläinen switch (get_key_type(key1)) { 182102b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 182203e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 182302b16804SVesa Jääskeläinen return PKCS11_CKR_OK; 182402b16804SVesa Jääskeläinen default: 182502b16804SVesa Jääskeläinen break; 182602b16804SVesa Jääskeläinen } 182702b16804SVesa Jääskeläinen 1828512cbf1dSJens Wiklander get_key_min_max_sizes(get_key_type(key1), &min_key_size, &max_key_size); 1829512cbf1dSJens Wiklander if (key_length < min_key_size || key_length > max_key_size) { 1830512cbf1dSJens Wiklander EMSG("Length %"PRIu32" vs range [%"PRIu32" %"PRIu32"]", 1831512cbf1dSJens Wiklander key_length, min_key_size, max_key_size); 1832512cbf1dSJens Wiklander 1833512cbf1dSJens Wiklander return PKCS11_CKR_KEY_SIZE_RANGE; 1834512cbf1dSJens Wiklander } 1835512cbf1dSJens Wiklander 183649ed60abSRuchika Gupta if (secret && get_key_type(secret) == PKCS11_CKK_AES) { 183749ed60abSRuchika Gupta if (key_length != 16 && key_length != 24 && key_length != 32) 183849ed60abSRuchika Gupta return PKCS11_CKR_KEY_SIZE_RANGE; 183949ed60abSRuchika Gupta } 184049ed60abSRuchika Gupta 1841512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1842512cbf1dSJens Wiklander } 1843512cbf1dSJens Wiklander 1844512cbf1dSJens Wiklander /* Check processing ID against attribute ALLOWED_MECHANISMS if any */ 1845512cbf1dSJens Wiklander static bool parent_key_complies_allowed_processings(uint32_t proc_id, 1846512cbf1dSJens Wiklander struct obj_attrs *head) 1847512cbf1dSJens Wiklander { 1848512cbf1dSJens Wiklander char *attr = NULL; 1849512cbf1dSJens Wiklander uint32_t size = 0; 1850512cbf1dSJens Wiklander uint32_t proc = 0; 1851512cbf1dSJens Wiklander size_t count = 0; 18526a760c9eSEtienne Carriere enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 1853512cbf1dSJens Wiklander 18546a760c9eSEtienne Carriere rc = get_attribute_ptr(head, PKCS11_CKA_ALLOWED_MECHANISMS, 18556a760c9eSEtienne Carriere (void *)&attr, &size); 18566a760c9eSEtienne Carriere if (rc == PKCS11_RV_NOT_FOUND) 1857512cbf1dSJens Wiklander return true; 18586a760c9eSEtienne Carriere if (rc) { 18596a760c9eSEtienne Carriere EMSG("unexpected attributes state"); 18606a760c9eSEtienne Carriere TEE_Panic(TEE_ERROR_BAD_STATE); 1861512cbf1dSJens Wiklander } 1862512cbf1dSJens Wiklander 1863512cbf1dSJens Wiklander for (count = size / sizeof(uint32_t); count; count--) { 1864512cbf1dSJens Wiklander TEE_MemMove(&proc, attr, sizeof(uint32_t)); 1865512cbf1dSJens Wiklander attr += sizeof(uint32_t); 1866512cbf1dSJens Wiklander 1867512cbf1dSJens Wiklander if (proc == proc_id) 1868512cbf1dSJens Wiklander return true; 1869512cbf1dSJens Wiklander } 1870512cbf1dSJens Wiklander 1871512cbf1dSJens Wiklander DMSG("can't find %s in allowed list", id2str_proc(proc_id)); 1872512cbf1dSJens Wiklander return false; 1873512cbf1dSJens Wiklander } 1874512cbf1dSJens Wiklander 1875512cbf1dSJens Wiklander static enum pkcs11_attr_id func_to_attr(enum processing_func func) 1876512cbf1dSJens Wiklander { 1877512cbf1dSJens Wiklander switch (func) { 1878512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 1879512cbf1dSJens Wiklander return PKCS11_CKA_ENCRYPT; 1880512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 1881512cbf1dSJens Wiklander return PKCS11_CKA_DECRYPT; 1882512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN: 1883512cbf1dSJens Wiklander return PKCS11_CKA_SIGN; 1884512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY: 1885512cbf1dSJens Wiklander return PKCS11_CKA_VERIFY; 1886512cbf1dSJens Wiklander case PKCS11_FUNCTION_WRAP: 1887512cbf1dSJens Wiklander return PKCS11_CKA_WRAP; 1888512cbf1dSJens Wiklander case PKCS11_FUNCTION_UNWRAP: 1889512cbf1dSJens Wiklander return PKCS11_CKA_UNWRAP; 1890512cbf1dSJens Wiklander case PKCS11_FUNCTION_DERIVE: 1891512cbf1dSJens Wiklander return PKCS11_CKA_DERIVE; 1892512cbf1dSJens Wiklander default: 1893512cbf1dSJens Wiklander return PKCS11_CKA_UNDEFINED_ID; 1894512cbf1dSJens Wiklander } 1895512cbf1dSJens Wiklander } 1896512cbf1dSJens Wiklander 1897512cbf1dSJens Wiklander enum pkcs11_rc 1898512cbf1dSJens Wiklander check_parent_attrs_against_processing(enum pkcs11_mechanism_id proc_id, 1899512cbf1dSJens Wiklander enum processing_func function, 1900512cbf1dSJens Wiklander struct obj_attrs *head) 1901512cbf1dSJens Wiklander { 1902512cbf1dSJens Wiklander enum pkcs11_class_id key_class = get_class(head); 1903512cbf1dSJens Wiklander enum pkcs11_key_type key_type = get_key_type(head); 1904512cbf1dSJens Wiklander enum pkcs11_attr_id attr = func_to_attr(function); 1905512cbf1dSJens Wiklander 1906512cbf1dSJens Wiklander if (!get_bool(head, attr)) { 1907512cbf1dSJens Wiklander DMSG("%s not permitted", id2str_attr(attr)); 1908512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1909512cbf1dSJens Wiklander } 1910512cbf1dSJens Wiklander 1911512cbf1dSJens Wiklander /* Check processing complies with parent key family */ 1912512cbf1dSJens Wiklander switch (proc_id) { 1913512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 1914512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 1915512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 1916512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 19170ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC: 19180ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC_GENERAL: 1919512cbf1dSJens Wiklander if (key_class == PKCS11_CKO_SECRET_KEY && 1920512cbf1dSJens Wiklander key_type == PKCS11_CKK_AES) 1921512cbf1dSJens Wiklander break; 1922512cbf1dSJens Wiklander 1923512cbf1dSJens Wiklander DMSG("%s invalid key %s/%s", id2str_proc(proc_id), 1924512cbf1dSJens Wiklander id2str_class(key_class), id2str_key_type(key_type)); 1925512cbf1dSJens Wiklander 19265f80f270SRuchika Gupta if (function == PKCS11_FUNCTION_WRAP) 19275f80f270SRuchika Gupta return PKCS11_CKR_WRAPPING_KEY_TYPE_INCONSISTENT; 1928e3f0cb56SRuchika Gupta else if (function == PKCS11_FUNCTION_UNWRAP) 1929e3f0cb56SRuchika Gupta return PKCS11_CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT; 19305f80f270SRuchika Gupta else 1931512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1932512cbf1dSJens Wiklander 1933c3033708SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 1934c3033708SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 1935c3033708SRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY && 1936c3033708SRuchika Gupta key_type != PKCS11_CKK_AES) 1937c3033708SRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1938c3033708SRuchika Gupta 1939c3033708SRuchika Gupta if (get_bool(head, PKCS11_CKA_ENCRYPT)) { 1940c3033708SRuchika Gupta /* 1941c3033708SRuchika Gupta * Intentionally refuse to proceed despite 1942c3033708SRuchika Gupta * PKCS#11 specifications v2.40 and v3.0 not expecting 1943c3033708SRuchika Gupta * this behavior to avoid potential security issue 1944c3033708SRuchika Gupta * where keys derived by these mechanisms can be 1945c3033708SRuchika Gupta * revealed by doing data encryption using parent key. 1946c3033708SRuchika Gupta */ 1947c3033708SRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED; 1948c3033708SRuchika Gupta } 1949c3033708SRuchika Gupta 1950c3033708SRuchika Gupta break; 1951689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 1952689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 1953689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 1954689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 1955689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 1956689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 195770b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 195870b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 195970b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 196070b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 196170b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 196270b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 1963689f4e5bSRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY) 1964689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1965689f4e5bSRuchika Gupta 1966689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_GENERIC_SECRET) 1967689f4e5bSRuchika Gupta break; 1968689f4e5bSRuchika Gupta 1969689f4e5bSRuchika Gupta switch (proc_id) { 1970689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 197170b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 1972689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_MD5_HMAC) 1973689f4e5bSRuchika Gupta break; 1974689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1975689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 197670b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 1977689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA_1_HMAC) 1978689f4e5bSRuchika Gupta break; 1979689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1980689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 198170b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 1982689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA224_HMAC) 1983689f4e5bSRuchika Gupta break; 1984689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1985689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 198670b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 1987689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA256_HMAC) 1988689f4e5bSRuchika Gupta break; 1989689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1990689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 199170b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 1992689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA384_HMAC) 1993689f4e5bSRuchika Gupta break; 1994689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1995689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 199670b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 1997689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA512_HMAC) 1998689f4e5bSRuchika Gupta break; 1999689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 2000689f4e5bSRuchika Gupta default: 2001689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 2002689f4e5bSRuchika Gupta } 2003689f4e5bSRuchika Gupta break; 2004689f4e5bSRuchika Gupta 200503e07432SValerii Chubar case PKCS11_CKM_EDDSA: 200603e07432SValerii Chubar if (key_type != PKCS11_CKK_EC_EDWARDS) { 200703e07432SValerii Chubar EMSG("Invalid key %s for mechanism %s", 200803e07432SValerii Chubar id2str_type(key_type, key_class), 200903e07432SValerii Chubar id2str_proc(proc_id)); 201003e07432SValerii Chubar return PKCS11_CKR_KEY_TYPE_INCONSISTENT; 201103e07432SValerii Chubar } 201203e07432SValerii Chubar if (key_class != PKCS11_CKO_PUBLIC_KEY && 201303e07432SValerii Chubar key_class != PKCS11_CKO_PRIVATE_KEY) { 201403e07432SValerii Chubar EMSG("Invalid key class for mechanism %s", 201503e07432SValerii Chubar id2str_proc(proc_id)); 201603e07432SValerii Chubar 201703e07432SValerii Chubar return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 201803e07432SValerii Chubar } 201903e07432SValerii Chubar break; 202003e07432SValerii Chubar 2021fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 2022fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 2023fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 2024fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 2025fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 2026fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 2027cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 2028fb279d8bSVesa Jääskeläinen if (key_type != PKCS11_CKK_EC) { 2029fb279d8bSVesa Jääskeläinen EMSG("Invalid key %s for mechanism %s", 2030fb279d8bSVesa Jääskeläinen id2str_type(key_type, key_class), 2031fb279d8bSVesa Jääskeläinen id2str_proc(proc_id)); 2032fb279d8bSVesa Jääskeläinen 2033fb279d8bSVesa Jääskeläinen return PKCS11_CKR_KEY_TYPE_INCONSISTENT; 2034fb279d8bSVesa Jääskeläinen } 2035fb279d8bSVesa Jääskeläinen if (key_class != PKCS11_CKO_PUBLIC_KEY && 2036fb279d8bSVesa Jääskeläinen key_class != PKCS11_CKO_PRIVATE_KEY) { 2037fb279d8bSVesa Jääskeläinen EMSG("Invalid key class for mechanism %s", 2038fb279d8bSVesa Jääskeläinen id2str_proc(proc_id)); 2039fb279d8bSVesa Jääskeläinen 2040fb279d8bSVesa Jääskeläinen return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 2041fb279d8bSVesa Jääskeläinen } 2042fb279d8bSVesa Jääskeläinen break; 20430442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 20440442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 20450442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 20460442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 20470442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 20480442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 20490442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 205045d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP: 2051dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 2052d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 2053d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 2054d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 2055d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 2056d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 2057d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 20580442c956SVesa Jääskeläinen if (key_type != PKCS11_CKK_RSA) { 20590442c956SVesa Jääskeläinen EMSG("Invalid key %s for mechanism %s", 20600442c956SVesa Jääskeläinen id2str_type(key_type, key_class), 20610442c956SVesa Jääskeläinen id2str_proc(proc_id)); 20620442c956SVesa Jääskeläinen 20630442c956SVesa Jääskeläinen return PKCS11_CKR_KEY_TYPE_INCONSISTENT; 20640442c956SVesa Jääskeläinen } 20650442c956SVesa Jääskeläinen if (key_class != PKCS11_CKO_PUBLIC_KEY && 20660442c956SVesa Jääskeläinen key_class != PKCS11_CKO_PRIVATE_KEY) { 20670442c956SVesa Jääskeläinen EMSG("Invalid key class for mechanism %s", 20680442c956SVesa Jääskeläinen id2str_proc(proc_id)); 20690442c956SVesa Jääskeläinen 20700442c956SVesa Jääskeläinen return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 20710442c956SVesa Jääskeläinen } 20720442c956SVesa Jääskeläinen break; 2073512cbf1dSJens Wiklander default: 2074512cbf1dSJens Wiklander DMSG("Invalid processing %#"PRIx32"/%s", proc_id, 2075512cbf1dSJens Wiklander id2str_proc(proc_id)); 2076512cbf1dSJens Wiklander 2077512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_INVALID; 2078512cbf1dSJens Wiklander } 2079512cbf1dSJens Wiklander 2080512cbf1dSJens Wiklander if (!parent_key_complies_allowed_processings(proc_id, head)) { 2081512cbf1dSJens Wiklander DMSG("Allowed mechanism failed"); 2082512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 2083512cbf1dSJens Wiklander } 2084512cbf1dSJens Wiklander 2085512cbf1dSJens Wiklander return PKCS11_CKR_OK; 2086512cbf1dSJens Wiklander } 2087783c1515SRuchika Gupta 2088783c1515SRuchika Gupta bool attribute_is_exportable(struct pkcs11_attribute_head *req_attr, 2089783c1515SRuchika Gupta struct pkcs11_object *obj) 2090783c1515SRuchika Gupta { 2091783c1515SRuchika Gupta uint8_t boolval = 0; 2092783c1515SRuchika Gupta uint32_t boolsize = 0; 2093783c1515SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 2094783c1515SRuchika Gupta enum pkcs11_class_id key_class = get_class(obj->attributes); 2095783c1515SRuchika Gupta 2096981966bcSVesa Jääskeläinen if (attribute_is_hidden(req_attr)) 2097981966bcSVesa Jääskeläinen return false; 2098981966bcSVesa Jääskeläinen 2099783c1515SRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY && 2100783c1515SRuchika Gupta key_class != PKCS11_CKO_PRIVATE_KEY) 2101783c1515SRuchika Gupta return true; 2102783c1515SRuchika Gupta 2103783c1515SRuchika Gupta switch (req_attr->id) { 2104783c1515SRuchika Gupta case PKCS11_CKA_PRIVATE_EXPONENT: 2105783c1515SRuchika Gupta case PKCS11_CKA_PRIME_1: 2106783c1515SRuchika Gupta case PKCS11_CKA_PRIME_2: 2107783c1515SRuchika Gupta case PKCS11_CKA_EXPONENT_1: 2108783c1515SRuchika Gupta case PKCS11_CKA_EXPONENT_2: 2109783c1515SRuchika Gupta case PKCS11_CKA_COEFFICIENT: 2110783c1515SRuchika Gupta case PKCS11_CKA_VALUE: 2111783c1515SRuchika Gupta boolsize = sizeof(boolval); 2112783c1515SRuchika Gupta rc = get_attribute(obj->attributes, PKCS11_CKA_EXTRACTABLE, 2113783c1515SRuchika Gupta &boolval, &boolsize); 2114783c1515SRuchika Gupta if (rc || boolval == PKCS11_FALSE) 2115783c1515SRuchika Gupta return false; 2116783c1515SRuchika Gupta 2117783c1515SRuchika Gupta boolsize = sizeof(boolval); 2118783c1515SRuchika Gupta rc = get_attribute(obj->attributes, PKCS11_CKA_SENSITIVE, 2119783c1515SRuchika Gupta &boolval, &boolsize); 2120783c1515SRuchika Gupta if (rc || boolval == PKCS11_TRUE) 2121783c1515SRuchika Gupta return false; 2122783c1515SRuchika Gupta break; 2123783c1515SRuchika Gupta default: 2124783c1515SRuchika Gupta break; 2125783c1515SRuchika Gupta } 2126783c1515SRuchika Gupta 2127783c1515SRuchika Gupta return true; 2128783c1515SRuchika Gupta } 21292d25a9bcSRuchika Gupta 21302d25a9bcSRuchika Gupta static bool attr_is_modifiable_any_key(struct pkcs11_attribute_head *attr) 21312d25a9bcSRuchika Gupta { 21322d25a9bcSRuchika Gupta switch (attr->id) { 21332d25a9bcSRuchika Gupta case PKCS11_CKA_ID: 21342d25a9bcSRuchika Gupta case PKCS11_CKA_START_DATE: 21352d25a9bcSRuchika Gupta case PKCS11_CKA_END_DATE: 21362d25a9bcSRuchika Gupta case PKCS11_CKA_DERIVE: 21372d25a9bcSRuchika Gupta return true; 21382d25a9bcSRuchika Gupta default: 21392d25a9bcSRuchika Gupta return false; 21402d25a9bcSRuchika Gupta } 21412d25a9bcSRuchika Gupta } 21422d25a9bcSRuchika Gupta 21432d25a9bcSRuchika Gupta static bool attr_is_modifiable_secret_key(struct pkcs11_attribute_head *attr, 21442d25a9bcSRuchika Gupta struct pkcs11_session *session, 21452d25a9bcSRuchika Gupta struct pkcs11_object *obj) 21462d25a9bcSRuchika Gupta { 21472d25a9bcSRuchika Gupta switch (attr->id) { 21482d25a9bcSRuchika Gupta case PKCS11_CKA_ENCRYPT: 21492d25a9bcSRuchika Gupta case PKCS11_CKA_DECRYPT: 21502d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN: 21512d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY: 21522d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP: 21532d25a9bcSRuchika Gupta case PKCS11_CKA_UNWRAP: 21542d25a9bcSRuchika Gupta return true; 21552d25a9bcSRuchika Gupta /* Can't be modified once set to CK_FALSE - 12 in Table 10 */ 21562d25a9bcSRuchika Gupta case PKCS11_CKA_EXTRACTABLE: 21572d25a9bcSRuchika Gupta return get_bool(obj->attributes, attr->id); 21582d25a9bcSRuchika Gupta /* Can't be modified once set to CK_TRUE - 11 in Table 10 */ 21592d25a9bcSRuchika Gupta case PKCS11_CKA_SENSITIVE: 21602d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP_WITH_TRUSTED: 21612d25a9bcSRuchika Gupta return !get_bool(obj->attributes, attr->id); 21622d25a9bcSRuchika Gupta /* Change in CKA_TRUSTED can only be done by SO */ 21632d25a9bcSRuchika Gupta case PKCS11_CKA_TRUSTED: 21642d25a9bcSRuchika Gupta return pkcs11_session_is_so(session); 21652d25a9bcSRuchika Gupta case PKCS11_CKA_NEVER_EXTRACTABLE: 21662d25a9bcSRuchika Gupta case PKCS11_CKA_ALWAYS_SENSITIVE: 21672d25a9bcSRuchika Gupta return false; 21682d25a9bcSRuchika Gupta default: 21692d25a9bcSRuchika Gupta return false; 21702d25a9bcSRuchika Gupta } 21712d25a9bcSRuchika Gupta } 21722d25a9bcSRuchika Gupta 21732d25a9bcSRuchika Gupta static bool attr_is_modifiable_public_key(struct pkcs11_attribute_head *attr, 21742d25a9bcSRuchika Gupta struct pkcs11_session *session, 21752d25a9bcSRuchika Gupta struct pkcs11_object *obj __unused) 21762d25a9bcSRuchika Gupta { 21772d25a9bcSRuchika Gupta switch (attr->id) { 21782d25a9bcSRuchika Gupta case PKCS11_CKA_SUBJECT: 21792d25a9bcSRuchika Gupta case PKCS11_CKA_ENCRYPT: 21802d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY: 21812d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY_RECOVER: 21822d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP: 21832d25a9bcSRuchika Gupta return true; 21842d25a9bcSRuchika Gupta case PKCS11_CKA_TRUSTED: 21852d25a9bcSRuchika Gupta /* Change in CKA_TRUSTED can only be done by SO */ 21862d25a9bcSRuchika Gupta return pkcs11_session_is_so(session); 21872d25a9bcSRuchika Gupta default: 21882d25a9bcSRuchika Gupta return false; 21892d25a9bcSRuchika Gupta } 21902d25a9bcSRuchika Gupta } 21912d25a9bcSRuchika Gupta 21922d25a9bcSRuchika Gupta static bool attr_is_modifiable_private_key(struct pkcs11_attribute_head *attr, 21932d25a9bcSRuchika Gupta struct pkcs11_session *sess __unused, 21942d25a9bcSRuchika Gupta struct pkcs11_object *obj) 21952d25a9bcSRuchika Gupta { 21962d25a9bcSRuchika Gupta switch (attr->id) { 21972d25a9bcSRuchika Gupta case PKCS11_CKA_SUBJECT: 21982d25a9bcSRuchika Gupta case PKCS11_CKA_DECRYPT: 21992d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN: 22002d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN_RECOVER: 22012d25a9bcSRuchika Gupta case PKCS11_CKA_UNWRAP: 22022d25a9bcSRuchika Gupta /* 22032d25a9bcSRuchika Gupta * TBD: Revisit if we don't support PKCS11_CKA_PUBLIC_KEY_INFO 22042d25a9bcSRuchika Gupta * Specification mentions that if this attribute is 22052d25a9bcSRuchika Gupta * supplied as part of a template for C_CreateObject, C_CopyObject or 22062d25a9bcSRuchika Gupta * C_SetAttributeValue for a private key, the token MUST verify 22072d25a9bcSRuchika Gupta * correspondence between the private key data and the public key data 22082d25a9bcSRuchika Gupta * as supplied in CKA_PUBLIC_KEY_INFO. This needs to be 22092d25a9bcSRuchika Gupta * taken care of when this object type will be implemented 22102d25a9bcSRuchika Gupta */ 22112d25a9bcSRuchika Gupta case PKCS11_CKA_PUBLIC_KEY_INFO: 22122d25a9bcSRuchika Gupta return true; 22132d25a9bcSRuchika Gupta /* Can't be modified once set to CK_FALSE - 12 in Table 10 */ 22142d25a9bcSRuchika Gupta case PKCS11_CKA_EXTRACTABLE: 22152d25a9bcSRuchika Gupta return get_bool(obj->attributes, attr->id); 22162d25a9bcSRuchika Gupta /* Can't be modified once set to CK_TRUE - 11 in Table 10 */ 22172d25a9bcSRuchika Gupta case PKCS11_CKA_SENSITIVE: 22182d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP_WITH_TRUSTED: 22192d25a9bcSRuchika Gupta return !get_bool(obj->attributes, attr->id); 22202d25a9bcSRuchika Gupta case PKCS11_CKA_NEVER_EXTRACTABLE: 22212d25a9bcSRuchika Gupta case PKCS11_CKA_ALWAYS_SENSITIVE: 22222d25a9bcSRuchika Gupta return false; 22232d25a9bcSRuchika Gupta default: 22242d25a9bcSRuchika Gupta return false; 22252d25a9bcSRuchika Gupta } 22262d25a9bcSRuchika Gupta } 22272d25a9bcSRuchika Gupta 22284137952dSVesa Jääskeläinen static bool attr_is_modifiable_certificate(struct pkcs11_attribute_head *attr, 22294137952dSVesa Jääskeläinen struct pkcs11_session *session, 22304137952dSVesa Jääskeläinen struct pkcs11_object *obj) 22314137952dSVesa Jääskeläinen { 22324137952dSVesa Jääskeläinen uint8_t boolval = 0; 22334137952dSVesa Jääskeläinen uint32_t boolsize = 0; 22344137952dSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 22354137952dSVesa Jääskeläinen 22364137952dSVesa Jääskeläinen /* Trusted certificates cannot be modified. */ 22374137952dSVesa Jääskeläinen rc = get_attribute(obj->attributes, PKCS11_CKA_TRUSTED, 22384137952dSVesa Jääskeläinen &boolval, &boolsize); 22394137952dSVesa Jääskeläinen if (rc || boolval == PKCS11_TRUE) 22404137952dSVesa Jääskeläinen return false; 22414137952dSVesa Jääskeläinen 22424137952dSVesa Jääskeläinen /* Common certificate attributes */ 22434137952dSVesa Jääskeläinen switch (attr->id) { 22444137952dSVesa Jääskeläinen case PKCS11_CKA_TRUSTED: 22454137952dSVesa Jääskeläinen /* 22464137952dSVesa Jääskeläinen * The CKA_TRUSTED attribute cannot be set to CK_TRUE by an 22474137952dSVesa Jääskeläinen * application. It MUST be set by a token initialization 22484137952dSVesa Jääskeläinen * application or by the token’s SO. 22494137952dSVesa Jääskeläinen */ 22504137952dSVesa Jääskeläinen return pkcs11_session_is_so(session); 22514137952dSVesa Jääskeläinen case PKCS11_CKA_CERTIFICATE_TYPE: 22524137952dSVesa Jääskeläinen case PKCS11_CKA_CERTIFICATE_CATEGORY: 22534137952dSVesa Jääskeläinen return false; 22544137952dSVesa Jääskeläinen default: 22554137952dSVesa Jääskeläinen break; 22564137952dSVesa Jääskeläinen } 22574137952dSVesa Jääskeläinen 22584137952dSVesa Jääskeläinen /* Certificate type specific attributes */ 22594137952dSVesa Jääskeläinen switch (get_certificate_type(obj->attributes)) { 22604137952dSVesa Jääskeläinen case PKCS11_CKC_X_509: 22614137952dSVesa Jääskeläinen /* 22624137952dSVesa Jääskeläinen * Only the CKA_ID, CKA_ISSUER, and CKA_SERIAL_NUMBER 22634137952dSVesa Jääskeläinen * attributes may be modified after the object is created. 22644137952dSVesa Jääskeläinen */ 22654137952dSVesa Jääskeläinen switch (attr->id) { 22664137952dSVesa Jääskeläinen case PKCS11_CKA_ID: 22674137952dSVesa Jääskeläinen case PKCS11_CKA_ISSUER: 22684137952dSVesa Jääskeläinen case PKCS11_CKA_SERIAL_NUMBER: 22694137952dSVesa Jääskeläinen return true; 22704137952dSVesa Jääskeläinen default: 22714137952dSVesa Jääskeläinen break; 22724137952dSVesa Jääskeläinen } 22734137952dSVesa Jääskeläinen break; 22744137952dSVesa Jääskeläinen default: 22754137952dSVesa Jääskeläinen /* Unsupported certificate type */ 22764137952dSVesa Jääskeläinen break; 22774137952dSVesa Jääskeläinen } 22784137952dSVesa Jääskeläinen 22794137952dSVesa Jääskeläinen return false; 22804137952dSVesa Jääskeläinen } 22814137952dSVesa Jääskeläinen 22822d25a9bcSRuchika Gupta static bool attribute_is_modifiable(struct pkcs11_session *session, 22832d25a9bcSRuchika Gupta struct pkcs11_attribute_head *req_attr, 22842d25a9bcSRuchika Gupta struct pkcs11_object *obj, 22852d25a9bcSRuchika Gupta enum pkcs11_class_id class, 22862d25a9bcSRuchika Gupta enum processing_func function) 22872d25a9bcSRuchika Gupta { 22882d25a9bcSRuchika Gupta /* Check modifiable attributes common to any object */ 22892d25a9bcSRuchika Gupta switch (req_attr->id) { 22902d25a9bcSRuchika Gupta case PKCS11_CKA_LABEL: 22912d25a9bcSRuchika Gupta return true; 22922d25a9bcSRuchika Gupta case PKCS11_CKA_TOKEN: 22932d25a9bcSRuchika Gupta case PKCS11_CKA_MODIFIABLE: 22942d25a9bcSRuchika Gupta case PKCS11_CKA_DESTROYABLE: 22952d25a9bcSRuchika Gupta case PKCS11_CKA_PRIVATE: 22962d25a9bcSRuchika Gupta return function == PKCS11_FUNCTION_COPY; 22972d25a9bcSRuchika Gupta case PKCS11_CKA_COPYABLE: 22982d25a9bcSRuchika Gupta /* 22992d25a9bcSRuchika Gupta * Specification mentions that if the attribute value is false 23002d25a9bcSRuchika Gupta * it can't be set to true. Reading this we assume that it 23012d25a9bcSRuchika Gupta * should be possible to modify this attribute even though this 23022d25a9bcSRuchika Gupta * is not marked as modifiable in Table 10 if done in right 23032d25a9bcSRuchika Gupta * direction i.e from TRUE -> FALSE. 23042d25a9bcSRuchika Gupta */ 23052d25a9bcSRuchika Gupta return get_bool(obj->attributes, req_attr->id); 23062d25a9bcSRuchika Gupta default: 23072d25a9bcSRuchika Gupta break; 23082d25a9bcSRuchika Gupta } 23092d25a9bcSRuchika Gupta 23102d25a9bcSRuchika Gupta /* Attribute checking based on class type */ 23112d25a9bcSRuchika Gupta switch (class) { 23122d25a9bcSRuchika Gupta case PKCS11_CKO_SECRET_KEY: 23132d25a9bcSRuchika Gupta case PKCS11_CKO_PUBLIC_KEY: 23142d25a9bcSRuchika Gupta case PKCS11_CKO_PRIVATE_KEY: 23152d25a9bcSRuchika Gupta if (attr_is_modifiable_any_key(req_attr)) 23162d25a9bcSRuchika Gupta return true; 23172d25a9bcSRuchika Gupta if (class == PKCS11_CKO_SECRET_KEY && 23182d25a9bcSRuchika Gupta attr_is_modifiable_secret_key(req_attr, session, obj)) 23192d25a9bcSRuchika Gupta return true; 23202d25a9bcSRuchika Gupta if (class == PKCS11_CKO_PUBLIC_KEY && 23212d25a9bcSRuchika Gupta attr_is_modifiable_public_key(req_attr, session, obj)) 23222d25a9bcSRuchika Gupta return true; 23232d25a9bcSRuchika Gupta if (class == PKCS11_CKO_PRIVATE_KEY && 23242d25a9bcSRuchika Gupta attr_is_modifiable_private_key(req_attr, session, obj)) 23252d25a9bcSRuchika Gupta return true; 23262d25a9bcSRuchika Gupta break; 23272d25a9bcSRuchika Gupta case PKCS11_CKO_DATA: 23282d25a9bcSRuchika Gupta /* None of the data object attributes are modifiable */ 23292d25a9bcSRuchika Gupta return false; 23304137952dSVesa Jääskeläinen case PKCS11_CKO_CERTIFICATE: 23314137952dSVesa Jääskeläinen return attr_is_modifiable_certificate(req_attr, session, obj); 23322d25a9bcSRuchika Gupta default: 23332d25a9bcSRuchika Gupta break; 23342d25a9bcSRuchika Gupta } 23352d25a9bcSRuchika Gupta 23362d25a9bcSRuchika Gupta return false; 23372d25a9bcSRuchika Gupta } 23382d25a9bcSRuchika Gupta 23392d25a9bcSRuchika Gupta enum pkcs11_rc check_attrs_against_modification(struct pkcs11_session *session, 23402d25a9bcSRuchika Gupta struct obj_attrs *head, 23412d25a9bcSRuchika Gupta struct pkcs11_object *obj, 23422d25a9bcSRuchika Gupta enum processing_func function) 23432d25a9bcSRuchika Gupta { 23442d25a9bcSRuchika Gupta enum pkcs11_class_id class = PKCS11_CKO_UNDEFINED_ID; 23452d25a9bcSRuchika Gupta char *cur = NULL; 23462d25a9bcSRuchika Gupta char *end = NULL; 23472d25a9bcSRuchika Gupta size_t len = 0; 23482d25a9bcSRuchika Gupta 23492d25a9bcSRuchika Gupta class = get_class(obj->attributes); 23502d25a9bcSRuchika Gupta 23512d25a9bcSRuchika Gupta cur = (char *)head + sizeof(struct obj_attrs); 23522d25a9bcSRuchika Gupta end = cur + head->attrs_size; 23532d25a9bcSRuchika Gupta 23542d25a9bcSRuchika Gupta for (; cur < end; cur += len) { 23552d25a9bcSRuchika Gupta /* Structure aligned copy of the pkcs11_ref in the object */ 23562d25a9bcSRuchika Gupta struct pkcs11_attribute_head cli_ref = { }; 23572d25a9bcSRuchika Gupta 23582d25a9bcSRuchika Gupta TEE_MemMove(&cli_ref, cur, sizeof(cli_ref)); 23592d25a9bcSRuchika Gupta len = sizeof(cli_ref) + cli_ref.size; 23602d25a9bcSRuchika Gupta 2361981966bcSVesa Jääskeläinen /* Protect hidden attributes */ 2362981966bcSVesa Jääskeläinen if (attribute_is_hidden(&cli_ref)) 2363981966bcSVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 2364981966bcSVesa Jääskeläinen 23652d25a9bcSRuchika Gupta /* 23662d25a9bcSRuchika Gupta * Check 1 - Check if attribute belongs to the object 23672d25a9bcSRuchika Gupta * The obj->attributes has all the attributes in 23682d25a9bcSRuchika Gupta * it which are allowed for an object. 23692d25a9bcSRuchika Gupta */ 23702d25a9bcSRuchika Gupta if (get_attribute_ptr(obj->attributes, cli_ref.id, NULL, 23712d25a9bcSRuchika Gupta NULL) == PKCS11_RV_NOT_FOUND) 23722d25a9bcSRuchika Gupta return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 23732d25a9bcSRuchika Gupta 23742d25a9bcSRuchika Gupta /* Check 2 - Is attribute modifiable */ 23752d25a9bcSRuchika Gupta if (!attribute_is_modifiable(session, &cli_ref, obj, class, 23762d25a9bcSRuchika Gupta function)) 23772d25a9bcSRuchika Gupta return PKCS11_CKR_ATTRIBUTE_READ_ONLY; 23782d25a9bcSRuchika Gupta 23792d25a9bcSRuchika Gupta /* 23802d25a9bcSRuchika Gupta * Checks for modification in PKCS11_CKA_TOKEN and 23812d25a9bcSRuchika Gupta * PKCS11_CKA_PRIVATE are required for PKCS11_FUNCTION_COPY 23822d25a9bcSRuchika Gupta * only, so skip them for PKCS11_FUNCTION_MODIFY. 23832d25a9bcSRuchika Gupta */ 23842d25a9bcSRuchika Gupta if (function == PKCS11_FUNCTION_MODIFY) 23852d25a9bcSRuchika Gupta continue; 23862d25a9bcSRuchika Gupta 23872d25a9bcSRuchika Gupta /* 23882d25a9bcSRuchika Gupta * An attempt to copy an object to a token will fail for 23892d25a9bcSRuchika Gupta * RO session 23902d25a9bcSRuchika Gupta */ 23912d25a9bcSRuchika Gupta if (cli_ref.id == PKCS11_CKA_TOKEN && 23922d25a9bcSRuchika Gupta get_bool(head, PKCS11_CKA_TOKEN)) { 23932d25a9bcSRuchika Gupta if (!pkcs11_session_is_read_write(session)) { 23942d25a9bcSRuchika Gupta DMSG("Can't copy to token in a RO session"); 23952d25a9bcSRuchika Gupta return PKCS11_CKR_SESSION_READ_ONLY; 23962d25a9bcSRuchika Gupta } 23972d25a9bcSRuchika Gupta } 23982d25a9bcSRuchika Gupta 23992d25a9bcSRuchika Gupta if (cli_ref.id == PKCS11_CKA_PRIVATE) { 24002d25a9bcSRuchika Gupta bool parent_priv = 24012d25a9bcSRuchika Gupta get_bool(obj->attributes, cli_ref.id); 24022d25a9bcSRuchika Gupta bool obj_priv = get_bool(head, cli_ref.id); 24032d25a9bcSRuchika Gupta 24042d25a9bcSRuchika Gupta /* 24052d25a9bcSRuchika Gupta * If PKCS11_CKA_PRIVATE is being set to TRUE from 24062d25a9bcSRuchika Gupta * FALSE, user has to be logged in 24072d25a9bcSRuchika Gupta */ 24082d25a9bcSRuchika Gupta if (!parent_priv && obj_priv) { 24092d25a9bcSRuchika Gupta if ((pkcs11_session_is_public(session) || 24102d25a9bcSRuchika Gupta pkcs11_session_is_so(session))) 24112d25a9bcSRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 24122d25a9bcSRuchika Gupta } 2413df017b2bSRuchika Gupta 2414df017b2bSRuchika Gupta /* 2415df017b2bSRuchika Gupta * Restriction added - Even for Copy, do not allow 2416df017b2bSRuchika Gupta * modification of CKA_PRIVATE from TRUE to FALSE 2417df017b2bSRuchika Gupta */ 2418df017b2bSRuchika Gupta if (parent_priv && !obj_priv) 2419df017b2bSRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 24202d25a9bcSRuchika Gupta } 24212d25a9bcSRuchika Gupta } 24222d25a9bcSRuchika Gupta 24232d25a9bcSRuchika Gupta return PKCS11_CKR_OK; 24242d25a9bcSRuchika Gupta } 24258c499324SRuchika Gupta 24268c499324SRuchika Gupta static enum pkcs11_rc set_secret_key_data(struct obj_attrs **head, void *data, 24278c499324SRuchika Gupta size_t key_size) 24288c499324SRuchika Gupta { 24298c499324SRuchika Gupta uint32_t size = sizeof(uint32_t); 24308c499324SRuchika Gupta uint32_t key_length = 0; 24318c499324SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 24328c499324SRuchika Gupta 24338c499324SRuchika Gupta /* Get key size if present in template */ 24348c499324SRuchika Gupta rc = get_attribute(*head, PKCS11_CKA_VALUE_LEN, &key_length, &size); 24358c499324SRuchika Gupta if (rc && rc != PKCS11_RV_NOT_FOUND) 24368c499324SRuchika Gupta return rc; 24378c499324SRuchika Gupta 24388c499324SRuchika Gupta if (key_length) { 24398c499324SRuchika Gupta if (key_size < key_length) 24408c499324SRuchika Gupta return PKCS11_CKR_DATA_LEN_RANGE; 24418c499324SRuchika Gupta } else { 24428c499324SRuchika Gupta key_length = key_size; 24438c499324SRuchika Gupta rc = set_attribute(head, PKCS11_CKA_VALUE_LEN, &key_length, 24448c499324SRuchika Gupta sizeof(uint32_t)); 24458c499324SRuchika Gupta if (rc) 24468c499324SRuchika Gupta return rc; 24478c499324SRuchika Gupta } 24488c499324SRuchika Gupta 24498c499324SRuchika Gupta /* Now we can check the VALUE_LEN field */ 24508c499324SRuchika Gupta rc = check_created_attrs(*head, NULL); 24518c499324SRuchika Gupta if (rc) 24528c499324SRuchika Gupta return rc; 24538c499324SRuchika Gupta 24548c499324SRuchika Gupta /* Remove the default empty value attribute if found */ 24558c499324SRuchika Gupta rc = remove_empty_attribute(head, PKCS11_CKA_VALUE); 24568c499324SRuchika Gupta if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND) 24578c499324SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 24588c499324SRuchika Gupta 24598c499324SRuchika Gupta return add_attribute(head, PKCS11_CKA_VALUE, data, key_length); 24608c499324SRuchika Gupta } 24618c499324SRuchika Gupta 246245d40bdaSValerii Chubar static enum pkcs11_rc set_private_key_data_rsa(struct obj_attrs **head, 246345d40bdaSValerii Chubar void *data, 246445d40bdaSValerii Chubar size_t key_size) 246545d40bdaSValerii Chubar { 246645d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 246745d40bdaSValerii Chubar int mbedtls_rc = 0; 246845d40bdaSValerii Chubar uint32_t key_bits = 0; 246945d40bdaSValerii Chubar uint32_t size = 0; 247045d40bdaSValerii Chubar uint32_t buffer_size = 0; 247145d40bdaSValerii Chubar void *buffer = NULL; 247245d40bdaSValerii Chubar mbedtls_pk_context pk = { }; 247345d40bdaSValerii Chubar mbedtls_rsa_context *rsa = NULL; 247445d40bdaSValerii Chubar mbedtls_mpi n = { }; 247545d40bdaSValerii Chubar mbedtls_mpi e = { }; 247645d40bdaSValerii Chubar mbedtls_mpi d = { }; 247745d40bdaSValerii Chubar mbedtls_mpi p = { }; 247845d40bdaSValerii Chubar mbedtls_mpi q = { }; 247945d40bdaSValerii Chubar 248045d40bdaSValerii Chubar rc = get_u32_attribute(*head, PKCS11_CKA_MODULUS_BITS, &key_bits); 248145d40bdaSValerii Chubar if (rc && rc != PKCS11_RV_NOT_FOUND) 248245d40bdaSValerii Chubar return rc; 248345d40bdaSValerii Chubar 248445d40bdaSValerii Chubar if (remove_empty_attribute(head, PKCS11_CKA_MODULUS) || 248545d40bdaSValerii Chubar remove_empty_attribute(head, PKCS11_CKA_PUBLIC_EXPONENT) || 248645d40bdaSValerii Chubar remove_empty_attribute(head, PKCS11_CKA_PRIVATE_EXPONENT) || 248745d40bdaSValerii Chubar remove_empty_attribute(head, PKCS11_CKA_PRIME_1) || 248845d40bdaSValerii Chubar remove_empty_attribute(head, PKCS11_CKA_PRIME_2)) 248945d40bdaSValerii Chubar return PKCS11_CKR_GENERAL_ERROR; 249045d40bdaSValerii Chubar 249145d40bdaSValerii Chubar mbedtls_pk_init(&pk); 249245d40bdaSValerii Chubar mbedtls_mpi_init(&n); 249345d40bdaSValerii Chubar mbedtls_mpi_init(&e); 249445d40bdaSValerii Chubar mbedtls_mpi_init(&d); 249545d40bdaSValerii Chubar mbedtls_mpi_init(&p); 249645d40bdaSValerii Chubar mbedtls_mpi_init(&q); 249745d40bdaSValerii Chubar 249845d40bdaSValerii Chubar mbedtls_rc = mbedtls_pk_parse_key(&pk, data, key_size, NULL, 0); 249945d40bdaSValerii Chubar if (mbedtls_rc) { 250045d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 250145d40bdaSValerii Chubar goto out; 250245d40bdaSValerii Chubar } 250345d40bdaSValerii Chubar 250445d40bdaSValerii Chubar rsa = mbedtls_pk_rsa(pk); 250545d40bdaSValerii Chubar mbedtls_rc = mbedtls_rsa_export(rsa, &n, &p, &q, &d, &e); 250645d40bdaSValerii Chubar if (mbedtls_rc) { 250745d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 250845d40bdaSValerii Chubar goto out; 250945d40bdaSValerii Chubar } 251045d40bdaSValerii Chubar 251145d40bdaSValerii Chubar if (key_bits && mbedtls_mpi_bitlen(&n) != key_bits) { 251245d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE; 251345d40bdaSValerii Chubar goto out; 251445d40bdaSValerii Chubar } 251545d40bdaSValerii Chubar 251645d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&n), 8); 251745d40bdaSValerii Chubar buffer_size = size; 251845d40bdaSValerii Chubar buffer = TEE_Malloc(buffer_size, TEE_USER_MEM_HINT_NO_FILL_ZERO); 251945d40bdaSValerii Chubar if (!buffer) { 252045d40bdaSValerii Chubar rc = PKCS11_CKR_DEVICE_MEMORY; 252145d40bdaSValerii Chubar goto out; 252245d40bdaSValerii Chubar } 252345d40bdaSValerii Chubar 252445d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&n, buffer, size); 252545d40bdaSValerii Chubar if (mbedtls_rc) { 252645d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 252745d40bdaSValerii Chubar goto out; 252845d40bdaSValerii Chubar } 252945d40bdaSValerii Chubar 253045d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_MODULUS, buffer, size); 253145d40bdaSValerii Chubar if (rc) 253245d40bdaSValerii Chubar goto out; 253345d40bdaSValerii Chubar 253445d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&e), 8); 253545d40bdaSValerii Chubar if (buffer_size < size) { 253645d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE; 253745d40bdaSValerii Chubar goto out; 253845d40bdaSValerii Chubar } 253945d40bdaSValerii Chubar 254045d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&e, buffer, size); 254145d40bdaSValerii Chubar if (mbedtls_rc) { 254245d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 254345d40bdaSValerii Chubar goto out; 254445d40bdaSValerii Chubar } 254545d40bdaSValerii Chubar 254645d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_PUBLIC_EXPONENT, buffer, size); 254745d40bdaSValerii Chubar if (rc) 254845d40bdaSValerii Chubar goto out; 254945d40bdaSValerii Chubar 255045d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&d), 8); 255145d40bdaSValerii Chubar if (buffer_size < size) { 255245d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE; 255345d40bdaSValerii Chubar goto out; 255445d40bdaSValerii Chubar } 255545d40bdaSValerii Chubar 255645d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&d, buffer, size); 255745d40bdaSValerii Chubar if (mbedtls_rc) { 255845d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 255945d40bdaSValerii Chubar goto out; 256045d40bdaSValerii Chubar } 256145d40bdaSValerii Chubar 256245d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_PRIVATE_EXPONENT, buffer, size); 256345d40bdaSValerii Chubar if (rc) 256445d40bdaSValerii Chubar goto out; 256545d40bdaSValerii Chubar 256645d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&p), 8); 256745d40bdaSValerii Chubar if (buffer_size < size) { 256845d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE; 256945d40bdaSValerii Chubar goto out; 257045d40bdaSValerii Chubar } 257145d40bdaSValerii Chubar 257245d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&p, buffer, size); 257345d40bdaSValerii Chubar if (mbedtls_rc) { 257445d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 257545d40bdaSValerii Chubar goto out; 257645d40bdaSValerii Chubar } 257745d40bdaSValerii Chubar 257845d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_PRIME_1, buffer, size); 257945d40bdaSValerii Chubar if (rc) 258045d40bdaSValerii Chubar goto out; 258145d40bdaSValerii Chubar 258245d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&q), 8); 258345d40bdaSValerii Chubar if (buffer_size < size) { 258445d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE; 258545d40bdaSValerii Chubar goto out; 258645d40bdaSValerii Chubar } 258745d40bdaSValerii Chubar 258845d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&q, buffer, size); 258945d40bdaSValerii Chubar if (mbedtls_rc) { 259045d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 259145d40bdaSValerii Chubar goto out; 259245d40bdaSValerii Chubar } 259345d40bdaSValerii Chubar 259445d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_PRIME_2, buffer, size); 259545d40bdaSValerii Chubar 259645d40bdaSValerii Chubar out: 259745d40bdaSValerii Chubar mbedtls_pk_free(&pk); 259845d40bdaSValerii Chubar mbedtls_mpi_free(&n); 259945d40bdaSValerii Chubar mbedtls_mpi_free(&e); 260045d40bdaSValerii Chubar mbedtls_mpi_free(&d); 260145d40bdaSValerii Chubar mbedtls_mpi_free(&p); 260245d40bdaSValerii Chubar mbedtls_mpi_free(&q); 260345d40bdaSValerii Chubar TEE_Free(buffer); 260445d40bdaSValerii Chubar return rc; 260545d40bdaSValerii Chubar } 260645d40bdaSValerii Chubar 26078c499324SRuchika Gupta enum pkcs11_rc set_key_data(struct obj_attrs **head, void *data, 26088c499324SRuchika Gupta size_t key_size) 26098c499324SRuchika Gupta { 26108c499324SRuchika Gupta switch (get_class(*head)) { 26118c499324SRuchika Gupta case PKCS11_CKO_SECRET_KEY: 26128c499324SRuchika Gupta return set_secret_key_data(head, data, key_size); 261345d40bdaSValerii Chubar case PKCS11_CKO_PRIVATE_KEY: 261445d40bdaSValerii Chubar if (get_key_type(*head) == PKCS11_CKK_RSA) 261545d40bdaSValerii Chubar return set_private_key_data_rsa(head, data, key_size); 261645d40bdaSValerii Chubar break; 26178c499324SRuchika Gupta default: 26188c499324SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 26198c499324SRuchika Gupta } 262045d40bdaSValerii Chubar 262145d40bdaSValerii Chubar return PKCS11_CKR_GENERAL_ERROR; 26228c499324SRuchika Gupta } 26235e1d94ebSVesa Jääskeläinen 2624a9aa45d8SValerii Chubar static enum pkcs11_rc alloc_copy_attribute_value(struct obj_attrs *head, 2625a9aa45d8SValerii Chubar void **data, uint32_t *sz) 2626a9aa45d8SValerii Chubar { 2627a9aa45d8SValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 2628a9aa45d8SValerii Chubar void *buffer = NULL; 2629a9aa45d8SValerii Chubar void *value = NULL; 2630a9aa45d8SValerii Chubar 2631a9aa45d8SValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_VALUE, &value, sz); 2632a9aa45d8SValerii Chubar if (rc) 2633a9aa45d8SValerii Chubar return PKCS11_CKR_ARGUMENTS_BAD; 2634a9aa45d8SValerii Chubar 2635a9aa45d8SValerii Chubar buffer = TEE_Malloc(*sz, TEE_USER_MEM_HINT_NO_FILL_ZERO); 2636a9aa45d8SValerii Chubar if (!buffer) 2637a9aa45d8SValerii Chubar return PKCS11_CKR_DEVICE_MEMORY; 2638a9aa45d8SValerii Chubar 2639a9aa45d8SValerii Chubar TEE_MemMove(buffer, value, *sz); 2640a9aa45d8SValerii Chubar *data = buffer; 2641a9aa45d8SValerii Chubar 2642a9aa45d8SValerii Chubar return PKCS11_CKR_OK; 2643a9aa45d8SValerii Chubar } 2644a9aa45d8SValerii Chubar 264545d40bdaSValerii Chubar static enum pkcs11_rc 264645d40bdaSValerii Chubar encode_rsa_private_key_der(struct obj_attrs *head, void **data, uint32_t *sz) 264745d40bdaSValerii Chubar { 264845d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 264945d40bdaSValerii Chubar int i = 0; 265045d40bdaSValerii Chubar int mbedtls_rc = 0; 265145d40bdaSValerii Chubar int start = 0; 265245d40bdaSValerii Chubar int der_size = 0; 265345d40bdaSValerii Chubar void *n = NULL; 265445d40bdaSValerii Chubar void *p = NULL; 265545d40bdaSValerii Chubar void *q = NULL; 265645d40bdaSValerii Chubar void *d = NULL; 265745d40bdaSValerii Chubar void *e = NULL; 265845d40bdaSValerii Chubar uint32_t n_len = 0; 265945d40bdaSValerii Chubar uint32_t p_len = 0; 266045d40bdaSValerii Chubar uint32_t q_len = 0; 266145d40bdaSValerii Chubar uint32_t d_len = 0; 266245d40bdaSValerii Chubar uint32_t e_len = 0; 266345d40bdaSValerii Chubar uint8_t *buffer = NULL; 266445d40bdaSValerii Chubar mbedtls_pk_context pk = { }; 266545d40bdaSValerii Chubar mbedtls_rsa_context *rsa = NULL; 266645d40bdaSValerii Chubar const mbedtls_pk_info_t *pk_info = NULL; 266745d40bdaSValerii Chubar 266845d40bdaSValerii Chubar mbedtls_pk_init(&pk); 266945d40bdaSValerii Chubar pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA); 267045d40bdaSValerii Chubar if (mbedtls_pk_setup(&pk, pk_info)) { 267145d40bdaSValerii Chubar rc = PKCS11_CKR_GENERAL_ERROR; 267245d40bdaSValerii Chubar goto out; 267345d40bdaSValerii Chubar } 267445d40bdaSValerii Chubar 267545d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_MODULUS, &n, &n_len); 267645d40bdaSValerii Chubar if (rc) 267745d40bdaSValerii Chubar goto out; 267845d40bdaSValerii Chubar 267945d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_PRIME_1, &p, &p_len); 268045d40bdaSValerii Chubar if (rc) 268145d40bdaSValerii Chubar goto out; 268245d40bdaSValerii Chubar 268345d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_PRIME_2, &q, &q_len); 268445d40bdaSValerii Chubar if (rc) 268545d40bdaSValerii Chubar goto out; 268645d40bdaSValerii Chubar 268745d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_PRIVATE_EXPONENT, &d, &d_len); 268845d40bdaSValerii Chubar if (rc) 268945d40bdaSValerii Chubar goto out; 269045d40bdaSValerii Chubar 269145d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_PUBLIC_EXPONENT, &e, &e_len); 269245d40bdaSValerii Chubar if (rc) 269345d40bdaSValerii Chubar goto out; 269445d40bdaSValerii Chubar 269545d40bdaSValerii Chubar rsa = mbedtls_pk_rsa(pk); 269645d40bdaSValerii Chubar mbedtls_rc = mbedtls_rsa_import_raw(rsa, n, n_len, p, p_len, 269745d40bdaSValerii Chubar q, q_len, d, d_len, e, e_len); 269845d40bdaSValerii Chubar if (mbedtls_rc) { 269945d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 270045d40bdaSValerii Chubar goto out; 270145d40bdaSValerii Chubar } 270245d40bdaSValerii Chubar 270345d40bdaSValerii Chubar if (mbedtls_rsa_complete(rsa)) { 270445d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 270545d40bdaSValerii Chubar goto out; 270645d40bdaSValerii Chubar } 270745d40bdaSValerii Chubar 270845d40bdaSValerii Chubar if (mbedtls_rsa_check_privkey(rsa)) { 270945d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 271045d40bdaSValerii Chubar goto out; 271145d40bdaSValerii Chubar } 271245d40bdaSValerii Chubar 271345d40bdaSValerii Chubar der_size = n_len * 8; 271445d40bdaSValerii Chubar buffer = TEE_Malloc(der_size, TEE_USER_MEM_HINT_NO_FILL_ZERO); 271545d40bdaSValerii Chubar if (!buffer) { 271645d40bdaSValerii Chubar rc = PKCS11_CKR_DEVICE_MEMORY; 271745d40bdaSValerii Chubar goto out; 271845d40bdaSValerii Chubar } 271945d40bdaSValerii Chubar 272045d40bdaSValerii Chubar mbedtls_rc = mbedtls_pk_write_key_der(&pk, buffer, der_size); 272145d40bdaSValerii Chubar if (mbedtls_rc < 0) { 272245d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 272345d40bdaSValerii Chubar goto out; 272445d40bdaSValerii Chubar } 272545d40bdaSValerii Chubar 272645d40bdaSValerii Chubar start = der_size - mbedtls_rc; 272745d40bdaSValerii Chubar for (i = 0; i < mbedtls_rc; i++) { 272845d40bdaSValerii Chubar buffer[i] = buffer[i + start]; 272945d40bdaSValerii Chubar buffer[i + start] = 0; 273045d40bdaSValerii Chubar } 273145d40bdaSValerii Chubar 273245d40bdaSValerii Chubar *data = buffer; 273345d40bdaSValerii Chubar *sz = mbedtls_rc; 273445d40bdaSValerii Chubar out: 273545d40bdaSValerii Chubar mbedtls_pk_free(&pk); 273645d40bdaSValerii Chubar 273745d40bdaSValerii Chubar if (rc) 273845d40bdaSValerii Chubar TEE_Free(buffer); 273945d40bdaSValerii Chubar 274045d40bdaSValerii Chubar return rc; 274145d40bdaSValerii Chubar } 274245d40bdaSValerii Chubar 2743a9aa45d8SValerii Chubar enum pkcs11_rc alloc_key_data_to_wrap(struct obj_attrs *head, void **data, 27445f80f270SRuchika Gupta uint32_t *sz) 27455f80f270SRuchika Gupta { 274645d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 274745d40bdaSValerii Chubar 27485f80f270SRuchika Gupta switch (get_class(head)) { 27495f80f270SRuchika Gupta case PKCS11_CKO_SECRET_KEY: 275045d40bdaSValerii Chubar rc = alloc_copy_attribute_value(head, data, sz); 275145d40bdaSValerii Chubar break; 275245d40bdaSValerii Chubar case PKCS11_CKO_PRIVATE_KEY: 275345d40bdaSValerii Chubar if (get_key_type(head) == PKCS11_CKK_RSA) 275445d40bdaSValerii Chubar rc = encode_rsa_private_key_der(head, data, sz); 275545d40bdaSValerii Chubar break; 27565f80f270SRuchika Gupta default: 275745d40bdaSValerii Chubar break; 27585f80f270SRuchika Gupta } 27595f80f270SRuchika Gupta 276045d40bdaSValerii Chubar return rc; 27615f80f270SRuchika Gupta } 27625f80f270SRuchika Gupta 27635e1d94ebSVesa Jääskeläinen enum pkcs11_rc add_missing_attribute_id(struct obj_attrs **pub_head, 27645e1d94ebSVesa Jääskeläinen struct obj_attrs **priv_head) 27655e1d94ebSVesa Jääskeläinen { 27665e1d94ebSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 27675e1d94ebSVesa Jääskeläinen void *id1 = NULL; 27685e1d94ebSVesa Jääskeläinen uint32_t id1_size = 0; 27695e1d94ebSVesa Jääskeläinen void *id2 = NULL; 27705e1d94ebSVesa Jääskeläinen uint32_t id2_size = 0; 27715e1d94ebSVesa Jääskeläinen 27725e1d94ebSVesa Jääskeläinen assert(pub_head); 27735e1d94ebSVesa Jääskeläinen assert(priv_head); 27745e1d94ebSVesa Jääskeläinen 27755e1d94ebSVesa Jääskeläinen rc = get_attribute_ptr(*pub_head, PKCS11_CKA_ID, &id1, &id1_size); 27765e1d94ebSVesa Jääskeläinen if (rc) { 27775e1d94ebSVesa Jääskeläinen if (rc != PKCS11_RV_NOT_FOUND) 27785e1d94ebSVesa Jääskeläinen return rc; 27795e1d94ebSVesa Jääskeläinen id1 = NULL; 27805e1d94ebSVesa Jääskeläinen } else if (!id1_size) { 27815e1d94ebSVesa Jääskeläinen id1 = NULL; 27825e1d94ebSVesa Jääskeläinen } 27835e1d94ebSVesa Jääskeläinen 27845e1d94ebSVesa Jääskeläinen rc = get_attribute_ptr(*priv_head, PKCS11_CKA_ID, &id2, &id2_size); 27855e1d94ebSVesa Jääskeläinen if (rc) { 27865e1d94ebSVesa Jääskeläinen if (rc != PKCS11_RV_NOT_FOUND) 27875e1d94ebSVesa Jääskeläinen return rc; 27885e1d94ebSVesa Jääskeläinen id2 = NULL; 27895e1d94ebSVesa Jääskeläinen } else if (!id2_size) { 27905e1d94ebSVesa Jääskeläinen id2 = NULL; 27915e1d94ebSVesa Jääskeläinen } 27925e1d94ebSVesa Jääskeläinen 27935e1d94ebSVesa Jääskeläinen /* Both have value -- let them be what caller has specified them */ 27945e1d94ebSVesa Jääskeläinen if (id1 && id2) 27955e1d94ebSVesa Jääskeläinen return PKCS11_CKR_OK; 27965e1d94ebSVesa Jääskeläinen 27975e1d94ebSVesa Jääskeläinen /* Both are empty -- leave empty values */ 27985e1d94ebSVesa Jääskeläinen if (!id1 && !id2) 27995e1d94ebSVesa Jääskeläinen return PKCS11_CKR_OK; 28005e1d94ebSVesa Jääskeläinen 28015e1d94ebSVesa Jääskeläinen /* Cross copy CKA_ID value */ 28025e1d94ebSVesa Jääskeläinen if (id1) 28035e1d94ebSVesa Jääskeläinen return set_attribute(priv_head, PKCS11_CKA_ID, id1, id1_size); 28045e1d94ebSVesa Jääskeläinen else 28055e1d94ebSVesa Jääskeläinen return set_attribute(pub_head, PKCS11_CKA_ID, id2, id2_size); 28065e1d94ebSVesa Jääskeläinen } 2807