163f89caaSJens Wiklander // SPDX-License-Identifier: BSD-2-Clause 263f89caaSJens Wiklander /* 363f89caaSJens Wiklander * Copyright (c) 2017-2020, Linaro Limited 463f89caaSJens Wiklander */ 563f89caaSJens Wiklander 663f89caaSJens Wiklander #include <assert.h> 763f89caaSJens Wiklander #include <inttypes.h> 863f89caaSJens Wiklander #include <pkcs11_ta.h> 963f89caaSJens Wiklander #include <stdlib.h> 1063f89caaSJens Wiklander #include <string_ext.h> 1163f89caaSJens Wiklander #include <tee_internal_api_extensions.h> 1263f89caaSJens Wiklander #include <tee_internal_api.h> 136a760c9eSEtienne Carriere #include <trace.h> 1463f89caaSJens Wiklander #include <util.h> 1563f89caaSJens Wiklander 1663f89caaSJens Wiklander #include "attributes.h" 1763f89caaSJens Wiklander #include "handle.h" 1863f89caaSJens Wiklander #include "pkcs11_attributes.h" 1963f89caaSJens Wiklander #include "pkcs11_helpers.h" 2063f89caaSJens Wiklander #include "pkcs11_token.h" 2163f89caaSJens Wiklander #include "sanitize_object.h" 2263f89caaSJens Wiklander #include "serializer.h" 2363f89caaSJens Wiklander #include "token_capabilities.h" 2463f89caaSJens Wiklander 25512cbf1dSJens Wiklander static uint32_t pkcs11_func2ckfm(enum processing_func function) 26512cbf1dSJens Wiklander { 27512cbf1dSJens Wiklander switch (function) { 28512cbf1dSJens Wiklander case PKCS11_FUNCTION_DIGEST: 29512cbf1dSJens Wiklander return PKCS11_CKFM_DIGEST; 30512cbf1dSJens Wiklander case PKCS11_FUNCTION_GENERATE: 31512cbf1dSJens Wiklander return PKCS11_CKFM_GENERATE; 32512cbf1dSJens Wiklander case PKCS11_FUNCTION_GENERATE_PAIR: 33512cbf1dSJens Wiklander return PKCS11_CKFM_GENERATE_KEY_PAIR; 34512cbf1dSJens Wiklander case PKCS11_FUNCTION_DERIVE: 35512cbf1dSJens Wiklander return PKCS11_CKFM_DERIVE; 36512cbf1dSJens Wiklander case PKCS11_FUNCTION_WRAP: 37512cbf1dSJens Wiklander return PKCS11_CKFM_WRAP; 38512cbf1dSJens Wiklander case PKCS11_FUNCTION_UNWRAP: 39512cbf1dSJens Wiklander return PKCS11_CKFM_UNWRAP; 40512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 41512cbf1dSJens Wiklander return PKCS11_CKFM_ENCRYPT; 42512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 43512cbf1dSJens Wiklander return PKCS11_CKFM_DECRYPT; 44512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN: 45512cbf1dSJens Wiklander return PKCS11_CKFM_SIGN; 46512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY: 47512cbf1dSJens Wiklander return PKCS11_CKFM_VERIFY; 48512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN_RECOVER: 49512cbf1dSJens Wiklander return PKCS11_CKFM_SIGN_RECOVER; 50512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY_RECOVER: 51512cbf1dSJens Wiklander return PKCS11_CKFM_VERIFY_RECOVER; 52512cbf1dSJens Wiklander default: 53512cbf1dSJens Wiklander return 0; 54512cbf1dSJens Wiklander } 55512cbf1dSJens Wiklander } 56512cbf1dSJens Wiklander 57512cbf1dSJens Wiklander enum pkcs11_rc 58512cbf1dSJens Wiklander check_mechanism_against_processing(struct pkcs11_session *session, 59512cbf1dSJens Wiklander enum pkcs11_mechanism_id mechanism_type, 60512cbf1dSJens Wiklander enum processing_func function, 61512cbf1dSJens Wiklander enum processing_step step) 62512cbf1dSJens Wiklander { 63512cbf1dSJens Wiklander bool allowed = false; 64512cbf1dSJens Wiklander 65512cbf1dSJens Wiklander switch (step) { 66512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_INIT: 67512cbf1dSJens Wiklander switch (function) { 68512cbf1dSJens Wiklander case PKCS11_FUNCTION_IMPORT: 69512cbf1dSJens Wiklander case PKCS11_FUNCTION_COPY: 70512cbf1dSJens Wiklander case PKCS11_FUNCTION_MODIFY: 71512cbf1dSJens Wiklander case PKCS11_FUNCTION_DESTROY: 72512cbf1dSJens Wiklander return PKCS11_CKR_OK; 73512cbf1dSJens Wiklander default: 74512cbf1dSJens Wiklander break; 75512cbf1dSJens Wiklander } 76512cbf1dSJens Wiklander /* 77512cbf1dSJens Wiklander * Check that the returned PKCS11_CKFM_* flag from 78512cbf1dSJens Wiklander * pkcs11_func2ckfm() is among the ones from 79512cbf1dSJens Wiklander * mechanism_supported_flags(). 80512cbf1dSJens Wiklander */ 81512cbf1dSJens Wiklander allowed = mechanism_supported_flags(mechanism_type) & 82512cbf1dSJens Wiklander pkcs11_func2ckfm(function); 83512cbf1dSJens Wiklander break; 84512cbf1dSJens Wiklander 85512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_ONESHOT: 860460a039SRuchika Gupta if (session->processing->always_authen && 870460a039SRuchika Gupta !session->processing->relogged) 880460a039SRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 890460a039SRuchika Gupta 902364aa69SRuchika Gupta if (session->processing->step == PKCS11_FUNC_STEP_UPDATE || 912364aa69SRuchika Gupta session->processing->step == PKCS11_FUNC_STEP_FINAL) { 922364aa69SRuchika Gupta EMSG("Cannot perform one-shot on active processing"); 930460a039SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE; 940460a039SRuchika Gupta } 950460a039SRuchika Gupta 960460a039SRuchika Gupta allowed = true; 970460a039SRuchika Gupta break; 980460a039SRuchika Gupta 99512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_UPDATE: 100512cbf1dSJens Wiklander if (session->processing->always_authen && 101512cbf1dSJens Wiklander !session->processing->relogged) 102512cbf1dSJens Wiklander return PKCS11_CKR_USER_NOT_LOGGED_IN; 103512cbf1dSJens Wiklander 1042364aa69SRuchika Gupta if (session->processing->step == PKCS11_FUNC_STEP_ONESHOT || 1052364aa69SRuchika Gupta session->processing->step == PKCS11_FUNC_STEP_FINAL) { 1062364aa69SRuchika Gupta EMSG("Cannot perform update on finalized processing"); 1072364aa69SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE; 1082364aa69SRuchika Gupta } 1092364aa69SRuchika Gupta 110512cbf1dSJens Wiklander allowed = !mechanism_is_one_shot_only(mechanism_type); 111512cbf1dSJens Wiklander break; 112512cbf1dSJens Wiklander 1139e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE_KEY: 1149e91a619SVesa Jääskeläinen assert(function == PKCS11_FUNCTION_DIGEST); 1159e91a619SVesa Jääskeläinen 1169e91a619SVesa Jääskeläinen if (session->processing->always_authen && 1179e91a619SVesa Jääskeläinen !session->processing->relogged) 1189e91a619SVesa Jääskeläinen return PKCS11_CKR_USER_NOT_LOGGED_IN; 1199e91a619SVesa Jääskeläinen 1209e91a619SVesa Jääskeläinen allowed = true; 1219e91a619SVesa Jääskeläinen break; 1229e91a619SVesa Jääskeläinen 123512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_FINAL: 124512cbf1dSJens Wiklander if (session->processing->always_authen && 125512cbf1dSJens Wiklander !session->processing->relogged) 126512cbf1dSJens Wiklander return PKCS11_CKR_USER_NOT_LOGGED_IN; 127512cbf1dSJens Wiklander 1282364aa69SRuchika Gupta if (session->processing->step == PKCS11_FUNC_STEP_ONESHOT) { 1292364aa69SRuchika Gupta EMSG("Cannot perform final on oneshot processing"); 1302364aa69SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE; 1312364aa69SRuchika Gupta } 132512cbf1dSJens Wiklander return PKCS11_CKR_OK; 133512cbf1dSJens Wiklander 134512cbf1dSJens Wiklander default: 135512cbf1dSJens Wiklander TEE_Panic(step); 136512cbf1dSJens Wiklander break; 137512cbf1dSJens Wiklander } 138512cbf1dSJens Wiklander 139512cbf1dSJens Wiklander if (!allowed) { 140512cbf1dSJens Wiklander EMSG("Processing %#x/%s not permitted (%u/%u)", 141512cbf1dSJens Wiklander (unsigned int)mechanism_type, id2str_proc(mechanism_type), 142512cbf1dSJens Wiklander function, step); 143df705578SRuchika Gupta return PKCS11_CKR_MECHANISM_INVALID; 144512cbf1dSJens Wiklander } 145512cbf1dSJens Wiklander 146512cbf1dSJens Wiklander return PKCS11_CKR_OK; 147512cbf1dSJens Wiklander } 148512cbf1dSJens Wiklander 14963f89caaSJens Wiklander /* 15063f89caaSJens Wiklander * Object default boolean attributes as per PKCS#11 15163f89caaSJens Wiklander */ 15263f89caaSJens Wiklander static uint8_t *pkcs11_object_default_boolprop(uint32_t attribute) 15363f89caaSJens Wiklander { 15463f89caaSJens Wiklander static const uint8_t bool_true = 1; 15563f89caaSJens Wiklander static const uint8_t bool_false; 15663f89caaSJens Wiklander 15763f89caaSJens Wiklander switch (attribute) { 15863f89caaSJens Wiklander /* As per PKCS#11 default value */ 15963f89caaSJens Wiklander case PKCS11_CKA_MODIFIABLE: 16063f89caaSJens Wiklander case PKCS11_CKA_COPYABLE: 16163f89caaSJens Wiklander case PKCS11_CKA_DESTROYABLE: 16263f89caaSJens Wiklander return (uint8_t *)&bool_true; 16363f89caaSJens Wiklander case PKCS11_CKA_TOKEN: 16463f89caaSJens Wiklander case PKCS11_CKA_PRIVATE: 16539fc24faSEtienne Carriere case PKCS11_CKA_WRAP_WITH_TRUSTED: 16639fc24faSEtienne Carriere case PKCS11_CKA_ALWAYS_AUTHENTICATE: 16763f89caaSJens Wiklander case PKCS11_CKA_SENSITIVE: 16863f89caaSJens Wiklander return (uint8_t *)&bool_false; 16963f89caaSJens Wiklander /* Token specific default value */ 17063f89caaSJens Wiklander case PKCS11_CKA_SIGN: 17163f89caaSJens Wiklander case PKCS11_CKA_VERIFY: 17263f89caaSJens Wiklander case PKCS11_CKA_DERIVE: 17363f89caaSJens Wiklander case PKCS11_CKA_ENCRYPT: 17463f89caaSJens Wiklander case PKCS11_CKA_DECRYPT: 17563f89caaSJens Wiklander case PKCS11_CKA_SIGN_RECOVER: 17663f89caaSJens Wiklander case PKCS11_CKA_VERIFY_RECOVER: 17763f89caaSJens Wiklander case PKCS11_CKA_WRAP: 17863f89caaSJens Wiklander case PKCS11_CKA_UNWRAP: 17963f89caaSJens Wiklander case PKCS11_CKA_EXTRACTABLE: 18063f89caaSJens Wiklander case PKCS11_CKA_TRUSTED: 18163f89caaSJens Wiklander return (uint8_t *)&bool_false; 18263f89caaSJens Wiklander default: 18363f89caaSJens Wiklander DMSG("No default for boolprop attribute %#"PRIx32, attribute); 18463f89caaSJens Wiklander return NULL; 18563f89caaSJens Wiklander } 18663f89caaSJens Wiklander } 18763f89caaSJens Wiklander 18863f89caaSJens Wiklander /* 18963f89caaSJens Wiklander * Object expects several boolean attributes to be set to a default value 19063f89caaSJens Wiklander * or to a validate client configuration value. This function append the input 19163f89caaSJens Wiklander * attribute (id/size/value) in the serialized object. 19263f89caaSJens Wiklander */ 19363f89caaSJens Wiklander static enum pkcs11_rc pkcs11_import_object_boolprop(struct obj_attrs **out, 19463f89caaSJens Wiklander struct obj_attrs *templ, 19563f89caaSJens Wiklander uint32_t attribute) 19663f89caaSJens Wiklander { 19763f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 19863f89caaSJens Wiklander uint8_t bbool = 0; 19963f89caaSJens Wiklander uint32_t size = sizeof(uint8_t); 20063f89caaSJens Wiklander void *attr = NULL; 20163f89caaSJens Wiklander 20263f89caaSJens Wiklander rc = get_attribute(templ, attribute, &bbool, &size); 20363f89caaSJens Wiklander if (rc) { 20463f89caaSJens Wiklander if (rc != PKCS11_RV_NOT_FOUND) 20563f89caaSJens Wiklander return rc; 20663f89caaSJens Wiklander attr = pkcs11_object_default_boolprop(attribute); 20763f89caaSJens Wiklander if (!attr) 20863f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCOMPLETE; 20963f89caaSJens Wiklander } else { 21063f89caaSJens Wiklander attr = &bbool; 21163f89caaSJens Wiklander } 21263f89caaSJens Wiklander 21363f89caaSJens Wiklander /* Boolean attributes are 1byte in the ABI, no alignment issue */ 21463f89caaSJens Wiklander return add_attribute(out, attribute, attr, sizeof(uint8_t)); 21563f89caaSJens Wiklander } 21663f89caaSJens Wiklander 21763f89caaSJens Wiklander static enum pkcs11_rc set_mandatory_boolprops(struct obj_attrs **out, 21863f89caaSJens Wiklander struct obj_attrs *temp, 21963f89caaSJens Wiklander uint32_t const *bp, 22063f89caaSJens Wiklander size_t bp_count) 22163f89caaSJens Wiklander { 22263f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 22363f89caaSJens Wiklander size_t n = 0; 22463f89caaSJens Wiklander 22563f89caaSJens Wiklander for (n = 0; n < bp_count; n++) { 22663f89caaSJens Wiklander rc = pkcs11_import_object_boolprop(out, temp, bp[n]); 22763f89caaSJens Wiklander if (rc) 22863f89caaSJens Wiklander return rc; 22963f89caaSJens Wiklander } 23063f89caaSJens Wiklander 23163f89caaSJens Wiklander return rc; 23263f89caaSJens Wiklander } 23363f89caaSJens Wiklander 23463f89caaSJens Wiklander static enum pkcs11_rc set_mandatory_attributes(struct obj_attrs **out, 23563f89caaSJens Wiklander struct obj_attrs *temp, 23616df60c7SEtienne Carriere uint32_t const *attrs, 23716df60c7SEtienne Carriere size_t attrs_count) 23863f89caaSJens Wiklander { 23963f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 24063f89caaSJens Wiklander size_t n = 0; 24163f89caaSJens Wiklander 24216df60c7SEtienne Carriere for (n = 0; n < attrs_count; n++) { 24363f89caaSJens Wiklander uint32_t size = 0; 24463f89caaSJens Wiklander void *value = NULL; 24563f89caaSJens Wiklander 24616df60c7SEtienne Carriere if (get_attribute_ptr(temp, attrs[n], &value, &size)) 24763f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCOMPLETE; 24863f89caaSJens Wiklander 24916df60c7SEtienne Carriere rc = add_attribute(out, attrs[n], value, size); 25063f89caaSJens Wiklander if (rc) 25163f89caaSJens Wiklander return rc; 25263f89caaSJens Wiklander } 25363f89caaSJens Wiklander 25463f89caaSJens Wiklander return rc; 25563f89caaSJens Wiklander } 25663f89caaSJens Wiklander 25763f89caaSJens Wiklander static enum pkcs11_rc get_default_value(enum pkcs11_attr_id id, void **value, 25863f89caaSJens Wiklander uint32_t *size) 25963f89caaSJens Wiklander { 26063f89caaSJens Wiklander /* should have been taken care of already */ 26163f89caaSJens Wiklander assert(!pkcs11_attr_is_boolean(id)); 26263f89caaSJens Wiklander 26363f89caaSJens Wiklander /* All other attributes have an empty default value */ 26463f89caaSJens Wiklander *value = NULL; 26563f89caaSJens Wiklander *size = 0; 26663f89caaSJens Wiklander return PKCS11_CKR_OK; 26763f89caaSJens Wiklander } 26863f89caaSJens Wiklander 2694eb88651SRuchika Gupta static enum pkcs11_rc set_optional_attributes_with_def(struct obj_attrs **out, 27063f89caaSJens Wiklander struct obj_attrs *temp, 27116df60c7SEtienne Carriere uint32_t const *attrs, 27216df60c7SEtienne Carriere size_t attrs_count, 2734eb88651SRuchika Gupta bool default_to_null) 27463f89caaSJens Wiklander { 27563f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 27663f89caaSJens Wiklander size_t n = 0; 27763f89caaSJens Wiklander 27816df60c7SEtienne Carriere for (n = 0; n < attrs_count; n++) { 27963f89caaSJens Wiklander uint32_t size = 0; 28063f89caaSJens Wiklander void *value = NULL; 28163f89caaSJens Wiklander 28216df60c7SEtienne Carriere rc = get_attribute_ptr(temp, attrs[n], &value, &size); 2834eb88651SRuchika Gupta if (rc == PKCS11_RV_NOT_FOUND) { 2844eb88651SRuchika Gupta if (default_to_null) { 28516df60c7SEtienne Carriere rc = get_default_value(attrs[n], &value, &size); 2864eb88651SRuchika Gupta } else { 2874eb88651SRuchika Gupta rc = PKCS11_CKR_OK; 2884eb88651SRuchika Gupta continue; 2894eb88651SRuchika Gupta } 2904eb88651SRuchika Gupta } 29163f89caaSJens Wiklander if (rc) 29263f89caaSJens Wiklander return rc; 29363f89caaSJens Wiklander 29416df60c7SEtienne Carriere rc = add_attribute(out, attrs[n], value, size); 29563f89caaSJens Wiklander if (rc) 29663f89caaSJens Wiklander return rc; 29763f89caaSJens Wiklander } 29863f89caaSJens Wiklander 29963f89caaSJens Wiklander return rc; 30063f89caaSJens Wiklander } 30163f89caaSJens Wiklander 3024eb88651SRuchika Gupta static enum pkcs11_rc set_attributes_opt_or_null(struct obj_attrs **out, 3034eb88651SRuchika Gupta struct obj_attrs *temp, 30416df60c7SEtienne Carriere uint32_t const *attrs, 30516df60c7SEtienne Carriere size_t attrs_count) 3064eb88651SRuchika Gupta { 30716df60c7SEtienne Carriere return set_optional_attributes_with_def(out, temp, attrs, attrs_count, 30816df60c7SEtienne Carriere true /* defaults to empty */); 3094eb88651SRuchika Gupta } 3104eb88651SRuchika Gupta 3114eb88651SRuchika Gupta static enum pkcs11_rc set_optional_attributes(struct obj_attrs **out, 3124eb88651SRuchika Gupta struct obj_attrs *temp, 31316df60c7SEtienne Carriere uint32_t const *attrs, 31416df60c7SEtienne Carriere size_t attrs_count) 3154eb88651SRuchika Gupta { 31616df60c7SEtienne Carriere return set_optional_attributes_with_def(out, temp, attrs, attrs_count, 31716df60c7SEtienne Carriere false /* no default value */); 3184eb88651SRuchika Gupta } 3194eb88651SRuchika Gupta 32063f89caaSJens Wiklander /* 32163f89caaSJens Wiklander * Below are listed the mandated or optional expected attributes for 32263f89caaSJens Wiklander * PKCS#11 storage objects. 32363f89caaSJens Wiklander * 32463f89caaSJens Wiklander * Note: boolprops (mandated boolean attributes) PKCS11_CKA_ALWAYS_SENSITIVE, 32563f89caaSJens Wiklander * and PKCS11_CKA_NEVER_EXTRACTABLE are set by the token, not provided 32663f89caaSJens Wiklander * in the client template. 32763f89caaSJens Wiklander */ 32863f89caaSJens Wiklander 32963f89caaSJens Wiklander /* PKCS#11 specification for any object (session/token) of the storage */ 3304eb88651SRuchika Gupta static const uint32_t any_object_boolprops[] = { 33163f89caaSJens Wiklander PKCS11_CKA_TOKEN, PKCS11_CKA_PRIVATE, 33263f89caaSJens Wiklander PKCS11_CKA_MODIFIABLE, PKCS11_CKA_COPYABLE, PKCS11_CKA_DESTROYABLE, 33363f89caaSJens Wiklander }; 33463f89caaSJens Wiklander 3354eb88651SRuchika Gupta static const uint32_t any_object_opt_or_null[] = { 33663f89caaSJens Wiklander PKCS11_CKA_LABEL, 33763f89caaSJens Wiklander }; 33863f89caaSJens Wiklander 3394eb88651SRuchika Gupta /* PKCS#11 specification for raw data object (+any_object_xxx) */ 3404eb88651SRuchika Gupta const uint32_t raw_data_opt_or_null[] = { 34163f89caaSJens Wiklander PKCS11_CKA_OBJECT_ID, PKCS11_CKA_APPLICATION, PKCS11_CKA_VALUE, 34263f89caaSJens Wiklander }; 34363f89caaSJens Wiklander 3444137952dSVesa Jääskeläinen /* PKCS#11 specification for certificate object (+pkcs11_any_object_xxx) */ 3454137952dSVesa Jääskeläinen static const uint32_t pkcs11_certificate_mandated[] = { 3464137952dSVesa Jääskeläinen PKCS11_CKA_CERTIFICATE_TYPE, 3474137952dSVesa Jääskeläinen }; 3484137952dSVesa Jääskeläinen 3494137952dSVesa Jääskeläinen static const uint32_t pkcs11_certificate_boolprops[] = { 3504137952dSVesa Jääskeläinen PKCS11_CKA_TRUSTED, 3514137952dSVesa Jääskeläinen }; 3524137952dSVesa Jääskeläinen 3534137952dSVesa Jääskeläinen static const uint32_t pkcs11_certificate_optional[] = { 3544137952dSVesa Jääskeläinen PKCS11_CKA_CERTIFICATE_CATEGORY, PKCS11_CKA_CHECK_VALUE, 3554137952dSVesa Jääskeläinen PKCS11_CKA_START_DATE, PKCS11_CKA_END_DATE, PKCS11_CKA_PUBLIC_KEY_INFO, 3564137952dSVesa Jääskeläinen }; 3574137952dSVesa Jääskeläinen 3584137952dSVesa Jääskeläinen /* 3594137952dSVesa Jääskeläinen * PKCS#11 specification for X.509 certificate object (+pkcs11_certificate_xxx) 3604137952dSVesa Jääskeläinen */ 3614137952dSVesa Jääskeläinen static const uint32_t pkcs11_x509_certificate_mandated[] = { 3624137952dSVesa Jääskeläinen PKCS11_CKA_SUBJECT, 3634137952dSVesa Jääskeläinen }; 3644137952dSVesa Jääskeläinen 3654137952dSVesa Jääskeläinen static const uint32_t pkcs11_x509_certificate_optional[] = { 3664137952dSVesa Jääskeläinen PKCS11_CKA_ID, PKCS11_CKA_ISSUER, PKCS11_CKA_SERIAL_NUMBER, 3674137952dSVesa Jääskeläinen PKCS11_CKA_VALUE, PKCS11_CKA_URL, 3684137952dSVesa Jääskeläinen PKCS11_CKA_HASH_OF_SUBJECT_PUBLIC_KEY, 3694137952dSVesa Jääskeläinen PKCS11_CKA_HASH_OF_ISSUER_PUBLIC_KEY, 3704137952dSVesa Jääskeläinen PKCS11_CKA_JAVA_MIDP_SECURITY_DOMAIN, PKCS11_CKA_NAME_HASH_ALGORITHM, 3714137952dSVesa Jääskeläinen }; 3724137952dSVesa Jääskeläinen 3734eb88651SRuchika Gupta /* PKCS#11 specification for any key object (+any_object_xxx) */ 3744eb88651SRuchika Gupta static const uint32_t any_key_boolprops[] = { 37563f89caaSJens Wiklander PKCS11_CKA_DERIVE, 37663f89caaSJens Wiklander }; 37763f89caaSJens Wiklander 3784eb88651SRuchika Gupta static const uint32_t any_key_opt_or_null[] = { 37963f89caaSJens Wiklander PKCS11_CKA_ID, 38063f89caaSJens Wiklander PKCS11_CKA_START_DATE, PKCS11_CKA_END_DATE, 3814eb88651SRuchika Gupta }; 3824eb88651SRuchika Gupta 3834eb88651SRuchika Gupta static const uint32_t any_key_optional[] = { 38463f89caaSJens Wiklander PKCS11_CKA_ALLOWED_MECHANISMS, 38563f89caaSJens Wiklander }; 38663f89caaSJens Wiklander 3874eb88651SRuchika Gupta /* PKCS#11 specification for any symmetric key (+any_key_xxx) */ 3884eb88651SRuchika Gupta static const uint32_t symm_key_boolprops[] = { 38963f89caaSJens Wiklander PKCS11_CKA_ENCRYPT, PKCS11_CKA_DECRYPT, 39063f89caaSJens Wiklander PKCS11_CKA_SIGN, PKCS11_CKA_VERIFY, 39163f89caaSJens Wiklander PKCS11_CKA_WRAP, PKCS11_CKA_UNWRAP, 39263f89caaSJens Wiklander PKCS11_CKA_SENSITIVE, PKCS11_CKA_EXTRACTABLE, 39363f89caaSJens Wiklander PKCS11_CKA_WRAP_WITH_TRUSTED, PKCS11_CKA_TRUSTED, 39463f89caaSJens Wiklander }; 39563f89caaSJens Wiklander 3964eb88651SRuchika Gupta static const uint32_t symm_key_opt_or_null[] = { 39763f89caaSJens Wiklander PKCS11_CKA_WRAP_TEMPLATE, PKCS11_CKA_UNWRAP_TEMPLATE, 3980ac5c695SRuchika Gupta PKCS11_CKA_DERIVE_TEMPLATE, PKCS11_CKA_VALUE, 3990ac5c695SRuchika Gupta }; 4000ac5c695SRuchika Gupta 4010ac5c695SRuchika Gupta static const uint32_t symm_key_optional[] = { 4020ac5c695SRuchika Gupta PKCS11_CKA_VALUE_LEN, 40363f89caaSJens Wiklander }; 40463f89caaSJens Wiklander 4054eb88651SRuchika Gupta /* PKCS#11 specification for any asymmetric public key (+any_key_xxx) */ 4064eb88651SRuchika Gupta static const uint32_t public_key_boolprops[] = { 40763f89caaSJens Wiklander PKCS11_CKA_ENCRYPT, PKCS11_CKA_VERIFY, PKCS11_CKA_VERIFY_RECOVER, 40863f89caaSJens Wiklander PKCS11_CKA_WRAP, 40963f89caaSJens Wiklander PKCS11_CKA_TRUSTED, 41063f89caaSJens Wiklander }; 41163f89caaSJens Wiklander 4124eb88651SRuchika Gupta static const uint32_t public_key_mandated[] = { 41363f89caaSJens Wiklander }; 41463f89caaSJens Wiklander 4154eb88651SRuchika Gupta static const uint32_t public_key_opt_or_null[] = { 416edd95148SVesa Jääskeläinen PKCS11_CKA_SUBJECT, PKCS11_CKA_WRAP_TEMPLATE, 417edd95148SVesa Jääskeläinen PKCS11_CKA_PUBLIC_KEY_INFO, 41863f89caaSJens Wiklander }; 41963f89caaSJens Wiklander 4204eb88651SRuchika Gupta /* PKCS#11 specification for any asymmetric private key (+any_key_xxx) */ 4214eb88651SRuchika Gupta static const uint32_t private_key_boolprops[] = { 42263f89caaSJens Wiklander PKCS11_CKA_DECRYPT, PKCS11_CKA_SIGN, PKCS11_CKA_SIGN_RECOVER, 42363f89caaSJens Wiklander PKCS11_CKA_UNWRAP, 42463f89caaSJens Wiklander PKCS11_CKA_SENSITIVE, PKCS11_CKA_EXTRACTABLE, 42563f89caaSJens Wiklander PKCS11_CKA_WRAP_WITH_TRUSTED, PKCS11_CKA_ALWAYS_AUTHENTICATE, 42663f89caaSJens Wiklander }; 42763f89caaSJens Wiklander 4284eb88651SRuchika Gupta static const uint32_t private_key_mandated[] = { 42963f89caaSJens Wiklander }; 43063f89caaSJens Wiklander 4314eb88651SRuchika Gupta static const uint32_t private_key_opt_or_null[] = { 432edd95148SVesa Jääskeläinen PKCS11_CKA_SUBJECT, PKCS11_CKA_UNWRAP_TEMPLATE, 433edd95148SVesa Jääskeläinen PKCS11_CKA_PUBLIC_KEY_INFO, 43463f89caaSJens Wiklander }; 43563f89caaSJens Wiklander 4364eb88651SRuchika Gupta /* PKCS#11 specification for any RSA key (+public/private_key_xxx) */ 4379cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_gen_mand[] = { 43863f89caaSJens Wiklander PKCS11_CKA_MODULUS_BITS, 43963f89caaSJens Wiklander }; 44063f89caaSJens Wiklander 4419cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_create_mand[] = { 44263f89caaSJens Wiklander PKCS11_CKA_MODULUS, PKCS11_CKA_PUBLIC_EXPONENT, 44363f89caaSJens Wiklander }; 44463f89caaSJens Wiklander 4459cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_gen_opt_or_null[] = { 4469cf1afceSVesa Jääskeläinen PKCS11_CKA_PUBLIC_EXPONENT, 4479cf1afceSVesa Jääskeläinen }; 4489cf1afceSVesa Jääskeläinen 4499cf1afceSVesa Jääskeläinen static const uint32_t rsa_priv_key_opt_or_null[] = { 45063f89caaSJens Wiklander PKCS11_CKA_MODULUS, PKCS11_CKA_PUBLIC_EXPONENT, 45163f89caaSJens Wiklander PKCS11_CKA_PRIVATE_EXPONENT, 45263f89caaSJens Wiklander PKCS11_CKA_PRIME_1, PKCS11_CKA_PRIME_2, 45363f89caaSJens Wiklander PKCS11_CKA_EXPONENT_1, PKCS11_CKA_EXPONENT_2, PKCS11_CKA_COEFFICIENT, 45463f89caaSJens Wiklander }; 45563f89caaSJens Wiklander 4564eb88651SRuchika Gupta /* PKCS#11 specification for any EC key (+public/private_key_xxx) */ 4574eb88651SRuchika Gupta static const uint32_t ec_public_key_mandated[] = { 45863f89caaSJens Wiklander PKCS11_CKA_EC_PARAMS, 45963f89caaSJens Wiklander }; 46063f89caaSJens Wiklander 4614eb88651SRuchika Gupta static const uint32_t ec_public_key_opt_or_null[] = { 46263f89caaSJens Wiklander PKCS11_CKA_EC_POINT, 46363f89caaSJens Wiklander }; 46463f89caaSJens Wiklander 4654eb88651SRuchika Gupta static const uint32_t ec_private_key_mandated[] = { 46663f89caaSJens Wiklander }; 46763f89caaSJens Wiklander 4684eb88651SRuchika Gupta static const uint32_t ec_private_key_opt_or_null[] = { 46902b16804SVesa Jääskeläinen PKCS11_CKA_EC_PARAMS, 47063f89caaSJens Wiklander PKCS11_CKA_VALUE, 47163f89caaSJens Wiklander }; 47263f89caaSJens Wiklander 473*03e07432SValerii Chubar static const uint32_t eddsa_private_key_opt_or_null[] = { 474*03e07432SValerii Chubar PKCS11_CKA_EC_PARAMS, 475*03e07432SValerii Chubar PKCS11_CKA_VALUE, 476*03e07432SValerii Chubar PKCS11_CKA_EC_POINT, 477*03e07432SValerii Chubar }; 478*03e07432SValerii Chubar 47963f89caaSJens Wiklander static enum pkcs11_rc create_storage_attributes(struct obj_attrs **out, 48063f89caaSJens Wiklander struct obj_attrs *temp) 48163f89caaSJens Wiklander { 48263f89caaSJens Wiklander enum pkcs11_class_id class = PKCS11_CKO_UNDEFINED_ID; 48363f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 48463f89caaSJens Wiklander 48563f89caaSJens Wiklander rc = init_attributes_head(out); 48663f89caaSJens Wiklander if (rc) 48763f89caaSJens Wiklander return rc; 48863f89caaSJens Wiklander 48963f89caaSJens Wiklander /* Object class is mandatory */ 49063f89caaSJens Wiklander class = get_class(temp); 49163f89caaSJens Wiklander if (class == PKCS11_CKO_UNDEFINED_ID) { 49263f89caaSJens Wiklander EMSG("Class attribute not found"); 49363f89caaSJens Wiklander 49463f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 49563f89caaSJens Wiklander } 49663f89caaSJens Wiklander rc = add_attribute(out, PKCS11_CKA_CLASS, &class, sizeof(uint32_t)); 49763f89caaSJens Wiklander if (rc) 49863f89caaSJens Wiklander return rc; 49963f89caaSJens Wiklander 5004eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, any_object_boolprops, 5014eb88651SRuchika Gupta ARRAY_SIZE(any_object_boolprops)); 50263f89caaSJens Wiklander if (rc) 50363f89caaSJens Wiklander return rc; 50463f89caaSJens Wiklander 5054eb88651SRuchika Gupta return set_attributes_opt_or_null(out, temp, any_object_opt_or_null, 5064eb88651SRuchika Gupta ARRAY_SIZE(any_object_opt_or_null)); 50763f89caaSJens Wiklander } 50863f89caaSJens Wiklander 50963f89caaSJens Wiklander static enum pkcs11_rc create_genkey_attributes(struct obj_attrs **out, 51063f89caaSJens Wiklander struct obj_attrs *temp) 51163f89caaSJens Wiklander { 51263f89caaSJens Wiklander uint32_t type = PKCS11_CKO_UNDEFINED_ID; 51363f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 51463f89caaSJens Wiklander 51563f89caaSJens Wiklander rc = create_storage_attributes(out, temp); 51663f89caaSJens Wiklander if (rc) 51763f89caaSJens Wiklander return rc; 51863f89caaSJens Wiklander 51963f89caaSJens Wiklander type = get_key_type(temp); 52063f89caaSJens Wiklander if (type == PKCS11_CKK_UNDEFINED_ID) { 52163f89caaSJens Wiklander EMSG("Key type attribute not found"); 52263f89caaSJens Wiklander 52363f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 52463f89caaSJens Wiklander } 52563f89caaSJens Wiklander rc = add_attribute(out, PKCS11_CKA_KEY_TYPE, &type, sizeof(uint32_t)); 52663f89caaSJens Wiklander if (rc) 52763f89caaSJens Wiklander return rc; 52863f89caaSJens Wiklander 5294eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, any_key_boolprops, 5304eb88651SRuchika Gupta ARRAY_SIZE(any_key_boolprops)); 53163f89caaSJens Wiklander if (rc) 53263f89caaSJens Wiklander return rc; 53363f89caaSJens Wiklander 5344eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, any_key_opt_or_null, 5354eb88651SRuchika Gupta ARRAY_SIZE(any_key_opt_or_null)); 5364eb88651SRuchika Gupta if (rc) 5374eb88651SRuchika Gupta return rc; 5384eb88651SRuchika Gupta 5394eb88651SRuchika Gupta return set_optional_attributes(out, temp, any_key_optional, 5404eb88651SRuchika Gupta ARRAY_SIZE(any_key_optional)); 5414eb88651SRuchika Gupta 54263f89caaSJens Wiklander } 54363f89caaSJens Wiklander 54463f89caaSJens Wiklander static enum pkcs11_rc create_symm_key_attributes(struct obj_attrs **out, 54563f89caaSJens Wiklander struct obj_attrs *temp) 54663f89caaSJens Wiklander { 54763f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 54863f89caaSJens Wiklander 54963f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_SECRET_KEY); 55063f89caaSJens Wiklander 55163f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 55263f89caaSJens Wiklander if (rc) 55363f89caaSJens Wiklander return rc; 55463f89caaSJens Wiklander 55563f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_SECRET_KEY); 55663f89caaSJens Wiklander 55763f89caaSJens Wiklander switch (get_key_type(*out)) { 55863f89caaSJens Wiklander case PKCS11_CKK_GENERIC_SECRET: 55963f89caaSJens Wiklander case PKCS11_CKK_AES: 56063f89caaSJens Wiklander case PKCS11_CKK_MD5_HMAC: 56163f89caaSJens Wiklander case PKCS11_CKK_SHA_1_HMAC: 56263f89caaSJens Wiklander case PKCS11_CKK_SHA256_HMAC: 56363f89caaSJens Wiklander case PKCS11_CKK_SHA384_HMAC: 56463f89caaSJens Wiklander case PKCS11_CKK_SHA512_HMAC: 56563f89caaSJens Wiklander case PKCS11_CKK_SHA224_HMAC: 56663f89caaSJens Wiklander break; 56763f89caaSJens Wiklander default: 56863f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 56963f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 57063f89caaSJens Wiklander 57163f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 57263f89caaSJens Wiklander } 57363f89caaSJens Wiklander 5744eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, symm_key_boolprops, 5754eb88651SRuchika Gupta ARRAY_SIZE(symm_key_boolprops)); 57663f89caaSJens Wiklander if (rc) 57763f89caaSJens Wiklander return rc; 57863f89caaSJens Wiklander 5790ac5c695SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, symm_key_opt_or_null, 5804eb88651SRuchika Gupta ARRAY_SIZE(symm_key_opt_or_null)); 5810ac5c695SRuchika Gupta if (rc) 5820ac5c695SRuchika Gupta return rc; 5830ac5c695SRuchika Gupta 5840ac5c695SRuchika Gupta return set_optional_attributes(out, temp, symm_key_optional, 5850ac5c695SRuchika Gupta ARRAY_SIZE(symm_key_optional)); 58663f89caaSJens Wiklander } 58763f89caaSJens Wiklander 58863f89caaSJens Wiklander static enum pkcs11_rc create_data_attributes(struct obj_attrs **out, 58963f89caaSJens Wiklander struct obj_attrs *temp) 59063f89caaSJens Wiklander { 59163f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 59263f89caaSJens Wiklander 59363f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_DATA); 59463f89caaSJens Wiklander 59563f89caaSJens Wiklander rc = create_storage_attributes(out, temp); 59663f89caaSJens Wiklander if (rc) 59763f89caaSJens Wiklander return rc; 59863f89caaSJens Wiklander 59963f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_DATA); 60063f89caaSJens Wiklander 6014eb88651SRuchika Gupta return set_attributes_opt_or_null(out, temp, raw_data_opt_or_null, 6024eb88651SRuchika Gupta ARRAY_SIZE(raw_data_opt_or_null)); 60363f89caaSJens Wiklander } 60463f89caaSJens Wiklander 6054137952dSVesa Jääskeläinen static enum pkcs11_rc create_certificate_attributes(struct obj_attrs **out, 6064137952dSVesa Jääskeläinen struct obj_attrs *temp) 6074137952dSVesa Jääskeläinen { 6084137952dSVesa Jääskeläinen uint32_t const *mandated = NULL; 6094137952dSVesa Jääskeläinen uint32_t const *optional = NULL; 6104137952dSVesa Jääskeläinen size_t mandated_count = 0; 6114137952dSVesa Jääskeläinen size_t optional_count = 0; 6124137952dSVesa Jääskeläinen void *attr_value = NULL; 6134137952dSVesa Jääskeläinen uint32_t attr_size = 0; 6144137952dSVesa Jääskeläinen uint32_t default_cert_category = 6154137952dSVesa Jääskeläinen PKCS11_CK_CERTIFICATE_CATEGORY_UNSPECIFIED; 6164137952dSVesa Jääskeläinen uint32_t default_name_hash_alg = PKCS11_CKM_SHA_1; 6174137952dSVesa Jääskeläinen uint32_t cert_category = 0; 6184137952dSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_OK; 6194137952dSVesa Jääskeläinen 6204137952dSVesa Jääskeläinen assert(get_class(temp) == PKCS11_CKO_CERTIFICATE); 6214137952dSVesa Jääskeläinen 6224137952dSVesa Jääskeläinen rc = create_storage_attributes(out, temp); 6234137952dSVesa Jääskeläinen if (rc) 6244137952dSVesa Jääskeläinen return rc; 6254137952dSVesa Jääskeläinen 6264137952dSVesa Jääskeläinen assert(get_class(*out) == PKCS11_CKO_CERTIFICATE); 6274137952dSVesa Jääskeläinen 6284137952dSVesa Jääskeläinen rc = set_mandatory_boolprops(out, temp, pkcs11_certificate_boolprops, 6294137952dSVesa Jääskeläinen ARRAY_SIZE(pkcs11_certificate_boolprops)); 6304137952dSVesa Jääskeläinen if (rc) 6314137952dSVesa Jääskeläinen return rc; 6324137952dSVesa Jääskeläinen 6334137952dSVesa Jääskeläinen rc = set_mandatory_attributes(out, temp, pkcs11_certificate_mandated, 6344137952dSVesa Jääskeläinen ARRAY_SIZE(pkcs11_certificate_mandated)); 6354137952dSVesa Jääskeläinen if (rc) 6364137952dSVesa Jääskeläinen return rc; 6374137952dSVesa Jääskeläinen 6384137952dSVesa Jääskeläinen rc = set_optional_attributes(out, temp, pkcs11_certificate_optional, 6394137952dSVesa Jääskeläinen ARRAY_SIZE(pkcs11_certificate_optional)); 6404137952dSVesa Jääskeläinen if (rc) 6414137952dSVesa Jääskeläinen return rc; 6424137952dSVesa Jääskeläinen 6434137952dSVesa Jääskeläinen switch (get_certificate_type(*out)) { 6444137952dSVesa Jääskeläinen case PKCS11_CKC_X_509: 6454137952dSVesa Jääskeläinen mandated = pkcs11_x509_certificate_mandated; 6464137952dSVesa Jääskeläinen optional = pkcs11_x509_certificate_optional; 6474137952dSVesa Jääskeläinen mandated_count = ARRAY_SIZE(pkcs11_x509_certificate_mandated); 6484137952dSVesa Jääskeläinen optional_count = ARRAY_SIZE(pkcs11_x509_certificate_optional); 6494137952dSVesa Jääskeläinen break; 6504137952dSVesa Jääskeläinen default: 6514137952dSVesa Jääskeläinen EMSG("Invalid certificate type %#"PRIx32"/%s", 6524137952dSVesa Jääskeläinen get_certificate_type(*out), 6534137952dSVesa Jääskeläinen id2str_certificate_type(get_certificate_type(*out))); 6544137952dSVesa Jääskeläinen 6554137952dSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 6564137952dSVesa Jääskeläinen } 6574137952dSVesa Jääskeläinen 6584137952dSVesa Jääskeläinen rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 6594137952dSVesa Jääskeläinen if (rc) 6604137952dSVesa Jääskeläinen return rc; 6614137952dSVesa Jääskeläinen 6624137952dSVesa Jääskeläinen rc = set_optional_attributes(out, temp, optional, optional_count); 6634137952dSVesa Jääskeläinen if (rc) 6644137952dSVesa Jääskeläinen return rc; 6654137952dSVesa Jääskeläinen 6664137952dSVesa Jääskeläinen attr_size = 0; 6674137952dSVesa Jääskeläinen rc = get_attribute_ptr(*out, PKCS11_CKA_CERTIFICATE_CATEGORY, 6684137952dSVesa Jääskeläinen &attr_value, &attr_size); 6694137952dSVesa Jääskeläinen if (rc == PKCS11_CKR_OK && attr_size == sizeof(cert_category)) { 6704137952dSVesa Jääskeläinen /* Sanitize certificate category */ 6714137952dSVesa Jääskeläinen TEE_MemMove(&cert_category, attr_value, sizeof(cert_category)); 6724137952dSVesa Jääskeläinen 6734137952dSVesa Jääskeläinen switch (cert_category) { 6744137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_UNSPECIFIED: 6754137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_TOKEN_USER: 6764137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_AUTHORITY: 6774137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_OTHER_ENTITY: 6784137952dSVesa Jääskeläinen break; 6794137952dSVesa Jääskeläinen default: 6804137952dSVesa Jääskeläinen EMSG("Invalid certificate category %#"PRIx32, 6814137952dSVesa Jääskeläinen cert_category); 6824137952dSVesa Jääskeläinen 6834137952dSVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 6844137952dSVesa Jääskeläinen } 6854137952dSVesa Jääskeläinen } else if (rc == PKCS11_RV_NOT_FOUND) { 6864137952dSVesa Jääskeläinen /* Set default category when missing */ 6874137952dSVesa Jääskeläinen rc = set_attribute(out, PKCS11_CKA_CERTIFICATE_CATEGORY, 6884137952dSVesa Jääskeläinen &default_cert_category, 6894137952dSVesa Jääskeläinen sizeof(default_cert_category)); 6904137952dSVesa Jääskeläinen if (rc) 6914137952dSVesa Jääskeläinen return rc; 6924137952dSVesa Jääskeläinen } else { 6934137952dSVesa Jääskeläinen /* All other cases are errors */ 6944137952dSVesa Jääskeläinen EMSG("Invalid certificate category"); 6954137952dSVesa Jääskeläinen 6964137952dSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 6974137952dSVesa Jääskeläinen } 6984137952dSVesa Jääskeläinen 6994137952dSVesa Jääskeläinen attr_size = 0; 7004137952dSVesa Jääskeläinen rc = get_attribute_ptr(*out, PKCS11_CKA_NAME_HASH_ALGORITHM, NULL, 7014137952dSVesa Jääskeläinen &attr_size); 7024137952dSVesa Jääskeläinen if (rc == PKCS11_CKR_OK && attr_size == sizeof(uint32_t)) { 7034137952dSVesa Jääskeläinen /* We accept any algorithm what caller wanted to specify */ 7044137952dSVesa Jääskeläinen } else if (rc == PKCS11_RV_NOT_FOUND) { 7054137952dSVesa Jääskeläinen /* Set default hash algorithm when missing */ 7064137952dSVesa Jääskeläinen rc = set_attribute(out, PKCS11_CKA_NAME_HASH_ALGORITHM, 7074137952dSVesa Jääskeläinen &default_name_hash_alg, 7084137952dSVesa Jääskeläinen sizeof(default_name_hash_alg)); 7094137952dSVesa Jääskeläinen if (rc) 7104137952dSVesa Jääskeläinen return rc; 7114137952dSVesa Jääskeläinen } else { 7124137952dSVesa Jääskeläinen /* All other cases are errors */ 7134137952dSVesa Jääskeläinen EMSG("Invalid name hash algorithm"); 7144137952dSVesa Jääskeläinen 7154137952dSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 7164137952dSVesa Jääskeläinen } 7174137952dSVesa Jääskeläinen 7184137952dSVesa Jääskeläinen return rc; 7194137952dSVesa Jääskeläinen } 7204137952dSVesa Jääskeläinen 72163f89caaSJens Wiklander static enum pkcs11_rc create_pub_key_attributes(struct obj_attrs **out, 7229cf1afceSVesa Jääskeläinen struct obj_attrs *temp, 7239cf1afceSVesa Jääskeläinen enum processing_func function) 72463f89caaSJens Wiklander { 72563f89caaSJens Wiklander uint32_t const *mandated = NULL; 7269cf1afceSVesa Jääskeläinen uint32_t const *oon = NULL; 72763f89caaSJens Wiklander size_t mandated_count = 0; 7289cf1afceSVesa Jääskeläinen size_t oon_count = 0; 72963f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 73063f89caaSJens Wiklander 73163f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_PUBLIC_KEY); 73263f89caaSJens Wiklander 73363f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 73463f89caaSJens Wiklander if (rc) 73563f89caaSJens Wiklander return rc; 73663f89caaSJens Wiklander 73763f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_PUBLIC_KEY); 73863f89caaSJens Wiklander 7394eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, public_key_boolprops, 7404eb88651SRuchika Gupta ARRAY_SIZE(public_key_boolprops)); 74163f89caaSJens Wiklander if (rc) 74263f89caaSJens Wiklander return rc; 74363f89caaSJens Wiklander 7444eb88651SRuchika Gupta rc = set_mandatory_attributes(out, temp, public_key_mandated, 7454eb88651SRuchika Gupta ARRAY_SIZE(public_key_mandated)); 74663f89caaSJens Wiklander if (rc) 74763f89caaSJens Wiklander return rc; 74863f89caaSJens Wiklander 7494eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, 7504eb88651SRuchika Gupta public_key_opt_or_null, 7514eb88651SRuchika Gupta ARRAY_SIZE(public_key_opt_or_null)); 75263f89caaSJens Wiklander if (rc) 75363f89caaSJens Wiklander return rc; 75463f89caaSJens Wiklander 75563f89caaSJens Wiklander switch (get_key_type(*out)) { 75663f89caaSJens Wiklander case PKCS11_CKK_RSA: 7579cf1afceSVesa Jääskeläinen switch (function) { 7589cf1afceSVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 7599cf1afceSVesa Jääskeläinen mandated = rsa_pub_key_gen_mand; 7609cf1afceSVesa Jääskeläinen oon = rsa_pub_key_gen_opt_or_null; 7619cf1afceSVesa Jääskeläinen mandated_count = ARRAY_SIZE(rsa_pub_key_gen_mand); 7629cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(rsa_pub_key_gen_opt_or_null); 7639cf1afceSVesa Jääskeläinen break; 7649cf1afceSVesa Jääskeläinen case PKCS11_FUNCTION_IMPORT: 7659cf1afceSVesa Jääskeläinen mandated = rsa_pub_key_create_mand; 7669cf1afceSVesa Jääskeläinen mandated_count = ARRAY_SIZE(rsa_pub_key_create_mand); 7679cf1afceSVesa Jääskeläinen break; 7689cf1afceSVesa Jääskeläinen default: 7699cf1afceSVesa Jääskeläinen EMSG("Unsupported function %#"PRIx32"/%s", function, 7709cf1afceSVesa Jääskeläinen id2str_function(function)); 7719cf1afceSVesa Jääskeläinen 7729cf1afceSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 7739cf1afceSVesa Jääskeläinen } 77463f89caaSJens Wiklander break; 77563f89caaSJens Wiklander case PKCS11_CKK_EC: 776*03e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 7774eb88651SRuchika Gupta mandated = ec_public_key_mandated; 7789cf1afceSVesa Jääskeläinen oon = ec_public_key_opt_or_null; 7794eb88651SRuchika Gupta mandated_count = ARRAY_SIZE(ec_public_key_mandated); 7809cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(ec_public_key_opt_or_null); 78163f89caaSJens Wiklander break; 78263f89caaSJens Wiklander default: 78363f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 78463f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 78563f89caaSJens Wiklander 78663f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 78763f89caaSJens Wiklander } 78863f89caaSJens Wiklander 78963f89caaSJens Wiklander rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 79063f89caaSJens Wiklander if (rc) 79163f89caaSJens Wiklander return rc; 79263f89caaSJens Wiklander 7939cf1afceSVesa Jääskeläinen return set_attributes_opt_or_null(out, temp, oon, oon_count); 79463f89caaSJens Wiklander } 79563f89caaSJens Wiklander 79663f89caaSJens Wiklander static enum pkcs11_rc create_priv_key_attributes(struct obj_attrs **out, 79763f89caaSJens Wiklander struct obj_attrs *temp) 79863f89caaSJens Wiklander { 79963f89caaSJens Wiklander uint32_t const *mandated = NULL; 8009cf1afceSVesa Jääskeläinen uint32_t const *oon = NULL; 80163f89caaSJens Wiklander size_t mandated_count = 0; 8029cf1afceSVesa Jääskeläinen size_t oon_count = 0; 80363f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 80463f89caaSJens Wiklander 80563f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_PRIVATE_KEY); 80663f89caaSJens Wiklander 80763f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 80863f89caaSJens Wiklander if (rc) 80963f89caaSJens Wiklander return rc; 81063f89caaSJens Wiklander 81163f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_PRIVATE_KEY); 81263f89caaSJens Wiklander 8134eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, private_key_boolprops, 8144eb88651SRuchika Gupta ARRAY_SIZE(private_key_boolprops)); 81563f89caaSJens Wiklander if (rc) 81663f89caaSJens Wiklander return rc; 81763f89caaSJens Wiklander 8184eb88651SRuchika Gupta rc = set_mandatory_attributes(out, temp, private_key_mandated, 8194eb88651SRuchika Gupta ARRAY_SIZE(private_key_mandated)); 82063f89caaSJens Wiklander if (rc) 82163f89caaSJens Wiklander return rc; 82263f89caaSJens Wiklander 8234eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, private_key_opt_or_null, 8244eb88651SRuchika Gupta ARRAY_SIZE(private_key_opt_or_null)); 82563f89caaSJens Wiklander if (rc) 82663f89caaSJens Wiklander return rc; 82763f89caaSJens Wiklander 82863f89caaSJens Wiklander switch (get_key_type(*out)) { 82963f89caaSJens Wiklander case PKCS11_CKK_RSA: 8309cf1afceSVesa Jääskeläinen oon = rsa_priv_key_opt_or_null; 8319cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(rsa_priv_key_opt_or_null); 83263f89caaSJens Wiklander break; 83363f89caaSJens Wiklander case PKCS11_CKK_EC: 8344eb88651SRuchika Gupta mandated = ec_private_key_mandated; 8359cf1afceSVesa Jääskeläinen oon = ec_private_key_opt_or_null; 8364eb88651SRuchika Gupta mandated_count = ARRAY_SIZE(ec_private_key_mandated); 8379cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(ec_private_key_opt_or_null); 83863f89caaSJens Wiklander break; 839*03e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 840*03e07432SValerii Chubar mandated = ec_private_key_mandated; 841*03e07432SValerii Chubar oon = eddsa_private_key_opt_or_null; 842*03e07432SValerii Chubar mandated_count = ARRAY_SIZE(ec_private_key_mandated); 843*03e07432SValerii Chubar oon_count = ARRAY_SIZE(eddsa_private_key_opt_or_null); 844*03e07432SValerii Chubar break; 84563f89caaSJens Wiklander default: 84663f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 84763f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 84863f89caaSJens Wiklander 84963f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 85063f89caaSJens Wiklander } 85163f89caaSJens Wiklander 85263f89caaSJens Wiklander rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 85363f89caaSJens Wiklander if (rc) 85463f89caaSJens Wiklander return rc; 85563f89caaSJens Wiklander 8569cf1afceSVesa Jääskeläinen return set_attributes_opt_or_null(out, temp, oon, oon_count); 85763f89caaSJens Wiklander } 85863f89caaSJens Wiklander 859196bcd93SRuchika Gupta static enum pkcs11_rc 860196bcd93SRuchika Gupta sanitize_symm_key_attributes(struct obj_attrs **temp, 861196bcd93SRuchika Gupta enum processing_func function) 862196bcd93SRuchika Gupta { 863196bcd93SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK; 864196bcd93SRuchika Gupta uint32_t a_size = 0; 865196bcd93SRuchika Gupta 866196bcd93SRuchika Gupta assert(get_class(*temp) == PKCS11_CKO_SECRET_KEY); 867196bcd93SRuchika Gupta 868196bcd93SRuchika Gupta rc = get_attribute_ptr(*temp, PKCS11_CKA_VALUE, NULL, &a_size); 869196bcd93SRuchika Gupta 870196bcd93SRuchika Gupta switch (get_key_type(*temp)) { 871196bcd93SRuchika Gupta case PKCS11_CKK_GENERIC_SECRET: 872196bcd93SRuchika Gupta case PKCS11_CKK_AES: 873196bcd93SRuchika Gupta case PKCS11_CKK_MD5_HMAC: 874196bcd93SRuchika Gupta case PKCS11_CKK_SHA_1_HMAC: 875196bcd93SRuchika Gupta case PKCS11_CKK_SHA256_HMAC: 876196bcd93SRuchika Gupta case PKCS11_CKK_SHA384_HMAC: 877196bcd93SRuchika Gupta case PKCS11_CKK_SHA512_HMAC: 878196bcd93SRuchika Gupta case PKCS11_CKK_SHA224_HMAC: 879196bcd93SRuchika Gupta switch (function) { 880196bcd93SRuchika Gupta case PKCS11_FUNCTION_IMPORT: 881196bcd93SRuchika Gupta /* CKA_VALUE is a mandatory with C_CreateObject */ 882196bcd93SRuchika Gupta if (rc || a_size == 0) 883196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 884196bcd93SRuchika Gupta 885196bcd93SRuchika Gupta if (get_attribute_ptr(*temp, PKCS11_CKA_VALUE_LEN, NULL, 886196bcd93SRuchika Gupta NULL) != PKCS11_RV_NOT_FOUND) 887196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 888196bcd93SRuchika Gupta 889196bcd93SRuchika Gupta return add_attribute(temp, PKCS11_CKA_VALUE_LEN, 890196bcd93SRuchika Gupta &a_size, sizeof(uint32_t)); 891196bcd93SRuchika Gupta case PKCS11_FUNCTION_GENERATE: 892196bcd93SRuchika Gupta if (rc != PKCS11_RV_NOT_FOUND) 893196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 894196bcd93SRuchika Gupta break; 895196bcd93SRuchika Gupta default: 896196bcd93SRuchika Gupta break; 897196bcd93SRuchika Gupta } 898196bcd93SRuchika Gupta break; 899196bcd93SRuchika Gupta default: 900196bcd93SRuchika Gupta EMSG("Invalid key type %#"PRIx32"/%s", 901196bcd93SRuchika Gupta get_key_type(*temp), id2str_key_type(get_key_type(*temp))); 902196bcd93SRuchika Gupta 903196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 904196bcd93SRuchika Gupta } 905196bcd93SRuchika Gupta 906196bcd93SRuchika Gupta return PKCS11_CKR_OK; 907196bcd93SRuchika Gupta } 908196bcd93SRuchika Gupta 90963f89caaSJens Wiklander /* 91063f89caaSJens Wiklander * Create an attribute list for a new object from a template and a parent 91163f89caaSJens Wiklander * object (optional) for an object generation function (generate, copy, 91263f89caaSJens Wiklander * derive...). 91363f89caaSJens Wiklander * 91463f89caaSJens Wiklander * PKCS#11 directives on the supplied template and expected return value: 91563f89caaSJens Wiklander * - template has an invalid attribute ID: ATTRIBUTE_TYPE_INVALID 91663f89caaSJens Wiklander * - template has an invalid value for an attribute: ATTRIBUTE_VALID_INVALID 91763f89caaSJens Wiklander * - template has value for a read-only attribute: ATTRIBUTE_READ_ONLY 91863f89caaSJens Wiklander * - template+default+parent => still miss an attribute: TEMPLATE_INCONSISTENT 91963f89caaSJens Wiklander * 92063f89caaSJens Wiklander * INFO on PKCS11_CMD_COPY_OBJECT: 92163f89caaSJens Wiklander * - parent PKCS11_CKA_COPYIABLE=false => return ACTION_PROHIBITED. 92263f89caaSJens Wiklander * - template can specify PKCS11_CKA_TOKEN, PKCS11_CKA_PRIVATE, 92363f89caaSJens Wiklander * PKCS11_CKA_MODIFIABLE, PKCS11_CKA_DESTROYABLE. 92463f89caaSJens Wiklander * - SENSITIVE can change from false to true, not from true to false. 92563f89caaSJens Wiklander * - LOCAL is the parent LOCAL 92663f89caaSJens Wiklander */ 92763f89caaSJens Wiklander enum pkcs11_rc 92863f89caaSJens Wiklander create_attributes_from_template(struct obj_attrs **out, void *template, 92963f89caaSJens Wiklander size_t template_size, 93048799892SRuchika Gupta struct obj_attrs *parent, 93163f89caaSJens Wiklander enum processing_func function, 9324cfce748SRuchika Gupta enum pkcs11_mechanism_id mecha, 93302b16804SVesa Jääskeläinen enum pkcs11_class_id template_class) 93463f89caaSJens Wiklander { 93563f89caaSJens Wiklander struct obj_attrs *temp = NULL; 93663f89caaSJens Wiklander struct obj_attrs *attrs = NULL; 93763f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 93863f89caaSJens Wiklander uint8_t local = 0; 93963f89caaSJens Wiklander uint8_t always_sensitive = 0; 94063f89caaSJens Wiklander uint8_t never_extract = 0; 941e3f0cb56SRuchika Gupta uint8_t extractable = 0; 942fa247a2aSRuchika Gupta uint32_t class = PKCS11_UNDEFINED_ID; 943fa247a2aSRuchika Gupta uint32_t type = PKCS11_UNDEFINED_ID; 94463f89caaSJens Wiklander uint32_t mechanism_id = PKCS11_CKM_UNDEFINED_ID; 945e3f0cb56SRuchika Gupta struct obj_attrs *req_attrs = NULL; 946e3f0cb56SRuchika Gupta uint32_t size = 0; 947e3f0cb56SRuchika Gupta uint32_t indirect_template = PKCS11_CKA_UNDEFINED_ID; 94863f89caaSJens Wiklander 94963f89caaSJens Wiklander #ifdef DEBUG /* Sanity: check function argument */ 95063f89caaSJens Wiklander trace_attributes_from_api_head("template", template, template_size); 95163f89caaSJens Wiklander switch (function) { 952fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 953013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 95463f89caaSJens Wiklander case PKCS11_FUNCTION_IMPORT: 9552d25a9bcSRuchika Gupta case PKCS11_FUNCTION_MODIFY: 95648799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 957e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 9582d25a9bcSRuchika Gupta case PKCS11_FUNCTION_COPY: 95963f89caaSJens Wiklander break; 96063f89caaSJens Wiklander default: 96163f89caaSJens Wiklander TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 96263f89caaSJens Wiklander } 96363f89caaSJens Wiklander #endif 96463f89caaSJens Wiklander 965dcad3409SRuchika Gupta /* 966dcad3409SRuchika Gupta * For PKCS11_FUNCTION_GENERATE, find the class and type 967dcad3409SRuchika Gupta * based on the mechanism. These will be passed as hint 968dcad3409SRuchika Gupta * sanitize_client_object() and added in temp if not 969dcad3409SRuchika Gupta * already present 970dcad3409SRuchika Gupta */ 971dcad3409SRuchika Gupta if (function == PKCS11_FUNCTION_GENERATE) { 972fa247a2aSRuchika Gupta switch (mecha) { 973fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 974fa247a2aSRuchika Gupta class = PKCS11_CKO_SECRET_KEY; 975fa247a2aSRuchika Gupta type = PKCS11_CKK_GENERIC_SECRET; 976fa247a2aSRuchika Gupta break; 977fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 978fa247a2aSRuchika Gupta class = PKCS11_CKO_SECRET_KEY; 979fa247a2aSRuchika Gupta type = PKCS11_CKK_AES; 980fa247a2aSRuchika Gupta break; 981fa247a2aSRuchika Gupta default: 982dcad3409SRuchika Gupta TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 983fa247a2aSRuchika Gupta } 984fa247a2aSRuchika Gupta } 985fa247a2aSRuchika Gupta 9862d25a9bcSRuchika Gupta /* 987013934d8SVesa Jääskeläinen * For PKCS11_FUNCTION_GENERATE_PAIR, find the class and type 988013934d8SVesa Jääskeläinen * based on the mechanism. These will be passed as hint 989013934d8SVesa Jääskeläinen * sanitize_client_object() and added in temp if not 990013934d8SVesa Jääskeläinen * already present 991013934d8SVesa Jääskeläinen */ 992013934d8SVesa Jääskeläinen if (function == PKCS11_FUNCTION_GENERATE_PAIR) { 993013934d8SVesa Jääskeläinen switch (mecha) { 994*03e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: 995*03e07432SValerii Chubar class = template_class; 996*03e07432SValerii Chubar type = PKCS11_CKK_EDDSA; 997*03e07432SValerii Chubar break; 99802b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 99902b16804SVesa Jääskeläinen class = template_class; 100002b16804SVesa Jääskeläinen type = PKCS11_CKK_EC; 100102b16804SVesa Jääskeläinen break; 100286922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 100386922832SVesa Jääskeläinen class = template_class; 100486922832SVesa Jääskeläinen type = PKCS11_CKK_RSA; 100586922832SVesa Jääskeläinen break; 1006013934d8SVesa Jääskeläinen default: 1007013934d8SVesa Jääskeläinen TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 1008013934d8SVesa Jääskeläinen } 1009013934d8SVesa Jääskeläinen } 1010013934d8SVesa Jääskeläinen 1011013934d8SVesa Jääskeläinen /* 10122d25a9bcSRuchika Gupta * Check and remove duplicates if any and create a new temporary 10132d25a9bcSRuchika Gupta * template 10142d25a9bcSRuchika Gupta */ 1015dcad3409SRuchika Gupta rc = sanitize_client_object(&temp, template, template_size, class, 1016dcad3409SRuchika Gupta type); 1017dcad3409SRuchika Gupta if (rc) 1018dcad3409SRuchika Gupta goto out; 1019dcad3409SRuchika Gupta 1020dcad3409SRuchika Gupta /* 10212d25a9bcSRuchika Gupta * For function type modify and copy return the created template 10222d25a9bcSRuchika Gupta * from here. Rest of the code below is for creating objects 10232d25a9bcSRuchika Gupta * or generating keys. 10242d25a9bcSRuchika Gupta */ 10252d25a9bcSRuchika Gupta switch (function) { 10262d25a9bcSRuchika Gupta case PKCS11_FUNCTION_MODIFY: 10272d25a9bcSRuchika Gupta case PKCS11_FUNCTION_COPY: 10282d25a9bcSRuchika Gupta *out = temp; 10292d25a9bcSRuchika Gupta return rc; 1030e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 1031e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 1032e3f0cb56SRuchika Gupta if (function == PKCS11_FUNCTION_UNWRAP) 1033e3f0cb56SRuchika Gupta indirect_template = PKCS11_CKA_UNWRAP_TEMPLATE; 1034e3f0cb56SRuchika Gupta else 1035e3f0cb56SRuchika Gupta indirect_template = PKCS11_CKA_DERIVE_TEMPLATE; 1036e3f0cb56SRuchika Gupta 1037e3f0cb56SRuchika Gupta rc = get_attribute_ptr(parent, indirect_template, 1038e3f0cb56SRuchika Gupta (void *)&req_attrs, &size); 1039e3f0cb56SRuchika Gupta if (rc == PKCS11_CKR_OK && size != 0) { 1040e3f0cb56SRuchika Gupta rc = attributes_match_add_reference(&temp, req_attrs); 1041e3f0cb56SRuchika Gupta if (rc) 1042e3f0cb56SRuchika Gupta goto out; 1043e3f0cb56SRuchika Gupta } 1044e3f0cb56SRuchika Gupta break; 10452d25a9bcSRuchika Gupta default: 10462d25a9bcSRuchika Gupta break; 10472d25a9bcSRuchika Gupta } 10482d25a9bcSRuchika Gupta 10492d25a9bcSRuchika Gupta /* 1050dcad3409SRuchika Gupta * Check if class and type in temp are consistent with the mechanism 1051dcad3409SRuchika Gupta */ 1052fa247a2aSRuchika Gupta switch (mecha) { 1053fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1054fa247a2aSRuchika Gupta if (get_class(temp) != PKCS11_CKO_SECRET_KEY || 1055fa247a2aSRuchika Gupta get_key_type(temp) != PKCS11_CKK_GENERIC_SECRET) { 1056fa247a2aSRuchika Gupta rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 1057fa247a2aSRuchika Gupta goto out; 1058fa247a2aSRuchika Gupta } 1059fa247a2aSRuchika Gupta break; 1060fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 1061fa247a2aSRuchika Gupta if (get_class(temp) != PKCS11_CKO_SECRET_KEY || 1062fa247a2aSRuchika Gupta get_key_type(temp) != PKCS11_CKK_AES) { 1063fa247a2aSRuchika Gupta rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 1064fa247a2aSRuchika Gupta goto out; 1065fa247a2aSRuchika Gupta } 1066fa247a2aSRuchika Gupta break; 106702b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 106802b16804SVesa Jääskeläinen if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && 106902b16804SVesa Jääskeläinen get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || 107002b16804SVesa Jääskeläinen get_key_type(temp) != PKCS11_CKK_EC) { 107102b16804SVesa Jääskeläinen rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 107202b16804SVesa Jääskeläinen goto out; 107302b16804SVesa Jääskeläinen } 107402b16804SVesa Jääskeläinen break; 1075*03e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: 1076*03e07432SValerii Chubar if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && 1077*03e07432SValerii Chubar get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || 1078*03e07432SValerii Chubar get_key_type(temp) != PKCS11_CKK_EC_EDWARDS) { 1079*03e07432SValerii Chubar rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 1080*03e07432SValerii Chubar goto out; 1081*03e07432SValerii Chubar } 1082*03e07432SValerii Chubar break; 108386922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 108486922832SVesa Jääskeläinen if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && 108586922832SVesa Jääskeläinen get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || 108686922832SVesa Jääskeläinen get_key_type(temp) != PKCS11_CKK_RSA) { 108786922832SVesa Jääskeläinen rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 108886922832SVesa Jääskeläinen goto out; 108986922832SVesa Jääskeläinen } 109086922832SVesa Jääskeläinen break; 1091fa247a2aSRuchika Gupta default: 1092fa247a2aSRuchika Gupta break; 1093fa247a2aSRuchika Gupta } 109463f89caaSJens Wiklander 109563f89caaSJens Wiklander if (!sanitize_consistent_class_and_type(temp)) { 109663f89caaSJens Wiklander EMSG("Inconsistent class/type"); 109763f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 109863f89caaSJens Wiklander goto out; 109963f89caaSJens Wiklander } 110063f89caaSJens Wiklander 1101e3f0cb56SRuchika Gupta /* 1102e3f0cb56SRuchika Gupta * TBD - Add a check to see if temp contains any attribute which 1103e3f0cb56SRuchika Gupta * is not consistent with the object class or type and return error. 1104e3f0cb56SRuchika Gupta * In current implementation such attributes are ignored and not 1105e3f0cb56SRuchika Gupta * added to final object while PKCS#11 specification expects a 1106e3f0cb56SRuchika Gupta * failure and an error code be returned. 1107e3f0cb56SRuchika Gupta */ 1108e3f0cb56SRuchika Gupta 110963f89caaSJens Wiklander switch (get_class(temp)) { 111063f89caaSJens Wiklander case PKCS11_CKO_DATA: 111163f89caaSJens Wiklander rc = create_data_attributes(&attrs, temp); 111263f89caaSJens Wiklander break; 11134137952dSVesa Jääskeläinen case PKCS11_CKO_CERTIFICATE: 11144137952dSVesa Jääskeläinen rc = create_certificate_attributes(&attrs, temp); 11154137952dSVesa Jääskeläinen break; 111663f89caaSJens Wiklander case PKCS11_CKO_SECRET_KEY: 1117196bcd93SRuchika Gupta rc = sanitize_symm_key_attributes(&temp, function); 1118196bcd93SRuchika Gupta if (rc) 1119196bcd93SRuchika Gupta goto out; 112063f89caaSJens Wiklander rc = create_symm_key_attributes(&attrs, temp); 112163f89caaSJens Wiklander break; 112263f89caaSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 11239cf1afceSVesa Jääskeläinen rc = create_pub_key_attributes(&attrs, temp, function); 112463f89caaSJens Wiklander break; 112563f89caaSJens Wiklander case PKCS11_CKO_PRIVATE_KEY: 112663f89caaSJens Wiklander rc = create_priv_key_attributes(&attrs, temp); 112763f89caaSJens Wiklander break; 112863f89caaSJens Wiklander default: 112963f89caaSJens Wiklander DMSG("Invalid object class %#"PRIx32"/%s", 113063f89caaSJens Wiklander get_class(temp), id2str_class(get_class(temp))); 113163f89caaSJens Wiklander 113263f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 113363f89caaSJens Wiklander break; 113463f89caaSJens Wiklander } 113563f89caaSJens Wiklander if (rc) 113663f89caaSJens Wiklander goto out; 113763f89caaSJens Wiklander 113890c47fe2SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_LOCAL, NULL, NULL) != 1139002f6b93SEtienne Carriere PKCS11_RV_NOT_FOUND) { 1140002f6b93SEtienne Carriere rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 114163f89caaSJens Wiklander goto out; 1142002f6b93SEtienne Carriere } 114363f89caaSJens Wiklander 114490c47fe2SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_KEY_GEN_MECHANISM, NULL, NULL) != 1145002f6b93SEtienne Carriere PKCS11_RV_NOT_FOUND) { 1146002f6b93SEtienne Carriere rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 114763f89caaSJens Wiklander goto out; 1148002f6b93SEtienne Carriere } 114963f89caaSJens Wiklander 115063f89caaSJens Wiklander switch (function) { 1151fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 1152013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 1153fa247a2aSRuchika Gupta local = PKCS11_TRUE; 1154fa247a2aSRuchika Gupta break; 115563f89caaSJens Wiklander case PKCS11_FUNCTION_IMPORT: 115648799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 1157e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 115863f89caaSJens Wiklander default: 115963f89caaSJens Wiklander local = PKCS11_FALSE; 116063f89caaSJens Wiklander break; 116163f89caaSJens Wiklander } 116263f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_LOCAL, &local, sizeof(local)); 116363f89caaSJens Wiklander if (rc) 116463f89caaSJens Wiklander goto out; 116563f89caaSJens Wiklander 116663f89caaSJens Wiklander switch (get_class(attrs)) { 116763f89caaSJens Wiklander case PKCS11_CKO_SECRET_KEY: 116863f89caaSJens Wiklander case PKCS11_CKO_PRIVATE_KEY: 116963f89caaSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 117063f89caaSJens Wiklander always_sensitive = PKCS11_FALSE; 117163f89caaSJens Wiklander never_extract = PKCS11_FALSE; 117263f89caaSJens Wiklander 1173fa247a2aSRuchika Gupta switch (function) { 117448799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 117548799892SRuchika Gupta always_sensitive = 117648799892SRuchika Gupta get_bool(parent, PKCS11_CKA_ALWAYS_SENSITIVE) && 117748799892SRuchika Gupta get_bool(attrs, PKCS11_CKA_SENSITIVE); 117848799892SRuchika Gupta never_extract = 117948799892SRuchika Gupta get_bool(parent, PKCS11_CKA_NEVER_EXTRACTABLE) && 118048799892SRuchika Gupta !get_bool(attrs, PKCS11_CKA_EXTRACTABLE); 118148799892SRuchika Gupta break; 1182e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 1183e3f0cb56SRuchika Gupta always_sensitive = PKCS11_FALSE; 1184e3f0cb56SRuchika Gupta never_extract = PKCS11_FALSE; 1185e3f0cb56SRuchika Gupta extractable = PKCS11_TRUE; 1186e3f0cb56SRuchika Gupta 1187e3f0cb56SRuchika Gupta /* 1188e3f0cb56SRuchika Gupta * Check if template passed by user has CKA_EXTRACTABLE. 1189e3f0cb56SRuchika Gupta * If not, by default value of CKA_EXTRACTABLE is set as 1190e3f0cb56SRuchika Gupta * TRUE. 1191e3f0cb56SRuchika Gupta */ 1192e3f0cb56SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_EXTRACTABLE, 1193e3f0cb56SRuchika Gupta NULL, 1194e3f0cb56SRuchika Gupta NULL) == PKCS11_RV_NOT_FOUND) { 1195e3f0cb56SRuchika Gupta rc = set_attribute(&attrs, 1196e3f0cb56SRuchika Gupta PKCS11_CKA_EXTRACTABLE, 1197e3f0cb56SRuchika Gupta &extractable, 1198e3f0cb56SRuchika Gupta sizeof(extractable)); 1199e3f0cb56SRuchika Gupta if (rc) 1200e3f0cb56SRuchika Gupta goto out; 1201e3f0cb56SRuchika Gupta } 1202e3f0cb56SRuchika Gupta break; 1203fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 1204013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 1205fa247a2aSRuchika Gupta always_sensitive = get_bool(attrs, 1206fa247a2aSRuchika Gupta PKCS11_CKA_SENSITIVE); 1207fa247a2aSRuchika Gupta never_extract = !get_bool(attrs, 1208fa247a2aSRuchika Gupta PKCS11_CKA_EXTRACTABLE); 1209fa247a2aSRuchika Gupta break; 1210fa247a2aSRuchika Gupta default: 1211fa247a2aSRuchika Gupta break; 1212fa247a2aSRuchika Gupta } 1213fa247a2aSRuchika Gupta 121463f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_ALWAYS_SENSITIVE, 121563f89caaSJens Wiklander &always_sensitive, sizeof(always_sensitive)); 121663f89caaSJens Wiklander if (rc) 121763f89caaSJens Wiklander goto out; 121863f89caaSJens Wiklander 121963f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_NEVER_EXTRACTABLE, 122063f89caaSJens Wiklander &never_extract, sizeof(never_extract)); 122163f89caaSJens Wiklander if (rc) 122263f89caaSJens Wiklander goto out; 122363f89caaSJens Wiklander 122463f89caaSJens Wiklander /* Keys mandate attribute PKCS11_CKA_KEY_GEN_MECHANISM */ 1225fa247a2aSRuchika Gupta if (local) 1226fa247a2aSRuchika Gupta mechanism_id = mecha; 1227fa247a2aSRuchika Gupta else 122863f89caaSJens Wiklander mechanism_id = PKCS11_CK_UNAVAILABLE_INFORMATION; 1229fa247a2aSRuchika Gupta 123063f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_KEY_GEN_MECHANISM, 123163f89caaSJens Wiklander &mechanism_id, sizeof(mechanism_id)); 123263f89caaSJens Wiklander if (rc) 123363f89caaSJens Wiklander goto out; 123463f89caaSJens Wiklander break; 123563f89caaSJens Wiklander 123663f89caaSJens Wiklander default: 123763f89caaSJens Wiklander break; 123863f89caaSJens Wiklander } 123963f89caaSJens Wiklander 124063f89caaSJens Wiklander *out = attrs; 124163f89caaSJens Wiklander 124263f89caaSJens Wiklander #ifdef DEBUG 124363f89caaSJens Wiklander trace_attributes("object", attrs); 124463f89caaSJens Wiklander #endif 124563f89caaSJens Wiklander 124663f89caaSJens Wiklander out: 124763f89caaSJens Wiklander TEE_Free(temp); 124863f89caaSJens Wiklander if (rc) 124963f89caaSJens Wiklander TEE_Free(attrs); 125063f89caaSJens Wiklander 125163f89caaSJens Wiklander return rc; 125263f89caaSJens Wiklander } 125363f89caaSJens Wiklander 125463f89caaSJens Wiklander static enum pkcs11_rc check_attrs_misc_integrity(struct obj_attrs *head) 125563f89caaSJens Wiklander { 125663f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_NEVER_EXTRACTABLE) && 125763f89caaSJens Wiklander get_bool(head, PKCS11_CKA_EXTRACTABLE)) { 125863f89caaSJens Wiklander DMSG("Never/Extractable attributes mismatch %d/%d", 125963f89caaSJens Wiklander get_bool(head, PKCS11_CKA_NEVER_EXTRACTABLE), 126063f89caaSJens Wiklander get_bool(head, PKCS11_CKA_EXTRACTABLE)); 126163f89caaSJens Wiklander 126263f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 126363f89caaSJens Wiklander } 126463f89caaSJens Wiklander 126563f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_ALWAYS_SENSITIVE) && 126663f89caaSJens Wiklander !get_bool(head, PKCS11_CKA_SENSITIVE)) { 126763f89caaSJens Wiklander DMSG("Sensitive/always attributes mismatch %d/%d", 126863f89caaSJens Wiklander get_bool(head, PKCS11_CKA_SENSITIVE), 126963f89caaSJens Wiklander get_bool(head, PKCS11_CKA_ALWAYS_SENSITIVE)); 127063f89caaSJens Wiklander 127163f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 127263f89caaSJens Wiklander } 127363f89caaSJens Wiklander 127463f89caaSJens Wiklander return PKCS11_CKR_OK; 127563f89caaSJens Wiklander } 127663f89caaSJens Wiklander 127789735787SRuchika Gupta bool object_is_private(struct obj_attrs *head) 127889735787SRuchika Gupta { 127965fb9092SVesa Jääskeläinen return get_bool(head, PKCS11_CKA_PRIVATE); 128089735787SRuchika Gupta } 128189735787SRuchika Gupta 12822d25a9bcSRuchika Gupta bool object_is_token(struct obj_attrs *head) 12832d25a9bcSRuchika Gupta { 12842d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_TOKEN); 12852d25a9bcSRuchika Gupta } 12862d25a9bcSRuchika Gupta 12872d25a9bcSRuchika Gupta bool object_is_modifiable(struct obj_attrs *head) 12882d25a9bcSRuchika Gupta { 12892d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_MODIFIABLE); 12902d25a9bcSRuchika Gupta } 12912d25a9bcSRuchika Gupta 12922d25a9bcSRuchika Gupta bool object_is_copyable(struct obj_attrs *head) 12932d25a9bcSRuchika Gupta { 12942d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_COPYABLE); 12952d25a9bcSRuchika Gupta } 12962d25a9bcSRuchika Gupta 129763f89caaSJens Wiklander /* 1298512cbf1dSJens Wiklander * Check access to object against authentication to token 1299512cbf1dSJens Wiklander */ 1300512cbf1dSJens Wiklander enum pkcs11_rc check_access_attrs_against_token(struct pkcs11_session *session, 1301512cbf1dSJens Wiklander struct obj_attrs *head) 1302512cbf1dSJens Wiklander { 1303512cbf1dSJens Wiklander bool private = true; 1304512cbf1dSJens Wiklander 1305512cbf1dSJens Wiklander switch (get_class(head)) { 1306512cbf1dSJens Wiklander case PKCS11_CKO_SECRET_KEY: 130765fb9092SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1308512cbf1dSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 1309512cbf1dSJens Wiklander case PKCS11_CKO_DATA: 13104137952dSVesa Jääskeläinen case PKCS11_CKO_CERTIFICATE: 131165fb9092SVesa Jääskeläinen private = object_is_private(head); 1312512cbf1dSJens Wiklander break; 1313512cbf1dSJens Wiklander default: 1314512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1315512cbf1dSJens Wiklander } 1316512cbf1dSJens Wiklander 13175db0fef4SRuchika Gupta if (private && (pkcs11_session_is_public(session) || 13185db0fef4SRuchika Gupta pkcs11_session_is_so(session))) { 13195db0fef4SRuchika Gupta DMSG("Private object access from a public or SO session"); 1320512cbf1dSJens Wiklander 132112f1ba86SRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 1322512cbf1dSJens Wiklander } 1323512cbf1dSJens Wiklander 1324512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1325512cbf1dSJens Wiklander } 1326512cbf1dSJens Wiklander 1327512cbf1dSJens Wiklander /* 132863f89caaSJens Wiklander * Check the attributes of a to-be-created object matches the token state 132963f89caaSJens Wiklander */ 133063f89caaSJens Wiklander enum pkcs11_rc check_created_attrs_against_token(struct pkcs11_session *session, 133163f89caaSJens Wiklander struct obj_attrs *head) 133263f89caaSJens Wiklander { 133363f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 133463f89caaSJens Wiklander 133563f89caaSJens Wiklander rc = check_attrs_misc_integrity(head); 133663f89caaSJens Wiklander if (rc) 133763f89caaSJens Wiklander return rc; 133863f89caaSJens Wiklander 133963f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_TRUSTED) && 134063f89caaSJens Wiklander !pkcs11_session_is_so(session)) { 134163f89caaSJens Wiklander DMSG("Can't create trusted object"); 134263f89caaSJens Wiklander 134363f89caaSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 134463f89caaSJens Wiklander } 134563f89caaSJens Wiklander 134663f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_TOKEN) && 134763f89caaSJens Wiklander !pkcs11_session_is_read_write(session)) { 134863f89caaSJens Wiklander DMSG("Can't create persistent object"); 134963f89caaSJens Wiklander 135063f89caaSJens Wiklander return PKCS11_CKR_SESSION_READ_ONLY; 135163f89caaSJens Wiklander } 135263f89caaSJens Wiklander 135363f89caaSJens Wiklander /* 135463f89caaSJens Wiklander * TODO: START_DATE and END_DATE: complies with current time? 135563f89caaSJens Wiklander */ 135663f89caaSJens Wiklander return PKCS11_CKR_OK; 135763f89caaSJens Wiklander } 135863f89caaSJens Wiklander 135963f89caaSJens Wiklander #define DMSG_BAD_BBOOL(attr, proc, head) \ 136063f89caaSJens Wiklander do { \ 136163f89caaSJens Wiklander uint32_t __maybe_unused _attr = (attr); \ 136263f89caaSJens Wiklander uint8_t __maybe_unused _bvalue = 0; \ 136363f89caaSJens Wiklander enum pkcs11_rc __maybe_unused _rc = PKCS11_CKR_OK; \ 136463f89caaSJens Wiklander \ 136563f89caaSJens Wiklander _rc = get_attribute((head), _attr, &_bvalue, NULL); \ 136663f89caaSJens Wiklander DMSG("%s issue for %s: %sfound, value %"PRIu8, \ 136763f89caaSJens Wiklander id2str_attr(_attr), id2str_proc((proc)), \ 136863f89caaSJens Wiklander _rc ? "not " : "", _bvalue); \ 136963f89caaSJens Wiklander } while (0) 137063f89caaSJens Wiklander 137163f89caaSJens Wiklander static bool __maybe_unused check_attr_bval(uint32_t proc_id __maybe_unused, 137263f89caaSJens Wiklander struct obj_attrs *head, 137363f89caaSJens Wiklander uint32_t attribute, bool val) 137463f89caaSJens Wiklander { 137563f89caaSJens Wiklander uint8_t bbool = 0; 137663f89caaSJens Wiklander uint32_t sz = sizeof(bbool); 137763f89caaSJens Wiklander 137863f89caaSJens Wiklander if (!get_attribute(head, attribute, &bbool, &sz) && !!bbool == val) 137963f89caaSJens Wiklander return true; 138063f89caaSJens Wiklander 138163f89caaSJens Wiklander DMSG_BAD_BBOOL(attribute, proc_id, head); 138263f89caaSJens Wiklander return false; 138363f89caaSJens Wiklander } 138463f89caaSJens Wiklander 138563f89caaSJens Wiklander /* 138663f89caaSJens Wiklander * Check the attributes of a new secret match the processing/mechanism 138763f89caaSJens Wiklander * used to create it. 138863f89caaSJens Wiklander * 138963f89caaSJens Wiklander * @proc_id - PKCS11_CKM_xxx 139063f89caaSJens Wiklander * @head - head of the attributes of the to-be-created object. 139163f89caaSJens Wiklander */ 139263f89caaSJens Wiklander enum pkcs11_rc check_created_attrs_against_processing(uint32_t proc_id, 139363f89caaSJens Wiklander struct obj_attrs *head) 139463f89caaSJens Wiklander { 139563f89caaSJens Wiklander /* 139663f89caaSJens Wiklander * Processings that do not create secrets are not expected to call 139763f89caaSJens Wiklander * this function which would panic. 139863f89caaSJens Wiklander */ 139963f89caaSJens Wiklander switch (proc_id) { 140063f89caaSJens Wiklander case PKCS11_PROCESSING_IMPORT: 1401cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 1402e3f0cb56SRuchika Gupta case PKCS11_CKM_AES_ECB: 1403e3f0cb56SRuchika Gupta case PKCS11_CKM_AES_CBC: 140448799892SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 140548799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 140663f89caaSJens Wiklander assert(check_attr_bval(proc_id, head, PKCS11_CKA_LOCAL, false)); 140763f89caaSJens Wiklander break; 1408fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1409fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 1410*03e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: 141102b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 141286922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 1413fa247a2aSRuchika Gupta assert(check_attr_bval(proc_id, head, PKCS11_CKA_LOCAL, true)); 1414fa247a2aSRuchika Gupta break; 141563f89caaSJens Wiklander default: 141663f89caaSJens Wiklander TEE_Panic(proc_id); 141763f89caaSJens Wiklander break; 141863f89caaSJens Wiklander } 141963f89caaSJens Wiklander 1420fa247a2aSRuchika Gupta switch (proc_id) { 1421fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1422fa247a2aSRuchika Gupta assert(get_key_type(head) == PKCS11_CKK_GENERIC_SECRET); 1423fa247a2aSRuchika Gupta break; 1424fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 1425fa247a2aSRuchika Gupta assert(get_key_type(head) == PKCS11_CKK_AES); 1426fa247a2aSRuchika Gupta break; 1427*03e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: 1428*03e07432SValerii Chubar assert(get_key_type(head) == PKCS11_CKK_EC_EDWARDS); 1429*03e07432SValerii Chubar break; 143002b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 143102b16804SVesa Jääskeläinen assert(get_key_type(head) == PKCS11_CKK_EC); 143202b16804SVesa Jääskeläinen break; 143386922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 143486922832SVesa Jääskeläinen assert(get_key_type(head) == PKCS11_CKK_RSA); 143586922832SVesa Jääskeläinen break; 1436fa247a2aSRuchika Gupta case PKCS11_PROCESSING_IMPORT: 1437cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 1438fa247a2aSRuchika Gupta default: 1439fa247a2aSRuchika Gupta break; 1440fa247a2aSRuchika Gupta } 1441fa247a2aSRuchika Gupta 144263f89caaSJens Wiklander return PKCS11_CKR_OK; 144363f89caaSJens Wiklander } 1444512cbf1dSJens Wiklander 14452d0cd829SRuchika Gupta /* Return min and max key size supported for a key_type in bytes */ 1446512cbf1dSJens Wiklander static void get_key_min_max_sizes(enum pkcs11_key_type key_type, 1447512cbf1dSJens Wiklander uint32_t *min_key_size, 1448512cbf1dSJens Wiklander uint32_t *max_key_size) 1449512cbf1dSJens Wiklander { 1450512cbf1dSJens Wiklander enum pkcs11_mechanism_id mechanism = PKCS11_CKM_UNDEFINED_ID; 1451512cbf1dSJens Wiklander 1452512cbf1dSJens Wiklander switch (key_type) { 1453fa247a2aSRuchika Gupta case PKCS11_CKK_GENERIC_SECRET: 1454fa247a2aSRuchika Gupta mechanism = PKCS11_CKM_GENERIC_SECRET_KEY_GEN; 1455fa247a2aSRuchika Gupta break; 1456512cbf1dSJens Wiklander case PKCS11_CKK_AES: 1457512cbf1dSJens Wiklander mechanism = PKCS11_CKM_AES_KEY_GEN; 1458512cbf1dSJens Wiklander break; 14591f45c9cfSRuchika Gupta case PKCS11_CKK_MD5_HMAC: 14601f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_MD5_HMAC; 14611f45c9cfSRuchika Gupta break; 14621f45c9cfSRuchika Gupta case PKCS11_CKK_SHA_1_HMAC: 14631f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA_1_HMAC; 14641f45c9cfSRuchika Gupta break; 14651f45c9cfSRuchika Gupta case PKCS11_CKK_SHA224_HMAC: 14661f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA224_HMAC; 14671f45c9cfSRuchika Gupta break; 1468a339a354SEtienne Carriere case PKCS11_CKK_SHA256_HMAC: 1469a339a354SEtienne Carriere mechanism = PKCS11_CKM_SHA256_HMAC; 1470a339a354SEtienne Carriere break; 14711f45c9cfSRuchika Gupta case PKCS11_CKK_SHA384_HMAC: 14721f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA384_HMAC; 14731f45c9cfSRuchika Gupta break; 14741f45c9cfSRuchika Gupta case PKCS11_CKK_SHA512_HMAC: 14751f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA512_HMAC; 14761f45c9cfSRuchika Gupta break; 1477db28c542SVesa Jääskeläinen case PKCS11_CKK_EC: 1478db28c542SVesa Jääskeläinen mechanism = PKCS11_CKM_EC_KEY_PAIR_GEN; 1479db28c542SVesa Jääskeläinen break; 1480*03e07432SValerii Chubar case PKCS11_CKK_EDDSA: 1481*03e07432SValerii Chubar mechanism = PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN; 1482*03e07432SValerii Chubar break; 148386922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 148486922832SVesa Jääskeläinen mechanism = PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN; 148586922832SVesa Jääskeläinen break; 1486512cbf1dSJens Wiklander default: 1487512cbf1dSJens Wiklander TEE_Panic(key_type); 1488512cbf1dSJens Wiklander break; 1489512cbf1dSJens Wiklander } 1490512cbf1dSJens Wiklander 14912d0cd829SRuchika Gupta mechanism_supported_key_sizes_bytes(mechanism, min_key_size, 1492512cbf1dSJens Wiklander max_key_size); 1493512cbf1dSJens Wiklander } 1494512cbf1dSJens Wiklander 1495512cbf1dSJens Wiklander enum pkcs11_rc check_created_attrs(struct obj_attrs *key1, 1496512cbf1dSJens Wiklander struct obj_attrs *key2) 1497512cbf1dSJens Wiklander { 1498512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 1499512cbf1dSJens Wiklander struct obj_attrs *secret = NULL; 1500013934d8SVesa Jääskeläinen struct obj_attrs *private = NULL; 1501013934d8SVesa Jääskeläinen struct obj_attrs *public = NULL; 1502512cbf1dSJens Wiklander uint32_t max_key_size = 0; 1503512cbf1dSJens Wiklander uint32_t min_key_size = 0; 1504512cbf1dSJens Wiklander uint32_t key_length = 0; 1505512cbf1dSJens Wiklander 1506512cbf1dSJens Wiklander switch (get_class(key1)) { 1507512cbf1dSJens Wiklander case PKCS11_CKO_SECRET_KEY: 1508512cbf1dSJens Wiklander secret = key1; 1509512cbf1dSJens Wiklander break; 1510013934d8SVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 1511013934d8SVesa Jääskeläinen public = key1; 1512013934d8SVesa Jääskeläinen break; 1513013934d8SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1514013934d8SVesa Jääskeläinen private = key1; 1515013934d8SVesa Jääskeläinen break; 1516512cbf1dSJens Wiklander default: 1517512cbf1dSJens Wiklander return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 1518512cbf1dSJens Wiklander } 1519512cbf1dSJens Wiklander 1520013934d8SVesa Jääskeläinen if (key2) { 1521013934d8SVesa Jääskeläinen switch (get_class(key2)) { 1522013934d8SVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 1523013934d8SVesa Jääskeläinen public = key2; 1524013934d8SVesa Jääskeläinen if (private == key1) 1525013934d8SVesa Jääskeläinen break; 1526013934d8SVesa Jääskeläinen 1527013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1528013934d8SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1529013934d8SVesa Jääskeläinen private = key2; 1530013934d8SVesa Jääskeläinen if (public == key1) 1531013934d8SVesa Jääskeläinen break; 1532013934d8SVesa Jääskeläinen 1533013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1534013934d8SVesa Jääskeläinen default: 1535512cbf1dSJens Wiklander return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 1536013934d8SVesa Jääskeläinen } 1537013934d8SVesa Jääskeläinen 1538013934d8SVesa Jääskeläinen if (get_key_type(private) != get_key_type(public)) 1539013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1540013934d8SVesa Jääskeläinen } 1541512cbf1dSJens Wiklander 1542512cbf1dSJens Wiklander if (secret) { 1543512cbf1dSJens Wiklander switch (get_key_type(secret)) { 1544512cbf1dSJens Wiklander case PKCS11_CKK_AES: 1545512cbf1dSJens Wiklander case PKCS11_CKK_GENERIC_SECRET: 1546512cbf1dSJens Wiklander case PKCS11_CKK_MD5_HMAC: 1547512cbf1dSJens Wiklander case PKCS11_CKK_SHA_1_HMAC: 1548512cbf1dSJens Wiklander case PKCS11_CKK_SHA224_HMAC: 1549512cbf1dSJens Wiklander case PKCS11_CKK_SHA256_HMAC: 1550512cbf1dSJens Wiklander case PKCS11_CKK_SHA384_HMAC: 1551512cbf1dSJens Wiklander case PKCS11_CKK_SHA512_HMAC: 1552512cbf1dSJens Wiklander break; 1553512cbf1dSJens Wiklander default: 1554512cbf1dSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1555512cbf1dSJens Wiklander } 1556512cbf1dSJens Wiklander 1557512cbf1dSJens Wiklander /* Get key size */ 1558512cbf1dSJens Wiklander rc = get_u32_attribute(secret, PKCS11_CKA_VALUE_LEN, 1559512cbf1dSJens Wiklander &key_length); 1560512cbf1dSJens Wiklander if (rc) 1561d1d44372SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCOMPLETE; 1562512cbf1dSJens Wiklander } 1563013934d8SVesa Jääskeläinen if (public) { 1564013934d8SVesa Jääskeläinen switch (get_key_type(public)) { 156586922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 156686922832SVesa Jääskeläinen /* Get key size */ 156786922832SVesa Jääskeläinen rc = get_u32_attribute(public, PKCS11_CKA_MODULUS_BITS, 156886922832SVesa Jääskeläinen &key_length); 156986922832SVesa Jääskeläinen if (rc) 157086922832SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 157186922832SVesa Jääskeläinen key_length = ROUNDUP(key_length, 8) / 8; 157286922832SVesa Jääskeläinen break; 157302b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 1574*03e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 157502b16804SVesa Jääskeläinen break; 1576013934d8SVesa Jääskeläinen default: 1577013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1578013934d8SVesa Jääskeläinen } 1579013934d8SVesa Jääskeläinen } 1580013934d8SVesa Jääskeläinen if (private) { 1581013934d8SVesa Jääskeläinen switch (get_key_type(private)) { 158286922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 158302b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 1584*03e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 158502b16804SVesa Jääskeläinen break; 1586013934d8SVesa Jääskeläinen default: 1587013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1588013934d8SVesa Jääskeläinen } 1589013934d8SVesa Jääskeläinen } 1590512cbf1dSJens Wiklander 159102b16804SVesa Jääskeläinen /* 159202b16804SVesa Jääskeläinen * Check key size for symmetric keys and RSA keys 159302b16804SVesa Jääskeläinen * EC is bound to domains, no need to check here. 159402b16804SVesa Jääskeläinen */ 159502b16804SVesa Jääskeläinen switch (get_key_type(key1)) { 159602b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 1597*03e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 159802b16804SVesa Jääskeläinen return PKCS11_CKR_OK; 159902b16804SVesa Jääskeläinen default: 160002b16804SVesa Jääskeläinen break; 160102b16804SVesa Jääskeläinen } 160202b16804SVesa Jääskeläinen 1603512cbf1dSJens Wiklander get_key_min_max_sizes(get_key_type(key1), &min_key_size, &max_key_size); 1604512cbf1dSJens Wiklander if (key_length < min_key_size || key_length > max_key_size) { 1605512cbf1dSJens Wiklander EMSG("Length %"PRIu32" vs range [%"PRIu32" %"PRIu32"]", 1606512cbf1dSJens Wiklander key_length, min_key_size, max_key_size); 1607512cbf1dSJens Wiklander 1608512cbf1dSJens Wiklander return PKCS11_CKR_KEY_SIZE_RANGE; 1609512cbf1dSJens Wiklander } 1610512cbf1dSJens Wiklander 161149ed60abSRuchika Gupta if (secret && get_key_type(secret) == PKCS11_CKK_AES) { 161249ed60abSRuchika Gupta if (key_length != 16 && key_length != 24 && key_length != 32) 161349ed60abSRuchika Gupta return PKCS11_CKR_KEY_SIZE_RANGE; 161449ed60abSRuchika Gupta } 161549ed60abSRuchika Gupta 1616512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1617512cbf1dSJens Wiklander } 1618512cbf1dSJens Wiklander 1619512cbf1dSJens Wiklander /* Check processing ID against attribute ALLOWED_MECHANISMS if any */ 1620512cbf1dSJens Wiklander static bool parent_key_complies_allowed_processings(uint32_t proc_id, 1621512cbf1dSJens Wiklander struct obj_attrs *head) 1622512cbf1dSJens Wiklander { 1623512cbf1dSJens Wiklander char *attr = NULL; 1624512cbf1dSJens Wiklander uint32_t size = 0; 1625512cbf1dSJens Wiklander uint32_t proc = 0; 1626512cbf1dSJens Wiklander size_t count = 0; 16276a760c9eSEtienne Carriere enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 1628512cbf1dSJens Wiklander 16296a760c9eSEtienne Carriere rc = get_attribute_ptr(head, PKCS11_CKA_ALLOWED_MECHANISMS, 16306a760c9eSEtienne Carriere (void *)&attr, &size); 16316a760c9eSEtienne Carriere if (rc == PKCS11_RV_NOT_FOUND) 1632512cbf1dSJens Wiklander return true; 16336a760c9eSEtienne Carriere if (rc) { 16346a760c9eSEtienne Carriere EMSG("unexpected attributes state"); 16356a760c9eSEtienne Carriere TEE_Panic(TEE_ERROR_BAD_STATE); 1636512cbf1dSJens Wiklander } 1637512cbf1dSJens Wiklander 1638512cbf1dSJens Wiklander for (count = size / sizeof(uint32_t); count; count--) { 1639512cbf1dSJens Wiklander TEE_MemMove(&proc, attr, sizeof(uint32_t)); 1640512cbf1dSJens Wiklander attr += sizeof(uint32_t); 1641512cbf1dSJens Wiklander 1642512cbf1dSJens Wiklander if (proc == proc_id) 1643512cbf1dSJens Wiklander return true; 1644512cbf1dSJens Wiklander } 1645512cbf1dSJens Wiklander 1646512cbf1dSJens Wiklander DMSG("can't find %s in allowed list", id2str_proc(proc_id)); 1647512cbf1dSJens Wiklander return false; 1648512cbf1dSJens Wiklander } 1649512cbf1dSJens Wiklander 1650512cbf1dSJens Wiklander static enum pkcs11_attr_id func_to_attr(enum processing_func func) 1651512cbf1dSJens Wiklander { 1652512cbf1dSJens Wiklander switch (func) { 1653512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 1654512cbf1dSJens Wiklander return PKCS11_CKA_ENCRYPT; 1655512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 1656512cbf1dSJens Wiklander return PKCS11_CKA_DECRYPT; 1657512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN: 1658512cbf1dSJens Wiklander return PKCS11_CKA_SIGN; 1659512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY: 1660512cbf1dSJens Wiklander return PKCS11_CKA_VERIFY; 1661512cbf1dSJens Wiklander case PKCS11_FUNCTION_WRAP: 1662512cbf1dSJens Wiklander return PKCS11_CKA_WRAP; 1663512cbf1dSJens Wiklander case PKCS11_FUNCTION_UNWRAP: 1664512cbf1dSJens Wiklander return PKCS11_CKA_UNWRAP; 1665512cbf1dSJens Wiklander case PKCS11_FUNCTION_DERIVE: 1666512cbf1dSJens Wiklander return PKCS11_CKA_DERIVE; 1667512cbf1dSJens Wiklander default: 1668512cbf1dSJens Wiklander return PKCS11_CKA_UNDEFINED_ID; 1669512cbf1dSJens Wiklander } 1670512cbf1dSJens Wiklander } 1671512cbf1dSJens Wiklander 1672512cbf1dSJens Wiklander enum pkcs11_rc 1673512cbf1dSJens Wiklander check_parent_attrs_against_processing(enum pkcs11_mechanism_id proc_id, 1674512cbf1dSJens Wiklander enum processing_func function, 1675512cbf1dSJens Wiklander struct obj_attrs *head) 1676512cbf1dSJens Wiklander { 1677512cbf1dSJens Wiklander enum pkcs11_class_id key_class = get_class(head); 1678512cbf1dSJens Wiklander enum pkcs11_key_type key_type = get_key_type(head); 1679512cbf1dSJens Wiklander enum pkcs11_attr_id attr = func_to_attr(function); 1680512cbf1dSJens Wiklander 1681512cbf1dSJens Wiklander if (!get_bool(head, attr)) { 1682512cbf1dSJens Wiklander DMSG("%s not permitted", id2str_attr(attr)); 1683512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1684512cbf1dSJens Wiklander } 1685512cbf1dSJens Wiklander 1686512cbf1dSJens Wiklander /* Check processing complies with parent key family */ 1687512cbf1dSJens Wiklander switch (proc_id) { 1688512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 1689512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 1690512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 1691512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 16920ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC: 16930ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC_GENERAL: 1694512cbf1dSJens Wiklander if (key_class == PKCS11_CKO_SECRET_KEY && 1695512cbf1dSJens Wiklander key_type == PKCS11_CKK_AES) 1696512cbf1dSJens Wiklander break; 1697512cbf1dSJens Wiklander 1698512cbf1dSJens Wiklander DMSG("%s invalid key %s/%s", id2str_proc(proc_id), 1699512cbf1dSJens Wiklander id2str_class(key_class), id2str_key_type(key_type)); 1700512cbf1dSJens Wiklander 17015f80f270SRuchika Gupta if (function == PKCS11_FUNCTION_WRAP) 17025f80f270SRuchika Gupta return PKCS11_CKR_WRAPPING_KEY_TYPE_INCONSISTENT; 1703e3f0cb56SRuchika Gupta else if (function == PKCS11_FUNCTION_UNWRAP) 1704e3f0cb56SRuchika Gupta return PKCS11_CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT; 17055f80f270SRuchika Gupta else 1706512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1707512cbf1dSJens Wiklander 1708c3033708SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 1709c3033708SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 1710c3033708SRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY && 1711c3033708SRuchika Gupta key_type != PKCS11_CKK_AES) 1712c3033708SRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1713c3033708SRuchika Gupta 1714c3033708SRuchika Gupta if (get_bool(head, PKCS11_CKA_ENCRYPT)) { 1715c3033708SRuchika Gupta /* 1716c3033708SRuchika Gupta * Intentionally refuse to proceed despite 1717c3033708SRuchika Gupta * PKCS#11 specifications v2.40 and v3.0 not expecting 1718c3033708SRuchika Gupta * this behavior to avoid potential security issue 1719c3033708SRuchika Gupta * where keys derived by these mechanisms can be 1720c3033708SRuchika Gupta * revealed by doing data encryption using parent key. 1721c3033708SRuchika Gupta */ 1722c3033708SRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED; 1723c3033708SRuchika Gupta } 1724c3033708SRuchika Gupta 1725c3033708SRuchika Gupta break; 1726689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 1727689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 1728689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 1729689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 1730689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 1731689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 173270b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 173370b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 173470b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 173570b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 173670b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 173770b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 1738689f4e5bSRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY) 1739689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1740689f4e5bSRuchika Gupta 1741689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_GENERIC_SECRET) 1742689f4e5bSRuchika Gupta break; 1743689f4e5bSRuchika Gupta 1744689f4e5bSRuchika Gupta switch (proc_id) { 1745689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 174670b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 1747689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_MD5_HMAC) 1748689f4e5bSRuchika Gupta break; 1749689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1750689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 175170b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 1752689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA_1_HMAC) 1753689f4e5bSRuchika Gupta break; 1754689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1755689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 175670b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 1757689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA224_HMAC) 1758689f4e5bSRuchika Gupta break; 1759689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1760689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 176170b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 1762689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA256_HMAC) 1763689f4e5bSRuchika Gupta break; 1764689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1765689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 176670b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 1767689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA384_HMAC) 1768689f4e5bSRuchika Gupta break; 1769689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1770689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 177170b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 1772689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA512_HMAC) 1773689f4e5bSRuchika Gupta break; 1774689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1775689f4e5bSRuchika Gupta default: 1776689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1777689f4e5bSRuchika Gupta } 1778689f4e5bSRuchika Gupta break; 1779689f4e5bSRuchika Gupta 1780*03e07432SValerii Chubar case PKCS11_CKM_EDDSA: 1781*03e07432SValerii Chubar if (key_type != PKCS11_CKK_EC_EDWARDS) { 1782*03e07432SValerii Chubar EMSG("Invalid key %s for mechanism %s", 1783*03e07432SValerii Chubar id2str_type(key_type, key_class), 1784*03e07432SValerii Chubar id2str_proc(proc_id)); 1785*03e07432SValerii Chubar return PKCS11_CKR_KEY_TYPE_INCONSISTENT; 1786*03e07432SValerii Chubar } 1787*03e07432SValerii Chubar if (key_class != PKCS11_CKO_PUBLIC_KEY && 1788*03e07432SValerii Chubar key_class != PKCS11_CKO_PRIVATE_KEY) { 1789*03e07432SValerii Chubar EMSG("Invalid key class for mechanism %s", 1790*03e07432SValerii Chubar id2str_proc(proc_id)); 1791*03e07432SValerii Chubar 1792*03e07432SValerii Chubar return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1793*03e07432SValerii Chubar } 1794*03e07432SValerii Chubar break; 1795*03e07432SValerii Chubar 1796fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 1797fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 1798fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 1799fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 1800fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 1801fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 1802cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 1803fb279d8bSVesa Jääskeläinen if (key_type != PKCS11_CKK_EC) { 1804fb279d8bSVesa Jääskeläinen EMSG("Invalid key %s for mechanism %s", 1805fb279d8bSVesa Jääskeläinen id2str_type(key_type, key_class), 1806fb279d8bSVesa Jääskeläinen id2str_proc(proc_id)); 1807fb279d8bSVesa Jääskeläinen 1808fb279d8bSVesa Jääskeläinen return PKCS11_CKR_KEY_TYPE_INCONSISTENT; 1809fb279d8bSVesa Jääskeläinen } 1810fb279d8bSVesa Jääskeläinen if (key_class != PKCS11_CKO_PUBLIC_KEY && 1811fb279d8bSVesa Jääskeläinen key_class != PKCS11_CKO_PRIVATE_KEY) { 1812fb279d8bSVesa Jääskeläinen EMSG("Invalid key class for mechanism %s", 1813fb279d8bSVesa Jääskeläinen id2str_proc(proc_id)); 1814fb279d8bSVesa Jääskeläinen 1815fb279d8bSVesa Jääskeläinen return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1816fb279d8bSVesa Jääskeläinen } 1817fb279d8bSVesa Jääskeläinen break; 18180442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 18190442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 18200442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 18210442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 18220442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 18230442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 18240442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 1825dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 1826d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 1827d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 1828d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 1829d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 1830d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 1831d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 18320442c956SVesa Jääskeläinen if (key_type != PKCS11_CKK_RSA) { 18330442c956SVesa Jääskeläinen EMSG("Invalid key %s for mechanism %s", 18340442c956SVesa Jääskeläinen id2str_type(key_type, key_class), 18350442c956SVesa Jääskeläinen id2str_proc(proc_id)); 18360442c956SVesa Jääskeläinen 18370442c956SVesa Jääskeläinen return PKCS11_CKR_KEY_TYPE_INCONSISTENT; 18380442c956SVesa Jääskeläinen } 18390442c956SVesa Jääskeläinen if (key_class != PKCS11_CKO_PUBLIC_KEY && 18400442c956SVesa Jääskeläinen key_class != PKCS11_CKO_PRIVATE_KEY) { 18410442c956SVesa Jääskeläinen EMSG("Invalid key class for mechanism %s", 18420442c956SVesa Jääskeläinen id2str_proc(proc_id)); 18430442c956SVesa Jääskeläinen 18440442c956SVesa Jääskeläinen return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 18450442c956SVesa Jääskeläinen } 18460442c956SVesa Jääskeläinen break; 1847512cbf1dSJens Wiklander default: 1848512cbf1dSJens Wiklander DMSG("Invalid processing %#"PRIx32"/%s", proc_id, 1849512cbf1dSJens Wiklander id2str_proc(proc_id)); 1850512cbf1dSJens Wiklander 1851512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_INVALID; 1852512cbf1dSJens Wiklander } 1853512cbf1dSJens Wiklander 1854512cbf1dSJens Wiklander if (!parent_key_complies_allowed_processings(proc_id, head)) { 1855512cbf1dSJens Wiklander DMSG("Allowed mechanism failed"); 1856512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1857512cbf1dSJens Wiklander } 1858512cbf1dSJens Wiklander 1859512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1860512cbf1dSJens Wiklander } 1861783c1515SRuchika Gupta 1862783c1515SRuchika Gupta bool attribute_is_exportable(struct pkcs11_attribute_head *req_attr, 1863783c1515SRuchika Gupta struct pkcs11_object *obj) 1864783c1515SRuchika Gupta { 1865783c1515SRuchika Gupta uint8_t boolval = 0; 1866783c1515SRuchika Gupta uint32_t boolsize = 0; 1867783c1515SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 1868783c1515SRuchika Gupta enum pkcs11_class_id key_class = get_class(obj->attributes); 1869783c1515SRuchika Gupta 1870783c1515SRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY && 1871783c1515SRuchika Gupta key_class != PKCS11_CKO_PRIVATE_KEY) 1872783c1515SRuchika Gupta return true; 1873783c1515SRuchika Gupta 1874783c1515SRuchika Gupta switch (req_attr->id) { 1875783c1515SRuchika Gupta case PKCS11_CKA_PRIVATE_EXPONENT: 1876783c1515SRuchika Gupta case PKCS11_CKA_PRIME_1: 1877783c1515SRuchika Gupta case PKCS11_CKA_PRIME_2: 1878783c1515SRuchika Gupta case PKCS11_CKA_EXPONENT_1: 1879783c1515SRuchika Gupta case PKCS11_CKA_EXPONENT_2: 1880783c1515SRuchika Gupta case PKCS11_CKA_COEFFICIENT: 1881783c1515SRuchika Gupta case PKCS11_CKA_VALUE: 1882783c1515SRuchika Gupta boolsize = sizeof(boolval); 1883783c1515SRuchika Gupta rc = get_attribute(obj->attributes, PKCS11_CKA_EXTRACTABLE, 1884783c1515SRuchika Gupta &boolval, &boolsize); 1885783c1515SRuchika Gupta if (rc || boolval == PKCS11_FALSE) 1886783c1515SRuchika Gupta return false; 1887783c1515SRuchika Gupta 1888783c1515SRuchika Gupta boolsize = sizeof(boolval); 1889783c1515SRuchika Gupta rc = get_attribute(obj->attributes, PKCS11_CKA_SENSITIVE, 1890783c1515SRuchika Gupta &boolval, &boolsize); 1891783c1515SRuchika Gupta if (rc || boolval == PKCS11_TRUE) 1892783c1515SRuchika Gupta return false; 1893783c1515SRuchika Gupta break; 1894783c1515SRuchika Gupta default: 1895783c1515SRuchika Gupta break; 1896783c1515SRuchika Gupta } 1897783c1515SRuchika Gupta 1898783c1515SRuchika Gupta return true; 1899783c1515SRuchika Gupta } 19002d25a9bcSRuchika Gupta 19012d25a9bcSRuchika Gupta static bool attr_is_modifiable_any_key(struct pkcs11_attribute_head *attr) 19022d25a9bcSRuchika Gupta { 19032d25a9bcSRuchika Gupta switch (attr->id) { 19042d25a9bcSRuchika Gupta case PKCS11_CKA_ID: 19052d25a9bcSRuchika Gupta case PKCS11_CKA_START_DATE: 19062d25a9bcSRuchika Gupta case PKCS11_CKA_END_DATE: 19072d25a9bcSRuchika Gupta case PKCS11_CKA_DERIVE: 19082d25a9bcSRuchika Gupta return true; 19092d25a9bcSRuchika Gupta default: 19102d25a9bcSRuchika Gupta return false; 19112d25a9bcSRuchika Gupta } 19122d25a9bcSRuchika Gupta } 19132d25a9bcSRuchika Gupta 19142d25a9bcSRuchika Gupta static bool attr_is_modifiable_secret_key(struct pkcs11_attribute_head *attr, 19152d25a9bcSRuchika Gupta struct pkcs11_session *session, 19162d25a9bcSRuchika Gupta struct pkcs11_object *obj) 19172d25a9bcSRuchika Gupta { 19182d25a9bcSRuchika Gupta switch (attr->id) { 19192d25a9bcSRuchika Gupta case PKCS11_CKA_ENCRYPT: 19202d25a9bcSRuchika Gupta case PKCS11_CKA_DECRYPT: 19212d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN: 19222d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY: 19232d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP: 19242d25a9bcSRuchika Gupta case PKCS11_CKA_UNWRAP: 19252d25a9bcSRuchika Gupta return true; 19262d25a9bcSRuchika Gupta /* Can't be modified once set to CK_FALSE - 12 in Table 10 */ 19272d25a9bcSRuchika Gupta case PKCS11_CKA_EXTRACTABLE: 19282d25a9bcSRuchika Gupta return get_bool(obj->attributes, attr->id); 19292d25a9bcSRuchika Gupta /* Can't be modified once set to CK_TRUE - 11 in Table 10 */ 19302d25a9bcSRuchika Gupta case PKCS11_CKA_SENSITIVE: 19312d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP_WITH_TRUSTED: 19322d25a9bcSRuchika Gupta return !get_bool(obj->attributes, attr->id); 19332d25a9bcSRuchika Gupta /* Change in CKA_TRUSTED can only be done by SO */ 19342d25a9bcSRuchika Gupta case PKCS11_CKA_TRUSTED: 19352d25a9bcSRuchika Gupta return pkcs11_session_is_so(session); 19362d25a9bcSRuchika Gupta case PKCS11_CKA_NEVER_EXTRACTABLE: 19372d25a9bcSRuchika Gupta case PKCS11_CKA_ALWAYS_SENSITIVE: 19382d25a9bcSRuchika Gupta return false; 19392d25a9bcSRuchika Gupta default: 19402d25a9bcSRuchika Gupta return false; 19412d25a9bcSRuchika Gupta } 19422d25a9bcSRuchika Gupta } 19432d25a9bcSRuchika Gupta 19442d25a9bcSRuchika Gupta static bool attr_is_modifiable_public_key(struct pkcs11_attribute_head *attr, 19452d25a9bcSRuchika Gupta struct pkcs11_session *session, 19462d25a9bcSRuchika Gupta struct pkcs11_object *obj __unused) 19472d25a9bcSRuchika Gupta { 19482d25a9bcSRuchika Gupta switch (attr->id) { 19492d25a9bcSRuchika Gupta case PKCS11_CKA_SUBJECT: 19502d25a9bcSRuchika Gupta case PKCS11_CKA_ENCRYPT: 19512d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY: 19522d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY_RECOVER: 19532d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP: 19542d25a9bcSRuchika Gupta return true; 19552d25a9bcSRuchika Gupta case PKCS11_CKA_TRUSTED: 19562d25a9bcSRuchika Gupta /* Change in CKA_TRUSTED can only be done by SO */ 19572d25a9bcSRuchika Gupta return pkcs11_session_is_so(session); 19582d25a9bcSRuchika Gupta default: 19592d25a9bcSRuchika Gupta return false; 19602d25a9bcSRuchika Gupta } 19612d25a9bcSRuchika Gupta } 19622d25a9bcSRuchika Gupta 19632d25a9bcSRuchika Gupta static bool attr_is_modifiable_private_key(struct pkcs11_attribute_head *attr, 19642d25a9bcSRuchika Gupta struct pkcs11_session *sess __unused, 19652d25a9bcSRuchika Gupta struct pkcs11_object *obj) 19662d25a9bcSRuchika Gupta { 19672d25a9bcSRuchika Gupta switch (attr->id) { 19682d25a9bcSRuchika Gupta case PKCS11_CKA_SUBJECT: 19692d25a9bcSRuchika Gupta case PKCS11_CKA_DECRYPT: 19702d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN: 19712d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN_RECOVER: 19722d25a9bcSRuchika Gupta case PKCS11_CKA_UNWRAP: 19732d25a9bcSRuchika Gupta /* 19742d25a9bcSRuchika Gupta * TBD: Revisit if we don't support PKCS11_CKA_PUBLIC_KEY_INFO 19752d25a9bcSRuchika Gupta * Specification mentions that if this attribute is 19762d25a9bcSRuchika Gupta * supplied as part of a template for C_CreateObject, C_CopyObject or 19772d25a9bcSRuchika Gupta * C_SetAttributeValue for a private key, the token MUST verify 19782d25a9bcSRuchika Gupta * correspondence between the private key data and the public key data 19792d25a9bcSRuchika Gupta * as supplied in CKA_PUBLIC_KEY_INFO. This needs to be 19802d25a9bcSRuchika Gupta * taken care of when this object type will be implemented 19812d25a9bcSRuchika Gupta */ 19822d25a9bcSRuchika Gupta case PKCS11_CKA_PUBLIC_KEY_INFO: 19832d25a9bcSRuchika Gupta return true; 19842d25a9bcSRuchika Gupta /* Can't be modified once set to CK_FALSE - 12 in Table 10 */ 19852d25a9bcSRuchika Gupta case PKCS11_CKA_EXTRACTABLE: 19862d25a9bcSRuchika Gupta return get_bool(obj->attributes, attr->id); 19872d25a9bcSRuchika Gupta /* Can't be modified once set to CK_TRUE - 11 in Table 10 */ 19882d25a9bcSRuchika Gupta case PKCS11_CKA_SENSITIVE: 19892d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP_WITH_TRUSTED: 19902d25a9bcSRuchika Gupta return !get_bool(obj->attributes, attr->id); 19912d25a9bcSRuchika Gupta case PKCS11_CKA_NEVER_EXTRACTABLE: 19922d25a9bcSRuchika Gupta case PKCS11_CKA_ALWAYS_SENSITIVE: 19932d25a9bcSRuchika Gupta return false; 19942d25a9bcSRuchika Gupta default: 19952d25a9bcSRuchika Gupta return false; 19962d25a9bcSRuchika Gupta } 19972d25a9bcSRuchika Gupta } 19982d25a9bcSRuchika Gupta 19994137952dSVesa Jääskeläinen static bool attr_is_modifiable_certificate(struct pkcs11_attribute_head *attr, 20004137952dSVesa Jääskeläinen struct pkcs11_session *session, 20014137952dSVesa Jääskeläinen struct pkcs11_object *obj) 20024137952dSVesa Jääskeläinen { 20034137952dSVesa Jääskeläinen uint8_t boolval = 0; 20044137952dSVesa Jääskeläinen uint32_t boolsize = 0; 20054137952dSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 20064137952dSVesa Jääskeläinen 20074137952dSVesa Jääskeläinen /* Trusted certificates cannot be modified. */ 20084137952dSVesa Jääskeläinen rc = get_attribute(obj->attributes, PKCS11_CKA_TRUSTED, 20094137952dSVesa Jääskeläinen &boolval, &boolsize); 20104137952dSVesa Jääskeläinen if (rc || boolval == PKCS11_TRUE) 20114137952dSVesa Jääskeläinen return false; 20124137952dSVesa Jääskeläinen 20134137952dSVesa Jääskeläinen /* Common certificate attributes */ 20144137952dSVesa Jääskeläinen switch (attr->id) { 20154137952dSVesa Jääskeläinen case PKCS11_CKA_TRUSTED: 20164137952dSVesa Jääskeläinen /* 20174137952dSVesa Jääskeläinen * The CKA_TRUSTED attribute cannot be set to CK_TRUE by an 20184137952dSVesa Jääskeläinen * application. It MUST be set by a token initialization 20194137952dSVesa Jääskeläinen * application or by the token’s SO. 20204137952dSVesa Jääskeläinen */ 20214137952dSVesa Jääskeläinen return pkcs11_session_is_so(session); 20224137952dSVesa Jääskeläinen case PKCS11_CKA_CERTIFICATE_TYPE: 20234137952dSVesa Jääskeläinen case PKCS11_CKA_CERTIFICATE_CATEGORY: 20244137952dSVesa Jääskeläinen return false; 20254137952dSVesa Jääskeläinen default: 20264137952dSVesa Jääskeläinen break; 20274137952dSVesa Jääskeläinen } 20284137952dSVesa Jääskeläinen 20294137952dSVesa Jääskeläinen /* Certificate type specific attributes */ 20304137952dSVesa Jääskeläinen switch (get_certificate_type(obj->attributes)) { 20314137952dSVesa Jääskeläinen case PKCS11_CKC_X_509: 20324137952dSVesa Jääskeläinen /* 20334137952dSVesa Jääskeläinen * Only the CKA_ID, CKA_ISSUER, and CKA_SERIAL_NUMBER 20344137952dSVesa Jääskeläinen * attributes may be modified after the object is created. 20354137952dSVesa Jääskeläinen */ 20364137952dSVesa Jääskeläinen switch (attr->id) { 20374137952dSVesa Jääskeläinen case PKCS11_CKA_ID: 20384137952dSVesa Jääskeläinen case PKCS11_CKA_ISSUER: 20394137952dSVesa Jääskeläinen case PKCS11_CKA_SERIAL_NUMBER: 20404137952dSVesa Jääskeläinen return true; 20414137952dSVesa Jääskeläinen default: 20424137952dSVesa Jääskeläinen break; 20434137952dSVesa Jääskeläinen } 20444137952dSVesa Jääskeläinen break; 20454137952dSVesa Jääskeläinen default: 20464137952dSVesa Jääskeläinen /* Unsupported certificate type */ 20474137952dSVesa Jääskeläinen break; 20484137952dSVesa Jääskeläinen } 20494137952dSVesa Jääskeläinen 20504137952dSVesa Jääskeläinen return false; 20514137952dSVesa Jääskeläinen } 20524137952dSVesa Jääskeläinen 20532d25a9bcSRuchika Gupta static bool attribute_is_modifiable(struct pkcs11_session *session, 20542d25a9bcSRuchika Gupta struct pkcs11_attribute_head *req_attr, 20552d25a9bcSRuchika Gupta struct pkcs11_object *obj, 20562d25a9bcSRuchika Gupta enum pkcs11_class_id class, 20572d25a9bcSRuchika Gupta enum processing_func function) 20582d25a9bcSRuchika Gupta { 20592d25a9bcSRuchika Gupta /* Check modifiable attributes common to any object */ 20602d25a9bcSRuchika Gupta switch (req_attr->id) { 20612d25a9bcSRuchika Gupta case PKCS11_CKA_LABEL: 20622d25a9bcSRuchika Gupta return true; 20632d25a9bcSRuchika Gupta case PKCS11_CKA_TOKEN: 20642d25a9bcSRuchika Gupta case PKCS11_CKA_MODIFIABLE: 20652d25a9bcSRuchika Gupta case PKCS11_CKA_DESTROYABLE: 20662d25a9bcSRuchika Gupta case PKCS11_CKA_PRIVATE: 20672d25a9bcSRuchika Gupta return function == PKCS11_FUNCTION_COPY; 20682d25a9bcSRuchika Gupta case PKCS11_CKA_COPYABLE: 20692d25a9bcSRuchika Gupta /* 20702d25a9bcSRuchika Gupta * Specification mentions that if the attribute value is false 20712d25a9bcSRuchika Gupta * it can't be set to true. Reading this we assume that it 20722d25a9bcSRuchika Gupta * should be possible to modify this attribute even though this 20732d25a9bcSRuchika Gupta * is not marked as modifiable in Table 10 if done in right 20742d25a9bcSRuchika Gupta * direction i.e from TRUE -> FALSE. 20752d25a9bcSRuchika Gupta */ 20762d25a9bcSRuchika Gupta return get_bool(obj->attributes, req_attr->id); 20772d25a9bcSRuchika Gupta default: 20782d25a9bcSRuchika Gupta break; 20792d25a9bcSRuchika Gupta } 20802d25a9bcSRuchika Gupta 20812d25a9bcSRuchika Gupta /* Attribute checking based on class type */ 20822d25a9bcSRuchika Gupta switch (class) { 20832d25a9bcSRuchika Gupta case PKCS11_CKO_SECRET_KEY: 20842d25a9bcSRuchika Gupta case PKCS11_CKO_PUBLIC_KEY: 20852d25a9bcSRuchika Gupta case PKCS11_CKO_PRIVATE_KEY: 20862d25a9bcSRuchika Gupta if (attr_is_modifiable_any_key(req_attr)) 20872d25a9bcSRuchika Gupta return true; 20882d25a9bcSRuchika Gupta if (class == PKCS11_CKO_SECRET_KEY && 20892d25a9bcSRuchika Gupta attr_is_modifiable_secret_key(req_attr, session, obj)) 20902d25a9bcSRuchika Gupta return true; 20912d25a9bcSRuchika Gupta if (class == PKCS11_CKO_PUBLIC_KEY && 20922d25a9bcSRuchika Gupta attr_is_modifiable_public_key(req_attr, session, obj)) 20932d25a9bcSRuchika Gupta return true; 20942d25a9bcSRuchika Gupta if (class == PKCS11_CKO_PRIVATE_KEY && 20952d25a9bcSRuchika Gupta attr_is_modifiable_private_key(req_attr, session, obj)) 20962d25a9bcSRuchika Gupta return true; 20972d25a9bcSRuchika Gupta break; 20982d25a9bcSRuchika Gupta case PKCS11_CKO_DATA: 20992d25a9bcSRuchika Gupta /* None of the data object attributes are modifiable */ 21002d25a9bcSRuchika Gupta return false; 21014137952dSVesa Jääskeläinen case PKCS11_CKO_CERTIFICATE: 21024137952dSVesa Jääskeläinen return attr_is_modifiable_certificate(req_attr, session, obj); 21032d25a9bcSRuchika Gupta default: 21042d25a9bcSRuchika Gupta break; 21052d25a9bcSRuchika Gupta } 21062d25a9bcSRuchika Gupta 21072d25a9bcSRuchika Gupta return false; 21082d25a9bcSRuchika Gupta } 21092d25a9bcSRuchika Gupta 21102d25a9bcSRuchika Gupta enum pkcs11_rc check_attrs_against_modification(struct pkcs11_session *session, 21112d25a9bcSRuchika Gupta struct obj_attrs *head, 21122d25a9bcSRuchika Gupta struct pkcs11_object *obj, 21132d25a9bcSRuchika Gupta enum processing_func function) 21142d25a9bcSRuchika Gupta { 21152d25a9bcSRuchika Gupta enum pkcs11_class_id class = PKCS11_CKO_UNDEFINED_ID; 21162d25a9bcSRuchika Gupta char *cur = NULL; 21172d25a9bcSRuchika Gupta char *end = NULL; 21182d25a9bcSRuchika Gupta size_t len = 0; 21192d25a9bcSRuchika Gupta 21202d25a9bcSRuchika Gupta class = get_class(obj->attributes); 21212d25a9bcSRuchika Gupta 21222d25a9bcSRuchika Gupta cur = (char *)head + sizeof(struct obj_attrs); 21232d25a9bcSRuchika Gupta end = cur + head->attrs_size; 21242d25a9bcSRuchika Gupta 21252d25a9bcSRuchika Gupta for (; cur < end; cur += len) { 21262d25a9bcSRuchika Gupta /* Structure aligned copy of the pkcs11_ref in the object */ 21272d25a9bcSRuchika Gupta struct pkcs11_attribute_head cli_ref = { }; 21282d25a9bcSRuchika Gupta 21292d25a9bcSRuchika Gupta TEE_MemMove(&cli_ref, cur, sizeof(cli_ref)); 21302d25a9bcSRuchika Gupta len = sizeof(cli_ref) + cli_ref.size; 21312d25a9bcSRuchika Gupta 21322d25a9bcSRuchika Gupta /* 21332d25a9bcSRuchika Gupta * Check 1 - Check if attribute belongs to the object 21342d25a9bcSRuchika Gupta * The obj->attributes has all the attributes in 21352d25a9bcSRuchika Gupta * it which are allowed for an object. 21362d25a9bcSRuchika Gupta */ 21372d25a9bcSRuchika Gupta if (get_attribute_ptr(obj->attributes, cli_ref.id, NULL, 21382d25a9bcSRuchika Gupta NULL) == PKCS11_RV_NOT_FOUND) 21392d25a9bcSRuchika Gupta return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 21402d25a9bcSRuchika Gupta 21412d25a9bcSRuchika Gupta /* Check 2 - Is attribute modifiable */ 21422d25a9bcSRuchika Gupta if (!attribute_is_modifiable(session, &cli_ref, obj, class, 21432d25a9bcSRuchika Gupta function)) 21442d25a9bcSRuchika Gupta return PKCS11_CKR_ATTRIBUTE_READ_ONLY; 21452d25a9bcSRuchika Gupta 21462d25a9bcSRuchika Gupta /* 21472d25a9bcSRuchika Gupta * Checks for modification in PKCS11_CKA_TOKEN and 21482d25a9bcSRuchika Gupta * PKCS11_CKA_PRIVATE are required for PKCS11_FUNCTION_COPY 21492d25a9bcSRuchika Gupta * only, so skip them for PKCS11_FUNCTION_MODIFY. 21502d25a9bcSRuchika Gupta */ 21512d25a9bcSRuchika Gupta if (function == PKCS11_FUNCTION_MODIFY) 21522d25a9bcSRuchika Gupta continue; 21532d25a9bcSRuchika Gupta 21542d25a9bcSRuchika Gupta /* 21552d25a9bcSRuchika Gupta * An attempt to copy an object to a token will fail for 21562d25a9bcSRuchika Gupta * RO session 21572d25a9bcSRuchika Gupta */ 21582d25a9bcSRuchika Gupta if (cli_ref.id == PKCS11_CKA_TOKEN && 21592d25a9bcSRuchika Gupta get_bool(head, PKCS11_CKA_TOKEN)) { 21602d25a9bcSRuchika Gupta if (!pkcs11_session_is_read_write(session)) { 21612d25a9bcSRuchika Gupta DMSG("Can't copy to token in a RO session"); 21622d25a9bcSRuchika Gupta return PKCS11_CKR_SESSION_READ_ONLY; 21632d25a9bcSRuchika Gupta } 21642d25a9bcSRuchika Gupta } 21652d25a9bcSRuchika Gupta 21662d25a9bcSRuchika Gupta if (cli_ref.id == PKCS11_CKA_PRIVATE) { 21672d25a9bcSRuchika Gupta bool parent_priv = 21682d25a9bcSRuchika Gupta get_bool(obj->attributes, cli_ref.id); 21692d25a9bcSRuchika Gupta bool obj_priv = get_bool(head, cli_ref.id); 21702d25a9bcSRuchika Gupta 21712d25a9bcSRuchika Gupta /* 21722d25a9bcSRuchika Gupta * If PKCS11_CKA_PRIVATE is being set to TRUE from 21732d25a9bcSRuchika Gupta * FALSE, user has to be logged in 21742d25a9bcSRuchika Gupta */ 21752d25a9bcSRuchika Gupta if (!parent_priv && obj_priv) { 21762d25a9bcSRuchika Gupta if ((pkcs11_session_is_public(session) || 21772d25a9bcSRuchika Gupta pkcs11_session_is_so(session))) 21782d25a9bcSRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 21792d25a9bcSRuchika Gupta } 2180df017b2bSRuchika Gupta 2181df017b2bSRuchika Gupta /* 2182df017b2bSRuchika Gupta * Restriction added - Even for Copy, do not allow 2183df017b2bSRuchika Gupta * modification of CKA_PRIVATE from TRUE to FALSE 2184df017b2bSRuchika Gupta */ 2185df017b2bSRuchika Gupta if (parent_priv && !obj_priv) 2186df017b2bSRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 21872d25a9bcSRuchika Gupta } 21882d25a9bcSRuchika Gupta } 21892d25a9bcSRuchika Gupta 21902d25a9bcSRuchika Gupta return PKCS11_CKR_OK; 21912d25a9bcSRuchika Gupta } 21928c499324SRuchika Gupta 21938c499324SRuchika Gupta static enum pkcs11_rc set_secret_key_data(struct obj_attrs **head, void *data, 21948c499324SRuchika Gupta size_t key_size) 21958c499324SRuchika Gupta { 21968c499324SRuchika Gupta uint32_t size = sizeof(uint32_t); 21978c499324SRuchika Gupta uint32_t key_length = 0; 21988c499324SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 21998c499324SRuchika Gupta 22008c499324SRuchika Gupta /* Get key size if present in template */ 22018c499324SRuchika Gupta rc = get_attribute(*head, PKCS11_CKA_VALUE_LEN, &key_length, &size); 22028c499324SRuchika Gupta if (rc && rc != PKCS11_RV_NOT_FOUND) 22038c499324SRuchika Gupta return rc; 22048c499324SRuchika Gupta 22058c499324SRuchika Gupta if (key_length) { 22068c499324SRuchika Gupta if (key_size < key_length) 22078c499324SRuchika Gupta return PKCS11_CKR_DATA_LEN_RANGE; 22088c499324SRuchika Gupta } else { 22098c499324SRuchika Gupta key_length = key_size; 22108c499324SRuchika Gupta rc = set_attribute(head, PKCS11_CKA_VALUE_LEN, &key_length, 22118c499324SRuchika Gupta sizeof(uint32_t)); 22128c499324SRuchika Gupta if (rc) 22138c499324SRuchika Gupta return rc; 22148c499324SRuchika Gupta } 22158c499324SRuchika Gupta 22168c499324SRuchika Gupta /* Now we can check the VALUE_LEN field */ 22178c499324SRuchika Gupta rc = check_created_attrs(*head, NULL); 22188c499324SRuchika Gupta if (rc) 22198c499324SRuchika Gupta return rc; 22208c499324SRuchika Gupta 22218c499324SRuchika Gupta /* Remove the default empty value attribute if found */ 22228c499324SRuchika Gupta rc = remove_empty_attribute(head, PKCS11_CKA_VALUE); 22238c499324SRuchika Gupta if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND) 22248c499324SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 22258c499324SRuchika Gupta 22268c499324SRuchika Gupta return add_attribute(head, PKCS11_CKA_VALUE, data, key_length); 22278c499324SRuchika Gupta } 22288c499324SRuchika Gupta 22298c499324SRuchika Gupta enum pkcs11_rc set_key_data(struct obj_attrs **head, void *data, 22308c499324SRuchika Gupta size_t key_size) 22318c499324SRuchika Gupta { 22328c499324SRuchika Gupta switch (get_class(*head)) { 22338c499324SRuchika Gupta case PKCS11_CKO_SECRET_KEY: 22348c499324SRuchika Gupta return set_secret_key_data(head, data, key_size); 22358c499324SRuchika Gupta default: 22368c499324SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 22378c499324SRuchika Gupta } 22388c499324SRuchika Gupta } 22395e1d94ebSVesa Jääskeläinen 22405f80f270SRuchika Gupta enum pkcs11_rc get_key_data_to_wrap(struct obj_attrs *head, void **data, 22415f80f270SRuchika Gupta uint32_t *sz) 22425f80f270SRuchika Gupta { 22435f80f270SRuchika Gupta switch (get_class(head)) { 22445f80f270SRuchika Gupta case PKCS11_CKO_SECRET_KEY: 22455f80f270SRuchika Gupta if (get_attribute_ptr(head, PKCS11_CKA_VALUE, data, sz)) 22465f80f270SRuchika Gupta return PKCS11_CKR_ARGUMENTS_BAD; 22475f80f270SRuchika Gupta break; 22485f80f270SRuchika Gupta default: 22495f80f270SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 22505f80f270SRuchika Gupta } 22515f80f270SRuchika Gupta 22525f80f270SRuchika Gupta return PKCS11_CKR_OK; 22535f80f270SRuchika Gupta } 22545f80f270SRuchika Gupta 22555e1d94ebSVesa Jääskeläinen enum pkcs11_rc add_missing_attribute_id(struct obj_attrs **pub_head, 22565e1d94ebSVesa Jääskeläinen struct obj_attrs **priv_head) 22575e1d94ebSVesa Jääskeläinen { 22585e1d94ebSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 22595e1d94ebSVesa Jääskeläinen void *id1 = NULL; 22605e1d94ebSVesa Jääskeläinen uint32_t id1_size = 0; 22615e1d94ebSVesa Jääskeläinen void *id2 = NULL; 22625e1d94ebSVesa Jääskeläinen uint32_t id2_size = 0; 22635e1d94ebSVesa Jääskeläinen 22645e1d94ebSVesa Jääskeläinen assert(pub_head); 22655e1d94ebSVesa Jääskeläinen assert(priv_head); 22665e1d94ebSVesa Jääskeläinen 22675e1d94ebSVesa Jääskeläinen rc = get_attribute_ptr(*pub_head, PKCS11_CKA_ID, &id1, &id1_size); 22685e1d94ebSVesa Jääskeläinen if (rc) { 22695e1d94ebSVesa Jääskeläinen if (rc != PKCS11_RV_NOT_FOUND) 22705e1d94ebSVesa Jääskeläinen return rc; 22715e1d94ebSVesa Jääskeläinen id1 = NULL; 22725e1d94ebSVesa Jääskeläinen } else if (!id1_size) { 22735e1d94ebSVesa Jääskeläinen id1 = NULL; 22745e1d94ebSVesa Jääskeläinen } 22755e1d94ebSVesa Jääskeläinen 22765e1d94ebSVesa Jääskeläinen rc = get_attribute_ptr(*priv_head, PKCS11_CKA_ID, &id2, &id2_size); 22775e1d94ebSVesa Jääskeläinen if (rc) { 22785e1d94ebSVesa Jääskeläinen if (rc != PKCS11_RV_NOT_FOUND) 22795e1d94ebSVesa Jääskeläinen return rc; 22805e1d94ebSVesa Jääskeläinen id2 = NULL; 22815e1d94ebSVesa Jääskeläinen } else if (!id2_size) { 22825e1d94ebSVesa Jääskeläinen id2 = NULL; 22835e1d94ebSVesa Jääskeläinen } 22845e1d94ebSVesa Jääskeläinen 22855e1d94ebSVesa Jääskeläinen /* Both have value -- let them be what caller has specified them */ 22865e1d94ebSVesa Jääskeläinen if (id1 && id2) 22875e1d94ebSVesa Jääskeläinen return PKCS11_CKR_OK; 22885e1d94ebSVesa Jääskeläinen 22895e1d94ebSVesa Jääskeläinen /* Both are empty -- leave empty values */ 22905e1d94ebSVesa Jääskeläinen if (!id1 && !id2) 22915e1d94ebSVesa Jääskeläinen return PKCS11_CKR_OK; 22925e1d94ebSVesa Jääskeläinen 22935e1d94ebSVesa Jääskeläinen /* Cross copy CKA_ID value */ 22945e1d94ebSVesa Jääskeläinen if (id1) 22955e1d94ebSVesa Jääskeläinen return set_attribute(priv_head, PKCS11_CKA_ID, id1, id1_size); 22965e1d94ebSVesa Jääskeläinen else 22975e1d94ebSVesa Jääskeläinen return set_attribute(pub_head, PKCS11_CKA_ID, id2, id2_size); 22985e1d94ebSVesa Jääskeläinen } 2299