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> 7bcac2127SMarouene Boubakri #include <config.h> 863f89caaSJens Wiklander #include <inttypes.h> 97c243321SVesa Jääskeläinen #include <mbedtls/asn1write.h> 107c243321SVesa Jääskeläinen #include <mbedtls/ecp.h> 1145d40bdaSValerii Chubar #include <mbedtls/pk.h> 1263f89caaSJens Wiklander #include <pkcs11_ta.h> 1363f89caaSJens Wiklander #include <stdlib.h> 1463f89caaSJens Wiklander #include <string_ext.h> 1563f89caaSJens Wiklander #include <tee_internal_api_extensions.h> 1663f89caaSJens Wiklander #include <tee_internal_api.h> 176a760c9eSEtienne Carriere #include <trace.h> 1863f89caaSJens Wiklander #include <util.h> 1963f89caaSJens Wiklander 2063f89caaSJens Wiklander #include "attributes.h" 2163f89caaSJens Wiklander #include "handle.h" 2263f89caaSJens Wiklander #include "pkcs11_attributes.h" 2363f89caaSJens Wiklander #include "pkcs11_helpers.h" 2463f89caaSJens Wiklander #include "pkcs11_token.h" 257c243321SVesa Jääskeläinen #include "processing.h" 2663f89caaSJens Wiklander #include "sanitize_object.h" 2763f89caaSJens Wiklander #include "serializer.h" 2863f89caaSJens Wiklander #include "token_capabilities.h" 2963f89caaSJens Wiklander 30512cbf1dSJens Wiklander static uint32_t pkcs11_func2ckfm(enum processing_func function) 31512cbf1dSJens Wiklander { 32512cbf1dSJens Wiklander switch (function) { 33512cbf1dSJens Wiklander case PKCS11_FUNCTION_DIGEST: 34512cbf1dSJens Wiklander return PKCS11_CKFM_DIGEST; 35512cbf1dSJens Wiklander case PKCS11_FUNCTION_GENERATE: 36512cbf1dSJens Wiklander return PKCS11_CKFM_GENERATE; 37512cbf1dSJens Wiklander case PKCS11_FUNCTION_GENERATE_PAIR: 38512cbf1dSJens Wiklander return PKCS11_CKFM_GENERATE_KEY_PAIR; 39512cbf1dSJens Wiklander case PKCS11_FUNCTION_DERIVE: 40512cbf1dSJens Wiklander return PKCS11_CKFM_DERIVE; 41512cbf1dSJens Wiklander case PKCS11_FUNCTION_WRAP: 42512cbf1dSJens Wiklander return PKCS11_CKFM_WRAP; 43512cbf1dSJens Wiklander case PKCS11_FUNCTION_UNWRAP: 44512cbf1dSJens Wiklander return PKCS11_CKFM_UNWRAP; 45512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 46512cbf1dSJens Wiklander return PKCS11_CKFM_ENCRYPT; 47512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 48512cbf1dSJens Wiklander return PKCS11_CKFM_DECRYPT; 49512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN: 50512cbf1dSJens Wiklander return PKCS11_CKFM_SIGN; 51512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY: 52512cbf1dSJens Wiklander return PKCS11_CKFM_VERIFY; 53512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN_RECOVER: 54512cbf1dSJens Wiklander return PKCS11_CKFM_SIGN_RECOVER; 55512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY_RECOVER: 56512cbf1dSJens Wiklander return PKCS11_CKFM_VERIFY_RECOVER; 57512cbf1dSJens Wiklander default: 58512cbf1dSJens Wiklander return 0; 59512cbf1dSJens Wiklander } 60512cbf1dSJens Wiklander } 61512cbf1dSJens Wiklander 62512cbf1dSJens Wiklander enum pkcs11_rc 63512cbf1dSJens Wiklander check_mechanism_against_processing(struct pkcs11_session *session, 64512cbf1dSJens Wiklander enum pkcs11_mechanism_id mechanism_type, 65512cbf1dSJens Wiklander enum processing_func function, 66512cbf1dSJens Wiklander enum processing_step step) 67512cbf1dSJens Wiklander { 68512cbf1dSJens Wiklander bool allowed = false; 69512cbf1dSJens Wiklander 70512cbf1dSJens Wiklander switch (step) { 71512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_INIT: 72512cbf1dSJens Wiklander switch (function) { 73512cbf1dSJens Wiklander case PKCS11_FUNCTION_IMPORT: 74512cbf1dSJens Wiklander case PKCS11_FUNCTION_COPY: 75512cbf1dSJens Wiklander case PKCS11_FUNCTION_MODIFY: 76512cbf1dSJens Wiklander case PKCS11_FUNCTION_DESTROY: 77512cbf1dSJens Wiklander return PKCS11_CKR_OK; 78512cbf1dSJens Wiklander default: 79512cbf1dSJens Wiklander break; 80512cbf1dSJens Wiklander } 81512cbf1dSJens Wiklander /* 82512cbf1dSJens Wiklander * Check that the returned PKCS11_CKFM_* flag from 83512cbf1dSJens Wiklander * pkcs11_func2ckfm() is among the ones from 84512cbf1dSJens Wiklander * mechanism_supported_flags(). 85512cbf1dSJens Wiklander */ 86512cbf1dSJens Wiklander allowed = mechanism_supported_flags(mechanism_type) & 87512cbf1dSJens Wiklander pkcs11_func2ckfm(function); 88512cbf1dSJens Wiklander break; 89512cbf1dSJens Wiklander 90512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_ONESHOT: 910460a039SRuchika Gupta if (session->processing->always_authen && 920460a039SRuchika Gupta !session->processing->relogged) 930460a039SRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 940460a039SRuchika Gupta 952364aa69SRuchika Gupta if (session->processing->step == PKCS11_FUNC_STEP_UPDATE || 962364aa69SRuchika Gupta session->processing->step == PKCS11_FUNC_STEP_FINAL) { 972364aa69SRuchika Gupta EMSG("Cannot perform one-shot on active processing"); 980460a039SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE; 990460a039SRuchika Gupta } 1000460a039SRuchika Gupta 1010460a039SRuchika Gupta allowed = true; 1020460a039SRuchika Gupta break; 1030460a039SRuchika Gupta 104512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_UPDATE: 105512cbf1dSJens Wiklander if (session->processing->always_authen && 106512cbf1dSJens Wiklander !session->processing->relogged) 107512cbf1dSJens Wiklander return PKCS11_CKR_USER_NOT_LOGGED_IN; 108512cbf1dSJens Wiklander 1092364aa69SRuchika Gupta if (session->processing->step == PKCS11_FUNC_STEP_ONESHOT || 1102364aa69SRuchika Gupta session->processing->step == PKCS11_FUNC_STEP_FINAL) { 1112364aa69SRuchika Gupta EMSG("Cannot perform update on finalized processing"); 1122364aa69SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE; 1132364aa69SRuchika Gupta } 1142364aa69SRuchika Gupta 115512cbf1dSJens Wiklander allowed = !mechanism_is_one_shot_only(mechanism_type); 116512cbf1dSJens Wiklander break; 117512cbf1dSJens Wiklander 1189e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE_KEY: 1199e91a619SVesa Jääskeläinen assert(function == PKCS11_FUNCTION_DIGEST); 1209e91a619SVesa Jääskeläinen 1219e91a619SVesa Jääskeläinen if (session->processing->always_authen && 1229e91a619SVesa Jääskeläinen !session->processing->relogged) 1239e91a619SVesa Jääskeläinen return PKCS11_CKR_USER_NOT_LOGGED_IN; 1249e91a619SVesa Jääskeläinen 1259e91a619SVesa Jääskeläinen allowed = true; 1269e91a619SVesa Jääskeläinen break; 1279e91a619SVesa Jääskeläinen 128512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_FINAL: 129512cbf1dSJens Wiklander if (session->processing->always_authen && 130512cbf1dSJens Wiklander !session->processing->relogged) 131512cbf1dSJens Wiklander return PKCS11_CKR_USER_NOT_LOGGED_IN; 132512cbf1dSJens Wiklander 1332364aa69SRuchika Gupta if (session->processing->step == PKCS11_FUNC_STEP_ONESHOT) { 1342364aa69SRuchika Gupta EMSG("Cannot perform final on oneshot processing"); 1352364aa69SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE; 1362364aa69SRuchika Gupta } 137512cbf1dSJens Wiklander return PKCS11_CKR_OK; 138512cbf1dSJens Wiklander 139512cbf1dSJens Wiklander default: 140512cbf1dSJens Wiklander TEE_Panic(step); 141512cbf1dSJens Wiklander break; 142512cbf1dSJens Wiklander } 143512cbf1dSJens Wiklander 144512cbf1dSJens Wiklander if (!allowed) { 145512cbf1dSJens Wiklander EMSG("Processing %#x/%s not permitted (%u/%u)", 146512cbf1dSJens Wiklander (unsigned int)mechanism_type, id2str_proc(mechanism_type), 147512cbf1dSJens Wiklander function, step); 148df705578SRuchika Gupta return PKCS11_CKR_MECHANISM_INVALID; 149512cbf1dSJens Wiklander } 150512cbf1dSJens Wiklander 151512cbf1dSJens Wiklander return PKCS11_CKR_OK; 152512cbf1dSJens Wiklander } 153512cbf1dSJens Wiklander 15463f89caaSJens Wiklander /* 15563f89caaSJens Wiklander * Object default boolean attributes as per PKCS#11 15663f89caaSJens Wiklander */ 15763f89caaSJens Wiklander static uint8_t *pkcs11_object_default_boolprop(uint32_t attribute) 15863f89caaSJens Wiklander { 15963f89caaSJens Wiklander static const uint8_t bool_true = 1; 16063f89caaSJens Wiklander static const uint8_t bool_false; 16163f89caaSJens Wiklander 16263f89caaSJens Wiklander switch (attribute) { 16363f89caaSJens Wiklander /* As per PKCS#11 default value */ 16463f89caaSJens Wiklander case PKCS11_CKA_MODIFIABLE: 16563f89caaSJens Wiklander case PKCS11_CKA_COPYABLE: 16663f89caaSJens Wiklander case PKCS11_CKA_DESTROYABLE: 16763f89caaSJens Wiklander return (uint8_t *)&bool_true; 16863f89caaSJens Wiklander case PKCS11_CKA_TOKEN: 16963f89caaSJens Wiklander case PKCS11_CKA_PRIVATE: 17039fc24faSEtienne Carriere case PKCS11_CKA_WRAP_WITH_TRUSTED: 17139fc24faSEtienne Carriere case PKCS11_CKA_ALWAYS_AUTHENTICATE: 17263f89caaSJens Wiklander case PKCS11_CKA_SENSITIVE: 17363f89caaSJens Wiklander return (uint8_t *)&bool_false; 17463f89caaSJens Wiklander /* Token specific default value */ 17563f89caaSJens Wiklander case PKCS11_CKA_SIGN: 17663f89caaSJens Wiklander case PKCS11_CKA_VERIFY: 17763f89caaSJens Wiklander case PKCS11_CKA_DERIVE: 17863f89caaSJens Wiklander case PKCS11_CKA_ENCRYPT: 17963f89caaSJens Wiklander case PKCS11_CKA_DECRYPT: 18063f89caaSJens Wiklander case PKCS11_CKA_SIGN_RECOVER: 18163f89caaSJens Wiklander case PKCS11_CKA_VERIFY_RECOVER: 18263f89caaSJens Wiklander case PKCS11_CKA_WRAP: 18363f89caaSJens Wiklander case PKCS11_CKA_UNWRAP: 18463f89caaSJens Wiklander case PKCS11_CKA_EXTRACTABLE: 18563f89caaSJens Wiklander case PKCS11_CKA_TRUSTED: 18663f89caaSJens Wiklander return (uint8_t *)&bool_false; 18763f89caaSJens Wiklander default: 18863f89caaSJens Wiklander DMSG("No default for boolprop attribute %#"PRIx32, attribute); 18963f89caaSJens Wiklander return NULL; 19063f89caaSJens Wiklander } 19163f89caaSJens Wiklander } 19263f89caaSJens Wiklander 19363f89caaSJens Wiklander /* 19463f89caaSJens Wiklander * Object expects several boolean attributes to be set to a default value 19563f89caaSJens Wiklander * or to a validate client configuration value. This function append the input 19663f89caaSJens Wiklander * attribute (id/size/value) in the serialized object. 19763f89caaSJens Wiklander */ 19863f89caaSJens Wiklander static enum pkcs11_rc pkcs11_import_object_boolprop(struct obj_attrs **out, 19963f89caaSJens Wiklander struct obj_attrs *templ, 20063f89caaSJens Wiklander uint32_t attribute) 20163f89caaSJens Wiklander { 20263f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 20363f89caaSJens Wiklander uint8_t bbool = 0; 20463f89caaSJens Wiklander uint32_t size = sizeof(uint8_t); 20563f89caaSJens Wiklander void *attr = NULL; 20663f89caaSJens Wiklander 20763f89caaSJens Wiklander rc = get_attribute(templ, attribute, &bbool, &size); 20863f89caaSJens Wiklander if (rc) { 20963f89caaSJens Wiklander if (rc != PKCS11_RV_NOT_FOUND) 21063f89caaSJens Wiklander return rc; 21163f89caaSJens Wiklander attr = pkcs11_object_default_boolprop(attribute); 21263f89caaSJens Wiklander if (!attr) 21363f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCOMPLETE; 21463f89caaSJens Wiklander } else { 21563f89caaSJens Wiklander attr = &bbool; 21663f89caaSJens Wiklander } 21763f89caaSJens Wiklander 21863f89caaSJens Wiklander /* Boolean attributes are 1byte in the ABI, no alignment issue */ 21963f89caaSJens Wiklander return add_attribute(out, attribute, attr, sizeof(uint8_t)); 22063f89caaSJens Wiklander } 22163f89caaSJens Wiklander 22263f89caaSJens Wiklander static enum pkcs11_rc set_mandatory_boolprops(struct obj_attrs **out, 22363f89caaSJens Wiklander struct obj_attrs *temp, 22463f89caaSJens Wiklander uint32_t const *bp, 22563f89caaSJens Wiklander size_t bp_count) 22663f89caaSJens Wiklander { 22763f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 22863f89caaSJens Wiklander size_t n = 0; 22963f89caaSJens Wiklander 23063f89caaSJens Wiklander for (n = 0; n < bp_count; n++) { 23163f89caaSJens Wiklander rc = pkcs11_import_object_boolprop(out, temp, bp[n]); 23263f89caaSJens Wiklander if (rc) 23363f89caaSJens Wiklander return rc; 23463f89caaSJens Wiklander } 23563f89caaSJens Wiklander 23663f89caaSJens Wiklander return rc; 23763f89caaSJens Wiklander } 23863f89caaSJens Wiklander 23963f89caaSJens Wiklander static enum pkcs11_rc set_mandatory_attributes(struct obj_attrs **out, 24063f89caaSJens Wiklander struct obj_attrs *temp, 24116df60c7SEtienne Carriere uint32_t const *attrs, 24216df60c7SEtienne Carriere size_t attrs_count) 24363f89caaSJens Wiklander { 24463f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 24563f89caaSJens Wiklander size_t n = 0; 24663f89caaSJens Wiklander 24716df60c7SEtienne Carriere for (n = 0; n < attrs_count; n++) { 24863f89caaSJens Wiklander uint32_t size = 0; 24963f89caaSJens Wiklander void *value = NULL; 25063f89caaSJens Wiklander 25116df60c7SEtienne Carriere if (get_attribute_ptr(temp, attrs[n], &value, &size)) 25263f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCOMPLETE; 25363f89caaSJens Wiklander 25416df60c7SEtienne Carriere rc = add_attribute(out, attrs[n], value, size); 25563f89caaSJens Wiklander if (rc) 25663f89caaSJens Wiklander return rc; 25763f89caaSJens Wiklander } 25863f89caaSJens Wiklander 25963f89caaSJens Wiklander return rc; 26063f89caaSJens Wiklander } 26163f89caaSJens Wiklander 26263f89caaSJens Wiklander static enum pkcs11_rc get_default_value(enum pkcs11_attr_id id, void **value, 26363f89caaSJens Wiklander uint32_t *size) 26463f89caaSJens Wiklander { 26563f89caaSJens Wiklander /* should have been taken care of already */ 26663f89caaSJens Wiklander assert(!pkcs11_attr_is_boolean(id)); 26763f89caaSJens Wiklander 26863f89caaSJens Wiklander /* All other attributes have an empty default value */ 26963f89caaSJens Wiklander *value = NULL; 27063f89caaSJens Wiklander *size = 0; 27163f89caaSJens Wiklander return PKCS11_CKR_OK; 27263f89caaSJens Wiklander } 27363f89caaSJens Wiklander 2744eb88651SRuchika Gupta static enum pkcs11_rc set_optional_attributes_with_def(struct obj_attrs **out, 27563f89caaSJens Wiklander struct obj_attrs *temp, 27616df60c7SEtienne Carriere uint32_t const *attrs, 27716df60c7SEtienne Carriere size_t attrs_count, 2784eb88651SRuchika Gupta bool default_to_null) 27963f89caaSJens Wiklander { 28063f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 28163f89caaSJens Wiklander size_t n = 0; 28263f89caaSJens Wiklander 28316df60c7SEtienne Carriere for (n = 0; n < attrs_count; n++) { 28463f89caaSJens Wiklander uint32_t size = 0; 28563f89caaSJens Wiklander void *value = NULL; 28663f89caaSJens Wiklander 28716df60c7SEtienne Carriere rc = get_attribute_ptr(temp, attrs[n], &value, &size); 2884eb88651SRuchika Gupta if (rc == PKCS11_RV_NOT_FOUND) { 2894eb88651SRuchika Gupta if (default_to_null) { 29016df60c7SEtienne Carriere rc = get_default_value(attrs[n], &value, &size); 2914eb88651SRuchika Gupta } else { 2924eb88651SRuchika Gupta rc = PKCS11_CKR_OK; 2934eb88651SRuchika Gupta continue; 2944eb88651SRuchika Gupta } 2954eb88651SRuchika Gupta } 29663f89caaSJens Wiklander if (rc) 29763f89caaSJens Wiklander return rc; 29863f89caaSJens Wiklander 29916df60c7SEtienne Carriere rc = add_attribute(out, attrs[n], value, size); 30063f89caaSJens Wiklander if (rc) 30163f89caaSJens Wiklander return rc; 30263f89caaSJens Wiklander } 30363f89caaSJens Wiklander 30463f89caaSJens Wiklander return rc; 30563f89caaSJens Wiklander } 30663f89caaSJens Wiklander 3074eb88651SRuchika Gupta static enum pkcs11_rc set_attributes_opt_or_null(struct obj_attrs **out, 3084eb88651SRuchika Gupta struct obj_attrs *temp, 30916df60c7SEtienne Carriere uint32_t const *attrs, 31016df60c7SEtienne Carriere size_t attrs_count) 3114eb88651SRuchika Gupta { 31216df60c7SEtienne Carriere return set_optional_attributes_with_def(out, temp, attrs, attrs_count, 31316df60c7SEtienne Carriere true /* defaults to empty */); 3144eb88651SRuchika Gupta } 3154eb88651SRuchika Gupta 3164eb88651SRuchika Gupta static enum pkcs11_rc set_optional_attributes(struct obj_attrs **out, 3174eb88651SRuchika Gupta struct obj_attrs *temp, 31816df60c7SEtienne Carriere uint32_t const *attrs, 31916df60c7SEtienne Carriere size_t attrs_count) 3204eb88651SRuchika Gupta { 32116df60c7SEtienne Carriere return set_optional_attributes_with_def(out, temp, attrs, attrs_count, 32216df60c7SEtienne Carriere false /* no default value */); 3234eb88651SRuchika Gupta } 3244eb88651SRuchika Gupta 32563f89caaSJens Wiklander /* 32663f89caaSJens Wiklander * Below are listed the mandated or optional expected attributes for 32763f89caaSJens Wiklander * PKCS#11 storage objects. 32863f89caaSJens Wiklander * 32963f89caaSJens Wiklander * Note: boolprops (mandated boolean attributes) PKCS11_CKA_ALWAYS_SENSITIVE, 33063f89caaSJens Wiklander * and PKCS11_CKA_NEVER_EXTRACTABLE are set by the token, not provided 33163f89caaSJens Wiklander * in the client template. 33263f89caaSJens Wiklander */ 33363f89caaSJens Wiklander 33463f89caaSJens Wiklander /* PKCS#11 specification for any object (session/token) of the storage */ 3354eb88651SRuchika Gupta static const uint32_t any_object_boolprops[] = { 33663f89caaSJens Wiklander PKCS11_CKA_TOKEN, PKCS11_CKA_PRIVATE, 33763f89caaSJens Wiklander PKCS11_CKA_MODIFIABLE, PKCS11_CKA_COPYABLE, PKCS11_CKA_DESTROYABLE, 33863f89caaSJens Wiklander }; 33963f89caaSJens Wiklander 3404eb88651SRuchika Gupta static const uint32_t any_object_opt_or_null[] = { 34163f89caaSJens Wiklander PKCS11_CKA_LABEL, 34263f89caaSJens Wiklander }; 34363f89caaSJens Wiklander 3444eb88651SRuchika Gupta /* PKCS#11 specification for raw data object (+any_object_xxx) */ 3454eb88651SRuchika Gupta const uint32_t raw_data_opt_or_null[] = { 34663f89caaSJens Wiklander PKCS11_CKA_OBJECT_ID, PKCS11_CKA_APPLICATION, PKCS11_CKA_VALUE, 34763f89caaSJens Wiklander }; 34863f89caaSJens Wiklander 3494137952dSVesa Jääskeläinen /* PKCS#11 specification for certificate object (+pkcs11_any_object_xxx) */ 3504137952dSVesa Jääskeläinen static const uint32_t pkcs11_certificate_mandated[] = { 3514137952dSVesa Jääskeläinen PKCS11_CKA_CERTIFICATE_TYPE, 3524137952dSVesa Jääskeläinen }; 3534137952dSVesa Jääskeläinen 3544137952dSVesa Jääskeläinen static const uint32_t pkcs11_certificate_boolprops[] = { 3554137952dSVesa Jääskeläinen PKCS11_CKA_TRUSTED, 3564137952dSVesa Jääskeläinen }; 3574137952dSVesa Jääskeläinen 3584137952dSVesa Jääskeläinen static const uint32_t pkcs11_certificate_optional[] = { 359bcac2127SMarouene Boubakri PKCS11_CKA_CERTIFICATE_CATEGORY, PKCS11_CKA_START_DATE, 360bcac2127SMarouene Boubakri PKCS11_CKA_END_DATE, PKCS11_CKA_PUBLIC_KEY_INFO, 361bcac2127SMarouene Boubakri #ifdef CFG_PKCS11_TA_CHECK_VALUE_ATTRIBUTE 362bcac2127SMarouene Boubakri /* Consider KCV attribute only when supported */ 363bcac2127SMarouene Boubakri PKCS11_CKA_CHECK_VALUE, 364bcac2127SMarouene Boubakri #endif 3654137952dSVesa Jääskeläinen }; 3664137952dSVesa Jääskeläinen 3674137952dSVesa Jääskeläinen /* 3684137952dSVesa Jääskeläinen * PKCS#11 specification for X.509 certificate object (+pkcs11_certificate_xxx) 3694137952dSVesa Jääskeläinen */ 3704137952dSVesa Jääskeläinen static const uint32_t pkcs11_x509_certificate_mandated[] = { 3714137952dSVesa Jääskeläinen PKCS11_CKA_SUBJECT, 3724137952dSVesa Jääskeläinen }; 3734137952dSVesa Jääskeläinen 3744137952dSVesa Jääskeläinen static const uint32_t pkcs11_x509_certificate_optional[] = { 3754137952dSVesa Jääskeläinen PKCS11_CKA_ID, PKCS11_CKA_ISSUER, PKCS11_CKA_SERIAL_NUMBER, 3764137952dSVesa Jääskeläinen PKCS11_CKA_VALUE, PKCS11_CKA_URL, 3774137952dSVesa Jääskeläinen PKCS11_CKA_HASH_OF_SUBJECT_PUBLIC_KEY, 3784137952dSVesa Jääskeläinen PKCS11_CKA_HASH_OF_ISSUER_PUBLIC_KEY, 3794137952dSVesa Jääskeläinen PKCS11_CKA_JAVA_MIDP_SECURITY_DOMAIN, PKCS11_CKA_NAME_HASH_ALGORITHM, 3804137952dSVesa Jääskeläinen }; 3814137952dSVesa Jääskeläinen 3824eb88651SRuchika Gupta /* PKCS#11 specification for any key object (+any_object_xxx) */ 3834eb88651SRuchika Gupta static const uint32_t any_key_boolprops[] = { 38463f89caaSJens Wiklander PKCS11_CKA_DERIVE, 38563f89caaSJens Wiklander }; 38663f89caaSJens Wiklander 3874eb88651SRuchika Gupta static const uint32_t any_key_opt_or_null[] = { 38863f89caaSJens Wiklander PKCS11_CKA_ID, 38963f89caaSJens Wiklander PKCS11_CKA_START_DATE, PKCS11_CKA_END_DATE, 3904eb88651SRuchika Gupta }; 3914eb88651SRuchika Gupta 3924eb88651SRuchika Gupta static const uint32_t any_key_optional[] = { 39363f89caaSJens Wiklander PKCS11_CKA_ALLOWED_MECHANISMS, 39463f89caaSJens Wiklander }; 39563f89caaSJens Wiklander 3964eb88651SRuchika Gupta /* PKCS#11 specification for any symmetric key (+any_key_xxx) */ 3974eb88651SRuchika Gupta static const uint32_t symm_key_boolprops[] = { 39863f89caaSJens Wiklander PKCS11_CKA_ENCRYPT, PKCS11_CKA_DECRYPT, 39963f89caaSJens Wiklander PKCS11_CKA_SIGN, PKCS11_CKA_VERIFY, 40063f89caaSJens Wiklander PKCS11_CKA_WRAP, PKCS11_CKA_UNWRAP, 40163f89caaSJens Wiklander PKCS11_CKA_SENSITIVE, PKCS11_CKA_EXTRACTABLE, 40263f89caaSJens Wiklander PKCS11_CKA_WRAP_WITH_TRUSTED, PKCS11_CKA_TRUSTED, 40363f89caaSJens Wiklander }; 40463f89caaSJens Wiklander 4054eb88651SRuchika Gupta static const uint32_t symm_key_opt_or_null[] = { 40663f89caaSJens Wiklander PKCS11_CKA_WRAP_TEMPLATE, PKCS11_CKA_UNWRAP_TEMPLATE, 4070ac5c695SRuchika Gupta PKCS11_CKA_DERIVE_TEMPLATE, PKCS11_CKA_VALUE, 4080ac5c695SRuchika Gupta }; 4090ac5c695SRuchika Gupta 4100ac5c695SRuchika Gupta static const uint32_t symm_key_optional[] = { 4110ac5c695SRuchika Gupta PKCS11_CKA_VALUE_LEN, 412bcac2127SMarouene Boubakri #ifdef CFG_PKCS11_TA_CHECK_VALUE_ATTRIBUTE 413bcac2127SMarouene Boubakri /* Consider KCV attribute only when supported */ 414bcac2127SMarouene Boubakri PKCS11_CKA_CHECK_VALUE, 415bcac2127SMarouene Boubakri #endif 41663f89caaSJens Wiklander }; 41763f89caaSJens Wiklander 4184eb88651SRuchika Gupta /* PKCS#11 specification for any asymmetric public key (+any_key_xxx) */ 4194eb88651SRuchika Gupta static const uint32_t public_key_boolprops[] = { 42063f89caaSJens Wiklander PKCS11_CKA_ENCRYPT, PKCS11_CKA_VERIFY, PKCS11_CKA_VERIFY_RECOVER, 42163f89caaSJens Wiklander PKCS11_CKA_WRAP, 42263f89caaSJens Wiklander PKCS11_CKA_TRUSTED, 42363f89caaSJens Wiklander }; 42463f89caaSJens Wiklander 4254eb88651SRuchika Gupta static const uint32_t public_key_mandated[] = { 42663f89caaSJens Wiklander }; 42763f89caaSJens Wiklander 4284eb88651SRuchika Gupta static const uint32_t public_key_opt_or_null[] = { 429edd95148SVesa Jääskeläinen PKCS11_CKA_SUBJECT, PKCS11_CKA_WRAP_TEMPLATE, 430edd95148SVesa Jääskeläinen PKCS11_CKA_PUBLIC_KEY_INFO, 43163f89caaSJens Wiklander }; 43263f89caaSJens Wiklander 4334eb88651SRuchika Gupta /* PKCS#11 specification for any asymmetric private key (+any_key_xxx) */ 4344eb88651SRuchika Gupta static const uint32_t private_key_boolprops[] = { 43563f89caaSJens Wiklander PKCS11_CKA_DECRYPT, PKCS11_CKA_SIGN, PKCS11_CKA_SIGN_RECOVER, 43663f89caaSJens Wiklander PKCS11_CKA_UNWRAP, 43763f89caaSJens Wiklander PKCS11_CKA_SENSITIVE, PKCS11_CKA_EXTRACTABLE, 43863f89caaSJens Wiklander PKCS11_CKA_WRAP_WITH_TRUSTED, PKCS11_CKA_ALWAYS_AUTHENTICATE, 43963f89caaSJens Wiklander }; 44063f89caaSJens Wiklander 4414eb88651SRuchika Gupta static const uint32_t private_key_mandated[] = { 44263f89caaSJens Wiklander }; 44363f89caaSJens Wiklander 4444eb88651SRuchika Gupta static const uint32_t private_key_opt_or_null[] = { 445edd95148SVesa Jääskeläinen PKCS11_CKA_SUBJECT, PKCS11_CKA_UNWRAP_TEMPLATE, 446edd95148SVesa Jääskeläinen PKCS11_CKA_PUBLIC_KEY_INFO, 44763f89caaSJens Wiklander }; 44863f89caaSJens Wiklander 4494eb88651SRuchika Gupta /* PKCS#11 specification for any RSA key (+public/private_key_xxx) */ 4509cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_gen_mand[] = { 45163f89caaSJens Wiklander PKCS11_CKA_MODULUS_BITS, 45263f89caaSJens Wiklander }; 45363f89caaSJens Wiklander 4549cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_create_mand[] = { 45563f89caaSJens Wiklander PKCS11_CKA_MODULUS, PKCS11_CKA_PUBLIC_EXPONENT, 45663f89caaSJens Wiklander }; 45763f89caaSJens Wiklander 4589cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_gen_opt_or_null[] = { 4599cf1afceSVesa Jääskeläinen PKCS11_CKA_PUBLIC_EXPONENT, 4609cf1afceSVesa Jääskeläinen }; 4619cf1afceSVesa Jääskeläinen 4629cf1afceSVesa Jääskeläinen static const uint32_t rsa_priv_key_opt_or_null[] = { 46363f89caaSJens Wiklander PKCS11_CKA_MODULUS, PKCS11_CKA_PUBLIC_EXPONENT, 46463f89caaSJens Wiklander PKCS11_CKA_PRIVATE_EXPONENT, 46563f89caaSJens Wiklander PKCS11_CKA_PRIME_1, PKCS11_CKA_PRIME_2, 46663f89caaSJens Wiklander PKCS11_CKA_EXPONENT_1, PKCS11_CKA_EXPONENT_2, PKCS11_CKA_COEFFICIENT, 46763f89caaSJens Wiklander }; 46863f89caaSJens Wiklander 4694eb88651SRuchika Gupta /* PKCS#11 specification for any EC key (+public/private_key_xxx) */ 4704eb88651SRuchika Gupta static const uint32_t ec_public_key_mandated[] = { 47163f89caaSJens Wiklander PKCS11_CKA_EC_PARAMS, 47263f89caaSJens Wiklander }; 47363f89caaSJens Wiklander 4744eb88651SRuchika Gupta static const uint32_t ec_public_key_opt_or_null[] = { 47563f89caaSJens Wiklander PKCS11_CKA_EC_POINT, 47663f89caaSJens Wiklander }; 47763f89caaSJens Wiklander 4784eb88651SRuchika Gupta static const uint32_t ec_private_key_mandated[] = { 47963f89caaSJens Wiklander }; 48063f89caaSJens Wiklander 4814eb88651SRuchika Gupta static const uint32_t ec_private_key_opt_or_null[] = { 48202b16804SVesa Jääskeläinen PKCS11_CKA_EC_PARAMS, 48363f89caaSJens Wiklander PKCS11_CKA_VALUE, 48463f89caaSJens Wiklander }; 48563f89caaSJens Wiklander 48603e07432SValerii Chubar static const uint32_t eddsa_private_key_opt_or_null[] = { 48703e07432SValerii Chubar PKCS11_CKA_EC_PARAMS, 48803e07432SValerii Chubar PKCS11_CKA_VALUE, 48903e07432SValerii Chubar PKCS11_CKA_EC_POINT, 49003e07432SValerii Chubar }; 49103e07432SValerii Chubar 49263f89caaSJens Wiklander static enum pkcs11_rc create_storage_attributes(struct obj_attrs **out, 49363f89caaSJens Wiklander struct obj_attrs *temp) 49463f89caaSJens Wiklander { 49563f89caaSJens Wiklander enum pkcs11_class_id class = PKCS11_CKO_UNDEFINED_ID; 49663f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 49763f89caaSJens Wiklander 49863f89caaSJens Wiklander rc = init_attributes_head(out); 49963f89caaSJens Wiklander if (rc) 50063f89caaSJens Wiklander return rc; 50163f89caaSJens Wiklander 50263f89caaSJens Wiklander /* Object class is mandatory */ 50363f89caaSJens Wiklander class = get_class(temp); 50463f89caaSJens Wiklander if (class == PKCS11_CKO_UNDEFINED_ID) { 50563f89caaSJens Wiklander EMSG("Class attribute not found"); 50663f89caaSJens Wiklander 50763f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 50863f89caaSJens Wiklander } 50963f89caaSJens Wiklander rc = add_attribute(out, PKCS11_CKA_CLASS, &class, sizeof(uint32_t)); 51063f89caaSJens Wiklander if (rc) 51163f89caaSJens Wiklander return rc; 51263f89caaSJens Wiklander 5134eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, any_object_boolprops, 5144eb88651SRuchika Gupta ARRAY_SIZE(any_object_boolprops)); 51563f89caaSJens Wiklander if (rc) 51663f89caaSJens Wiklander return rc; 51763f89caaSJens Wiklander 5184eb88651SRuchika Gupta return set_attributes_opt_or_null(out, temp, any_object_opt_or_null, 5194eb88651SRuchika Gupta ARRAY_SIZE(any_object_opt_or_null)); 52063f89caaSJens Wiklander } 52163f89caaSJens Wiklander 52263f89caaSJens Wiklander static enum pkcs11_rc create_genkey_attributes(struct obj_attrs **out, 52363f89caaSJens Wiklander struct obj_attrs *temp) 52463f89caaSJens Wiklander { 52563f89caaSJens Wiklander uint32_t type = PKCS11_CKO_UNDEFINED_ID; 52663f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 52763f89caaSJens Wiklander 52863f89caaSJens Wiklander rc = create_storage_attributes(out, temp); 52963f89caaSJens Wiklander if (rc) 53063f89caaSJens Wiklander return rc; 53163f89caaSJens Wiklander 53263f89caaSJens Wiklander type = get_key_type(temp); 53363f89caaSJens Wiklander if (type == PKCS11_CKK_UNDEFINED_ID) { 53463f89caaSJens Wiklander EMSG("Key type attribute not found"); 53563f89caaSJens Wiklander 53663f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 53763f89caaSJens Wiklander } 53863f89caaSJens Wiklander rc = add_attribute(out, PKCS11_CKA_KEY_TYPE, &type, sizeof(uint32_t)); 53963f89caaSJens Wiklander if (rc) 54063f89caaSJens Wiklander return rc; 54163f89caaSJens Wiklander 5424eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, any_key_boolprops, 5434eb88651SRuchika Gupta ARRAY_SIZE(any_key_boolprops)); 54463f89caaSJens Wiklander if (rc) 54563f89caaSJens Wiklander return rc; 54663f89caaSJens Wiklander 5474eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, any_key_opt_or_null, 5484eb88651SRuchika Gupta ARRAY_SIZE(any_key_opt_or_null)); 5494eb88651SRuchika Gupta if (rc) 5504eb88651SRuchika Gupta return rc; 5514eb88651SRuchika Gupta 5524eb88651SRuchika Gupta return set_optional_attributes(out, temp, any_key_optional, 5534eb88651SRuchika Gupta ARRAY_SIZE(any_key_optional)); 5544eb88651SRuchika Gupta 55563f89caaSJens Wiklander } 55663f89caaSJens Wiklander 55763f89caaSJens Wiklander static enum pkcs11_rc create_symm_key_attributes(struct obj_attrs **out, 55863f89caaSJens Wiklander struct obj_attrs *temp) 55963f89caaSJens Wiklander { 56063f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 56163f89caaSJens Wiklander 56263f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_SECRET_KEY); 56363f89caaSJens Wiklander 56463f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 56563f89caaSJens Wiklander if (rc) 56663f89caaSJens Wiklander return rc; 56763f89caaSJens Wiklander 56863f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_SECRET_KEY); 56963f89caaSJens Wiklander 57063f89caaSJens Wiklander switch (get_key_type(*out)) { 57163f89caaSJens Wiklander case PKCS11_CKK_GENERIC_SECRET: 57263f89caaSJens Wiklander case PKCS11_CKK_AES: 57363f89caaSJens Wiklander case PKCS11_CKK_MD5_HMAC: 57463f89caaSJens Wiklander case PKCS11_CKK_SHA_1_HMAC: 57563f89caaSJens Wiklander case PKCS11_CKK_SHA256_HMAC: 57663f89caaSJens Wiklander case PKCS11_CKK_SHA384_HMAC: 57763f89caaSJens Wiklander case PKCS11_CKK_SHA512_HMAC: 57863f89caaSJens Wiklander case PKCS11_CKK_SHA224_HMAC: 57963f89caaSJens Wiklander break; 58063f89caaSJens Wiklander default: 58163f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 58263f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 58363f89caaSJens Wiklander 58463f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 58563f89caaSJens Wiklander } 58663f89caaSJens Wiklander 5874eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, symm_key_boolprops, 5884eb88651SRuchika Gupta ARRAY_SIZE(symm_key_boolprops)); 58963f89caaSJens Wiklander if (rc) 59063f89caaSJens Wiklander return rc; 59163f89caaSJens Wiklander 5920ac5c695SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, symm_key_opt_or_null, 5934eb88651SRuchika Gupta ARRAY_SIZE(symm_key_opt_or_null)); 5940ac5c695SRuchika Gupta if (rc) 5950ac5c695SRuchika Gupta return rc; 5960ac5c695SRuchika Gupta 5970ac5c695SRuchika Gupta return set_optional_attributes(out, temp, symm_key_optional, 5980ac5c695SRuchika Gupta ARRAY_SIZE(symm_key_optional)); 59963f89caaSJens Wiklander } 60063f89caaSJens Wiklander 60163f89caaSJens Wiklander static enum pkcs11_rc create_data_attributes(struct obj_attrs **out, 60263f89caaSJens Wiklander struct obj_attrs *temp) 60363f89caaSJens Wiklander { 60463f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 60563f89caaSJens Wiklander 60663f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_DATA); 60763f89caaSJens Wiklander 60863f89caaSJens Wiklander rc = create_storage_attributes(out, temp); 60963f89caaSJens Wiklander if (rc) 61063f89caaSJens Wiklander return rc; 61163f89caaSJens Wiklander 61263f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_DATA); 61363f89caaSJens Wiklander 6144eb88651SRuchika Gupta return set_attributes_opt_or_null(out, temp, raw_data_opt_or_null, 6154eb88651SRuchika Gupta ARRAY_SIZE(raw_data_opt_or_null)); 61663f89caaSJens Wiklander } 61763f89caaSJens Wiklander 6184137952dSVesa Jääskeläinen static enum pkcs11_rc create_certificate_attributes(struct obj_attrs **out, 6194137952dSVesa Jääskeläinen struct obj_attrs *temp) 6204137952dSVesa Jääskeläinen { 6214137952dSVesa Jääskeläinen uint32_t const *mandated = NULL; 6224137952dSVesa Jääskeläinen uint32_t const *optional = NULL; 6234137952dSVesa Jääskeläinen size_t mandated_count = 0; 6244137952dSVesa Jääskeläinen size_t optional_count = 0; 6254137952dSVesa Jääskeläinen void *attr_value = NULL; 6264137952dSVesa Jääskeläinen uint32_t attr_size = 0; 6274137952dSVesa Jääskeläinen uint32_t default_cert_category = 6284137952dSVesa Jääskeläinen PKCS11_CK_CERTIFICATE_CATEGORY_UNSPECIFIED; 6294137952dSVesa Jääskeläinen uint32_t default_name_hash_alg = PKCS11_CKM_SHA_1; 6304137952dSVesa Jääskeläinen uint32_t cert_category = 0; 6314137952dSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_OK; 6324137952dSVesa Jääskeläinen 6334137952dSVesa Jääskeläinen assert(get_class(temp) == PKCS11_CKO_CERTIFICATE); 6344137952dSVesa Jääskeläinen 6354137952dSVesa Jääskeläinen rc = create_storage_attributes(out, temp); 6364137952dSVesa Jääskeläinen if (rc) 6374137952dSVesa Jääskeläinen return rc; 6384137952dSVesa Jääskeläinen 6394137952dSVesa Jääskeläinen assert(get_class(*out) == PKCS11_CKO_CERTIFICATE); 6404137952dSVesa Jääskeläinen 6414137952dSVesa Jääskeläinen rc = set_mandatory_boolprops(out, temp, pkcs11_certificate_boolprops, 6424137952dSVesa Jääskeläinen ARRAY_SIZE(pkcs11_certificate_boolprops)); 6434137952dSVesa Jääskeläinen if (rc) 6444137952dSVesa Jääskeläinen return rc; 6454137952dSVesa Jääskeläinen 6464137952dSVesa Jääskeläinen rc = set_mandatory_attributes(out, temp, pkcs11_certificate_mandated, 6474137952dSVesa Jääskeläinen ARRAY_SIZE(pkcs11_certificate_mandated)); 6484137952dSVesa Jääskeläinen if (rc) 6494137952dSVesa Jääskeläinen return rc; 6504137952dSVesa Jääskeläinen 6514137952dSVesa Jääskeläinen rc = set_optional_attributes(out, temp, pkcs11_certificate_optional, 6524137952dSVesa Jääskeläinen ARRAY_SIZE(pkcs11_certificate_optional)); 6534137952dSVesa Jääskeläinen if (rc) 6544137952dSVesa Jääskeläinen return rc; 6554137952dSVesa Jääskeläinen 6564137952dSVesa Jääskeläinen switch (get_certificate_type(*out)) { 6574137952dSVesa Jääskeläinen case PKCS11_CKC_X_509: 6584137952dSVesa Jääskeläinen mandated = pkcs11_x509_certificate_mandated; 6594137952dSVesa Jääskeläinen optional = pkcs11_x509_certificate_optional; 6604137952dSVesa Jääskeläinen mandated_count = ARRAY_SIZE(pkcs11_x509_certificate_mandated); 6614137952dSVesa Jääskeläinen optional_count = ARRAY_SIZE(pkcs11_x509_certificate_optional); 6624137952dSVesa Jääskeläinen break; 6634137952dSVesa Jääskeläinen default: 6644137952dSVesa Jääskeläinen EMSG("Invalid certificate type %#"PRIx32"/%s", 6654137952dSVesa Jääskeläinen get_certificate_type(*out), 6664137952dSVesa Jääskeläinen id2str_certificate_type(get_certificate_type(*out))); 6674137952dSVesa Jääskeläinen 6684137952dSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 6694137952dSVesa Jääskeläinen } 6704137952dSVesa Jääskeläinen 6714137952dSVesa Jääskeläinen rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 6724137952dSVesa Jääskeläinen if (rc) 6734137952dSVesa Jääskeläinen return rc; 6744137952dSVesa Jääskeläinen 6754137952dSVesa Jääskeläinen rc = set_optional_attributes(out, temp, optional, optional_count); 6764137952dSVesa Jääskeläinen if (rc) 6774137952dSVesa Jääskeläinen return rc; 6784137952dSVesa Jääskeläinen 6794137952dSVesa Jääskeläinen attr_size = 0; 6804137952dSVesa Jääskeläinen rc = get_attribute_ptr(*out, PKCS11_CKA_CERTIFICATE_CATEGORY, 6814137952dSVesa Jääskeläinen &attr_value, &attr_size); 6824137952dSVesa Jääskeläinen if (rc == PKCS11_CKR_OK && attr_size == sizeof(cert_category)) { 6834137952dSVesa Jääskeläinen /* Sanitize certificate category */ 6844137952dSVesa Jääskeläinen TEE_MemMove(&cert_category, attr_value, sizeof(cert_category)); 6854137952dSVesa Jääskeläinen 6864137952dSVesa Jääskeläinen switch (cert_category) { 6874137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_UNSPECIFIED: 6884137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_TOKEN_USER: 6894137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_AUTHORITY: 6904137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_OTHER_ENTITY: 6914137952dSVesa Jääskeläinen break; 6924137952dSVesa Jääskeläinen default: 6934137952dSVesa Jääskeläinen EMSG("Invalid certificate category %#"PRIx32, 6944137952dSVesa Jääskeläinen cert_category); 6954137952dSVesa Jääskeläinen 6964137952dSVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 6974137952dSVesa Jääskeläinen } 6984137952dSVesa Jääskeläinen } else if (rc == PKCS11_RV_NOT_FOUND) { 6994137952dSVesa Jääskeläinen /* Set default category when missing */ 7004137952dSVesa Jääskeläinen rc = set_attribute(out, PKCS11_CKA_CERTIFICATE_CATEGORY, 7014137952dSVesa Jääskeläinen &default_cert_category, 7024137952dSVesa Jääskeläinen sizeof(default_cert_category)); 7034137952dSVesa Jääskeläinen if (rc) 7044137952dSVesa Jääskeläinen return rc; 7054137952dSVesa Jääskeläinen } else { 7064137952dSVesa Jääskeläinen /* All other cases are errors */ 7074137952dSVesa Jääskeläinen EMSG("Invalid certificate category"); 7084137952dSVesa Jääskeläinen 7094137952dSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 7104137952dSVesa Jääskeläinen } 7114137952dSVesa Jääskeläinen 7124137952dSVesa Jääskeläinen attr_size = 0; 7134137952dSVesa Jääskeläinen rc = get_attribute_ptr(*out, PKCS11_CKA_NAME_HASH_ALGORITHM, NULL, 7144137952dSVesa Jääskeläinen &attr_size); 7154137952dSVesa Jääskeläinen if (rc == PKCS11_CKR_OK && attr_size == sizeof(uint32_t)) { 7164137952dSVesa Jääskeläinen /* We accept any algorithm what caller wanted to specify */ 7174137952dSVesa Jääskeläinen } else if (rc == PKCS11_RV_NOT_FOUND) { 7184137952dSVesa Jääskeläinen /* Set default hash algorithm when missing */ 7194137952dSVesa Jääskeläinen rc = set_attribute(out, PKCS11_CKA_NAME_HASH_ALGORITHM, 7204137952dSVesa Jääskeläinen &default_name_hash_alg, 7214137952dSVesa Jääskeläinen sizeof(default_name_hash_alg)); 7224137952dSVesa Jääskeläinen if (rc) 7234137952dSVesa Jääskeläinen return rc; 7244137952dSVesa Jääskeläinen } else { 7254137952dSVesa Jääskeläinen /* All other cases are errors */ 7264137952dSVesa Jääskeläinen EMSG("Invalid name hash algorithm"); 7274137952dSVesa Jääskeläinen 7284137952dSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 7294137952dSVesa Jääskeläinen } 7304137952dSVesa Jääskeläinen 7314137952dSVesa Jääskeläinen return rc; 7324137952dSVesa Jääskeläinen } 7334137952dSVesa Jääskeläinen 73463f89caaSJens Wiklander static enum pkcs11_rc create_pub_key_attributes(struct obj_attrs **out, 7359cf1afceSVesa Jääskeläinen struct obj_attrs *temp, 7369cf1afceSVesa Jääskeläinen enum processing_func function) 73763f89caaSJens Wiklander { 73863f89caaSJens Wiklander uint32_t const *mandated = NULL; 7399cf1afceSVesa Jääskeläinen uint32_t const *oon = NULL; 74063f89caaSJens Wiklander size_t mandated_count = 0; 7419cf1afceSVesa Jääskeläinen size_t oon_count = 0; 74263f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 74363f89caaSJens Wiklander 74463f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_PUBLIC_KEY); 74563f89caaSJens Wiklander 74663f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 74763f89caaSJens Wiklander if (rc) 74863f89caaSJens Wiklander return rc; 74963f89caaSJens Wiklander 75063f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_PUBLIC_KEY); 75163f89caaSJens Wiklander 7524eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, public_key_boolprops, 7534eb88651SRuchika Gupta ARRAY_SIZE(public_key_boolprops)); 75463f89caaSJens Wiklander if (rc) 75563f89caaSJens Wiklander return rc; 75663f89caaSJens Wiklander 7574eb88651SRuchika Gupta rc = set_mandatory_attributes(out, temp, public_key_mandated, 7584eb88651SRuchika Gupta ARRAY_SIZE(public_key_mandated)); 75963f89caaSJens Wiklander if (rc) 76063f89caaSJens Wiklander return rc; 76163f89caaSJens Wiklander 7624eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, 7634eb88651SRuchika Gupta public_key_opt_or_null, 7644eb88651SRuchika Gupta ARRAY_SIZE(public_key_opt_or_null)); 76563f89caaSJens Wiklander if (rc) 76663f89caaSJens Wiklander return rc; 76763f89caaSJens Wiklander 76863f89caaSJens Wiklander switch (get_key_type(*out)) { 76963f89caaSJens Wiklander case PKCS11_CKK_RSA: 7709cf1afceSVesa Jääskeläinen switch (function) { 7719cf1afceSVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 7729cf1afceSVesa Jääskeläinen mandated = rsa_pub_key_gen_mand; 7739cf1afceSVesa Jääskeläinen oon = rsa_pub_key_gen_opt_or_null; 7749cf1afceSVesa Jääskeläinen mandated_count = ARRAY_SIZE(rsa_pub_key_gen_mand); 7759cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(rsa_pub_key_gen_opt_or_null); 7769cf1afceSVesa Jääskeläinen break; 7779cf1afceSVesa Jääskeläinen case PKCS11_FUNCTION_IMPORT: 7789cf1afceSVesa Jääskeläinen mandated = rsa_pub_key_create_mand; 7799cf1afceSVesa Jääskeläinen mandated_count = ARRAY_SIZE(rsa_pub_key_create_mand); 7809cf1afceSVesa Jääskeläinen break; 7819cf1afceSVesa Jääskeläinen default: 7829cf1afceSVesa Jääskeläinen EMSG("Unsupported function %#"PRIx32"/%s", function, 7839cf1afceSVesa Jääskeläinen id2str_function(function)); 7849cf1afceSVesa Jääskeläinen 7859cf1afceSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 7869cf1afceSVesa Jääskeläinen } 78763f89caaSJens Wiklander break; 78863f89caaSJens Wiklander case PKCS11_CKK_EC: 78903e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 7904eb88651SRuchika Gupta mandated = ec_public_key_mandated; 7919cf1afceSVesa Jääskeläinen oon = ec_public_key_opt_or_null; 7924eb88651SRuchika Gupta mandated_count = ARRAY_SIZE(ec_public_key_mandated); 7939cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(ec_public_key_opt_or_null); 79463f89caaSJens Wiklander break; 79563f89caaSJens Wiklander default: 79663f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 79763f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 79863f89caaSJens Wiklander 79963f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 80063f89caaSJens Wiklander } 80163f89caaSJens Wiklander 80263f89caaSJens Wiklander rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 80363f89caaSJens Wiklander if (rc) 80463f89caaSJens Wiklander return rc; 80563f89caaSJens Wiklander 8069cf1afceSVesa Jääskeläinen return set_attributes_opt_or_null(out, temp, oon, oon_count); 80763f89caaSJens Wiklander } 80863f89caaSJens Wiklander 8095071d7d1SVesa Jääskeläinen static enum pkcs11_rc 8105071d7d1SVesa Jääskeläinen create_pub_key_rsa_generated_attributes(struct obj_attrs **out, 8115071d7d1SVesa Jääskeläinen struct obj_attrs *temp, 8125071d7d1SVesa Jääskeläinen enum processing_func function) 8135071d7d1SVesa Jääskeläinen { 8145071d7d1SVesa Jääskeläinen uint32_t key_bits = 0; 8155071d7d1SVesa Jääskeläinen void *a_ptr = NULL; 8165071d7d1SVesa Jääskeläinen uint32_t a_size = 0; 8175071d7d1SVesa Jääskeläinen 8185071d7d1SVesa Jääskeläinen if (function != PKCS11_FUNCTION_IMPORT) 8195071d7d1SVesa Jääskeläinen return PKCS11_CKR_OK; 8205071d7d1SVesa Jääskeläinen 8215071d7d1SVesa Jääskeläinen /* Calculate CKA_MODULUS_BITS */ 8225071d7d1SVesa Jääskeläinen 8235071d7d1SVesa Jääskeläinen if (get_attribute_ptr(temp, PKCS11_CKA_MODULUS, 8245071d7d1SVesa Jääskeläinen &a_ptr, &a_size) || !a_ptr) { 8255071d7d1SVesa Jääskeläinen EMSG("No CKA_MODULUS attribute found in public key"); 8265071d7d1SVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 8275071d7d1SVesa Jääskeläinen } 8285071d7d1SVesa Jääskeläinen 8295071d7d1SVesa Jääskeläinen key_bits = a_size * 8; 8305071d7d1SVesa Jääskeläinen 8315071d7d1SVesa Jääskeläinen return add_attribute(out, PKCS11_CKA_MODULUS_BITS, &key_bits, 8325071d7d1SVesa Jääskeläinen sizeof(key_bits)); 8335071d7d1SVesa Jääskeläinen } 8345071d7d1SVesa Jääskeläinen 8355071d7d1SVesa Jääskeläinen static enum pkcs11_rc 8365071d7d1SVesa Jääskeläinen create_pub_key_generated_attributes(struct obj_attrs **out, 8375071d7d1SVesa Jääskeläinen struct obj_attrs *temp, 8385071d7d1SVesa Jääskeläinen enum processing_func function) 8395071d7d1SVesa Jääskeläinen { 8405071d7d1SVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_OK; 8415071d7d1SVesa Jääskeläinen 8425071d7d1SVesa Jääskeläinen switch (get_key_type(*out)) { 8435071d7d1SVesa Jääskeläinen case PKCS11_CKK_RSA: 8445071d7d1SVesa Jääskeläinen rc = create_pub_key_rsa_generated_attributes(out, temp, 8455071d7d1SVesa Jääskeläinen function); 8465071d7d1SVesa Jääskeläinen break; 8475071d7d1SVesa Jääskeläinen default: 8485071d7d1SVesa Jääskeläinen /* no-op */ 8495071d7d1SVesa Jääskeläinen break; 8505071d7d1SVesa Jääskeläinen } 8515071d7d1SVesa Jääskeläinen 8525071d7d1SVesa Jääskeläinen return rc; 8535071d7d1SVesa Jääskeläinen } 8545071d7d1SVesa Jääskeläinen 85563f89caaSJens Wiklander static enum pkcs11_rc create_priv_key_attributes(struct obj_attrs **out, 85663f89caaSJens Wiklander struct obj_attrs *temp) 85763f89caaSJens Wiklander { 85863f89caaSJens Wiklander uint32_t const *mandated = NULL; 8599cf1afceSVesa Jääskeläinen uint32_t const *oon = NULL; 86063f89caaSJens Wiklander size_t mandated_count = 0; 8619cf1afceSVesa Jääskeläinen size_t oon_count = 0; 86263f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 86363f89caaSJens Wiklander 86463f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_PRIVATE_KEY); 86563f89caaSJens Wiklander 86663f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 86763f89caaSJens Wiklander if (rc) 86863f89caaSJens Wiklander return rc; 86963f89caaSJens Wiklander 87063f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_PRIVATE_KEY); 87163f89caaSJens Wiklander 8724eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, private_key_boolprops, 8734eb88651SRuchika Gupta ARRAY_SIZE(private_key_boolprops)); 87463f89caaSJens Wiklander if (rc) 87563f89caaSJens Wiklander return rc; 87663f89caaSJens Wiklander 8774eb88651SRuchika Gupta rc = set_mandatory_attributes(out, temp, private_key_mandated, 8784eb88651SRuchika Gupta ARRAY_SIZE(private_key_mandated)); 87963f89caaSJens Wiklander if (rc) 88063f89caaSJens Wiklander return rc; 88163f89caaSJens Wiklander 8824eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, private_key_opt_or_null, 8834eb88651SRuchika Gupta ARRAY_SIZE(private_key_opt_or_null)); 88463f89caaSJens Wiklander if (rc) 88563f89caaSJens Wiklander return rc; 88663f89caaSJens Wiklander 88763f89caaSJens Wiklander switch (get_key_type(*out)) { 88863f89caaSJens Wiklander case PKCS11_CKK_RSA: 8899cf1afceSVesa Jääskeläinen oon = rsa_priv_key_opt_or_null; 8909cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(rsa_priv_key_opt_or_null); 89163f89caaSJens Wiklander break; 89263f89caaSJens Wiklander case PKCS11_CKK_EC: 8934eb88651SRuchika Gupta mandated = ec_private_key_mandated; 8949cf1afceSVesa Jääskeläinen oon = ec_private_key_opt_or_null; 8954eb88651SRuchika Gupta mandated_count = ARRAY_SIZE(ec_private_key_mandated); 8969cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(ec_private_key_opt_or_null); 89763f89caaSJens Wiklander break; 89803e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 89903e07432SValerii Chubar mandated = ec_private_key_mandated; 90003e07432SValerii Chubar oon = eddsa_private_key_opt_or_null; 90103e07432SValerii Chubar mandated_count = ARRAY_SIZE(ec_private_key_mandated); 90203e07432SValerii Chubar oon_count = ARRAY_SIZE(eddsa_private_key_opt_or_null); 90303e07432SValerii Chubar break; 90463f89caaSJens Wiklander default: 90563f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 90663f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 90763f89caaSJens Wiklander 90863f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 90963f89caaSJens Wiklander } 91063f89caaSJens Wiklander 91163f89caaSJens Wiklander rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 91263f89caaSJens Wiklander if (rc) 91363f89caaSJens Wiklander return rc; 91463f89caaSJens Wiklander 9159cf1afceSVesa Jääskeläinen return set_attributes_opt_or_null(out, temp, oon, oon_count); 91663f89caaSJens Wiklander } 91763f89caaSJens Wiklander 91832b31808SJens Wiklander static int mbd_rand(void *rng_state __unused, unsigned char *output, size_t len) 91932b31808SJens Wiklander { 92032b31808SJens Wiklander TEE_GenerateRandom(output, len); 92132b31808SJens Wiklander return 0; 92232b31808SJens Wiklander } 92332b31808SJens Wiklander 924196bcd93SRuchika Gupta static enum pkcs11_rc 9257c243321SVesa Jääskeläinen create_ec_priv_key_hidden_attributes(struct obj_attrs **out, 9267c243321SVesa Jääskeläinen struct obj_attrs *temp, 9277c243321SVesa Jääskeläinen enum processing_func function) 9287c243321SVesa Jääskeläinen { 9297c243321SVesa Jääskeläinen struct mbedtls_ecp_keypair key_pair = { }; 9307c243321SVesa Jääskeläinen mbedtls_ecp_group_id ec_curve = MBEDTLS_ECP_DP_NONE; 93132b31808SJens Wiklander mbedtls_ecp_group key_pair_grp = { }; 93232b31808SJens Wiklander mbedtls_ecp_point key_pair_Q = { }; 93332b31808SJens Wiklander mbedtls_mpi key_pair_d = { }; 9347c243321SVesa Jääskeläinen size_t buflen = 0; 9357c243321SVesa Jääskeläinen uint8_t *buf = NULL; 9367c243321SVesa Jääskeläinen size_t asnbuflen = 0; 9377c243321SVesa Jääskeläinen uint8_t *asnbuf = NULL; 9387c243321SVesa Jääskeläinen uint8_t *ptr = NULL; 9397c243321SVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 9407c243321SVesa Jääskeläinen int tee_size = 0; 9417c243321SVesa Jääskeläinen int tee_curve = 0; 9427c243321SVesa Jääskeläinen void *a_ptr = NULL; 9437c243321SVesa Jääskeläinen uint32_t a_size = 0; 9447c243321SVesa Jääskeläinen int ret = 0; 9457c243321SVesa Jääskeläinen 9467c243321SVesa Jääskeläinen if (function != PKCS11_FUNCTION_IMPORT) 9477c243321SVesa Jääskeläinen return PKCS11_CKR_OK; 9487c243321SVesa Jääskeläinen 9497c243321SVesa Jääskeläinen /* 9507c243321SVesa Jääskeläinen * TEE internal API requires that for private key operations there 9517c243321SVesa Jääskeläinen * needs to be also public key available. 9527c243321SVesa Jääskeläinen * 9537c243321SVesa Jääskeläinen * Generate hidden EC point from private key. 9547c243321SVesa Jääskeläinen */ 9557c243321SVesa Jääskeläinen 9567c243321SVesa Jääskeläinen if (get_attribute_ptr(temp, PKCS11_CKA_EC_PARAMS, 9577c243321SVesa Jääskeläinen &a_ptr, &a_size) || !a_ptr) { 9587c243321SVesa Jääskeläinen EMSG("No EC_PARAMS attribute found in private key"); 9597c243321SVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 9607c243321SVesa Jääskeläinen } 9617c243321SVesa Jääskeläinen 9627c243321SVesa Jääskeläinen /* Just valdiate that curve is found */ 9637c243321SVesa Jääskeläinen tee_size = ec_params2tee_keysize(a_ptr, a_size); 9647c243321SVesa Jääskeläinen if (!tee_size) { 9657c243321SVesa Jääskeläinen EMSG("Unsupported EC_PARAMS curve"); 9667c243321SVesa Jääskeläinen return PKCS11_CKR_CURVE_NOT_SUPPORTED; 9677c243321SVesa Jääskeläinen } 9687c243321SVesa Jääskeläinen 9697c243321SVesa Jääskeläinen tee_curve = ec_params2tee_curve(a_ptr, a_size); 9707c243321SVesa Jääskeläinen 9717c243321SVesa Jääskeläinen switch (tee_curve) { 9727c243321SVesa Jääskeläinen case TEE_ECC_CURVE_NIST_P192: 9737c243321SVesa Jääskeläinen ec_curve = MBEDTLS_ECP_DP_SECP192R1; 9747c243321SVesa Jääskeläinen break; 9757c243321SVesa Jääskeläinen case TEE_ECC_CURVE_NIST_P224: 9767c243321SVesa Jääskeläinen ec_curve = MBEDTLS_ECP_DP_SECP224R1; 9777c243321SVesa Jääskeläinen break; 9787c243321SVesa Jääskeläinen case TEE_ECC_CURVE_NIST_P256: 9797c243321SVesa Jääskeläinen ec_curve = MBEDTLS_ECP_DP_SECP256R1; 9807c243321SVesa Jääskeläinen break; 9817c243321SVesa Jääskeläinen case TEE_ECC_CURVE_NIST_P384: 9827c243321SVesa Jääskeläinen ec_curve = MBEDTLS_ECP_DP_SECP384R1; 9837c243321SVesa Jääskeläinen break; 9847c243321SVesa Jääskeläinen case TEE_ECC_CURVE_NIST_P521: 9857c243321SVesa Jääskeläinen ec_curve = MBEDTLS_ECP_DP_SECP521R1; 9867c243321SVesa Jääskeläinen break; 9877c243321SVesa Jääskeläinen default: 9887c243321SVesa Jääskeläinen EMSG("Failed to map EC_PARAMS to supported curve"); 9897c243321SVesa Jääskeläinen return PKCS11_CKR_CURVE_NOT_SUPPORTED; 9907c243321SVesa Jääskeläinen } 9917c243321SVesa Jääskeläinen 9927c243321SVesa Jääskeläinen if (get_attribute_ptr(temp, PKCS11_CKA_VALUE, 9937c243321SVesa Jääskeläinen &a_ptr, &a_size) || !a_ptr) { 9947c243321SVesa Jääskeläinen EMSG("No VALUE attribute found in private key"); 9957c243321SVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 9967c243321SVesa Jääskeläinen } 9977c243321SVesa Jääskeläinen 9987c243321SVesa Jääskeläinen mbedtls_ecp_keypair_init(&key_pair); 99932b31808SJens Wiklander mbedtls_ecp_group_init(&key_pair_grp); 100032b31808SJens Wiklander mbedtls_mpi_init(&key_pair_d); 100132b31808SJens Wiklander mbedtls_ecp_point_init(&key_pair_Q); 10027c243321SVesa Jääskeläinen 10037c243321SVesa Jääskeläinen ret = mbedtls_ecp_read_key(ec_curve, &key_pair, a_ptr, a_size); 10047c243321SVesa Jääskeläinen if (ret) { 10057c243321SVesa Jääskeläinen EMSG("Failed to parse CKA_VALUE"); 10067c243321SVesa Jääskeläinen rc = PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 10077c243321SVesa Jääskeläinen goto out; 10087c243321SVesa Jääskeläinen } 10097c243321SVesa Jääskeläinen 101032b31808SJens Wiklander ret = mbedtls_ecp_export(&key_pair, &key_pair_grp, &key_pair_d, 101132b31808SJens Wiklander &key_pair_Q); 101232b31808SJens Wiklander if (ret) { 101332b31808SJens Wiklander EMSG("Failed to export key"); 101432b31808SJens Wiklander goto out; 101532b31808SJens Wiklander } 101632b31808SJens Wiklander 101732b31808SJens Wiklander ret = mbedtls_ecp_mul(&key_pair_grp, &key_pair_Q, &key_pair_d, 101832b31808SJens Wiklander &key_pair_grp.G, mbd_rand, NULL); 10197c243321SVesa Jääskeläinen if (ret) { 10207c243321SVesa Jääskeläinen EMSG("Failed to create public key"); 10217c243321SVesa Jääskeläinen goto out; 10227c243321SVesa Jääskeläinen } 10237c243321SVesa Jääskeläinen 102432b31808SJens Wiklander ret = mbedtls_ecp_check_privkey(&key_pair_grp, &key_pair_d); 10257c243321SVesa Jääskeläinen if (ret) { 10267c243321SVesa Jääskeläinen EMSG("Failed to verify private key"); 10277c243321SVesa Jääskeläinen goto out; 10287c243321SVesa Jääskeläinen } 10297c243321SVesa Jääskeläinen 103032b31808SJens Wiklander ret = mbedtls_ecp_check_pubkey(&key_pair_grp, &key_pair_Q); 10317c243321SVesa Jääskeläinen if (ret) { 10327c243321SVesa Jääskeläinen EMSG("Failed to verify public key"); 10337c243321SVesa Jääskeläinen goto out; 10347c243321SVesa Jääskeläinen } 10357c243321SVesa Jääskeläinen 103632b31808SJens Wiklander ret = mbedtls_ecp_point_write_binary(&key_pair_grp, &key_pair_Q, 10377c243321SVesa Jääskeläinen MBEDTLS_ECP_PF_UNCOMPRESSED, 10387c243321SVesa Jääskeläinen &buflen, NULL, 0); 10397c243321SVesa Jääskeläinen if (ret != MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL) { 10407c243321SVesa Jääskeläinen EMSG("Failed to determine size of binary public key"); 10417c243321SVesa Jääskeläinen goto out; 10427c243321SVesa Jääskeläinen } 10437c243321SVesa Jääskeläinen 10447c243321SVesa Jääskeläinen buf = TEE_Malloc(buflen, TEE_MALLOC_FILL_ZERO); 10457c243321SVesa Jääskeläinen if (!buf) { 10467c243321SVesa Jääskeläinen EMSG("Failed to allocate memory for public key"); 10477c243321SVesa Jääskeläinen rc = PKCS11_CKR_DEVICE_MEMORY; 10487c243321SVesa Jääskeläinen goto out; 10497c243321SVesa Jääskeläinen } 10507c243321SVesa Jääskeläinen 10517c243321SVesa Jääskeläinen asnbuflen = 1 /* octet string */ + 5 /* length */ + buflen; 10527c243321SVesa Jääskeläinen 10537c243321SVesa Jääskeläinen asnbuf = TEE_Malloc(asnbuflen, TEE_MALLOC_FILL_ZERO); 10547c243321SVesa Jääskeläinen if (!asnbuf) { 10557c243321SVesa Jääskeläinen EMSG("Failed to allocate memory for public key"); 10567c243321SVesa Jääskeläinen rc = PKCS11_CKR_DEVICE_MEMORY; 10577c243321SVesa Jääskeläinen goto out; 10587c243321SVesa Jääskeläinen } 10597c243321SVesa Jääskeläinen 106032b31808SJens Wiklander ret = mbedtls_ecp_point_write_binary(&key_pair_grp, &key_pair_Q, 10617c243321SVesa Jääskeläinen MBEDTLS_ECP_PF_UNCOMPRESSED, 10627c243321SVesa Jääskeläinen &buflen, buf, buflen); 10637c243321SVesa Jääskeläinen if (ret) { 10647c243321SVesa Jääskeläinen EMSG("Failed to write binary public key"); 10657c243321SVesa Jääskeläinen goto out; 10667c243321SVesa Jääskeläinen } 10677c243321SVesa Jääskeläinen 10687c243321SVesa Jääskeläinen /* Note: ASN.1 writing works backwards */ 10697c243321SVesa Jääskeläinen ptr = asnbuf + asnbuflen; 10707c243321SVesa Jääskeläinen 10717c243321SVesa Jääskeläinen ret = mbedtls_asn1_write_octet_string(&ptr, asnbuf, buf, buflen); 10727c243321SVesa Jääskeläinen if (ret < 0) { 10737c243321SVesa Jääskeläinen EMSG("Failed to write asn1 public key"); 10747c243321SVesa Jääskeläinen goto out; 10757c243321SVesa Jääskeläinen } 10767c243321SVesa Jääskeläinen 10777c243321SVesa Jääskeläinen rc = add_attribute(out, PKCS11_CKA_OPTEE_HIDDEN_EC_POINT, ptr, 10787c243321SVesa Jääskeläinen (size_t)ret); 10797c243321SVesa Jääskeläinen 10807c243321SVesa Jääskeläinen out: 10817c243321SVesa Jääskeläinen TEE_Free(asnbuf); 10827c243321SVesa Jääskeläinen TEE_Free(buf); 10837c243321SVesa Jääskeläinen mbedtls_ecp_keypair_free(&key_pair); 108432b31808SJens Wiklander mbedtls_ecp_group_free(&key_pair_grp); 108532b31808SJens Wiklander mbedtls_mpi_free(&key_pair_d); 108632b31808SJens Wiklander mbedtls_ecp_point_free(&key_pair_Q); 10877c243321SVesa Jääskeläinen 10887c243321SVesa Jääskeläinen return rc; 10897c243321SVesa Jääskeläinen } 10907c243321SVesa Jääskeläinen 10917c243321SVesa Jääskeläinen static enum pkcs11_rc 10927c243321SVesa Jääskeläinen create_priv_key_hidden_attributes(struct obj_attrs **out, 10937c243321SVesa Jääskeläinen struct obj_attrs *temp, 10947c243321SVesa Jääskeläinen enum processing_func function) 10957c243321SVesa Jääskeläinen { 10967c243321SVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_OK; 10977c243321SVesa Jääskeläinen 10987c243321SVesa Jääskeläinen switch (get_key_type(*out)) { 10997c243321SVesa Jääskeläinen case PKCS11_CKK_EC: 11007c243321SVesa Jääskeläinen rc = create_ec_priv_key_hidden_attributes(out, temp, function); 11017c243321SVesa Jääskeläinen break; 11027c243321SVesa Jääskeläinen default: 11037c243321SVesa Jääskeläinen /* no-op */ 11047c243321SVesa Jääskeläinen break; 11057c243321SVesa Jääskeläinen } 11067c243321SVesa Jääskeläinen 11077c243321SVesa Jääskeläinen return rc; 11087c243321SVesa Jääskeläinen } 11097c243321SVesa Jääskeläinen 11107c243321SVesa Jääskeläinen static enum pkcs11_rc 1111196bcd93SRuchika Gupta sanitize_symm_key_attributes(struct obj_attrs **temp, 1112196bcd93SRuchika Gupta enum processing_func function) 1113196bcd93SRuchika Gupta { 1114196bcd93SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK; 1115196bcd93SRuchika Gupta uint32_t a_size = 0; 1116196bcd93SRuchika Gupta 1117196bcd93SRuchika Gupta assert(get_class(*temp) == PKCS11_CKO_SECRET_KEY); 1118196bcd93SRuchika Gupta 1119196bcd93SRuchika Gupta rc = get_attribute_ptr(*temp, PKCS11_CKA_VALUE, NULL, &a_size); 1120196bcd93SRuchika Gupta 1121196bcd93SRuchika Gupta switch (get_key_type(*temp)) { 1122196bcd93SRuchika Gupta case PKCS11_CKK_GENERIC_SECRET: 1123196bcd93SRuchika Gupta case PKCS11_CKK_AES: 1124196bcd93SRuchika Gupta case PKCS11_CKK_MD5_HMAC: 1125196bcd93SRuchika Gupta case PKCS11_CKK_SHA_1_HMAC: 1126196bcd93SRuchika Gupta case PKCS11_CKK_SHA256_HMAC: 1127196bcd93SRuchika Gupta case PKCS11_CKK_SHA384_HMAC: 1128196bcd93SRuchika Gupta case PKCS11_CKK_SHA512_HMAC: 1129196bcd93SRuchika Gupta case PKCS11_CKK_SHA224_HMAC: 1130196bcd93SRuchika Gupta switch (function) { 1131196bcd93SRuchika Gupta case PKCS11_FUNCTION_IMPORT: 1132196bcd93SRuchika Gupta /* CKA_VALUE is a mandatory with C_CreateObject */ 1133196bcd93SRuchika Gupta if (rc || a_size == 0) 1134196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1135196bcd93SRuchika Gupta 1136196bcd93SRuchika Gupta if (get_attribute_ptr(*temp, PKCS11_CKA_VALUE_LEN, NULL, 1137196bcd93SRuchika Gupta NULL) != PKCS11_RV_NOT_FOUND) 1138196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1139196bcd93SRuchika Gupta 1140196bcd93SRuchika Gupta return add_attribute(temp, PKCS11_CKA_VALUE_LEN, 1141196bcd93SRuchika Gupta &a_size, sizeof(uint32_t)); 1142196bcd93SRuchika Gupta case PKCS11_FUNCTION_GENERATE: 1143196bcd93SRuchika Gupta if (rc != PKCS11_RV_NOT_FOUND) 1144196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1145196bcd93SRuchika Gupta break; 1146196bcd93SRuchika Gupta default: 1147196bcd93SRuchika Gupta break; 1148196bcd93SRuchika Gupta } 1149196bcd93SRuchika Gupta break; 1150196bcd93SRuchika Gupta default: 1151196bcd93SRuchika Gupta EMSG("Invalid key type %#"PRIx32"/%s", 1152196bcd93SRuchika Gupta get_key_type(*temp), id2str_key_type(get_key_type(*temp))); 1153196bcd93SRuchika Gupta 1154196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1155196bcd93SRuchika Gupta } 1156196bcd93SRuchika Gupta 1157196bcd93SRuchika Gupta return PKCS11_CKR_OK; 1158196bcd93SRuchika Gupta } 1159196bcd93SRuchika Gupta 116063f89caaSJens Wiklander /* 116163f89caaSJens Wiklander * Create an attribute list for a new object from a template and a parent 116263f89caaSJens Wiklander * object (optional) for an object generation function (generate, copy, 116363f89caaSJens Wiklander * derive...). 116463f89caaSJens Wiklander * 116563f89caaSJens Wiklander * PKCS#11 directives on the supplied template and expected return value: 116663f89caaSJens Wiklander * - template has an invalid attribute ID: ATTRIBUTE_TYPE_INVALID 116763f89caaSJens Wiklander * - template has an invalid value for an attribute: ATTRIBUTE_VALID_INVALID 116863f89caaSJens Wiklander * - template has value for a read-only attribute: ATTRIBUTE_READ_ONLY 116963f89caaSJens Wiklander * - template+default+parent => still miss an attribute: TEMPLATE_INCONSISTENT 117063f89caaSJens Wiklander * 117163f89caaSJens Wiklander * INFO on PKCS11_CMD_COPY_OBJECT: 117263f89caaSJens Wiklander * - parent PKCS11_CKA_COPYIABLE=false => return ACTION_PROHIBITED. 117363f89caaSJens Wiklander * - template can specify PKCS11_CKA_TOKEN, PKCS11_CKA_PRIVATE, 117463f89caaSJens Wiklander * PKCS11_CKA_MODIFIABLE, PKCS11_CKA_DESTROYABLE. 117563f89caaSJens Wiklander * - SENSITIVE can change from false to true, not from true to false. 117663f89caaSJens Wiklander * - LOCAL is the parent LOCAL 117763f89caaSJens Wiklander */ 117863f89caaSJens Wiklander enum pkcs11_rc 117963f89caaSJens Wiklander create_attributes_from_template(struct obj_attrs **out, void *template, 118063f89caaSJens Wiklander size_t template_size, 118148799892SRuchika Gupta struct obj_attrs *parent, 118263f89caaSJens Wiklander enum processing_func function, 11834cfce748SRuchika Gupta enum pkcs11_mechanism_id mecha, 118402b16804SVesa Jääskeläinen enum pkcs11_class_id template_class) 118563f89caaSJens Wiklander { 118663f89caaSJens Wiklander struct obj_attrs *temp = NULL; 118763f89caaSJens Wiklander struct obj_attrs *attrs = NULL; 118863f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 118963f89caaSJens Wiklander uint8_t local = 0; 119063f89caaSJens Wiklander uint8_t always_sensitive = 0; 119163f89caaSJens Wiklander uint8_t never_extract = 0; 1192e3f0cb56SRuchika Gupta uint8_t extractable = 0; 1193fa247a2aSRuchika Gupta uint32_t class = PKCS11_UNDEFINED_ID; 1194fa247a2aSRuchika Gupta uint32_t type = PKCS11_UNDEFINED_ID; 119563f89caaSJens Wiklander uint32_t mechanism_id = PKCS11_CKM_UNDEFINED_ID; 1196e3f0cb56SRuchika Gupta struct obj_attrs *req_attrs = NULL; 1197e3f0cb56SRuchika Gupta uint32_t size = 0; 1198e3f0cb56SRuchika Gupta uint32_t indirect_template = PKCS11_CKA_UNDEFINED_ID; 119963f89caaSJens Wiklander 120063f89caaSJens Wiklander #ifdef DEBUG /* Sanity: check function argument */ 120163f89caaSJens Wiklander trace_attributes_from_api_head("template", template, template_size); 120263f89caaSJens Wiklander switch (function) { 1203fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 1204013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 120563f89caaSJens Wiklander case PKCS11_FUNCTION_IMPORT: 12062d25a9bcSRuchika Gupta case PKCS11_FUNCTION_MODIFY: 120748799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 1208e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 12092d25a9bcSRuchika Gupta case PKCS11_FUNCTION_COPY: 121063f89caaSJens Wiklander break; 121163f89caaSJens Wiklander default: 121263f89caaSJens Wiklander TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 121363f89caaSJens Wiklander } 121463f89caaSJens Wiklander #endif 121563f89caaSJens Wiklander 1216dcad3409SRuchika Gupta /* 1217dcad3409SRuchika Gupta * For PKCS11_FUNCTION_GENERATE, find the class and type 1218dcad3409SRuchika Gupta * based on the mechanism. These will be passed as hint 1219dcad3409SRuchika Gupta * sanitize_client_object() and added in temp if not 1220dcad3409SRuchika Gupta * already present 1221dcad3409SRuchika Gupta */ 1222dcad3409SRuchika Gupta if (function == PKCS11_FUNCTION_GENERATE) { 1223fa247a2aSRuchika Gupta switch (mecha) { 1224fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1225fa247a2aSRuchika Gupta class = PKCS11_CKO_SECRET_KEY; 1226fa247a2aSRuchika Gupta type = PKCS11_CKK_GENERIC_SECRET; 1227fa247a2aSRuchika Gupta break; 1228fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 1229fa247a2aSRuchika Gupta class = PKCS11_CKO_SECRET_KEY; 1230fa247a2aSRuchika Gupta type = PKCS11_CKK_AES; 1231fa247a2aSRuchika Gupta break; 1232fa247a2aSRuchika Gupta default: 1233dcad3409SRuchika Gupta TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 1234fa247a2aSRuchika Gupta } 1235fa247a2aSRuchika Gupta } 1236fa247a2aSRuchika Gupta 12372d25a9bcSRuchika Gupta /* 1238013934d8SVesa Jääskeläinen * For PKCS11_FUNCTION_GENERATE_PAIR, find the class and type 1239013934d8SVesa Jääskeläinen * based on the mechanism. These will be passed as hint 1240013934d8SVesa Jääskeläinen * sanitize_client_object() and added in temp if not 1241013934d8SVesa Jääskeläinen * already present 1242013934d8SVesa Jääskeläinen */ 1243013934d8SVesa Jääskeläinen if (function == PKCS11_FUNCTION_GENERATE_PAIR) { 1244013934d8SVesa Jääskeläinen switch (mecha) { 124503e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: 124603e07432SValerii Chubar class = template_class; 124703e07432SValerii Chubar type = PKCS11_CKK_EDDSA; 124803e07432SValerii Chubar break; 124902b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 125002b16804SVesa Jääskeläinen class = template_class; 125102b16804SVesa Jääskeläinen type = PKCS11_CKK_EC; 125202b16804SVesa Jääskeläinen break; 125386922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 125486922832SVesa Jääskeläinen class = template_class; 125586922832SVesa Jääskeläinen type = PKCS11_CKK_RSA; 125686922832SVesa Jääskeläinen break; 1257013934d8SVesa Jääskeläinen default: 1258013934d8SVesa Jääskeläinen TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 1259013934d8SVesa Jääskeläinen } 1260013934d8SVesa Jääskeläinen } 1261013934d8SVesa Jääskeläinen 1262013934d8SVesa Jääskeläinen /* 12632d25a9bcSRuchika Gupta * Check and remove duplicates if any and create a new temporary 12642d25a9bcSRuchika Gupta * template 12652d25a9bcSRuchika Gupta */ 1266dcad3409SRuchika Gupta rc = sanitize_client_object(&temp, template, template_size, class, 1267dcad3409SRuchika Gupta type); 1268dcad3409SRuchika Gupta if (rc) 1269dcad3409SRuchika Gupta goto out; 1270dcad3409SRuchika Gupta 1271dcad3409SRuchika Gupta /* 12722d25a9bcSRuchika Gupta * For function type modify and copy return the created template 12732d25a9bcSRuchika Gupta * from here. Rest of the code below is for creating objects 12742d25a9bcSRuchika Gupta * or generating keys. 12752d25a9bcSRuchika Gupta */ 12762d25a9bcSRuchika Gupta switch (function) { 12772d25a9bcSRuchika Gupta case PKCS11_FUNCTION_MODIFY: 12782d25a9bcSRuchika Gupta case PKCS11_FUNCTION_COPY: 12792d25a9bcSRuchika Gupta *out = temp; 12802d25a9bcSRuchika Gupta return rc; 1281e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 1282e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 1283e3f0cb56SRuchika Gupta if (function == PKCS11_FUNCTION_UNWRAP) 1284e3f0cb56SRuchika Gupta indirect_template = PKCS11_CKA_UNWRAP_TEMPLATE; 1285e3f0cb56SRuchika Gupta else 1286e3f0cb56SRuchika Gupta indirect_template = PKCS11_CKA_DERIVE_TEMPLATE; 1287e3f0cb56SRuchika Gupta 1288e3f0cb56SRuchika Gupta rc = get_attribute_ptr(parent, indirect_template, 1289e3f0cb56SRuchika Gupta (void *)&req_attrs, &size); 1290e3f0cb56SRuchika Gupta if (rc == PKCS11_CKR_OK && size != 0) { 1291e3f0cb56SRuchika Gupta rc = attributes_match_add_reference(&temp, req_attrs); 1292e3f0cb56SRuchika Gupta if (rc) 1293e3f0cb56SRuchika Gupta goto out; 1294e3f0cb56SRuchika Gupta } 1295e3f0cb56SRuchika Gupta break; 12962d25a9bcSRuchika Gupta default: 12972d25a9bcSRuchika Gupta break; 12982d25a9bcSRuchika Gupta } 12992d25a9bcSRuchika Gupta 13002d25a9bcSRuchika Gupta /* 1301dcad3409SRuchika Gupta * Check if class and type in temp are consistent with the mechanism 1302dcad3409SRuchika Gupta */ 1303fa247a2aSRuchika Gupta switch (mecha) { 1304fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1305fa247a2aSRuchika Gupta if (get_class(temp) != PKCS11_CKO_SECRET_KEY || 1306fa247a2aSRuchika Gupta get_key_type(temp) != PKCS11_CKK_GENERIC_SECRET) { 1307fa247a2aSRuchika Gupta rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 1308fa247a2aSRuchika Gupta goto out; 1309fa247a2aSRuchika Gupta } 1310fa247a2aSRuchika Gupta break; 1311fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 1312fa247a2aSRuchika Gupta if (get_class(temp) != PKCS11_CKO_SECRET_KEY || 1313fa247a2aSRuchika Gupta get_key_type(temp) != PKCS11_CKK_AES) { 1314fa247a2aSRuchika Gupta rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 1315fa247a2aSRuchika Gupta goto out; 1316fa247a2aSRuchika Gupta } 1317fa247a2aSRuchika Gupta break; 131802b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 131902b16804SVesa Jääskeläinen if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && 132002b16804SVesa Jääskeläinen get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || 132102b16804SVesa Jääskeläinen get_key_type(temp) != PKCS11_CKK_EC) { 132202b16804SVesa Jääskeläinen rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 132302b16804SVesa Jääskeläinen goto out; 132402b16804SVesa Jääskeläinen } 132502b16804SVesa Jääskeläinen break; 132603e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: 132703e07432SValerii Chubar if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && 132803e07432SValerii Chubar get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || 132903e07432SValerii Chubar get_key_type(temp) != PKCS11_CKK_EC_EDWARDS) { 133003e07432SValerii Chubar rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 133103e07432SValerii Chubar goto out; 133203e07432SValerii Chubar } 133303e07432SValerii Chubar break; 133486922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 133586922832SVesa Jääskeläinen if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && 133686922832SVesa Jääskeläinen get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || 133786922832SVesa Jääskeläinen get_key_type(temp) != PKCS11_CKK_RSA) { 133886922832SVesa Jääskeläinen rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 133986922832SVesa Jääskeläinen goto out; 134086922832SVesa Jääskeläinen } 134186922832SVesa Jääskeläinen break; 1342fa247a2aSRuchika Gupta default: 1343fa247a2aSRuchika Gupta break; 1344fa247a2aSRuchika Gupta } 134563f89caaSJens Wiklander 134663f89caaSJens Wiklander if (!sanitize_consistent_class_and_type(temp)) { 134763f89caaSJens Wiklander EMSG("Inconsistent class/type"); 134863f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 134963f89caaSJens Wiklander goto out; 135063f89caaSJens Wiklander } 135163f89caaSJens Wiklander 1352e3f0cb56SRuchika Gupta /* 1353e3f0cb56SRuchika Gupta * TBD - Add a check to see if temp contains any attribute which 1354e3f0cb56SRuchika Gupta * is not consistent with the object class or type and return error. 1355e3f0cb56SRuchika Gupta * In current implementation such attributes are ignored and not 1356e3f0cb56SRuchika Gupta * added to final object while PKCS#11 specification expects a 1357e3f0cb56SRuchika Gupta * failure and an error code be returned. 1358e3f0cb56SRuchika Gupta */ 1359e3f0cb56SRuchika Gupta 136063f89caaSJens Wiklander switch (get_class(temp)) { 136163f89caaSJens Wiklander case PKCS11_CKO_DATA: 136263f89caaSJens Wiklander rc = create_data_attributes(&attrs, temp); 136363f89caaSJens Wiklander break; 13644137952dSVesa Jääskeläinen case PKCS11_CKO_CERTIFICATE: 13654137952dSVesa Jääskeläinen rc = create_certificate_attributes(&attrs, temp); 13664137952dSVesa Jääskeläinen break; 136763f89caaSJens Wiklander case PKCS11_CKO_SECRET_KEY: 1368196bcd93SRuchika Gupta rc = sanitize_symm_key_attributes(&temp, function); 1369196bcd93SRuchika Gupta if (rc) 1370196bcd93SRuchika Gupta goto out; 137163f89caaSJens Wiklander rc = create_symm_key_attributes(&attrs, temp); 137263f89caaSJens Wiklander break; 137363f89caaSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 13749cf1afceSVesa Jääskeläinen rc = create_pub_key_attributes(&attrs, temp, function); 13755071d7d1SVesa Jääskeläinen if (rc) 13765071d7d1SVesa Jääskeläinen goto out; 13775071d7d1SVesa Jääskeläinen rc = create_pub_key_generated_attributes(&attrs, temp, 13785071d7d1SVesa Jääskeläinen function); 137963f89caaSJens Wiklander break; 138063f89caaSJens Wiklander case PKCS11_CKO_PRIVATE_KEY: 138163f89caaSJens Wiklander rc = create_priv_key_attributes(&attrs, temp); 13827c243321SVesa Jääskeläinen if (rc) 13837c243321SVesa Jääskeläinen goto out; 13847c243321SVesa Jääskeläinen rc = create_priv_key_hidden_attributes(&attrs, temp, function); 138563f89caaSJens Wiklander break; 138663f89caaSJens Wiklander default: 138763f89caaSJens Wiklander DMSG("Invalid object class %#"PRIx32"/%s", 138863f89caaSJens Wiklander get_class(temp), id2str_class(get_class(temp))); 138963f89caaSJens Wiklander 139063f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 139163f89caaSJens Wiklander break; 139263f89caaSJens Wiklander } 139363f89caaSJens Wiklander if (rc) 139463f89caaSJens Wiklander goto out; 139563f89caaSJens Wiklander 139690c47fe2SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_LOCAL, NULL, NULL) != 1397002f6b93SEtienne Carriere PKCS11_RV_NOT_FOUND) { 1398002f6b93SEtienne Carriere rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 139963f89caaSJens Wiklander goto out; 1400002f6b93SEtienne Carriere } 140163f89caaSJens Wiklander 140290c47fe2SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_KEY_GEN_MECHANISM, NULL, NULL) != 1403002f6b93SEtienne Carriere PKCS11_RV_NOT_FOUND) { 1404002f6b93SEtienne Carriere rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 140563f89caaSJens Wiklander goto out; 1406002f6b93SEtienne Carriere } 140763f89caaSJens Wiklander 140863f89caaSJens Wiklander switch (function) { 1409fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 1410013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 1411fa247a2aSRuchika Gupta local = PKCS11_TRUE; 1412fa247a2aSRuchika Gupta break; 141363f89caaSJens Wiklander case PKCS11_FUNCTION_IMPORT: 141448799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 1415e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 141663f89caaSJens Wiklander default: 141763f89caaSJens Wiklander local = PKCS11_FALSE; 141863f89caaSJens Wiklander break; 141963f89caaSJens Wiklander } 142063f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_LOCAL, &local, sizeof(local)); 142163f89caaSJens Wiklander if (rc) 142263f89caaSJens Wiklander goto out; 142363f89caaSJens Wiklander 142463f89caaSJens Wiklander switch (get_class(attrs)) { 142563f89caaSJens Wiklander case PKCS11_CKO_SECRET_KEY: 142663f89caaSJens Wiklander case PKCS11_CKO_PRIVATE_KEY: 142763f89caaSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 142863f89caaSJens Wiklander always_sensitive = PKCS11_FALSE; 142963f89caaSJens Wiklander never_extract = PKCS11_FALSE; 143063f89caaSJens Wiklander 1431fa247a2aSRuchika Gupta switch (function) { 143248799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 143348799892SRuchika Gupta always_sensitive = 143448799892SRuchika Gupta get_bool(parent, PKCS11_CKA_ALWAYS_SENSITIVE) && 143548799892SRuchika Gupta get_bool(attrs, PKCS11_CKA_SENSITIVE); 143648799892SRuchika Gupta never_extract = 143748799892SRuchika Gupta get_bool(parent, PKCS11_CKA_NEVER_EXTRACTABLE) && 143848799892SRuchika Gupta !get_bool(attrs, PKCS11_CKA_EXTRACTABLE); 143948799892SRuchika Gupta break; 1440e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 1441e3f0cb56SRuchika Gupta always_sensitive = PKCS11_FALSE; 1442e3f0cb56SRuchika Gupta never_extract = PKCS11_FALSE; 1443e3f0cb56SRuchika Gupta extractable = PKCS11_TRUE; 1444e3f0cb56SRuchika Gupta 1445e3f0cb56SRuchika Gupta /* 1446e3f0cb56SRuchika Gupta * Check if template passed by user has CKA_EXTRACTABLE. 1447e3f0cb56SRuchika Gupta * If not, by default value of CKA_EXTRACTABLE is set as 1448e3f0cb56SRuchika Gupta * TRUE. 1449e3f0cb56SRuchika Gupta */ 1450e3f0cb56SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_EXTRACTABLE, 1451e3f0cb56SRuchika Gupta NULL, 1452e3f0cb56SRuchika Gupta NULL) == PKCS11_RV_NOT_FOUND) { 1453e3f0cb56SRuchika Gupta rc = set_attribute(&attrs, 1454e3f0cb56SRuchika Gupta PKCS11_CKA_EXTRACTABLE, 1455e3f0cb56SRuchika Gupta &extractable, 1456e3f0cb56SRuchika Gupta sizeof(extractable)); 1457e3f0cb56SRuchika Gupta if (rc) 1458e3f0cb56SRuchika Gupta goto out; 1459e3f0cb56SRuchika Gupta } 1460e3f0cb56SRuchika Gupta break; 1461fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 1462013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 1463fa247a2aSRuchika Gupta always_sensitive = get_bool(attrs, 1464fa247a2aSRuchika Gupta PKCS11_CKA_SENSITIVE); 1465fa247a2aSRuchika Gupta never_extract = !get_bool(attrs, 1466fa247a2aSRuchika Gupta PKCS11_CKA_EXTRACTABLE); 1467fa247a2aSRuchika Gupta break; 1468fa247a2aSRuchika Gupta default: 1469fa247a2aSRuchika Gupta break; 1470fa247a2aSRuchika Gupta } 1471fa247a2aSRuchika Gupta 147263f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_ALWAYS_SENSITIVE, 147363f89caaSJens Wiklander &always_sensitive, sizeof(always_sensitive)); 147463f89caaSJens Wiklander if (rc) 147563f89caaSJens Wiklander goto out; 147663f89caaSJens Wiklander 147763f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_NEVER_EXTRACTABLE, 147863f89caaSJens Wiklander &never_extract, sizeof(never_extract)); 147963f89caaSJens Wiklander if (rc) 148063f89caaSJens Wiklander goto out; 148163f89caaSJens Wiklander 148263f89caaSJens Wiklander /* Keys mandate attribute PKCS11_CKA_KEY_GEN_MECHANISM */ 1483fa247a2aSRuchika Gupta if (local) 1484fa247a2aSRuchika Gupta mechanism_id = mecha; 1485fa247a2aSRuchika Gupta else 148663f89caaSJens Wiklander mechanism_id = PKCS11_CK_UNAVAILABLE_INFORMATION; 1487fa247a2aSRuchika Gupta 148863f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_KEY_GEN_MECHANISM, 148963f89caaSJens Wiklander &mechanism_id, sizeof(mechanism_id)); 149063f89caaSJens Wiklander if (rc) 149163f89caaSJens Wiklander goto out; 149263f89caaSJens Wiklander break; 149363f89caaSJens Wiklander 149463f89caaSJens Wiklander default: 149563f89caaSJens Wiklander break; 149663f89caaSJens Wiklander } 149763f89caaSJens Wiklander 149863f89caaSJens Wiklander *out = attrs; 149963f89caaSJens Wiklander 150063f89caaSJens Wiklander #ifdef DEBUG 150163f89caaSJens Wiklander trace_attributes("object", attrs); 150263f89caaSJens Wiklander #endif 150363f89caaSJens Wiklander 150463f89caaSJens Wiklander out: 150563f89caaSJens Wiklander TEE_Free(temp); 150663f89caaSJens Wiklander if (rc) 150763f89caaSJens Wiklander TEE_Free(attrs); 150863f89caaSJens Wiklander 150963f89caaSJens Wiklander return rc; 151063f89caaSJens Wiklander } 151163f89caaSJens Wiklander 151263f89caaSJens Wiklander static enum pkcs11_rc check_attrs_misc_integrity(struct obj_attrs *head) 151363f89caaSJens Wiklander { 151463f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_NEVER_EXTRACTABLE) && 151563f89caaSJens Wiklander get_bool(head, PKCS11_CKA_EXTRACTABLE)) { 151663f89caaSJens Wiklander DMSG("Never/Extractable attributes mismatch %d/%d", 151763f89caaSJens Wiklander get_bool(head, PKCS11_CKA_NEVER_EXTRACTABLE), 151863f89caaSJens Wiklander get_bool(head, PKCS11_CKA_EXTRACTABLE)); 151963f89caaSJens Wiklander 152063f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 152163f89caaSJens Wiklander } 152263f89caaSJens Wiklander 152363f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_ALWAYS_SENSITIVE) && 152463f89caaSJens Wiklander !get_bool(head, PKCS11_CKA_SENSITIVE)) { 152563f89caaSJens Wiklander DMSG("Sensitive/always attributes mismatch %d/%d", 152663f89caaSJens Wiklander get_bool(head, PKCS11_CKA_SENSITIVE), 152763f89caaSJens Wiklander get_bool(head, PKCS11_CKA_ALWAYS_SENSITIVE)); 152863f89caaSJens Wiklander 152963f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 153063f89caaSJens Wiklander } 153163f89caaSJens Wiklander 153263f89caaSJens Wiklander return PKCS11_CKR_OK; 153363f89caaSJens Wiklander } 153463f89caaSJens Wiklander 153589735787SRuchika Gupta bool object_is_private(struct obj_attrs *head) 153689735787SRuchika Gupta { 153765fb9092SVesa Jääskeläinen return get_bool(head, PKCS11_CKA_PRIVATE); 153889735787SRuchika Gupta } 153989735787SRuchika Gupta 15402d25a9bcSRuchika Gupta bool object_is_token(struct obj_attrs *head) 15412d25a9bcSRuchika Gupta { 15422d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_TOKEN); 15432d25a9bcSRuchika Gupta } 15442d25a9bcSRuchika Gupta 15452d25a9bcSRuchika Gupta bool object_is_modifiable(struct obj_attrs *head) 15462d25a9bcSRuchika Gupta { 15472d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_MODIFIABLE); 15482d25a9bcSRuchika Gupta } 15492d25a9bcSRuchika Gupta 15502d25a9bcSRuchika Gupta bool object_is_copyable(struct obj_attrs *head) 15512d25a9bcSRuchika Gupta { 15522d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_COPYABLE); 15532d25a9bcSRuchika Gupta } 15542d25a9bcSRuchika Gupta 155563f89caaSJens Wiklander /* 1556512cbf1dSJens Wiklander * Check access to object against authentication to token 1557512cbf1dSJens Wiklander */ 1558512cbf1dSJens Wiklander enum pkcs11_rc check_access_attrs_against_token(struct pkcs11_session *session, 1559512cbf1dSJens Wiklander struct obj_attrs *head) 1560512cbf1dSJens Wiklander { 1561512cbf1dSJens Wiklander bool private = true; 1562512cbf1dSJens Wiklander 1563512cbf1dSJens Wiklander switch (get_class(head)) { 1564512cbf1dSJens Wiklander case PKCS11_CKO_SECRET_KEY: 156565fb9092SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1566512cbf1dSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 1567512cbf1dSJens Wiklander case PKCS11_CKO_DATA: 15684137952dSVesa Jääskeläinen case PKCS11_CKO_CERTIFICATE: 156965fb9092SVesa Jääskeläinen private = object_is_private(head); 1570512cbf1dSJens Wiklander break; 1571512cbf1dSJens Wiklander default: 1572512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1573512cbf1dSJens Wiklander } 1574512cbf1dSJens Wiklander 15755db0fef4SRuchika Gupta if (private && (pkcs11_session_is_public(session) || 15765db0fef4SRuchika Gupta pkcs11_session_is_so(session))) { 15775db0fef4SRuchika Gupta DMSG("Private object access from a public or SO session"); 1578512cbf1dSJens Wiklander 157912f1ba86SRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 1580512cbf1dSJens Wiklander } 1581512cbf1dSJens Wiklander 1582512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1583512cbf1dSJens Wiklander } 1584512cbf1dSJens Wiklander 1585512cbf1dSJens Wiklander /* 158663f89caaSJens Wiklander * Check the attributes of a to-be-created object matches the token state 158763f89caaSJens Wiklander */ 158863f89caaSJens Wiklander enum pkcs11_rc check_created_attrs_against_token(struct pkcs11_session *session, 158963f89caaSJens Wiklander struct obj_attrs *head) 159063f89caaSJens Wiklander { 159163f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 159263f89caaSJens Wiklander 159363f89caaSJens Wiklander rc = check_attrs_misc_integrity(head); 159463f89caaSJens Wiklander if (rc) 159563f89caaSJens Wiklander return rc; 159663f89caaSJens Wiklander 159763f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_TRUSTED) && 159863f89caaSJens Wiklander !pkcs11_session_is_so(session)) { 159963f89caaSJens Wiklander DMSG("Can't create trusted object"); 160063f89caaSJens Wiklander 160163f89caaSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 160263f89caaSJens Wiklander } 160363f89caaSJens Wiklander 160463f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_TOKEN) && 160563f89caaSJens Wiklander !pkcs11_session_is_read_write(session)) { 160663f89caaSJens Wiklander DMSG("Can't create persistent object"); 160763f89caaSJens Wiklander 160863f89caaSJens Wiklander return PKCS11_CKR_SESSION_READ_ONLY; 160963f89caaSJens Wiklander } 161063f89caaSJens Wiklander 161163f89caaSJens Wiklander return PKCS11_CKR_OK; 161263f89caaSJens Wiklander } 161363f89caaSJens Wiklander 161463f89caaSJens Wiklander #define DMSG_BAD_BBOOL(attr, proc, head) \ 161563f89caaSJens Wiklander do { \ 161663f89caaSJens Wiklander uint32_t __maybe_unused _attr = (attr); \ 161763f89caaSJens Wiklander uint8_t __maybe_unused _bvalue = 0; \ 161863f89caaSJens Wiklander enum pkcs11_rc __maybe_unused _rc = PKCS11_CKR_OK; \ 161963f89caaSJens Wiklander \ 162063f89caaSJens Wiklander _rc = get_attribute((head), _attr, &_bvalue, NULL); \ 162163f89caaSJens Wiklander DMSG("%s issue for %s: %sfound, value %"PRIu8, \ 162263f89caaSJens Wiklander id2str_attr(_attr), id2str_proc((proc)), \ 162363f89caaSJens Wiklander _rc ? "not " : "", _bvalue); \ 162463f89caaSJens Wiklander } while (0) 162563f89caaSJens Wiklander 162663f89caaSJens Wiklander static bool __maybe_unused check_attr_bval(uint32_t proc_id __maybe_unused, 162763f89caaSJens Wiklander struct obj_attrs *head, 162863f89caaSJens Wiklander uint32_t attribute, bool val) 162963f89caaSJens Wiklander { 163063f89caaSJens Wiklander uint8_t bbool = 0; 163163f89caaSJens Wiklander uint32_t sz = sizeof(bbool); 163263f89caaSJens Wiklander 163363f89caaSJens Wiklander if (!get_attribute(head, attribute, &bbool, &sz) && !!bbool == val) 163463f89caaSJens Wiklander return true; 163563f89caaSJens Wiklander 163663f89caaSJens Wiklander DMSG_BAD_BBOOL(attribute, proc_id, head); 163763f89caaSJens Wiklander return false; 163863f89caaSJens Wiklander } 163963f89caaSJens Wiklander 164063f89caaSJens Wiklander /* 164163f89caaSJens Wiklander * Check the attributes of a new secret match the processing/mechanism 164263f89caaSJens Wiklander * used to create it. 164363f89caaSJens Wiklander * 164463f89caaSJens Wiklander * @proc_id - PKCS11_CKM_xxx 164563f89caaSJens Wiklander * @head - head of the attributes of the to-be-created object. 164663f89caaSJens Wiklander */ 164763f89caaSJens Wiklander enum pkcs11_rc check_created_attrs_against_processing(uint32_t proc_id, 164863f89caaSJens Wiklander struct obj_attrs *head) 164963f89caaSJens Wiklander { 165063f89caaSJens Wiklander /* 165163f89caaSJens Wiklander * Processings that do not create secrets are not expected to call 165263f89caaSJens Wiklander * this function which would panic. 165363f89caaSJens Wiklander */ 165463f89caaSJens Wiklander switch (proc_id) { 165563f89caaSJens Wiklander case PKCS11_PROCESSING_IMPORT: 1656cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 1657e3f0cb56SRuchika Gupta case PKCS11_CKM_AES_ECB: 1658e3f0cb56SRuchika Gupta case PKCS11_CKM_AES_CBC: 165948799892SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 166048799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 166145d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP: 166263f89caaSJens Wiklander assert(check_attr_bval(proc_id, head, PKCS11_CKA_LOCAL, false)); 166363f89caaSJens Wiklander break; 1664fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1665fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 166603e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: 166702b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 166886922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 1669fa247a2aSRuchika Gupta assert(check_attr_bval(proc_id, head, PKCS11_CKA_LOCAL, true)); 1670fa247a2aSRuchika Gupta break; 167163f89caaSJens Wiklander default: 167263f89caaSJens Wiklander TEE_Panic(proc_id); 167363f89caaSJens Wiklander break; 167463f89caaSJens Wiklander } 167563f89caaSJens Wiklander 1676fa247a2aSRuchika Gupta switch (proc_id) { 1677fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1678fa247a2aSRuchika Gupta assert(get_key_type(head) == PKCS11_CKK_GENERIC_SECRET); 1679fa247a2aSRuchika Gupta break; 1680fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 1681fa247a2aSRuchika Gupta assert(get_key_type(head) == PKCS11_CKK_AES); 1682fa247a2aSRuchika Gupta break; 168303e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: 168403e07432SValerii Chubar assert(get_key_type(head) == PKCS11_CKK_EC_EDWARDS); 168503e07432SValerii Chubar break; 168602b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 168702b16804SVesa Jääskeläinen assert(get_key_type(head) == PKCS11_CKK_EC); 168802b16804SVesa Jääskeläinen break; 168986922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 169086922832SVesa Jääskeläinen assert(get_key_type(head) == PKCS11_CKK_RSA); 169186922832SVesa Jääskeläinen break; 1692fa247a2aSRuchika Gupta case PKCS11_PROCESSING_IMPORT: 1693cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 1694fa247a2aSRuchika Gupta default: 1695fa247a2aSRuchika Gupta break; 1696fa247a2aSRuchika Gupta } 1697fa247a2aSRuchika Gupta 169863f89caaSJens Wiklander return PKCS11_CKR_OK; 169963f89caaSJens Wiklander } 1700512cbf1dSJens Wiklander 17012d0cd829SRuchika Gupta /* Return min and max key size supported for a key_type in bytes */ 1702512cbf1dSJens Wiklander static void get_key_min_max_sizes(enum pkcs11_key_type key_type, 1703512cbf1dSJens Wiklander uint32_t *min_key_size, 1704512cbf1dSJens Wiklander uint32_t *max_key_size) 1705512cbf1dSJens Wiklander { 1706512cbf1dSJens Wiklander enum pkcs11_mechanism_id mechanism = PKCS11_CKM_UNDEFINED_ID; 1707512cbf1dSJens Wiklander 1708512cbf1dSJens Wiklander switch (key_type) { 1709fa247a2aSRuchika Gupta case PKCS11_CKK_GENERIC_SECRET: 1710fa247a2aSRuchika Gupta mechanism = PKCS11_CKM_GENERIC_SECRET_KEY_GEN; 1711fa247a2aSRuchika Gupta break; 1712512cbf1dSJens Wiklander case PKCS11_CKK_AES: 1713512cbf1dSJens Wiklander mechanism = PKCS11_CKM_AES_KEY_GEN; 1714512cbf1dSJens Wiklander break; 17151f45c9cfSRuchika Gupta case PKCS11_CKK_MD5_HMAC: 17161f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_MD5_HMAC; 17171f45c9cfSRuchika Gupta break; 17181f45c9cfSRuchika Gupta case PKCS11_CKK_SHA_1_HMAC: 17191f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA_1_HMAC; 17201f45c9cfSRuchika Gupta break; 17211f45c9cfSRuchika Gupta case PKCS11_CKK_SHA224_HMAC: 17221f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA224_HMAC; 17231f45c9cfSRuchika Gupta break; 1724a339a354SEtienne Carriere case PKCS11_CKK_SHA256_HMAC: 1725a339a354SEtienne Carriere mechanism = PKCS11_CKM_SHA256_HMAC; 1726a339a354SEtienne Carriere break; 17271f45c9cfSRuchika Gupta case PKCS11_CKK_SHA384_HMAC: 17281f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA384_HMAC; 17291f45c9cfSRuchika Gupta break; 17301f45c9cfSRuchika Gupta case PKCS11_CKK_SHA512_HMAC: 17311f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA512_HMAC; 17321f45c9cfSRuchika Gupta break; 1733db28c542SVesa Jääskeläinen case PKCS11_CKK_EC: 1734db28c542SVesa Jääskeläinen mechanism = PKCS11_CKM_EC_KEY_PAIR_GEN; 1735db28c542SVesa Jääskeläinen break; 173603e07432SValerii Chubar case PKCS11_CKK_EDDSA: 173703e07432SValerii Chubar mechanism = PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN; 173803e07432SValerii Chubar break; 173986922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 174086922832SVesa Jääskeläinen mechanism = PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN; 174186922832SVesa Jääskeläinen break; 1742512cbf1dSJens Wiklander default: 1743512cbf1dSJens Wiklander TEE_Panic(key_type); 1744512cbf1dSJens Wiklander break; 1745512cbf1dSJens Wiklander } 1746512cbf1dSJens Wiklander 17472d0cd829SRuchika Gupta mechanism_supported_key_sizes_bytes(mechanism, min_key_size, 1748512cbf1dSJens Wiklander max_key_size); 1749512cbf1dSJens Wiklander } 1750512cbf1dSJens Wiklander 1751512cbf1dSJens Wiklander enum pkcs11_rc check_created_attrs(struct obj_attrs *key1, 1752512cbf1dSJens Wiklander struct obj_attrs *key2) 1753512cbf1dSJens Wiklander { 1754512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 1755512cbf1dSJens Wiklander struct obj_attrs *secret = NULL; 1756013934d8SVesa Jääskeläinen struct obj_attrs *private = NULL; 1757013934d8SVesa Jääskeläinen struct obj_attrs *public = NULL; 1758512cbf1dSJens Wiklander uint32_t max_key_size = 0; 1759512cbf1dSJens Wiklander uint32_t min_key_size = 0; 1760512cbf1dSJens Wiklander uint32_t key_length = 0; 1761512cbf1dSJens Wiklander 1762512cbf1dSJens Wiklander switch (get_class(key1)) { 1763512cbf1dSJens Wiklander case PKCS11_CKO_SECRET_KEY: 1764512cbf1dSJens Wiklander secret = key1; 1765512cbf1dSJens Wiklander break; 1766013934d8SVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 1767013934d8SVesa Jääskeläinen public = key1; 1768013934d8SVesa Jääskeläinen break; 1769013934d8SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1770013934d8SVesa Jääskeläinen private = key1; 1771013934d8SVesa Jääskeläinen break; 1772512cbf1dSJens Wiklander default: 1773512cbf1dSJens Wiklander return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 1774512cbf1dSJens Wiklander } 1775512cbf1dSJens Wiklander 1776013934d8SVesa Jääskeläinen if (key2) { 1777013934d8SVesa Jääskeläinen switch (get_class(key2)) { 1778013934d8SVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 1779013934d8SVesa Jääskeläinen public = key2; 1780013934d8SVesa Jääskeläinen if (private == key1) 1781013934d8SVesa Jääskeläinen break; 1782013934d8SVesa Jääskeläinen 1783013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1784013934d8SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1785013934d8SVesa Jääskeläinen private = key2; 1786013934d8SVesa Jääskeläinen if (public == key1) 1787013934d8SVesa Jääskeläinen break; 1788013934d8SVesa Jääskeläinen 1789013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1790013934d8SVesa Jääskeläinen default: 1791512cbf1dSJens Wiklander return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 1792013934d8SVesa Jääskeläinen } 1793013934d8SVesa Jääskeläinen 1794013934d8SVesa Jääskeläinen if (get_key_type(private) != get_key_type(public)) 1795013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1796013934d8SVesa Jääskeläinen } 1797512cbf1dSJens Wiklander 1798512cbf1dSJens Wiklander if (secret) { 1799512cbf1dSJens Wiklander switch (get_key_type(secret)) { 1800512cbf1dSJens Wiklander case PKCS11_CKK_AES: 1801512cbf1dSJens Wiklander case PKCS11_CKK_GENERIC_SECRET: 1802512cbf1dSJens Wiklander case PKCS11_CKK_MD5_HMAC: 1803512cbf1dSJens Wiklander case PKCS11_CKK_SHA_1_HMAC: 1804512cbf1dSJens Wiklander case PKCS11_CKK_SHA224_HMAC: 1805512cbf1dSJens Wiklander case PKCS11_CKK_SHA256_HMAC: 1806512cbf1dSJens Wiklander case PKCS11_CKK_SHA384_HMAC: 1807512cbf1dSJens Wiklander case PKCS11_CKK_SHA512_HMAC: 1808512cbf1dSJens Wiklander break; 1809512cbf1dSJens Wiklander default: 1810512cbf1dSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1811512cbf1dSJens Wiklander } 1812512cbf1dSJens Wiklander 1813512cbf1dSJens Wiklander /* Get key size */ 1814512cbf1dSJens Wiklander rc = get_u32_attribute(secret, PKCS11_CKA_VALUE_LEN, 1815512cbf1dSJens Wiklander &key_length); 1816512cbf1dSJens Wiklander if (rc) 1817d1d44372SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCOMPLETE; 1818512cbf1dSJens Wiklander } 1819013934d8SVesa Jääskeläinen if (public) { 1820013934d8SVesa Jääskeläinen switch (get_key_type(public)) { 182186922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 182286922832SVesa Jääskeläinen /* Get key size */ 182386922832SVesa Jääskeläinen rc = get_u32_attribute(public, PKCS11_CKA_MODULUS_BITS, 182486922832SVesa Jääskeläinen &key_length); 182586922832SVesa Jääskeläinen if (rc) 182686922832SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 182786922832SVesa Jääskeläinen key_length = ROUNDUP(key_length, 8) / 8; 182886922832SVesa Jääskeläinen break; 182902b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 183003e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 183102b16804SVesa Jääskeläinen break; 1832013934d8SVesa Jääskeläinen default: 1833013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1834013934d8SVesa Jääskeläinen } 1835013934d8SVesa Jääskeläinen } 1836013934d8SVesa Jääskeläinen if (private) { 1837013934d8SVesa Jääskeläinen switch (get_key_type(private)) { 183886922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 183902b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 184003e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 184102b16804SVesa Jääskeläinen break; 1842013934d8SVesa Jääskeläinen default: 1843013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1844013934d8SVesa Jääskeläinen } 1845013934d8SVesa Jääskeläinen } 1846512cbf1dSJens Wiklander 184702b16804SVesa Jääskeläinen /* 184802b16804SVesa Jääskeläinen * Check key size for symmetric keys and RSA keys 184902b16804SVesa Jääskeläinen * EC is bound to domains, no need to check here. 185002b16804SVesa Jääskeläinen */ 185102b16804SVesa Jääskeläinen switch (get_key_type(key1)) { 185202b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 185303e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 185402b16804SVesa Jääskeläinen return PKCS11_CKR_OK; 185502b16804SVesa Jääskeläinen default: 185602b16804SVesa Jääskeläinen break; 185702b16804SVesa Jääskeläinen } 185802b16804SVesa Jääskeläinen 1859512cbf1dSJens Wiklander get_key_min_max_sizes(get_key_type(key1), &min_key_size, &max_key_size); 1860512cbf1dSJens Wiklander if (key_length < min_key_size || key_length > max_key_size) { 1861512cbf1dSJens Wiklander EMSG("Length %"PRIu32" vs range [%"PRIu32" %"PRIu32"]", 1862512cbf1dSJens Wiklander key_length, min_key_size, max_key_size); 1863512cbf1dSJens Wiklander 1864512cbf1dSJens Wiklander return PKCS11_CKR_KEY_SIZE_RANGE; 1865512cbf1dSJens Wiklander } 1866512cbf1dSJens Wiklander 186749ed60abSRuchika Gupta if (secret && get_key_type(secret) == PKCS11_CKK_AES) { 186849ed60abSRuchika Gupta if (key_length != 16 && key_length != 24 && key_length != 32) 186949ed60abSRuchika Gupta return PKCS11_CKR_KEY_SIZE_RANGE; 187049ed60abSRuchika Gupta } 187149ed60abSRuchika Gupta 1872512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1873512cbf1dSJens Wiklander } 1874512cbf1dSJens Wiklander 1875512cbf1dSJens Wiklander /* Check processing ID against attribute ALLOWED_MECHANISMS if any */ 1876512cbf1dSJens Wiklander static bool parent_key_complies_allowed_processings(uint32_t proc_id, 1877512cbf1dSJens Wiklander struct obj_attrs *head) 1878512cbf1dSJens Wiklander { 1879512cbf1dSJens Wiklander char *attr = NULL; 1880512cbf1dSJens Wiklander uint32_t size = 0; 1881512cbf1dSJens Wiklander uint32_t proc = 0; 1882512cbf1dSJens Wiklander size_t count = 0; 18836a760c9eSEtienne Carriere enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 1884512cbf1dSJens Wiklander 18856a760c9eSEtienne Carriere rc = get_attribute_ptr(head, PKCS11_CKA_ALLOWED_MECHANISMS, 18866a760c9eSEtienne Carriere (void *)&attr, &size); 18876a760c9eSEtienne Carriere if (rc == PKCS11_RV_NOT_FOUND) 1888512cbf1dSJens Wiklander return true; 18896a760c9eSEtienne Carriere if (rc) { 18906a760c9eSEtienne Carriere EMSG("unexpected attributes state"); 18916a760c9eSEtienne Carriere TEE_Panic(TEE_ERROR_BAD_STATE); 1892512cbf1dSJens Wiklander } 1893512cbf1dSJens Wiklander 1894512cbf1dSJens Wiklander for (count = size / sizeof(uint32_t); count; count--) { 1895512cbf1dSJens Wiklander TEE_MemMove(&proc, attr, sizeof(uint32_t)); 1896512cbf1dSJens Wiklander attr += sizeof(uint32_t); 1897512cbf1dSJens Wiklander 1898512cbf1dSJens Wiklander if (proc == proc_id) 1899512cbf1dSJens Wiklander return true; 1900512cbf1dSJens Wiklander } 1901512cbf1dSJens Wiklander 1902512cbf1dSJens Wiklander DMSG("can't find %s in allowed list", id2str_proc(proc_id)); 1903512cbf1dSJens Wiklander return false; 1904512cbf1dSJens Wiklander } 1905512cbf1dSJens Wiklander 1906512cbf1dSJens Wiklander static enum pkcs11_attr_id func_to_attr(enum processing_func func) 1907512cbf1dSJens Wiklander { 1908512cbf1dSJens Wiklander switch (func) { 1909512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 1910512cbf1dSJens Wiklander return PKCS11_CKA_ENCRYPT; 1911512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 1912512cbf1dSJens Wiklander return PKCS11_CKA_DECRYPT; 1913512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN: 1914512cbf1dSJens Wiklander return PKCS11_CKA_SIGN; 1915512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY: 1916512cbf1dSJens Wiklander return PKCS11_CKA_VERIFY; 1917512cbf1dSJens Wiklander case PKCS11_FUNCTION_WRAP: 1918512cbf1dSJens Wiklander return PKCS11_CKA_WRAP; 1919512cbf1dSJens Wiklander case PKCS11_FUNCTION_UNWRAP: 1920512cbf1dSJens Wiklander return PKCS11_CKA_UNWRAP; 1921512cbf1dSJens Wiklander case PKCS11_FUNCTION_DERIVE: 1922512cbf1dSJens Wiklander return PKCS11_CKA_DERIVE; 1923512cbf1dSJens Wiklander default: 1924512cbf1dSJens Wiklander return PKCS11_CKA_UNDEFINED_ID; 1925512cbf1dSJens Wiklander } 1926512cbf1dSJens Wiklander } 1927512cbf1dSJens Wiklander 1928512cbf1dSJens Wiklander enum pkcs11_rc 1929512cbf1dSJens Wiklander check_parent_attrs_against_processing(enum pkcs11_mechanism_id proc_id, 1930512cbf1dSJens Wiklander enum processing_func function, 1931512cbf1dSJens Wiklander struct obj_attrs *head) 1932512cbf1dSJens Wiklander { 1933512cbf1dSJens Wiklander enum pkcs11_class_id key_class = get_class(head); 1934512cbf1dSJens Wiklander enum pkcs11_key_type key_type = get_key_type(head); 1935512cbf1dSJens Wiklander enum pkcs11_attr_id attr = func_to_attr(function); 1936512cbf1dSJens Wiklander 1937512cbf1dSJens Wiklander if (!get_bool(head, attr)) { 1938512cbf1dSJens Wiklander DMSG("%s not permitted", id2str_attr(attr)); 1939512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1940512cbf1dSJens Wiklander } 1941512cbf1dSJens Wiklander 1942512cbf1dSJens Wiklander /* Check processing complies with parent key family */ 1943512cbf1dSJens Wiklander switch (proc_id) { 1944512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 1945512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 1946512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 1947512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 19480ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC: 19490ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC_GENERAL: 1950512cbf1dSJens Wiklander if (key_class == PKCS11_CKO_SECRET_KEY && 1951512cbf1dSJens Wiklander key_type == PKCS11_CKK_AES) 1952512cbf1dSJens Wiklander break; 1953512cbf1dSJens Wiklander 1954512cbf1dSJens Wiklander DMSG("%s invalid key %s/%s", id2str_proc(proc_id), 1955512cbf1dSJens Wiklander id2str_class(key_class), id2str_key_type(key_type)); 1956512cbf1dSJens Wiklander 19575f80f270SRuchika Gupta if (function == PKCS11_FUNCTION_WRAP) 19585f80f270SRuchika Gupta return PKCS11_CKR_WRAPPING_KEY_TYPE_INCONSISTENT; 1959e3f0cb56SRuchika Gupta else if (function == PKCS11_FUNCTION_UNWRAP) 1960e3f0cb56SRuchika Gupta return PKCS11_CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT; 19615f80f270SRuchika Gupta else 1962512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1963512cbf1dSJens Wiklander 1964c3033708SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 1965c3033708SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 1966c3033708SRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY && 1967c3033708SRuchika Gupta key_type != PKCS11_CKK_AES) 1968c3033708SRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1969c3033708SRuchika Gupta 1970c3033708SRuchika Gupta if (get_bool(head, PKCS11_CKA_ENCRYPT)) { 1971c3033708SRuchika Gupta /* 1972c3033708SRuchika Gupta * Intentionally refuse to proceed despite 1973c3033708SRuchika Gupta * PKCS#11 specifications v2.40 and v3.0 not expecting 1974c3033708SRuchika Gupta * this behavior to avoid potential security issue 1975c3033708SRuchika Gupta * where keys derived by these mechanisms can be 1976c3033708SRuchika Gupta * revealed by doing data encryption using parent key. 1977c3033708SRuchika Gupta */ 1978c3033708SRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED; 1979c3033708SRuchika Gupta } 1980c3033708SRuchika Gupta 1981c3033708SRuchika Gupta break; 1982689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 1983689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 1984689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 1985689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 1986689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 1987689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 198870b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 198970b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 199070b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 199170b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 199270b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 199370b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 1994689f4e5bSRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY) 1995689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1996689f4e5bSRuchika Gupta 1997689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_GENERIC_SECRET) 1998689f4e5bSRuchika Gupta break; 1999689f4e5bSRuchika Gupta 2000689f4e5bSRuchika Gupta switch (proc_id) { 2001689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 200270b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 2003689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_MD5_HMAC) 2004689f4e5bSRuchika Gupta break; 2005689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 2006689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 200770b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 2008689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA_1_HMAC) 2009689f4e5bSRuchika Gupta break; 2010689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 2011689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 201270b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 2013689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA224_HMAC) 2014689f4e5bSRuchika Gupta break; 2015689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 2016689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 201770b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 2018689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA256_HMAC) 2019689f4e5bSRuchika Gupta break; 2020689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 2021689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 202270b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 2023689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA384_HMAC) 2024689f4e5bSRuchika Gupta break; 2025689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 2026689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 202770b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 2028689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA512_HMAC) 2029689f4e5bSRuchika Gupta break; 2030689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 2031689f4e5bSRuchika Gupta default: 2032689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 2033689f4e5bSRuchika Gupta } 2034689f4e5bSRuchika Gupta break; 2035689f4e5bSRuchika Gupta 203603e07432SValerii Chubar case PKCS11_CKM_EDDSA: 203703e07432SValerii Chubar if (key_type != PKCS11_CKK_EC_EDWARDS) { 203803e07432SValerii Chubar EMSG("Invalid key %s for mechanism %s", 203903e07432SValerii Chubar id2str_type(key_type, key_class), 204003e07432SValerii Chubar id2str_proc(proc_id)); 204103e07432SValerii Chubar return PKCS11_CKR_KEY_TYPE_INCONSISTENT; 204203e07432SValerii Chubar } 204303e07432SValerii Chubar if (key_class != PKCS11_CKO_PUBLIC_KEY && 204403e07432SValerii Chubar key_class != PKCS11_CKO_PRIVATE_KEY) { 204503e07432SValerii Chubar EMSG("Invalid key class for mechanism %s", 204603e07432SValerii Chubar id2str_proc(proc_id)); 204703e07432SValerii Chubar 204803e07432SValerii Chubar return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 204903e07432SValerii Chubar } 205003e07432SValerii Chubar break; 205103e07432SValerii Chubar 2052fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 2053fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 2054fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 2055fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 2056fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 2057fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 2058cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 2059fb279d8bSVesa Jääskeläinen if (key_type != PKCS11_CKK_EC) { 2060fb279d8bSVesa Jääskeläinen EMSG("Invalid key %s for mechanism %s", 2061fb279d8bSVesa Jääskeläinen id2str_type(key_type, key_class), 2062fb279d8bSVesa Jääskeläinen id2str_proc(proc_id)); 2063fb279d8bSVesa Jääskeläinen 2064fb279d8bSVesa Jääskeläinen return PKCS11_CKR_KEY_TYPE_INCONSISTENT; 2065fb279d8bSVesa Jääskeläinen } 2066fb279d8bSVesa Jääskeläinen if (key_class != PKCS11_CKO_PUBLIC_KEY && 2067fb279d8bSVesa Jääskeläinen key_class != PKCS11_CKO_PRIVATE_KEY) { 2068fb279d8bSVesa Jääskeläinen EMSG("Invalid key class for mechanism %s", 2069fb279d8bSVesa Jääskeläinen id2str_proc(proc_id)); 2070fb279d8bSVesa Jääskeläinen 2071fb279d8bSVesa Jääskeläinen return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 2072fb279d8bSVesa Jääskeläinen } 2073fb279d8bSVesa Jääskeläinen break; 20740442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 20750442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 20760442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 20770442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 20780442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 20790442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 20800442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 208145d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP: 2082dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 2083d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 2084d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 2085d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 2086d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 2087d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 2088d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 20890442c956SVesa Jääskeläinen if (key_type != PKCS11_CKK_RSA) { 20900442c956SVesa Jääskeläinen EMSG("Invalid key %s for mechanism %s", 20910442c956SVesa Jääskeläinen id2str_type(key_type, key_class), 20920442c956SVesa Jääskeläinen id2str_proc(proc_id)); 20930442c956SVesa Jääskeläinen 20940442c956SVesa Jääskeläinen return PKCS11_CKR_KEY_TYPE_INCONSISTENT; 20950442c956SVesa Jääskeläinen } 20960442c956SVesa Jääskeläinen if (key_class != PKCS11_CKO_PUBLIC_KEY && 20970442c956SVesa Jääskeläinen key_class != PKCS11_CKO_PRIVATE_KEY) { 20980442c956SVesa Jääskeläinen EMSG("Invalid key class for mechanism %s", 20990442c956SVesa Jääskeläinen id2str_proc(proc_id)); 21000442c956SVesa Jääskeläinen 21010442c956SVesa Jääskeläinen return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 21020442c956SVesa Jääskeläinen } 21030442c956SVesa Jääskeläinen break; 2104512cbf1dSJens Wiklander default: 2105512cbf1dSJens Wiklander DMSG("Invalid processing %#"PRIx32"/%s", proc_id, 2106512cbf1dSJens Wiklander id2str_proc(proc_id)); 2107512cbf1dSJens Wiklander 2108512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_INVALID; 2109512cbf1dSJens Wiklander } 2110512cbf1dSJens Wiklander 2111512cbf1dSJens Wiklander if (!parent_key_complies_allowed_processings(proc_id, head)) { 2112512cbf1dSJens Wiklander DMSG("Allowed mechanism failed"); 2113512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 2114512cbf1dSJens Wiklander } 2115512cbf1dSJens Wiklander 2116512cbf1dSJens Wiklander return PKCS11_CKR_OK; 2117512cbf1dSJens Wiklander } 2118783c1515SRuchika Gupta 2119783c1515SRuchika Gupta bool attribute_is_exportable(struct pkcs11_attribute_head *req_attr, 2120783c1515SRuchika Gupta struct pkcs11_object *obj) 2121783c1515SRuchika Gupta { 2122783c1515SRuchika Gupta uint8_t boolval = 0; 2123783c1515SRuchika Gupta uint32_t boolsize = 0; 2124783c1515SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 2125783c1515SRuchika Gupta enum pkcs11_class_id key_class = get_class(obj->attributes); 2126783c1515SRuchika Gupta 2127981966bcSVesa Jääskeläinen if (attribute_is_hidden(req_attr)) 2128981966bcSVesa Jääskeläinen return false; 2129981966bcSVesa Jääskeläinen 2130783c1515SRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY && 2131783c1515SRuchika Gupta key_class != PKCS11_CKO_PRIVATE_KEY) 2132783c1515SRuchika Gupta return true; 2133783c1515SRuchika Gupta 2134783c1515SRuchika Gupta switch (req_attr->id) { 2135783c1515SRuchika Gupta case PKCS11_CKA_PRIVATE_EXPONENT: 2136783c1515SRuchika Gupta case PKCS11_CKA_PRIME_1: 2137783c1515SRuchika Gupta case PKCS11_CKA_PRIME_2: 2138783c1515SRuchika Gupta case PKCS11_CKA_EXPONENT_1: 2139783c1515SRuchika Gupta case PKCS11_CKA_EXPONENT_2: 2140783c1515SRuchika Gupta case PKCS11_CKA_COEFFICIENT: 2141783c1515SRuchika Gupta case PKCS11_CKA_VALUE: 2142783c1515SRuchika Gupta boolsize = sizeof(boolval); 2143783c1515SRuchika Gupta rc = get_attribute(obj->attributes, PKCS11_CKA_EXTRACTABLE, 2144783c1515SRuchika Gupta &boolval, &boolsize); 2145783c1515SRuchika Gupta if (rc || boolval == PKCS11_FALSE) 2146783c1515SRuchika Gupta return false; 2147783c1515SRuchika Gupta 2148783c1515SRuchika Gupta boolsize = sizeof(boolval); 2149783c1515SRuchika Gupta rc = get_attribute(obj->attributes, PKCS11_CKA_SENSITIVE, 2150783c1515SRuchika Gupta &boolval, &boolsize); 2151783c1515SRuchika Gupta if (rc || boolval == PKCS11_TRUE) 2152783c1515SRuchika Gupta return false; 2153783c1515SRuchika Gupta break; 2154783c1515SRuchika Gupta default: 2155783c1515SRuchika Gupta break; 2156783c1515SRuchika Gupta } 2157783c1515SRuchika Gupta 2158783c1515SRuchika Gupta return true; 2159783c1515SRuchika Gupta } 21602d25a9bcSRuchika Gupta 21612d25a9bcSRuchika Gupta static bool attr_is_modifiable_any_key(struct pkcs11_attribute_head *attr) 21622d25a9bcSRuchika Gupta { 21632d25a9bcSRuchika Gupta switch (attr->id) { 21642d25a9bcSRuchika Gupta case PKCS11_CKA_ID: 21652d25a9bcSRuchika Gupta case PKCS11_CKA_START_DATE: 21662d25a9bcSRuchika Gupta case PKCS11_CKA_END_DATE: 21672d25a9bcSRuchika Gupta case PKCS11_CKA_DERIVE: 21682d25a9bcSRuchika Gupta return true; 21692d25a9bcSRuchika Gupta default: 21702d25a9bcSRuchika Gupta return false; 21712d25a9bcSRuchika Gupta } 21722d25a9bcSRuchika Gupta } 21732d25a9bcSRuchika Gupta 21742d25a9bcSRuchika Gupta static bool attr_is_modifiable_secret_key(struct pkcs11_attribute_head *attr, 21752d25a9bcSRuchika Gupta struct pkcs11_session *session, 21762d25a9bcSRuchika Gupta struct pkcs11_object *obj) 21772d25a9bcSRuchika Gupta { 21782d25a9bcSRuchika Gupta switch (attr->id) { 21792d25a9bcSRuchika Gupta case PKCS11_CKA_ENCRYPT: 21802d25a9bcSRuchika Gupta case PKCS11_CKA_DECRYPT: 21812d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN: 21822d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY: 21832d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP: 21842d25a9bcSRuchika Gupta case PKCS11_CKA_UNWRAP: 2185bcac2127SMarouene Boubakri case PKCS11_CKA_CHECK_VALUE: 21862d25a9bcSRuchika Gupta return true; 21872d25a9bcSRuchika Gupta /* Can't be modified once set to CK_FALSE - 12 in Table 10 */ 21882d25a9bcSRuchika Gupta case PKCS11_CKA_EXTRACTABLE: 21892d25a9bcSRuchika Gupta return get_bool(obj->attributes, attr->id); 21902d25a9bcSRuchika Gupta /* Can't be modified once set to CK_TRUE - 11 in Table 10 */ 21912d25a9bcSRuchika Gupta case PKCS11_CKA_SENSITIVE: 21922d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP_WITH_TRUSTED: 21932d25a9bcSRuchika Gupta return !get_bool(obj->attributes, attr->id); 21942d25a9bcSRuchika Gupta /* Change in CKA_TRUSTED can only be done by SO */ 21952d25a9bcSRuchika Gupta case PKCS11_CKA_TRUSTED: 21962d25a9bcSRuchika Gupta return pkcs11_session_is_so(session); 21972d25a9bcSRuchika Gupta case PKCS11_CKA_NEVER_EXTRACTABLE: 21982d25a9bcSRuchika Gupta case PKCS11_CKA_ALWAYS_SENSITIVE: 21992d25a9bcSRuchika Gupta return false; 22002d25a9bcSRuchika Gupta default: 22012d25a9bcSRuchika Gupta return false; 22022d25a9bcSRuchika Gupta } 22032d25a9bcSRuchika Gupta } 22042d25a9bcSRuchika Gupta 22052d25a9bcSRuchika Gupta static bool attr_is_modifiable_public_key(struct pkcs11_attribute_head *attr, 22062d25a9bcSRuchika Gupta struct pkcs11_session *session, 22072d25a9bcSRuchika Gupta struct pkcs11_object *obj __unused) 22082d25a9bcSRuchika Gupta { 22092d25a9bcSRuchika Gupta switch (attr->id) { 22102d25a9bcSRuchika Gupta case PKCS11_CKA_SUBJECT: 22112d25a9bcSRuchika Gupta case PKCS11_CKA_ENCRYPT: 22122d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY: 22132d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY_RECOVER: 22142d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP: 22152d25a9bcSRuchika Gupta return true; 22162d25a9bcSRuchika Gupta case PKCS11_CKA_TRUSTED: 22172d25a9bcSRuchika Gupta /* Change in CKA_TRUSTED can only be done by SO */ 22182d25a9bcSRuchika Gupta return pkcs11_session_is_so(session); 22192d25a9bcSRuchika Gupta default: 22202d25a9bcSRuchika Gupta return false; 22212d25a9bcSRuchika Gupta } 22222d25a9bcSRuchika Gupta } 22232d25a9bcSRuchika Gupta 22242d25a9bcSRuchika Gupta static bool attr_is_modifiable_private_key(struct pkcs11_attribute_head *attr, 22252d25a9bcSRuchika Gupta struct pkcs11_session *sess __unused, 22262d25a9bcSRuchika Gupta struct pkcs11_object *obj) 22272d25a9bcSRuchika Gupta { 22282d25a9bcSRuchika Gupta switch (attr->id) { 22292d25a9bcSRuchika Gupta case PKCS11_CKA_SUBJECT: 22302d25a9bcSRuchika Gupta case PKCS11_CKA_DECRYPT: 22312d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN: 22322d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN_RECOVER: 22332d25a9bcSRuchika Gupta case PKCS11_CKA_UNWRAP: 22342d25a9bcSRuchika Gupta /* 22352d25a9bcSRuchika Gupta * TBD: Revisit if we don't support PKCS11_CKA_PUBLIC_KEY_INFO 22362d25a9bcSRuchika Gupta * Specification mentions that if this attribute is 22372d25a9bcSRuchika Gupta * supplied as part of a template for C_CreateObject, C_CopyObject or 22382d25a9bcSRuchika Gupta * C_SetAttributeValue for a private key, the token MUST verify 22392d25a9bcSRuchika Gupta * correspondence between the private key data and the public key data 22402d25a9bcSRuchika Gupta * as supplied in CKA_PUBLIC_KEY_INFO. This needs to be 22412d25a9bcSRuchika Gupta * taken care of when this object type will be implemented 22422d25a9bcSRuchika Gupta */ 22432d25a9bcSRuchika Gupta case PKCS11_CKA_PUBLIC_KEY_INFO: 22442d25a9bcSRuchika Gupta return true; 22452d25a9bcSRuchika Gupta /* Can't be modified once set to CK_FALSE - 12 in Table 10 */ 22462d25a9bcSRuchika Gupta case PKCS11_CKA_EXTRACTABLE: 22472d25a9bcSRuchika Gupta return get_bool(obj->attributes, attr->id); 22482d25a9bcSRuchika Gupta /* Can't be modified once set to CK_TRUE - 11 in Table 10 */ 22492d25a9bcSRuchika Gupta case PKCS11_CKA_SENSITIVE: 22502d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP_WITH_TRUSTED: 22512d25a9bcSRuchika Gupta return !get_bool(obj->attributes, attr->id); 22522d25a9bcSRuchika Gupta case PKCS11_CKA_NEVER_EXTRACTABLE: 22532d25a9bcSRuchika Gupta case PKCS11_CKA_ALWAYS_SENSITIVE: 22542d25a9bcSRuchika Gupta return false; 22552d25a9bcSRuchika Gupta default: 22562d25a9bcSRuchika Gupta return false; 22572d25a9bcSRuchika Gupta } 22582d25a9bcSRuchika Gupta } 22592d25a9bcSRuchika Gupta 22604137952dSVesa Jääskeläinen static bool attr_is_modifiable_certificate(struct pkcs11_attribute_head *attr, 22614137952dSVesa Jääskeläinen struct pkcs11_session *session, 22624137952dSVesa Jääskeläinen struct pkcs11_object *obj) 22634137952dSVesa Jääskeläinen { 22644137952dSVesa Jääskeläinen uint8_t boolval = 0; 22654137952dSVesa Jääskeläinen uint32_t boolsize = 0; 22664137952dSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 22674137952dSVesa Jääskeläinen 22684137952dSVesa Jääskeläinen /* Trusted certificates cannot be modified. */ 22694137952dSVesa Jääskeläinen rc = get_attribute(obj->attributes, PKCS11_CKA_TRUSTED, 22704137952dSVesa Jääskeläinen &boolval, &boolsize); 22714137952dSVesa Jääskeläinen if (rc || boolval == PKCS11_TRUE) 22724137952dSVesa Jääskeläinen return false; 22734137952dSVesa Jääskeläinen 22744137952dSVesa Jääskeläinen /* Common certificate attributes */ 22754137952dSVesa Jääskeläinen switch (attr->id) { 22764137952dSVesa Jääskeläinen case PKCS11_CKA_TRUSTED: 22774137952dSVesa Jääskeläinen /* 22784137952dSVesa Jääskeläinen * The CKA_TRUSTED attribute cannot be set to CK_TRUE by an 22794137952dSVesa Jääskeläinen * application. It MUST be set by a token initialization 22804137952dSVesa Jääskeläinen * application or by the token’s SO. 22814137952dSVesa Jääskeläinen */ 22824137952dSVesa Jääskeläinen return pkcs11_session_is_so(session); 22834137952dSVesa Jääskeläinen case PKCS11_CKA_CERTIFICATE_TYPE: 22844137952dSVesa Jääskeläinen case PKCS11_CKA_CERTIFICATE_CATEGORY: 22854137952dSVesa Jääskeläinen return false; 22864137952dSVesa Jääskeläinen default: 22874137952dSVesa Jääskeläinen break; 22884137952dSVesa Jääskeläinen } 22894137952dSVesa Jääskeläinen 22904137952dSVesa Jääskeläinen /* Certificate type specific attributes */ 22914137952dSVesa Jääskeläinen switch (get_certificate_type(obj->attributes)) { 22924137952dSVesa Jääskeläinen case PKCS11_CKC_X_509: 22934137952dSVesa Jääskeläinen /* 22944137952dSVesa Jääskeläinen * Only the CKA_ID, CKA_ISSUER, and CKA_SERIAL_NUMBER 22954137952dSVesa Jääskeläinen * attributes may be modified after the object is created. 22964137952dSVesa Jääskeläinen */ 22974137952dSVesa Jääskeläinen switch (attr->id) { 22984137952dSVesa Jääskeläinen case PKCS11_CKA_ID: 22994137952dSVesa Jääskeläinen case PKCS11_CKA_ISSUER: 23004137952dSVesa Jääskeläinen case PKCS11_CKA_SERIAL_NUMBER: 23014137952dSVesa Jääskeläinen return true; 23024137952dSVesa Jääskeläinen default: 23034137952dSVesa Jääskeläinen break; 23044137952dSVesa Jääskeläinen } 23054137952dSVesa Jääskeläinen break; 23064137952dSVesa Jääskeläinen default: 23074137952dSVesa Jääskeläinen /* Unsupported certificate type */ 23084137952dSVesa Jääskeläinen break; 23094137952dSVesa Jääskeläinen } 23104137952dSVesa Jääskeläinen 23114137952dSVesa Jääskeläinen return false; 23124137952dSVesa Jääskeläinen } 23134137952dSVesa Jääskeläinen 23142d25a9bcSRuchika Gupta static bool attribute_is_modifiable(struct pkcs11_session *session, 23152d25a9bcSRuchika Gupta struct pkcs11_attribute_head *req_attr, 23162d25a9bcSRuchika Gupta struct pkcs11_object *obj, 23172d25a9bcSRuchika Gupta enum pkcs11_class_id class, 23182d25a9bcSRuchika Gupta enum processing_func function) 23192d25a9bcSRuchika Gupta { 23202d25a9bcSRuchika Gupta /* Check modifiable attributes common to any object */ 23212d25a9bcSRuchika Gupta switch (req_attr->id) { 23222d25a9bcSRuchika Gupta case PKCS11_CKA_LABEL: 23232d25a9bcSRuchika Gupta return true; 23242d25a9bcSRuchika Gupta case PKCS11_CKA_TOKEN: 23252d25a9bcSRuchika Gupta case PKCS11_CKA_MODIFIABLE: 23262d25a9bcSRuchika Gupta case PKCS11_CKA_DESTROYABLE: 23272d25a9bcSRuchika Gupta case PKCS11_CKA_PRIVATE: 23282d25a9bcSRuchika Gupta return function == PKCS11_FUNCTION_COPY; 23292d25a9bcSRuchika Gupta case PKCS11_CKA_COPYABLE: 23302d25a9bcSRuchika Gupta /* 23312d25a9bcSRuchika Gupta * Specification mentions that if the attribute value is false 23322d25a9bcSRuchika Gupta * it can't be set to true. Reading this we assume that it 23332d25a9bcSRuchika Gupta * should be possible to modify this attribute even though this 23342d25a9bcSRuchika Gupta * is not marked as modifiable in Table 10 if done in right 23352d25a9bcSRuchika Gupta * direction i.e from TRUE -> FALSE. 23362d25a9bcSRuchika Gupta */ 23372d25a9bcSRuchika Gupta return get_bool(obj->attributes, req_attr->id); 23382d25a9bcSRuchika Gupta default: 23392d25a9bcSRuchika Gupta break; 23402d25a9bcSRuchika Gupta } 23412d25a9bcSRuchika Gupta 23422d25a9bcSRuchika Gupta /* Attribute checking based on class type */ 23432d25a9bcSRuchika Gupta switch (class) { 23442d25a9bcSRuchika Gupta case PKCS11_CKO_SECRET_KEY: 23452d25a9bcSRuchika Gupta case PKCS11_CKO_PUBLIC_KEY: 23462d25a9bcSRuchika Gupta case PKCS11_CKO_PRIVATE_KEY: 23472d25a9bcSRuchika Gupta if (attr_is_modifiable_any_key(req_attr)) 23482d25a9bcSRuchika Gupta return true; 23492d25a9bcSRuchika Gupta if (class == PKCS11_CKO_SECRET_KEY && 23502d25a9bcSRuchika Gupta attr_is_modifiable_secret_key(req_attr, session, obj)) 23512d25a9bcSRuchika Gupta return true; 23522d25a9bcSRuchika Gupta if (class == PKCS11_CKO_PUBLIC_KEY && 23532d25a9bcSRuchika Gupta attr_is_modifiable_public_key(req_attr, session, obj)) 23542d25a9bcSRuchika Gupta return true; 23552d25a9bcSRuchika Gupta if (class == PKCS11_CKO_PRIVATE_KEY && 23562d25a9bcSRuchika Gupta attr_is_modifiable_private_key(req_attr, session, obj)) 23572d25a9bcSRuchika Gupta return true; 23582d25a9bcSRuchika Gupta break; 23592d25a9bcSRuchika Gupta case PKCS11_CKO_DATA: 23602d25a9bcSRuchika Gupta /* None of the data object attributes are modifiable */ 23612d25a9bcSRuchika Gupta return false; 23624137952dSVesa Jääskeläinen case PKCS11_CKO_CERTIFICATE: 23634137952dSVesa Jääskeläinen return attr_is_modifiable_certificate(req_attr, session, obj); 23642d25a9bcSRuchika Gupta default: 23652d25a9bcSRuchika Gupta break; 23662d25a9bcSRuchika Gupta } 23672d25a9bcSRuchika Gupta 23682d25a9bcSRuchika Gupta return false; 23692d25a9bcSRuchika Gupta } 23702d25a9bcSRuchika Gupta 23712d25a9bcSRuchika Gupta enum pkcs11_rc check_attrs_against_modification(struct pkcs11_session *session, 23722d25a9bcSRuchika Gupta struct obj_attrs *head, 23732d25a9bcSRuchika Gupta struct pkcs11_object *obj, 23742d25a9bcSRuchika Gupta enum processing_func function) 23752d25a9bcSRuchika Gupta { 23762d25a9bcSRuchika Gupta enum pkcs11_class_id class = PKCS11_CKO_UNDEFINED_ID; 23772d25a9bcSRuchika Gupta char *cur = NULL; 23782d25a9bcSRuchika Gupta char *end = NULL; 23792d25a9bcSRuchika Gupta size_t len = 0; 23802d25a9bcSRuchika Gupta 23812d25a9bcSRuchika Gupta class = get_class(obj->attributes); 23822d25a9bcSRuchika Gupta 23832d25a9bcSRuchika Gupta cur = (char *)head + sizeof(struct obj_attrs); 23842d25a9bcSRuchika Gupta end = cur + head->attrs_size; 23852d25a9bcSRuchika Gupta 23862d25a9bcSRuchika Gupta for (; cur < end; cur += len) { 23872d25a9bcSRuchika Gupta /* Structure aligned copy of the pkcs11_ref in the object */ 23882d25a9bcSRuchika Gupta struct pkcs11_attribute_head cli_ref = { }; 23892d25a9bcSRuchika Gupta 23902d25a9bcSRuchika Gupta TEE_MemMove(&cli_ref, cur, sizeof(cli_ref)); 23912d25a9bcSRuchika Gupta len = sizeof(cli_ref) + cli_ref.size; 23922d25a9bcSRuchika Gupta 2393981966bcSVesa Jääskeläinen /* Protect hidden attributes */ 2394981966bcSVesa Jääskeläinen if (attribute_is_hidden(&cli_ref)) 2395981966bcSVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 2396981966bcSVesa Jääskeläinen 23972d25a9bcSRuchika Gupta /* 23982d25a9bcSRuchika Gupta * Check 1 - Check if attribute belongs to the object 23992d25a9bcSRuchika Gupta * The obj->attributes has all the attributes in 24002d25a9bcSRuchika Gupta * it which are allowed for an object. 24012d25a9bcSRuchika Gupta */ 24022d25a9bcSRuchika Gupta if (get_attribute_ptr(obj->attributes, cli_ref.id, NULL, 24032d25a9bcSRuchika Gupta NULL) == PKCS11_RV_NOT_FOUND) 24042d25a9bcSRuchika Gupta return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 24052d25a9bcSRuchika Gupta 24062d25a9bcSRuchika Gupta /* Check 2 - Is attribute modifiable */ 24072d25a9bcSRuchika Gupta if (!attribute_is_modifiable(session, &cli_ref, obj, class, 24082d25a9bcSRuchika Gupta function)) 24092d25a9bcSRuchika Gupta return PKCS11_CKR_ATTRIBUTE_READ_ONLY; 24102d25a9bcSRuchika Gupta 24112d25a9bcSRuchika Gupta /* 24122d25a9bcSRuchika Gupta * Checks for modification in PKCS11_CKA_TOKEN and 24132d25a9bcSRuchika Gupta * PKCS11_CKA_PRIVATE are required for PKCS11_FUNCTION_COPY 24142d25a9bcSRuchika Gupta * only, so skip them for PKCS11_FUNCTION_MODIFY. 24152d25a9bcSRuchika Gupta */ 24162d25a9bcSRuchika Gupta if (function == PKCS11_FUNCTION_MODIFY) 24172d25a9bcSRuchika Gupta continue; 24182d25a9bcSRuchika Gupta 24192d25a9bcSRuchika Gupta /* 24202d25a9bcSRuchika Gupta * An attempt to copy an object to a token will fail for 24212d25a9bcSRuchika Gupta * RO session 24222d25a9bcSRuchika Gupta */ 24232d25a9bcSRuchika Gupta if (cli_ref.id == PKCS11_CKA_TOKEN && 24242d25a9bcSRuchika Gupta get_bool(head, PKCS11_CKA_TOKEN)) { 24252d25a9bcSRuchika Gupta if (!pkcs11_session_is_read_write(session)) { 24262d25a9bcSRuchika Gupta DMSG("Can't copy to token in a RO session"); 24272d25a9bcSRuchika Gupta return PKCS11_CKR_SESSION_READ_ONLY; 24282d25a9bcSRuchika Gupta } 24292d25a9bcSRuchika Gupta } 24302d25a9bcSRuchika Gupta 24312d25a9bcSRuchika Gupta if (cli_ref.id == PKCS11_CKA_PRIVATE) { 24322d25a9bcSRuchika Gupta bool parent_priv = 24332d25a9bcSRuchika Gupta get_bool(obj->attributes, cli_ref.id); 24342d25a9bcSRuchika Gupta bool obj_priv = get_bool(head, cli_ref.id); 24352d25a9bcSRuchika Gupta 24362d25a9bcSRuchika Gupta /* 24372d25a9bcSRuchika Gupta * If PKCS11_CKA_PRIVATE is being set to TRUE from 24382d25a9bcSRuchika Gupta * FALSE, user has to be logged in 24392d25a9bcSRuchika Gupta */ 24402d25a9bcSRuchika Gupta if (!parent_priv && obj_priv) { 24412d25a9bcSRuchika Gupta if ((pkcs11_session_is_public(session) || 24422d25a9bcSRuchika Gupta pkcs11_session_is_so(session))) 24432d25a9bcSRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 24442d25a9bcSRuchika Gupta } 2445df017b2bSRuchika Gupta 2446df017b2bSRuchika Gupta /* 2447df017b2bSRuchika Gupta * Restriction added - Even for Copy, do not allow 2448df017b2bSRuchika Gupta * modification of CKA_PRIVATE from TRUE to FALSE 2449df017b2bSRuchika Gupta */ 2450df017b2bSRuchika Gupta if (parent_priv && !obj_priv) 2451df017b2bSRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 24522d25a9bcSRuchika Gupta } 24532d25a9bcSRuchika Gupta } 24542d25a9bcSRuchika Gupta 24552d25a9bcSRuchika Gupta return PKCS11_CKR_OK; 24562d25a9bcSRuchika Gupta } 24578c499324SRuchika Gupta 24588c499324SRuchika Gupta static enum pkcs11_rc set_secret_key_data(struct obj_attrs **head, void *data, 24598c499324SRuchika Gupta size_t key_size) 24608c499324SRuchika Gupta { 24618c499324SRuchika Gupta uint32_t size = sizeof(uint32_t); 24628c499324SRuchika Gupta uint32_t key_length = 0; 24638c499324SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 24648c499324SRuchika Gupta 24658c499324SRuchika Gupta /* Get key size if present in template */ 24668c499324SRuchika Gupta rc = get_attribute(*head, PKCS11_CKA_VALUE_LEN, &key_length, &size); 24678c499324SRuchika Gupta if (rc && rc != PKCS11_RV_NOT_FOUND) 24688c499324SRuchika Gupta return rc; 24698c499324SRuchika Gupta 24708c499324SRuchika Gupta if (key_length) { 24718c499324SRuchika Gupta if (key_size < key_length) 24728c499324SRuchika Gupta return PKCS11_CKR_DATA_LEN_RANGE; 24738c499324SRuchika Gupta } else { 24748c499324SRuchika Gupta key_length = key_size; 24758c499324SRuchika Gupta rc = set_attribute(head, PKCS11_CKA_VALUE_LEN, &key_length, 24768c499324SRuchika Gupta sizeof(uint32_t)); 24778c499324SRuchika Gupta if (rc) 24788c499324SRuchika Gupta return rc; 24798c499324SRuchika Gupta } 24808c499324SRuchika Gupta 24818c499324SRuchika Gupta /* Now we can check the VALUE_LEN field */ 24828c499324SRuchika Gupta rc = check_created_attrs(*head, NULL); 24838c499324SRuchika Gupta if (rc) 24848c499324SRuchika Gupta return rc; 24858c499324SRuchika Gupta 24868c499324SRuchika Gupta /* Remove the default empty value attribute if found */ 24878c499324SRuchika Gupta rc = remove_empty_attribute(head, PKCS11_CKA_VALUE); 24888c499324SRuchika Gupta if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND) 24898c499324SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 24908c499324SRuchika Gupta 2491bcac2127SMarouene Boubakri rc = add_attribute(head, PKCS11_CKA_VALUE, data, key_length); 2492bcac2127SMarouene Boubakri if (rc) 2493bcac2127SMarouene Boubakri return rc; 2494bcac2127SMarouene Boubakri 2495bcac2127SMarouene Boubakri return set_check_value_attr(head); 24968c499324SRuchika Gupta } 24978c499324SRuchika Gupta 249845d40bdaSValerii Chubar static enum pkcs11_rc set_private_key_data_rsa(struct obj_attrs **head, 249945d40bdaSValerii Chubar void *data, 250045d40bdaSValerii Chubar size_t key_size) 250145d40bdaSValerii Chubar { 250245d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 250345d40bdaSValerii Chubar int mbedtls_rc = 0; 250445d40bdaSValerii Chubar uint32_t key_bits = 0; 250545d40bdaSValerii Chubar uint32_t size = 0; 250645d40bdaSValerii Chubar uint32_t buffer_size = 0; 250745d40bdaSValerii Chubar void *buffer = NULL; 250845d40bdaSValerii Chubar mbedtls_pk_context pk = { }; 250945d40bdaSValerii Chubar mbedtls_rsa_context *rsa = NULL; 251045d40bdaSValerii Chubar mbedtls_mpi n = { }; 251145d40bdaSValerii Chubar mbedtls_mpi e = { }; 251245d40bdaSValerii Chubar mbedtls_mpi d = { }; 251345d40bdaSValerii Chubar mbedtls_mpi p = { }; 251445d40bdaSValerii Chubar mbedtls_mpi q = { }; 251545d40bdaSValerii Chubar 251645d40bdaSValerii Chubar rc = get_u32_attribute(*head, PKCS11_CKA_MODULUS_BITS, &key_bits); 251745d40bdaSValerii Chubar if (rc && rc != PKCS11_RV_NOT_FOUND) 251845d40bdaSValerii Chubar return rc; 251945d40bdaSValerii Chubar 252045d40bdaSValerii Chubar if (remove_empty_attribute(head, PKCS11_CKA_MODULUS) || 252145d40bdaSValerii Chubar remove_empty_attribute(head, PKCS11_CKA_PUBLIC_EXPONENT) || 252245d40bdaSValerii Chubar remove_empty_attribute(head, PKCS11_CKA_PRIVATE_EXPONENT) || 252345d40bdaSValerii Chubar remove_empty_attribute(head, PKCS11_CKA_PRIME_1) || 252445d40bdaSValerii Chubar remove_empty_attribute(head, PKCS11_CKA_PRIME_2)) 252545d40bdaSValerii Chubar return PKCS11_CKR_GENERAL_ERROR; 252645d40bdaSValerii Chubar 252745d40bdaSValerii Chubar mbedtls_pk_init(&pk); 252845d40bdaSValerii Chubar mbedtls_mpi_init(&n); 252945d40bdaSValerii Chubar mbedtls_mpi_init(&e); 253045d40bdaSValerii Chubar mbedtls_mpi_init(&d); 253145d40bdaSValerii Chubar mbedtls_mpi_init(&p); 253245d40bdaSValerii Chubar mbedtls_mpi_init(&q); 253345d40bdaSValerii Chubar 253432b31808SJens Wiklander mbedtls_rc = mbedtls_pk_parse_key(&pk, data, key_size, 253532b31808SJens Wiklander NULL, 0, mbd_rand, NULL); 253645d40bdaSValerii Chubar if (mbedtls_rc) { 253745d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 253845d40bdaSValerii Chubar goto out; 253945d40bdaSValerii Chubar } 254045d40bdaSValerii Chubar 254145d40bdaSValerii Chubar rsa = mbedtls_pk_rsa(pk); 254245d40bdaSValerii Chubar mbedtls_rc = mbedtls_rsa_export(rsa, &n, &p, &q, &d, &e); 254345d40bdaSValerii Chubar if (mbedtls_rc) { 254445d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 254545d40bdaSValerii Chubar goto out; 254645d40bdaSValerii Chubar } 254745d40bdaSValerii Chubar 254845d40bdaSValerii Chubar if (key_bits && mbedtls_mpi_bitlen(&n) != key_bits) { 254945d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE; 255045d40bdaSValerii Chubar goto out; 255145d40bdaSValerii Chubar } 255245d40bdaSValerii Chubar 255345d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&n), 8); 255445d40bdaSValerii Chubar buffer_size = size; 255545d40bdaSValerii Chubar buffer = TEE_Malloc(buffer_size, TEE_USER_MEM_HINT_NO_FILL_ZERO); 255645d40bdaSValerii Chubar if (!buffer) { 255745d40bdaSValerii Chubar rc = PKCS11_CKR_DEVICE_MEMORY; 255845d40bdaSValerii Chubar goto out; 255945d40bdaSValerii Chubar } 256045d40bdaSValerii Chubar 256145d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&n, buffer, size); 256245d40bdaSValerii Chubar if (mbedtls_rc) { 256345d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 256445d40bdaSValerii Chubar goto out; 256545d40bdaSValerii Chubar } 256645d40bdaSValerii Chubar 256745d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_MODULUS, buffer, size); 256845d40bdaSValerii Chubar if (rc) 256945d40bdaSValerii Chubar goto out; 257045d40bdaSValerii Chubar 257145d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&e), 8); 257245d40bdaSValerii Chubar if (buffer_size < size) { 257345d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE; 257445d40bdaSValerii Chubar goto out; 257545d40bdaSValerii Chubar } 257645d40bdaSValerii Chubar 257745d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&e, buffer, size); 257845d40bdaSValerii Chubar if (mbedtls_rc) { 257945d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 258045d40bdaSValerii Chubar goto out; 258145d40bdaSValerii Chubar } 258245d40bdaSValerii Chubar 258345d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_PUBLIC_EXPONENT, buffer, size); 258445d40bdaSValerii Chubar if (rc) 258545d40bdaSValerii Chubar goto out; 258645d40bdaSValerii Chubar 258745d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&d), 8); 258845d40bdaSValerii Chubar if (buffer_size < size) { 258945d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE; 259045d40bdaSValerii Chubar goto out; 259145d40bdaSValerii Chubar } 259245d40bdaSValerii Chubar 259345d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&d, buffer, size); 259445d40bdaSValerii Chubar if (mbedtls_rc) { 259545d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 259645d40bdaSValerii Chubar goto out; 259745d40bdaSValerii Chubar } 259845d40bdaSValerii Chubar 259945d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_PRIVATE_EXPONENT, buffer, size); 260045d40bdaSValerii Chubar if (rc) 260145d40bdaSValerii Chubar goto out; 260245d40bdaSValerii Chubar 260345d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&p), 8); 260445d40bdaSValerii Chubar if (buffer_size < size) { 260545d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE; 260645d40bdaSValerii Chubar goto out; 260745d40bdaSValerii Chubar } 260845d40bdaSValerii Chubar 260945d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&p, buffer, size); 261045d40bdaSValerii Chubar if (mbedtls_rc) { 261145d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 261245d40bdaSValerii Chubar goto out; 261345d40bdaSValerii Chubar } 261445d40bdaSValerii Chubar 261545d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_PRIME_1, buffer, size); 261645d40bdaSValerii Chubar if (rc) 261745d40bdaSValerii Chubar goto out; 261845d40bdaSValerii Chubar 261945d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&q), 8); 262045d40bdaSValerii Chubar if (buffer_size < size) { 262145d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE; 262245d40bdaSValerii Chubar goto out; 262345d40bdaSValerii Chubar } 262445d40bdaSValerii Chubar 262545d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&q, buffer, size); 262645d40bdaSValerii Chubar if (mbedtls_rc) { 262745d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 262845d40bdaSValerii Chubar goto out; 262945d40bdaSValerii Chubar } 263045d40bdaSValerii Chubar 263145d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_PRIME_2, buffer, size); 263245d40bdaSValerii Chubar 263345d40bdaSValerii Chubar out: 263445d40bdaSValerii Chubar mbedtls_pk_free(&pk); 263545d40bdaSValerii Chubar mbedtls_mpi_free(&n); 263645d40bdaSValerii Chubar mbedtls_mpi_free(&e); 263745d40bdaSValerii Chubar mbedtls_mpi_free(&d); 263845d40bdaSValerii Chubar mbedtls_mpi_free(&p); 263945d40bdaSValerii Chubar mbedtls_mpi_free(&q); 264045d40bdaSValerii Chubar TEE_Free(buffer); 264145d40bdaSValerii Chubar return rc; 264245d40bdaSValerii Chubar } 264345d40bdaSValerii Chubar 26448c499324SRuchika Gupta enum pkcs11_rc set_key_data(struct obj_attrs **head, void *data, 26458c499324SRuchika Gupta size_t key_size) 26468c499324SRuchika Gupta { 26478c499324SRuchika Gupta switch (get_class(*head)) { 26488c499324SRuchika Gupta case PKCS11_CKO_SECRET_KEY: 26498c499324SRuchika Gupta return set_secret_key_data(head, data, key_size); 265045d40bdaSValerii Chubar case PKCS11_CKO_PRIVATE_KEY: 265145d40bdaSValerii Chubar if (get_key_type(*head) == PKCS11_CKK_RSA) 265245d40bdaSValerii Chubar return set_private_key_data_rsa(head, data, key_size); 265345d40bdaSValerii Chubar break; 26548c499324SRuchika Gupta default: 26558c499324SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 26568c499324SRuchika Gupta } 265745d40bdaSValerii Chubar 265845d40bdaSValerii Chubar return PKCS11_CKR_GENERAL_ERROR; 26598c499324SRuchika Gupta } 26605e1d94ebSVesa Jääskeläinen 2661a9aa45d8SValerii Chubar static enum pkcs11_rc alloc_copy_attribute_value(struct obj_attrs *head, 2662a9aa45d8SValerii Chubar void **data, uint32_t *sz) 2663a9aa45d8SValerii Chubar { 2664a9aa45d8SValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 2665a9aa45d8SValerii Chubar void *buffer = NULL; 2666a9aa45d8SValerii Chubar void *value = NULL; 2667a9aa45d8SValerii Chubar 2668a9aa45d8SValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_VALUE, &value, sz); 2669a9aa45d8SValerii Chubar if (rc) 2670a9aa45d8SValerii Chubar return PKCS11_CKR_ARGUMENTS_BAD; 2671a9aa45d8SValerii Chubar 2672a9aa45d8SValerii Chubar buffer = TEE_Malloc(*sz, TEE_USER_MEM_HINT_NO_FILL_ZERO); 2673a9aa45d8SValerii Chubar if (!buffer) 2674a9aa45d8SValerii Chubar return PKCS11_CKR_DEVICE_MEMORY; 2675a9aa45d8SValerii Chubar 2676a9aa45d8SValerii Chubar TEE_MemMove(buffer, value, *sz); 2677a9aa45d8SValerii Chubar *data = buffer; 2678a9aa45d8SValerii Chubar 2679a9aa45d8SValerii Chubar return PKCS11_CKR_OK; 2680a9aa45d8SValerii Chubar } 2681a9aa45d8SValerii Chubar 268245d40bdaSValerii Chubar static enum pkcs11_rc 268345d40bdaSValerii Chubar encode_rsa_private_key_der(struct obj_attrs *head, void **data, uint32_t *sz) 268445d40bdaSValerii Chubar { 268545d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 268645d40bdaSValerii Chubar int i = 0; 268745d40bdaSValerii Chubar int mbedtls_rc = 0; 268845d40bdaSValerii Chubar int start = 0; 268945d40bdaSValerii Chubar int der_size = 0; 269045d40bdaSValerii Chubar void *n = NULL; 269145d40bdaSValerii Chubar void *p = NULL; 269245d40bdaSValerii Chubar void *q = NULL; 269345d40bdaSValerii Chubar void *d = NULL; 269445d40bdaSValerii Chubar void *e = NULL; 269545d40bdaSValerii Chubar uint32_t n_len = 0; 269645d40bdaSValerii Chubar uint32_t p_len = 0; 269745d40bdaSValerii Chubar uint32_t q_len = 0; 269845d40bdaSValerii Chubar uint32_t d_len = 0; 269945d40bdaSValerii Chubar uint32_t e_len = 0; 270045d40bdaSValerii Chubar uint8_t *buffer = NULL; 270145d40bdaSValerii Chubar mbedtls_pk_context pk = { }; 270245d40bdaSValerii Chubar mbedtls_rsa_context *rsa = NULL; 270345d40bdaSValerii Chubar const mbedtls_pk_info_t *pk_info = NULL; 270445d40bdaSValerii Chubar 270545d40bdaSValerii Chubar mbedtls_pk_init(&pk); 270645d40bdaSValerii Chubar pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA); 270745d40bdaSValerii Chubar if (mbedtls_pk_setup(&pk, pk_info)) { 270845d40bdaSValerii Chubar rc = PKCS11_CKR_GENERAL_ERROR; 270945d40bdaSValerii Chubar goto out; 271045d40bdaSValerii Chubar } 271145d40bdaSValerii Chubar 271245d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_MODULUS, &n, &n_len); 271345d40bdaSValerii Chubar if (rc) 271445d40bdaSValerii Chubar goto out; 271545d40bdaSValerii Chubar 271645d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_PRIME_1, &p, &p_len); 271745d40bdaSValerii Chubar if (rc) 271845d40bdaSValerii Chubar goto out; 271945d40bdaSValerii Chubar 272045d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_PRIME_2, &q, &q_len); 272145d40bdaSValerii Chubar if (rc) 272245d40bdaSValerii Chubar goto out; 272345d40bdaSValerii Chubar 272445d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_PRIVATE_EXPONENT, &d, &d_len); 272545d40bdaSValerii Chubar if (rc) 272645d40bdaSValerii Chubar goto out; 272745d40bdaSValerii Chubar 272845d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_PUBLIC_EXPONENT, &e, &e_len); 272945d40bdaSValerii Chubar if (rc) 273045d40bdaSValerii Chubar goto out; 273145d40bdaSValerii Chubar 273245d40bdaSValerii Chubar rsa = mbedtls_pk_rsa(pk); 273345d40bdaSValerii Chubar mbedtls_rc = mbedtls_rsa_import_raw(rsa, n, n_len, p, p_len, 273445d40bdaSValerii Chubar q, q_len, d, d_len, e, e_len); 273545d40bdaSValerii Chubar if (mbedtls_rc) { 273645d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 273745d40bdaSValerii Chubar goto out; 273845d40bdaSValerii Chubar } 273945d40bdaSValerii Chubar 274045d40bdaSValerii Chubar if (mbedtls_rsa_complete(rsa)) { 274145d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 274245d40bdaSValerii Chubar goto out; 274345d40bdaSValerii Chubar } 274445d40bdaSValerii Chubar 274545d40bdaSValerii Chubar if (mbedtls_rsa_check_privkey(rsa)) { 274645d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 274745d40bdaSValerii Chubar goto out; 274845d40bdaSValerii Chubar } 274945d40bdaSValerii Chubar 275045d40bdaSValerii Chubar der_size = n_len * 8; 275145d40bdaSValerii Chubar buffer = TEE_Malloc(der_size, TEE_USER_MEM_HINT_NO_FILL_ZERO); 275245d40bdaSValerii Chubar if (!buffer) { 275345d40bdaSValerii Chubar rc = PKCS11_CKR_DEVICE_MEMORY; 275445d40bdaSValerii Chubar goto out; 275545d40bdaSValerii Chubar } 275645d40bdaSValerii Chubar 275745d40bdaSValerii Chubar mbedtls_rc = mbedtls_pk_write_key_der(&pk, buffer, der_size); 275845d40bdaSValerii Chubar if (mbedtls_rc < 0) { 275945d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 276045d40bdaSValerii Chubar goto out; 276145d40bdaSValerii Chubar } 276245d40bdaSValerii Chubar 276345d40bdaSValerii Chubar start = der_size - mbedtls_rc; 276445d40bdaSValerii Chubar for (i = 0; i < mbedtls_rc; i++) { 276545d40bdaSValerii Chubar buffer[i] = buffer[i + start]; 276645d40bdaSValerii Chubar buffer[i + start] = 0; 276745d40bdaSValerii Chubar } 276845d40bdaSValerii Chubar 276945d40bdaSValerii Chubar *data = buffer; 277045d40bdaSValerii Chubar *sz = mbedtls_rc; 277145d40bdaSValerii Chubar out: 277245d40bdaSValerii Chubar mbedtls_pk_free(&pk); 277345d40bdaSValerii Chubar 277445d40bdaSValerii Chubar if (rc) 277545d40bdaSValerii Chubar TEE_Free(buffer); 277645d40bdaSValerii Chubar 277745d40bdaSValerii Chubar return rc; 277845d40bdaSValerii Chubar } 277945d40bdaSValerii Chubar 2780a9aa45d8SValerii Chubar enum pkcs11_rc alloc_key_data_to_wrap(struct obj_attrs *head, void **data, 27815f80f270SRuchika Gupta uint32_t *sz) 27825f80f270SRuchika Gupta { 278345d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 278445d40bdaSValerii Chubar 27855f80f270SRuchika Gupta switch (get_class(head)) { 27865f80f270SRuchika Gupta case PKCS11_CKO_SECRET_KEY: 278745d40bdaSValerii Chubar rc = alloc_copy_attribute_value(head, data, sz); 278845d40bdaSValerii Chubar break; 278945d40bdaSValerii Chubar case PKCS11_CKO_PRIVATE_KEY: 279045d40bdaSValerii Chubar if (get_key_type(head) == PKCS11_CKK_RSA) 279145d40bdaSValerii Chubar rc = encode_rsa_private_key_der(head, data, sz); 279245d40bdaSValerii Chubar break; 27935f80f270SRuchika Gupta default: 279445d40bdaSValerii Chubar break; 27955f80f270SRuchika Gupta } 27965f80f270SRuchika Gupta 279745d40bdaSValerii Chubar return rc; 27985f80f270SRuchika Gupta } 27995f80f270SRuchika Gupta 28005e1d94ebSVesa Jääskeläinen enum pkcs11_rc add_missing_attribute_id(struct obj_attrs **pub_head, 28015e1d94ebSVesa Jääskeläinen struct obj_attrs **priv_head) 28025e1d94ebSVesa Jääskeläinen { 28035e1d94ebSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 28045e1d94ebSVesa Jääskeläinen void *id1 = NULL; 28055e1d94ebSVesa Jääskeläinen uint32_t id1_size = 0; 28065e1d94ebSVesa Jääskeläinen void *id2 = NULL; 28075e1d94ebSVesa Jääskeläinen uint32_t id2_size = 0; 28085e1d94ebSVesa Jääskeläinen 28095e1d94ebSVesa Jääskeläinen assert(pub_head); 28105e1d94ebSVesa Jääskeläinen assert(priv_head); 28115e1d94ebSVesa Jääskeläinen 28125e1d94ebSVesa Jääskeläinen rc = get_attribute_ptr(*pub_head, PKCS11_CKA_ID, &id1, &id1_size); 28135e1d94ebSVesa Jääskeläinen if (rc) { 28145e1d94ebSVesa Jääskeläinen if (rc != PKCS11_RV_NOT_FOUND) 28155e1d94ebSVesa Jääskeläinen return rc; 28165e1d94ebSVesa Jääskeläinen id1 = NULL; 28175e1d94ebSVesa Jääskeläinen } else if (!id1_size) { 28185e1d94ebSVesa Jääskeläinen id1 = NULL; 28195e1d94ebSVesa Jääskeläinen } 28205e1d94ebSVesa Jääskeläinen 28215e1d94ebSVesa Jääskeläinen rc = get_attribute_ptr(*priv_head, PKCS11_CKA_ID, &id2, &id2_size); 28225e1d94ebSVesa Jääskeläinen if (rc) { 28235e1d94ebSVesa Jääskeläinen if (rc != PKCS11_RV_NOT_FOUND) 28245e1d94ebSVesa Jääskeläinen return rc; 28255e1d94ebSVesa Jääskeläinen id2 = NULL; 28265e1d94ebSVesa Jääskeläinen } else if (!id2_size) { 28275e1d94ebSVesa Jääskeläinen id2 = NULL; 28285e1d94ebSVesa Jääskeläinen } 28295e1d94ebSVesa Jääskeläinen 28305e1d94ebSVesa Jääskeläinen /* Both have value -- let them be what caller has specified them */ 28315e1d94ebSVesa Jääskeläinen if (id1 && id2) 28325e1d94ebSVesa Jääskeläinen return PKCS11_CKR_OK; 28335e1d94ebSVesa Jääskeläinen 28345e1d94ebSVesa Jääskeläinen /* Both are empty -- leave empty values */ 28355e1d94ebSVesa Jääskeläinen if (!id1 && !id2) 28365e1d94ebSVesa Jääskeläinen return PKCS11_CKR_OK; 28375e1d94ebSVesa Jääskeläinen 28385e1d94ebSVesa Jääskeläinen /* Cross copy CKA_ID value */ 28395e1d94ebSVesa Jääskeläinen if (id1) 28405e1d94ebSVesa Jääskeläinen return set_attribute(priv_head, PKCS11_CKA_ID, id1, id1_size); 28415e1d94ebSVesa Jääskeläinen else 28425e1d94ebSVesa Jääskeläinen return set_attribute(pub_head, PKCS11_CKA_ID, id2, id2_size); 28435e1d94ebSVesa Jääskeläinen } 2844bcac2127SMarouene Boubakri 2845bcac2127SMarouene Boubakri /* 2846bcac2127SMarouene Boubakri * The key check value is derived from the object by taking the first 2847bcac2127SMarouene Boubakri * three bytes of the SHA-1 hash of the object's CKA_VALUE attribute. 2848bcac2127SMarouene Boubakri */ 2849bcac2127SMarouene Boubakri static enum pkcs11_rc compute_check_value_with_sha1(void *key, 2850bcac2127SMarouene Boubakri uint32_t key_size, 2851bcac2127SMarouene Boubakri void *kcv) 2852bcac2127SMarouene Boubakri { 2853bcac2127SMarouene Boubakri enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 2854bcac2127SMarouene Boubakri TEE_Result res = TEE_ERROR_GENERIC; 2855bcac2127SMarouene Boubakri TEE_OperationHandle op = TEE_HANDLE_NULL; 2856bcac2127SMarouene Boubakri size_t buf_size = TEE_MAX_HASH_SIZE; 2857bcac2127SMarouene Boubakri uint8_t *buf = NULL; 2858bcac2127SMarouene Boubakri 2859bcac2127SMarouene Boubakri assert(key && kcv); 2860bcac2127SMarouene Boubakri 2861bcac2127SMarouene Boubakri res = TEE_AllocateOperation(&op, TEE_ALG_SHA1, TEE_MODE_DIGEST, 0); 2862bcac2127SMarouene Boubakri rc = tee2pkcs_error(res); 2863bcac2127SMarouene Boubakri if (rc != PKCS11_CKR_OK) 2864bcac2127SMarouene Boubakri goto out; 2865bcac2127SMarouene Boubakri 2866bcac2127SMarouene Boubakri buf = TEE_Malloc(buf_size, TEE_MALLOC_FILL_ZERO); 2867bcac2127SMarouene Boubakri if (!buf) { 2868bcac2127SMarouene Boubakri rc = PKCS11_CKR_DEVICE_MEMORY; 2869bcac2127SMarouene Boubakri goto out; 2870bcac2127SMarouene Boubakri } 2871bcac2127SMarouene Boubakri 2872bcac2127SMarouene Boubakri res = TEE_DigestDoFinal(op, key, key_size, buf, &buf_size); 2873bcac2127SMarouene Boubakri rc = tee2pkcs_error(res); 2874bcac2127SMarouene Boubakri if (rc != PKCS11_CKR_OK) 2875bcac2127SMarouene Boubakri goto out; 2876bcac2127SMarouene Boubakri 2877bcac2127SMarouene Boubakri TEE_MemMove(kcv, buf, PKCS11_CKA_CHECK_VALUE_SIZE); 2878bcac2127SMarouene Boubakri 2879bcac2127SMarouene Boubakri out: 2880bcac2127SMarouene Boubakri TEE_Free(buf); 2881bcac2127SMarouene Boubakri TEE_FreeOperation(op); 2882bcac2127SMarouene Boubakri 2883bcac2127SMarouene Boubakri return rc; 2884bcac2127SMarouene Boubakri } 2885bcac2127SMarouene Boubakri 2886bcac2127SMarouene Boubakri /* 2887bcac2127SMarouene Boubakri * The key check value that is calculated as follows: 2888bcac2127SMarouene Boubakri * 1) Take a buffer of the cipher block size of binary zeros (0x00). 2889bcac2127SMarouene Boubakri * 2) Encrypt this block in ECB mode. 2890bcac2127SMarouene Boubakri * 3) Take the first three bytes of cipher text as the check value. 2891bcac2127SMarouene Boubakri */ 2892bcac2127SMarouene Boubakri static enum pkcs11_rc compute_check_value_with_ecb(void *key, uint32_t key_size, 2893bcac2127SMarouene Boubakri void *kcv) 2894bcac2127SMarouene Boubakri { 2895bcac2127SMarouene Boubakri enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 2896bcac2127SMarouene Boubakri TEE_Result res = TEE_ERROR_GENERIC; 2897bcac2127SMarouene Boubakri TEE_OperationHandle op = TEE_HANDLE_NULL; 2898bcac2127SMarouene Boubakri TEE_ObjectHandle hkey = TEE_HANDLE_NULL; 2899bcac2127SMarouene Boubakri TEE_Attribute attr = { }; 2900adfad2cdSEtienne Carriere uint8_t buf[TEE_AES_BLOCK_SIZE] = { }; 2901adfad2cdSEtienne Carriere size_t buf_size = sizeof(buf); 2902bcac2127SMarouene Boubakri 2903bcac2127SMarouene Boubakri assert(key && kcv); 2904bcac2127SMarouene Boubakri 2905bcac2127SMarouene Boubakri res = TEE_AllocateOperation(&op, TEE_ALG_AES_ECB_NOPAD, 2906bcac2127SMarouene Boubakri TEE_MODE_ENCRYPT, key_size * 8); 2907bcac2127SMarouene Boubakri rc = tee2pkcs_error(res); 2908bcac2127SMarouene Boubakri if (rc != PKCS11_CKR_OK) 2909bcac2127SMarouene Boubakri goto out; 2910bcac2127SMarouene Boubakri 2911bcac2127SMarouene Boubakri res = TEE_AllocateTransientObject(TEE_TYPE_AES, key_size * 8, &hkey); 2912bcac2127SMarouene Boubakri rc = tee2pkcs_error(res); 2913bcac2127SMarouene Boubakri if (rc != PKCS11_CKR_OK) 2914bcac2127SMarouene Boubakri goto out; 2915bcac2127SMarouene Boubakri 29163bc92b91SEtienne Carriere TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, key, key_size); 2917bcac2127SMarouene Boubakri 2918bcac2127SMarouene Boubakri res = TEE_PopulateTransientObject(hkey, &attr, 1); 2919bcac2127SMarouene Boubakri rc = tee2pkcs_error(res); 2920bcac2127SMarouene Boubakri if (rc != PKCS11_CKR_OK) 2921bcac2127SMarouene Boubakri goto out; 2922bcac2127SMarouene Boubakri 2923bcac2127SMarouene Boubakri res = TEE_SetOperationKey(op, hkey); 2924bcac2127SMarouene Boubakri rc = tee2pkcs_error(res); 2925bcac2127SMarouene Boubakri if (rc != PKCS11_CKR_OK) 2926bcac2127SMarouene Boubakri goto out; 2927bcac2127SMarouene Boubakri 2928bcac2127SMarouene Boubakri TEE_CipherInit(op, NULL, 0); 2929bcac2127SMarouene Boubakri 2930bcac2127SMarouene Boubakri res = TEE_CipherDoFinal(op, buf, buf_size, buf, &buf_size); 2931bcac2127SMarouene Boubakri rc = tee2pkcs_error(res); 2932bcac2127SMarouene Boubakri if (rc != PKCS11_CKR_OK) 2933bcac2127SMarouene Boubakri goto out; 2934bcac2127SMarouene Boubakri 2935bcac2127SMarouene Boubakri TEE_MemMove(kcv, buf, PKCS11_CKA_CHECK_VALUE_SIZE); 2936bcac2127SMarouene Boubakri 2937bcac2127SMarouene Boubakri out: 2938bcac2127SMarouene Boubakri TEE_FreeTransientObject(hkey); 2939bcac2127SMarouene Boubakri TEE_FreeOperation(op); 2940bcac2127SMarouene Boubakri 2941bcac2127SMarouene Boubakri return rc; 2942bcac2127SMarouene Boubakri } 2943bcac2127SMarouene Boubakri 2944bcac2127SMarouene Boubakri enum pkcs11_rc set_check_value_attr(struct obj_attrs **head) 2945bcac2127SMarouene Boubakri { 2946bcac2127SMarouene Boubakri enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 2947bcac2127SMarouene Boubakri uint32_t val_len = 0; 2948bcac2127SMarouene Boubakri uint32_t kcv2_len = 0; 2949bcac2127SMarouene Boubakri void *val = NULL; 2950bcac2127SMarouene Boubakri uint8_t kcv[PKCS11_CKA_CHECK_VALUE_SIZE] = { }; 2951bcac2127SMarouene Boubakri void *kcv2 = NULL; 2952bcac2127SMarouene Boubakri 2953bcac2127SMarouene Boubakri assert(head && *head); 2954bcac2127SMarouene Boubakri 2955bcac2127SMarouene Boubakri if (!IS_ENABLED(CFG_PKCS11_TA_CHECK_VALUE_ATTRIBUTE)) 2956bcac2127SMarouene Boubakri return PKCS11_CKR_OK; 2957bcac2127SMarouene Boubakri 2958bcac2127SMarouene Boubakri switch (get_class(*head)) { 2959bcac2127SMarouene Boubakri case PKCS11_CKO_SECRET_KEY: 2960bcac2127SMarouene Boubakri case PKCS11_CKO_CERTIFICATE: 2961bcac2127SMarouene Boubakri break; 2962bcac2127SMarouene Boubakri default: 2963cfbe7874SEtienne Carriere /* Nothing to do */ 2964cfbe7874SEtienne Carriere return PKCS11_CKR_OK; 2965bcac2127SMarouene Boubakri } 2966bcac2127SMarouene Boubakri 2967bcac2127SMarouene Boubakri /* Check whether CKA_CHECK_VALUE has been provided in the template */ 2968bcac2127SMarouene Boubakri rc = get_attribute_ptr(*head, PKCS11_CKA_CHECK_VALUE, &kcv2, &kcv2_len); 2969bcac2127SMarouene Boubakri 2970bcac2127SMarouene Boubakri if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND) 2971bcac2127SMarouene Boubakri return PKCS11_CKR_GENERAL_ERROR; 2972bcac2127SMarouene Boubakri 2973bcac2127SMarouene Boubakri /* 2974bcac2127SMarouene Boubakri * The generation of the KCV may be prevented by the application 2975bcac2127SMarouene Boubakri * supplying the attribute in the template as a no-value (0 length) 2976bcac2127SMarouene Boubakri * entry. 2977bcac2127SMarouene Boubakri */ 2978bcac2127SMarouene Boubakri if (rc == PKCS11_CKR_OK && !kcv2_len) 2979bcac2127SMarouene Boubakri return PKCS11_CKR_OK; 2980bcac2127SMarouene Boubakri 2981bcac2127SMarouene Boubakri if (rc == PKCS11_CKR_OK && kcv2_len != PKCS11_CKA_CHECK_VALUE_SIZE) 2982*2ea9746dSEtienne Carriere return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 2983bcac2127SMarouene Boubakri 2984bcac2127SMarouene Boubakri /* Get key CKA_VALUE */ 2985bcac2127SMarouene Boubakri rc = get_attribute_ptr(*head, PKCS11_CKA_VALUE, &val, &val_len); 2986bcac2127SMarouene Boubakri if (rc) 2987bcac2127SMarouene Boubakri return rc; 2988bcac2127SMarouene Boubakri 2989bcac2127SMarouene Boubakri if (get_class(*head) == PKCS11_CKO_SECRET_KEY) { 2990bcac2127SMarouene Boubakri switch (get_key_type(*head)) { 2991bcac2127SMarouene Boubakri case PKCS11_CKK_AES: 2992bcac2127SMarouene Boubakri rc = compute_check_value_with_ecb(val, val_len, kcv); 2993bcac2127SMarouene Boubakri break; 2994bcac2127SMarouene Boubakri case PKCS11_CKK_GENERIC_SECRET: 2995bcac2127SMarouene Boubakri case PKCS11_CKK_MD5_HMAC: 2996bcac2127SMarouene Boubakri case PKCS11_CKK_SHA_1_HMAC: 2997bcac2127SMarouene Boubakri case PKCS11_CKK_SHA256_HMAC: 2998bcac2127SMarouene Boubakri case PKCS11_CKK_SHA384_HMAC: 2999bcac2127SMarouene Boubakri case PKCS11_CKK_SHA512_HMAC: 3000bcac2127SMarouene Boubakri case PKCS11_CKK_SHA224_HMAC: 3001bcac2127SMarouene Boubakri rc = compute_check_value_with_sha1(val, val_len, kcv); 3002bcac2127SMarouene Boubakri break; 3003bcac2127SMarouene Boubakri default: 3004bcac2127SMarouene Boubakri rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 3005bcac2127SMarouene Boubakri break; 3006bcac2127SMarouene Boubakri } 3007bcac2127SMarouene Boubakri } else { 3008bcac2127SMarouene Boubakri rc = compute_check_value_with_sha1(val, val_len, kcv); 3009bcac2127SMarouene Boubakri } 3010bcac2127SMarouene Boubakri 3011bcac2127SMarouene Boubakri if (rc) 3012bcac2127SMarouene Boubakri return rc; 3013bcac2127SMarouene Boubakri 3014bcac2127SMarouene Boubakri /* 3015bcac2127SMarouene Boubakri * If the computed KCV does not match the provided one 3016bcac2127SMarouene Boubakri * then return CKR_ATTRIBUTE_VALUE_INVALID 3017bcac2127SMarouene Boubakri */ 3018bcac2127SMarouene Boubakri if (kcv2_len) { 3019bcac2127SMarouene Boubakri /* Provided KCV value shall match the computed one */ 3020bcac2127SMarouene Boubakri if (TEE_MemCompare(kcv2, kcv, PKCS11_CKA_CHECK_VALUE_SIZE)) 3021bcac2127SMarouene Boubakri rc = PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 3022bcac2127SMarouene Boubakri } else { 3023bcac2127SMarouene Boubakri rc = add_attribute(head, PKCS11_CKA_CHECK_VALUE, kcv, 3024bcac2127SMarouene Boubakri PKCS11_CKA_CHECK_VALUE_SIZE); 3025bcac2127SMarouene Boubakri } 3026bcac2127SMarouene Boubakri 3027bcac2127SMarouene Boubakri return rc; 3028bcac2127SMarouene Boubakri } 3029