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 344*4137952dSVesa Jääskeläinen /* PKCS#11 specification for certificate object (+pkcs11_any_object_xxx) */ 345*4137952dSVesa Jääskeläinen static const uint32_t pkcs11_certificate_mandated[] = { 346*4137952dSVesa Jääskeläinen PKCS11_CKA_CERTIFICATE_TYPE, 347*4137952dSVesa Jääskeläinen }; 348*4137952dSVesa Jääskeläinen 349*4137952dSVesa Jääskeläinen static const uint32_t pkcs11_certificate_boolprops[] = { 350*4137952dSVesa Jääskeläinen PKCS11_CKA_TRUSTED, 351*4137952dSVesa Jääskeläinen }; 352*4137952dSVesa Jääskeläinen 353*4137952dSVesa Jääskeläinen static const uint32_t pkcs11_certificate_optional[] = { 354*4137952dSVesa Jääskeläinen PKCS11_CKA_CERTIFICATE_CATEGORY, PKCS11_CKA_CHECK_VALUE, 355*4137952dSVesa Jääskeläinen PKCS11_CKA_START_DATE, PKCS11_CKA_END_DATE, PKCS11_CKA_PUBLIC_KEY_INFO, 356*4137952dSVesa Jääskeläinen }; 357*4137952dSVesa Jääskeläinen 358*4137952dSVesa Jääskeläinen /* 359*4137952dSVesa Jääskeläinen * PKCS#11 specification for X.509 certificate object (+pkcs11_certificate_xxx) 360*4137952dSVesa Jääskeläinen */ 361*4137952dSVesa Jääskeläinen static const uint32_t pkcs11_x509_certificate_mandated[] = { 362*4137952dSVesa Jääskeläinen PKCS11_CKA_SUBJECT, 363*4137952dSVesa Jääskeläinen }; 364*4137952dSVesa Jääskeläinen 365*4137952dSVesa Jääskeläinen static const uint32_t pkcs11_x509_certificate_optional[] = { 366*4137952dSVesa Jääskeläinen PKCS11_CKA_ID, PKCS11_CKA_ISSUER, PKCS11_CKA_SERIAL_NUMBER, 367*4137952dSVesa Jääskeläinen PKCS11_CKA_VALUE, PKCS11_CKA_URL, 368*4137952dSVesa Jääskeläinen PKCS11_CKA_HASH_OF_SUBJECT_PUBLIC_KEY, 369*4137952dSVesa Jääskeläinen PKCS11_CKA_HASH_OF_ISSUER_PUBLIC_KEY, 370*4137952dSVesa Jääskeläinen PKCS11_CKA_JAVA_MIDP_SECURITY_DOMAIN, PKCS11_CKA_NAME_HASH_ALGORITHM, 371*4137952dSVesa Jääskeläinen }; 372*4137952dSVesa 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 47363f89caaSJens Wiklander static enum pkcs11_rc create_storage_attributes(struct obj_attrs **out, 47463f89caaSJens Wiklander struct obj_attrs *temp) 47563f89caaSJens Wiklander { 47663f89caaSJens Wiklander enum pkcs11_class_id class = PKCS11_CKO_UNDEFINED_ID; 47763f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 47863f89caaSJens Wiklander 47963f89caaSJens Wiklander rc = init_attributes_head(out); 48063f89caaSJens Wiklander if (rc) 48163f89caaSJens Wiklander return rc; 48263f89caaSJens Wiklander 48363f89caaSJens Wiklander /* Object class is mandatory */ 48463f89caaSJens Wiklander class = get_class(temp); 48563f89caaSJens Wiklander if (class == PKCS11_CKO_UNDEFINED_ID) { 48663f89caaSJens Wiklander EMSG("Class attribute not found"); 48763f89caaSJens Wiklander 48863f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 48963f89caaSJens Wiklander } 49063f89caaSJens Wiklander rc = add_attribute(out, PKCS11_CKA_CLASS, &class, sizeof(uint32_t)); 49163f89caaSJens Wiklander if (rc) 49263f89caaSJens Wiklander return rc; 49363f89caaSJens Wiklander 4944eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, any_object_boolprops, 4954eb88651SRuchika Gupta ARRAY_SIZE(any_object_boolprops)); 49663f89caaSJens Wiklander if (rc) 49763f89caaSJens Wiklander return rc; 49863f89caaSJens Wiklander 4994eb88651SRuchika Gupta return set_attributes_opt_or_null(out, temp, any_object_opt_or_null, 5004eb88651SRuchika Gupta ARRAY_SIZE(any_object_opt_or_null)); 50163f89caaSJens Wiklander } 50263f89caaSJens Wiklander 50363f89caaSJens Wiklander static enum pkcs11_rc create_genkey_attributes(struct obj_attrs **out, 50463f89caaSJens Wiklander struct obj_attrs *temp) 50563f89caaSJens Wiklander { 50663f89caaSJens Wiklander uint32_t type = PKCS11_CKO_UNDEFINED_ID; 50763f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 50863f89caaSJens Wiklander 50963f89caaSJens Wiklander rc = create_storage_attributes(out, temp); 51063f89caaSJens Wiklander if (rc) 51163f89caaSJens Wiklander return rc; 51263f89caaSJens Wiklander 51363f89caaSJens Wiklander type = get_key_type(temp); 51463f89caaSJens Wiklander if (type == PKCS11_CKK_UNDEFINED_ID) { 51563f89caaSJens Wiklander EMSG("Key type attribute not found"); 51663f89caaSJens Wiklander 51763f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 51863f89caaSJens Wiklander } 51963f89caaSJens Wiklander rc = add_attribute(out, PKCS11_CKA_KEY_TYPE, &type, sizeof(uint32_t)); 52063f89caaSJens Wiklander if (rc) 52163f89caaSJens Wiklander return rc; 52263f89caaSJens Wiklander 5234eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, any_key_boolprops, 5244eb88651SRuchika Gupta ARRAY_SIZE(any_key_boolprops)); 52563f89caaSJens Wiklander if (rc) 52663f89caaSJens Wiklander return rc; 52763f89caaSJens Wiklander 5284eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, any_key_opt_or_null, 5294eb88651SRuchika Gupta ARRAY_SIZE(any_key_opt_or_null)); 5304eb88651SRuchika Gupta if (rc) 5314eb88651SRuchika Gupta return rc; 5324eb88651SRuchika Gupta 5334eb88651SRuchika Gupta return set_optional_attributes(out, temp, any_key_optional, 5344eb88651SRuchika Gupta ARRAY_SIZE(any_key_optional)); 5354eb88651SRuchika Gupta 53663f89caaSJens Wiklander } 53763f89caaSJens Wiklander 53863f89caaSJens Wiklander static enum pkcs11_rc create_symm_key_attributes(struct obj_attrs **out, 53963f89caaSJens Wiklander struct obj_attrs *temp) 54063f89caaSJens Wiklander { 54163f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 54263f89caaSJens Wiklander 54363f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_SECRET_KEY); 54463f89caaSJens Wiklander 54563f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 54663f89caaSJens Wiklander if (rc) 54763f89caaSJens Wiklander return rc; 54863f89caaSJens Wiklander 54963f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_SECRET_KEY); 55063f89caaSJens Wiklander 55163f89caaSJens Wiklander switch (get_key_type(*out)) { 55263f89caaSJens Wiklander case PKCS11_CKK_GENERIC_SECRET: 55363f89caaSJens Wiklander case PKCS11_CKK_AES: 55463f89caaSJens Wiklander case PKCS11_CKK_MD5_HMAC: 55563f89caaSJens Wiklander case PKCS11_CKK_SHA_1_HMAC: 55663f89caaSJens Wiklander case PKCS11_CKK_SHA256_HMAC: 55763f89caaSJens Wiklander case PKCS11_CKK_SHA384_HMAC: 55863f89caaSJens Wiklander case PKCS11_CKK_SHA512_HMAC: 55963f89caaSJens Wiklander case PKCS11_CKK_SHA224_HMAC: 56063f89caaSJens Wiklander break; 56163f89caaSJens Wiklander default: 56263f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 56363f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 56463f89caaSJens Wiklander 56563f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 56663f89caaSJens Wiklander } 56763f89caaSJens Wiklander 5684eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, symm_key_boolprops, 5694eb88651SRuchika Gupta ARRAY_SIZE(symm_key_boolprops)); 57063f89caaSJens Wiklander if (rc) 57163f89caaSJens Wiklander return rc; 57263f89caaSJens Wiklander 5730ac5c695SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, symm_key_opt_or_null, 5744eb88651SRuchika Gupta ARRAY_SIZE(symm_key_opt_or_null)); 5750ac5c695SRuchika Gupta if (rc) 5760ac5c695SRuchika Gupta return rc; 5770ac5c695SRuchika Gupta 5780ac5c695SRuchika Gupta return set_optional_attributes(out, temp, symm_key_optional, 5790ac5c695SRuchika Gupta ARRAY_SIZE(symm_key_optional)); 58063f89caaSJens Wiklander } 58163f89caaSJens Wiklander 58263f89caaSJens Wiklander static enum pkcs11_rc create_data_attributes(struct obj_attrs **out, 58363f89caaSJens Wiklander struct obj_attrs *temp) 58463f89caaSJens Wiklander { 58563f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 58663f89caaSJens Wiklander 58763f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_DATA); 58863f89caaSJens Wiklander 58963f89caaSJens Wiklander rc = create_storage_attributes(out, temp); 59063f89caaSJens Wiklander if (rc) 59163f89caaSJens Wiklander return rc; 59263f89caaSJens Wiklander 59363f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_DATA); 59463f89caaSJens Wiklander 5954eb88651SRuchika Gupta return set_attributes_opt_or_null(out, temp, raw_data_opt_or_null, 5964eb88651SRuchika Gupta ARRAY_SIZE(raw_data_opt_or_null)); 59763f89caaSJens Wiklander } 59863f89caaSJens Wiklander 599*4137952dSVesa Jääskeläinen static enum pkcs11_rc create_certificate_attributes(struct obj_attrs **out, 600*4137952dSVesa Jääskeläinen struct obj_attrs *temp) 601*4137952dSVesa Jääskeläinen { 602*4137952dSVesa Jääskeläinen uint32_t const *mandated = NULL; 603*4137952dSVesa Jääskeläinen uint32_t const *optional = NULL; 604*4137952dSVesa Jääskeläinen size_t mandated_count = 0; 605*4137952dSVesa Jääskeläinen size_t optional_count = 0; 606*4137952dSVesa Jääskeläinen void *attr_value = NULL; 607*4137952dSVesa Jääskeläinen uint32_t attr_size = 0; 608*4137952dSVesa Jääskeläinen uint32_t default_cert_category = 609*4137952dSVesa Jääskeläinen PKCS11_CK_CERTIFICATE_CATEGORY_UNSPECIFIED; 610*4137952dSVesa Jääskeläinen uint32_t default_name_hash_alg = PKCS11_CKM_SHA_1; 611*4137952dSVesa Jääskeläinen uint32_t cert_category = 0; 612*4137952dSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_OK; 613*4137952dSVesa Jääskeläinen 614*4137952dSVesa Jääskeläinen assert(get_class(temp) == PKCS11_CKO_CERTIFICATE); 615*4137952dSVesa Jääskeläinen 616*4137952dSVesa Jääskeläinen rc = create_storage_attributes(out, temp); 617*4137952dSVesa Jääskeläinen if (rc) 618*4137952dSVesa Jääskeläinen return rc; 619*4137952dSVesa Jääskeläinen 620*4137952dSVesa Jääskeläinen assert(get_class(*out) == PKCS11_CKO_CERTIFICATE); 621*4137952dSVesa Jääskeläinen 622*4137952dSVesa Jääskeläinen rc = set_mandatory_boolprops(out, temp, pkcs11_certificate_boolprops, 623*4137952dSVesa Jääskeläinen ARRAY_SIZE(pkcs11_certificate_boolprops)); 624*4137952dSVesa Jääskeläinen if (rc) 625*4137952dSVesa Jääskeläinen return rc; 626*4137952dSVesa Jääskeläinen 627*4137952dSVesa Jääskeläinen rc = set_mandatory_attributes(out, temp, pkcs11_certificate_mandated, 628*4137952dSVesa Jääskeläinen ARRAY_SIZE(pkcs11_certificate_mandated)); 629*4137952dSVesa Jääskeläinen if (rc) 630*4137952dSVesa Jääskeläinen return rc; 631*4137952dSVesa Jääskeläinen 632*4137952dSVesa Jääskeläinen rc = set_optional_attributes(out, temp, pkcs11_certificate_optional, 633*4137952dSVesa Jääskeläinen ARRAY_SIZE(pkcs11_certificate_optional)); 634*4137952dSVesa Jääskeläinen if (rc) 635*4137952dSVesa Jääskeläinen return rc; 636*4137952dSVesa Jääskeläinen 637*4137952dSVesa Jääskeläinen switch (get_certificate_type(*out)) { 638*4137952dSVesa Jääskeläinen case PKCS11_CKC_X_509: 639*4137952dSVesa Jääskeläinen mandated = pkcs11_x509_certificate_mandated; 640*4137952dSVesa Jääskeläinen optional = pkcs11_x509_certificate_optional; 641*4137952dSVesa Jääskeläinen mandated_count = ARRAY_SIZE(pkcs11_x509_certificate_mandated); 642*4137952dSVesa Jääskeläinen optional_count = ARRAY_SIZE(pkcs11_x509_certificate_optional); 643*4137952dSVesa Jääskeläinen break; 644*4137952dSVesa Jääskeläinen default: 645*4137952dSVesa Jääskeläinen EMSG("Invalid certificate type %#"PRIx32"/%s", 646*4137952dSVesa Jääskeläinen get_certificate_type(*out), 647*4137952dSVesa Jääskeläinen id2str_certificate_type(get_certificate_type(*out))); 648*4137952dSVesa Jääskeläinen 649*4137952dSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 650*4137952dSVesa Jääskeläinen } 651*4137952dSVesa Jääskeläinen 652*4137952dSVesa Jääskeläinen rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 653*4137952dSVesa Jääskeläinen if (rc) 654*4137952dSVesa Jääskeläinen return rc; 655*4137952dSVesa Jääskeläinen 656*4137952dSVesa Jääskeläinen rc = set_optional_attributes(out, temp, optional, optional_count); 657*4137952dSVesa Jääskeläinen if (rc) 658*4137952dSVesa Jääskeläinen return rc; 659*4137952dSVesa Jääskeläinen 660*4137952dSVesa Jääskeläinen attr_size = 0; 661*4137952dSVesa Jääskeläinen rc = get_attribute_ptr(*out, PKCS11_CKA_CERTIFICATE_CATEGORY, 662*4137952dSVesa Jääskeläinen &attr_value, &attr_size); 663*4137952dSVesa Jääskeläinen if (rc == PKCS11_CKR_OK && attr_size == sizeof(cert_category)) { 664*4137952dSVesa Jääskeläinen /* Sanitize certificate category */ 665*4137952dSVesa Jääskeläinen TEE_MemMove(&cert_category, attr_value, sizeof(cert_category)); 666*4137952dSVesa Jääskeläinen 667*4137952dSVesa Jääskeläinen switch (cert_category) { 668*4137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_UNSPECIFIED: 669*4137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_TOKEN_USER: 670*4137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_AUTHORITY: 671*4137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_OTHER_ENTITY: 672*4137952dSVesa Jääskeläinen break; 673*4137952dSVesa Jääskeläinen default: 674*4137952dSVesa Jääskeläinen EMSG("Invalid certificate category %#"PRIx32, 675*4137952dSVesa Jääskeläinen cert_category); 676*4137952dSVesa Jääskeläinen 677*4137952dSVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 678*4137952dSVesa Jääskeläinen } 679*4137952dSVesa Jääskeläinen } else if (rc == PKCS11_RV_NOT_FOUND) { 680*4137952dSVesa Jääskeläinen /* Set default category when missing */ 681*4137952dSVesa Jääskeläinen rc = set_attribute(out, PKCS11_CKA_CERTIFICATE_CATEGORY, 682*4137952dSVesa Jääskeläinen &default_cert_category, 683*4137952dSVesa Jääskeläinen sizeof(default_cert_category)); 684*4137952dSVesa Jääskeläinen if (rc) 685*4137952dSVesa Jääskeläinen return rc; 686*4137952dSVesa Jääskeläinen } else { 687*4137952dSVesa Jääskeläinen /* All other cases are errors */ 688*4137952dSVesa Jääskeläinen EMSG("Invalid certificate category"); 689*4137952dSVesa Jääskeläinen 690*4137952dSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 691*4137952dSVesa Jääskeläinen } 692*4137952dSVesa Jääskeläinen 693*4137952dSVesa Jääskeläinen attr_size = 0; 694*4137952dSVesa Jääskeläinen rc = get_attribute_ptr(*out, PKCS11_CKA_NAME_HASH_ALGORITHM, NULL, 695*4137952dSVesa Jääskeläinen &attr_size); 696*4137952dSVesa Jääskeläinen if (rc == PKCS11_CKR_OK && attr_size == sizeof(uint32_t)) { 697*4137952dSVesa Jääskeläinen /* We accept any algorithm what caller wanted to specify */ 698*4137952dSVesa Jääskeläinen } else if (rc == PKCS11_RV_NOT_FOUND) { 699*4137952dSVesa Jääskeläinen /* Set default hash algorithm when missing */ 700*4137952dSVesa Jääskeläinen rc = set_attribute(out, PKCS11_CKA_NAME_HASH_ALGORITHM, 701*4137952dSVesa Jääskeläinen &default_name_hash_alg, 702*4137952dSVesa Jääskeläinen sizeof(default_name_hash_alg)); 703*4137952dSVesa Jääskeläinen if (rc) 704*4137952dSVesa Jääskeläinen return rc; 705*4137952dSVesa Jääskeläinen } else { 706*4137952dSVesa Jääskeläinen /* All other cases are errors */ 707*4137952dSVesa Jääskeläinen EMSG("Invalid name hash algorithm"); 708*4137952dSVesa Jääskeläinen 709*4137952dSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 710*4137952dSVesa Jääskeläinen } 711*4137952dSVesa Jääskeläinen 712*4137952dSVesa Jääskeläinen return rc; 713*4137952dSVesa Jääskeläinen } 714*4137952dSVesa Jääskeläinen 71563f89caaSJens Wiklander static enum pkcs11_rc create_pub_key_attributes(struct obj_attrs **out, 7169cf1afceSVesa Jääskeläinen struct obj_attrs *temp, 7179cf1afceSVesa Jääskeläinen enum processing_func function) 71863f89caaSJens Wiklander { 71963f89caaSJens Wiklander uint32_t const *mandated = NULL; 7209cf1afceSVesa Jääskeläinen uint32_t const *oon = NULL; 72163f89caaSJens Wiklander size_t mandated_count = 0; 7229cf1afceSVesa Jääskeläinen size_t oon_count = 0; 72363f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 72463f89caaSJens Wiklander 72563f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_PUBLIC_KEY); 72663f89caaSJens Wiklander 72763f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 72863f89caaSJens Wiklander if (rc) 72963f89caaSJens Wiklander return rc; 73063f89caaSJens Wiklander 73163f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_PUBLIC_KEY); 73263f89caaSJens Wiklander 7334eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, public_key_boolprops, 7344eb88651SRuchika Gupta ARRAY_SIZE(public_key_boolprops)); 73563f89caaSJens Wiklander if (rc) 73663f89caaSJens Wiklander return rc; 73763f89caaSJens Wiklander 7384eb88651SRuchika Gupta rc = set_mandatory_attributes(out, temp, public_key_mandated, 7394eb88651SRuchika Gupta ARRAY_SIZE(public_key_mandated)); 74063f89caaSJens Wiklander if (rc) 74163f89caaSJens Wiklander return rc; 74263f89caaSJens Wiklander 7434eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, 7444eb88651SRuchika Gupta public_key_opt_or_null, 7454eb88651SRuchika Gupta ARRAY_SIZE(public_key_opt_or_null)); 74663f89caaSJens Wiklander if (rc) 74763f89caaSJens Wiklander return rc; 74863f89caaSJens Wiklander 74963f89caaSJens Wiklander switch (get_key_type(*out)) { 75063f89caaSJens Wiklander case PKCS11_CKK_RSA: 7519cf1afceSVesa Jääskeläinen switch (function) { 7529cf1afceSVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 7539cf1afceSVesa Jääskeläinen mandated = rsa_pub_key_gen_mand; 7549cf1afceSVesa Jääskeläinen oon = rsa_pub_key_gen_opt_or_null; 7559cf1afceSVesa Jääskeläinen mandated_count = ARRAY_SIZE(rsa_pub_key_gen_mand); 7569cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(rsa_pub_key_gen_opt_or_null); 7579cf1afceSVesa Jääskeläinen break; 7589cf1afceSVesa Jääskeläinen case PKCS11_FUNCTION_IMPORT: 7599cf1afceSVesa Jääskeläinen mandated = rsa_pub_key_create_mand; 7609cf1afceSVesa Jääskeläinen mandated_count = ARRAY_SIZE(rsa_pub_key_create_mand); 7619cf1afceSVesa Jääskeläinen break; 7629cf1afceSVesa Jääskeläinen default: 7639cf1afceSVesa Jääskeläinen EMSG("Unsupported function %#"PRIx32"/%s", function, 7649cf1afceSVesa Jääskeläinen id2str_function(function)); 7659cf1afceSVesa Jääskeläinen 7669cf1afceSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 7679cf1afceSVesa Jääskeläinen } 76863f89caaSJens Wiklander break; 76963f89caaSJens Wiklander case PKCS11_CKK_EC: 7704eb88651SRuchika Gupta mandated = ec_public_key_mandated; 7719cf1afceSVesa Jääskeläinen oon = ec_public_key_opt_or_null; 7724eb88651SRuchika Gupta mandated_count = ARRAY_SIZE(ec_public_key_mandated); 7739cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(ec_public_key_opt_or_null); 77463f89caaSJens Wiklander break; 77563f89caaSJens Wiklander default: 77663f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 77763f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 77863f89caaSJens Wiklander 77963f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 78063f89caaSJens Wiklander } 78163f89caaSJens Wiklander 78263f89caaSJens Wiklander rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 78363f89caaSJens Wiklander if (rc) 78463f89caaSJens Wiklander return rc; 78563f89caaSJens Wiklander 7869cf1afceSVesa Jääskeläinen return set_attributes_opt_or_null(out, temp, oon, oon_count); 78763f89caaSJens Wiklander } 78863f89caaSJens Wiklander 78963f89caaSJens Wiklander static enum pkcs11_rc create_priv_key_attributes(struct obj_attrs **out, 79063f89caaSJens Wiklander struct obj_attrs *temp) 79163f89caaSJens Wiklander { 79263f89caaSJens Wiklander uint32_t const *mandated = NULL; 7939cf1afceSVesa Jääskeläinen uint32_t const *oon = NULL; 79463f89caaSJens Wiklander size_t mandated_count = 0; 7959cf1afceSVesa Jääskeläinen size_t oon_count = 0; 79663f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 79763f89caaSJens Wiklander 79863f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_PRIVATE_KEY); 79963f89caaSJens Wiklander 80063f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 80163f89caaSJens Wiklander if (rc) 80263f89caaSJens Wiklander return rc; 80363f89caaSJens Wiklander 80463f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_PRIVATE_KEY); 80563f89caaSJens Wiklander 8064eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, private_key_boolprops, 8074eb88651SRuchika Gupta ARRAY_SIZE(private_key_boolprops)); 80863f89caaSJens Wiklander if (rc) 80963f89caaSJens Wiklander return rc; 81063f89caaSJens Wiklander 8114eb88651SRuchika Gupta rc = set_mandatory_attributes(out, temp, private_key_mandated, 8124eb88651SRuchika Gupta ARRAY_SIZE(private_key_mandated)); 81363f89caaSJens Wiklander if (rc) 81463f89caaSJens Wiklander return rc; 81563f89caaSJens Wiklander 8164eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, private_key_opt_or_null, 8174eb88651SRuchika Gupta ARRAY_SIZE(private_key_opt_or_null)); 81863f89caaSJens Wiklander if (rc) 81963f89caaSJens Wiklander return rc; 82063f89caaSJens Wiklander 82163f89caaSJens Wiklander switch (get_key_type(*out)) { 82263f89caaSJens Wiklander case PKCS11_CKK_RSA: 8239cf1afceSVesa Jääskeläinen oon = rsa_priv_key_opt_or_null; 8249cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(rsa_priv_key_opt_or_null); 82563f89caaSJens Wiklander break; 82663f89caaSJens Wiklander case PKCS11_CKK_EC: 8274eb88651SRuchika Gupta mandated = ec_private_key_mandated; 8289cf1afceSVesa Jääskeläinen oon = ec_private_key_opt_or_null; 8294eb88651SRuchika Gupta mandated_count = ARRAY_SIZE(ec_private_key_mandated); 8309cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(ec_private_key_opt_or_null); 83163f89caaSJens Wiklander break; 83263f89caaSJens Wiklander default: 83363f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 83463f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 83563f89caaSJens Wiklander 83663f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 83763f89caaSJens Wiklander } 83863f89caaSJens Wiklander 83963f89caaSJens Wiklander rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 84063f89caaSJens Wiklander if (rc) 84163f89caaSJens Wiklander return rc; 84263f89caaSJens Wiklander 8439cf1afceSVesa Jääskeläinen return set_attributes_opt_or_null(out, temp, oon, oon_count); 84463f89caaSJens Wiklander } 84563f89caaSJens Wiklander 846196bcd93SRuchika Gupta static enum pkcs11_rc 847196bcd93SRuchika Gupta sanitize_symm_key_attributes(struct obj_attrs **temp, 848196bcd93SRuchika Gupta enum processing_func function) 849196bcd93SRuchika Gupta { 850196bcd93SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK; 851196bcd93SRuchika Gupta uint32_t a_size = 0; 852196bcd93SRuchika Gupta 853196bcd93SRuchika Gupta assert(get_class(*temp) == PKCS11_CKO_SECRET_KEY); 854196bcd93SRuchika Gupta 855196bcd93SRuchika Gupta rc = get_attribute_ptr(*temp, PKCS11_CKA_VALUE, NULL, &a_size); 856196bcd93SRuchika Gupta 857196bcd93SRuchika Gupta switch (get_key_type(*temp)) { 858196bcd93SRuchika Gupta case PKCS11_CKK_GENERIC_SECRET: 859196bcd93SRuchika Gupta case PKCS11_CKK_AES: 860196bcd93SRuchika Gupta case PKCS11_CKK_MD5_HMAC: 861196bcd93SRuchika Gupta case PKCS11_CKK_SHA_1_HMAC: 862196bcd93SRuchika Gupta case PKCS11_CKK_SHA256_HMAC: 863196bcd93SRuchika Gupta case PKCS11_CKK_SHA384_HMAC: 864196bcd93SRuchika Gupta case PKCS11_CKK_SHA512_HMAC: 865196bcd93SRuchika Gupta case PKCS11_CKK_SHA224_HMAC: 866196bcd93SRuchika Gupta switch (function) { 867196bcd93SRuchika Gupta case PKCS11_FUNCTION_IMPORT: 868196bcd93SRuchika Gupta /* CKA_VALUE is a mandatory with C_CreateObject */ 869196bcd93SRuchika Gupta if (rc || a_size == 0) 870196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 871196bcd93SRuchika Gupta 872196bcd93SRuchika Gupta if (get_attribute_ptr(*temp, PKCS11_CKA_VALUE_LEN, NULL, 873196bcd93SRuchika Gupta NULL) != PKCS11_RV_NOT_FOUND) 874196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 875196bcd93SRuchika Gupta 876196bcd93SRuchika Gupta return add_attribute(temp, PKCS11_CKA_VALUE_LEN, 877196bcd93SRuchika Gupta &a_size, sizeof(uint32_t)); 878196bcd93SRuchika Gupta case PKCS11_FUNCTION_GENERATE: 879196bcd93SRuchika Gupta if (rc != PKCS11_RV_NOT_FOUND) 880196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 881196bcd93SRuchika Gupta break; 882196bcd93SRuchika Gupta default: 883196bcd93SRuchika Gupta break; 884196bcd93SRuchika Gupta } 885196bcd93SRuchika Gupta break; 886196bcd93SRuchika Gupta default: 887196bcd93SRuchika Gupta EMSG("Invalid key type %#"PRIx32"/%s", 888196bcd93SRuchika Gupta get_key_type(*temp), id2str_key_type(get_key_type(*temp))); 889196bcd93SRuchika Gupta 890196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 891196bcd93SRuchika Gupta } 892196bcd93SRuchika Gupta 893196bcd93SRuchika Gupta return PKCS11_CKR_OK; 894196bcd93SRuchika Gupta } 895196bcd93SRuchika Gupta 89663f89caaSJens Wiklander /* 89763f89caaSJens Wiklander * Create an attribute list for a new object from a template and a parent 89863f89caaSJens Wiklander * object (optional) for an object generation function (generate, copy, 89963f89caaSJens Wiklander * derive...). 90063f89caaSJens Wiklander * 90163f89caaSJens Wiklander * PKCS#11 directives on the supplied template and expected return value: 90263f89caaSJens Wiklander * - template has an invalid attribute ID: ATTRIBUTE_TYPE_INVALID 90363f89caaSJens Wiklander * - template has an invalid value for an attribute: ATTRIBUTE_VALID_INVALID 90463f89caaSJens Wiklander * - template has value for a read-only attribute: ATTRIBUTE_READ_ONLY 90563f89caaSJens Wiklander * - template+default+parent => still miss an attribute: TEMPLATE_INCONSISTENT 90663f89caaSJens Wiklander * 90763f89caaSJens Wiklander * INFO on PKCS11_CMD_COPY_OBJECT: 90863f89caaSJens Wiklander * - parent PKCS11_CKA_COPYIABLE=false => return ACTION_PROHIBITED. 90963f89caaSJens Wiklander * - template can specify PKCS11_CKA_TOKEN, PKCS11_CKA_PRIVATE, 91063f89caaSJens Wiklander * PKCS11_CKA_MODIFIABLE, PKCS11_CKA_DESTROYABLE. 91163f89caaSJens Wiklander * - SENSITIVE can change from false to true, not from true to false. 91263f89caaSJens Wiklander * - LOCAL is the parent LOCAL 91363f89caaSJens Wiklander */ 91463f89caaSJens Wiklander enum pkcs11_rc 91563f89caaSJens Wiklander create_attributes_from_template(struct obj_attrs **out, void *template, 91663f89caaSJens Wiklander size_t template_size, 91748799892SRuchika Gupta struct obj_attrs *parent, 91863f89caaSJens Wiklander enum processing_func function, 9194cfce748SRuchika Gupta enum pkcs11_mechanism_id mecha, 92002b16804SVesa Jääskeläinen enum pkcs11_class_id template_class) 92163f89caaSJens Wiklander { 92263f89caaSJens Wiklander struct obj_attrs *temp = NULL; 92363f89caaSJens Wiklander struct obj_attrs *attrs = NULL; 92463f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 92563f89caaSJens Wiklander uint8_t local = 0; 92663f89caaSJens Wiklander uint8_t always_sensitive = 0; 92763f89caaSJens Wiklander uint8_t never_extract = 0; 928e3f0cb56SRuchika Gupta uint8_t extractable = 0; 929fa247a2aSRuchika Gupta uint32_t class = PKCS11_UNDEFINED_ID; 930fa247a2aSRuchika Gupta uint32_t type = PKCS11_UNDEFINED_ID; 93163f89caaSJens Wiklander uint32_t mechanism_id = PKCS11_CKM_UNDEFINED_ID; 932e3f0cb56SRuchika Gupta struct obj_attrs *req_attrs = NULL; 933e3f0cb56SRuchika Gupta uint32_t size = 0; 934e3f0cb56SRuchika Gupta uint32_t indirect_template = PKCS11_CKA_UNDEFINED_ID; 93563f89caaSJens Wiklander 93663f89caaSJens Wiklander #ifdef DEBUG /* Sanity: check function argument */ 93763f89caaSJens Wiklander trace_attributes_from_api_head("template", template, template_size); 93863f89caaSJens Wiklander switch (function) { 939fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 940013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 94163f89caaSJens Wiklander case PKCS11_FUNCTION_IMPORT: 9422d25a9bcSRuchika Gupta case PKCS11_FUNCTION_MODIFY: 94348799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 944e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 9452d25a9bcSRuchika Gupta case PKCS11_FUNCTION_COPY: 94663f89caaSJens Wiklander break; 94763f89caaSJens Wiklander default: 94863f89caaSJens Wiklander TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 94963f89caaSJens Wiklander } 95063f89caaSJens Wiklander #endif 95163f89caaSJens Wiklander 952dcad3409SRuchika Gupta /* 953dcad3409SRuchika Gupta * For PKCS11_FUNCTION_GENERATE, find the class and type 954dcad3409SRuchika Gupta * based on the mechanism. These will be passed as hint 955dcad3409SRuchika Gupta * sanitize_client_object() and added in temp if not 956dcad3409SRuchika Gupta * already present 957dcad3409SRuchika Gupta */ 958dcad3409SRuchika Gupta if (function == PKCS11_FUNCTION_GENERATE) { 959fa247a2aSRuchika Gupta switch (mecha) { 960fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 961fa247a2aSRuchika Gupta class = PKCS11_CKO_SECRET_KEY; 962fa247a2aSRuchika Gupta type = PKCS11_CKK_GENERIC_SECRET; 963fa247a2aSRuchika Gupta break; 964fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 965fa247a2aSRuchika Gupta class = PKCS11_CKO_SECRET_KEY; 966fa247a2aSRuchika Gupta type = PKCS11_CKK_AES; 967fa247a2aSRuchika Gupta break; 968fa247a2aSRuchika Gupta default: 969dcad3409SRuchika Gupta TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 970fa247a2aSRuchika Gupta } 971fa247a2aSRuchika Gupta } 972fa247a2aSRuchika Gupta 9732d25a9bcSRuchika Gupta /* 974013934d8SVesa Jääskeläinen * For PKCS11_FUNCTION_GENERATE_PAIR, find the class and type 975013934d8SVesa Jääskeläinen * based on the mechanism. These will be passed as hint 976013934d8SVesa Jääskeläinen * sanitize_client_object() and added in temp if not 977013934d8SVesa Jääskeläinen * already present 978013934d8SVesa Jääskeläinen */ 979013934d8SVesa Jääskeläinen if (function == PKCS11_FUNCTION_GENERATE_PAIR) { 980013934d8SVesa Jääskeläinen switch (mecha) { 98102b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 98202b16804SVesa Jääskeläinen class = template_class; 98302b16804SVesa Jääskeläinen type = PKCS11_CKK_EC; 98402b16804SVesa Jääskeläinen break; 98586922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 98686922832SVesa Jääskeläinen class = template_class; 98786922832SVesa Jääskeläinen type = PKCS11_CKK_RSA; 98886922832SVesa Jääskeläinen break; 989013934d8SVesa Jääskeläinen default: 990013934d8SVesa Jääskeläinen TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 991013934d8SVesa Jääskeläinen } 992013934d8SVesa Jääskeläinen } 993013934d8SVesa Jääskeläinen 994013934d8SVesa Jääskeläinen /* 9952d25a9bcSRuchika Gupta * Check and remove duplicates if any and create a new temporary 9962d25a9bcSRuchika Gupta * template 9972d25a9bcSRuchika Gupta */ 998dcad3409SRuchika Gupta rc = sanitize_client_object(&temp, template, template_size, class, 999dcad3409SRuchika Gupta type); 1000dcad3409SRuchika Gupta if (rc) 1001dcad3409SRuchika Gupta goto out; 1002dcad3409SRuchika Gupta 1003dcad3409SRuchika Gupta /* 10042d25a9bcSRuchika Gupta * For function type modify and copy return the created template 10052d25a9bcSRuchika Gupta * from here. Rest of the code below is for creating objects 10062d25a9bcSRuchika Gupta * or generating keys. 10072d25a9bcSRuchika Gupta */ 10082d25a9bcSRuchika Gupta switch (function) { 10092d25a9bcSRuchika Gupta case PKCS11_FUNCTION_MODIFY: 10102d25a9bcSRuchika Gupta case PKCS11_FUNCTION_COPY: 10112d25a9bcSRuchika Gupta *out = temp; 10122d25a9bcSRuchika Gupta return rc; 1013e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 1014e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 1015e3f0cb56SRuchika Gupta if (function == PKCS11_FUNCTION_UNWRAP) 1016e3f0cb56SRuchika Gupta indirect_template = PKCS11_CKA_UNWRAP_TEMPLATE; 1017e3f0cb56SRuchika Gupta else 1018e3f0cb56SRuchika Gupta indirect_template = PKCS11_CKA_DERIVE_TEMPLATE; 1019e3f0cb56SRuchika Gupta 1020e3f0cb56SRuchika Gupta rc = get_attribute_ptr(parent, indirect_template, 1021e3f0cb56SRuchika Gupta (void *)&req_attrs, &size); 1022e3f0cb56SRuchika Gupta if (rc == PKCS11_CKR_OK && size != 0) { 1023e3f0cb56SRuchika Gupta rc = attributes_match_add_reference(&temp, req_attrs); 1024e3f0cb56SRuchika Gupta if (rc) 1025e3f0cb56SRuchika Gupta goto out; 1026e3f0cb56SRuchika Gupta } 1027e3f0cb56SRuchika Gupta break; 10282d25a9bcSRuchika Gupta default: 10292d25a9bcSRuchika Gupta break; 10302d25a9bcSRuchika Gupta } 10312d25a9bcSRuchika Gupta 10322d25a9bcSRuchika Gupta /* 1033dcad3409SRuchika Gupta * Check if class and type in temp are consistent with the mechanism 1034dcad3409SRuchika Gupta */ 1035fa247a2aSRuchika Gupta switch (mecha) { 1036fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1037fa247a2aSRuchika Gupta if (get_class(temp) != PKCS11_CKO_SECRET_KEY || 1038fa247a2aSRuchika Gupta get_key_type(temp) != PKCS11_CKK_GENERIC_SECRET) { 1039fa247a2aSRuchika Gupta rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 1040fa247a2aSRuchika Gupta goto out; 1041fa247a2aSRuchika Gupta } 1042fa247a2aSRuchika Gupta break; 1043fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 1044fa247a2aSRuchika Gupta if (get_class(temp) != PKCS11_CKO_SECRET_KEY || 1045fa247a2aSRuchika Gupta get_key_type(temp) != PKCS11_CKK_AES) { 1046fa247a2aSRuchika Gupta rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 1047fa247a2aSRuchika Gupta goto out; 1048fa247a2aSRuchika Gupta } 1049fa247a2aSRuchika Gupta break; 105002b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 105102b16804SVesa Jääskeläinen if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && 105202b16804SVesa Jääskeläinen get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || 105302b16804SVesa Jääskeläinen get_key_type(temp) != PKCS11_CKK_EC) { 105402b16804SVesa Jääskeläinen rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 105502b16804SVesa Jääskeläinen goto out; 105602b16804SVesa Jääskeläinen } 105702b16804SVesa Jääskeläinen break; 105886922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 105986922832SVesa Jääskeläinen if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && 106086922832SVesa Jääskeläinen get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || 106186922832SVesa Jääskeläinen get_key_type(temp) != PKCS11_CKK_RSA) { 106286922832SVesa Jääskeläinen rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 106386922832SVesa Jääskeläinen goto out; 106486922832SVesa Jääskeläinen } 106586922832SVesa Jääskeläinen break; 1066fa247a2aSRuchika Gupta default: 1067fa247a2aSRuchika Gupta break; 1068fa247a2aSRuchika Gupta } 106963f89caaSJens Wiklander 107063f89caaSJens Wiklander if (!sanitize_consistent_class_and_type(temp)) { 107163f89caaSJens Wiklander EMSG("Inconsistent class/type"); 107263f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 107363f89caaSJens Wiklander goto out; 107463f89caaSJens Wiklander } 107563f89caaSJens Wiklander 1076e3f0cb56SRuchika Gupta /* 1077e3f0cb56SRuchika Gupta * TBD - Add a check to see if temp contains any attribute which 1078e3f0cb56SRuchika Gupta * is not consistent with the object class or type and return error. 1079e3f0cb56SRuchika Gupta * In current implementation such attributes are ignored and not 1080e3f0cb56SRuchika Gupta * added to final object while PKCS#11 specification expects a 1081e3f0cb56SRuchika Gupta * failure and an error code be returned. 1082e3f0cb56SRuchika Gupta */ 1083e3f0cb56SRuchika Gupta 108463f89caaSJens Wiklander switch (get_class(temp)) { 108563f89caaSJens Wiklander case PKCS11_CKO_DATA: 108663f89caaSJens Wiklander rc = create_data_attributes(&attrs, temp); 108763f89caaSJens Wiklander break; 1088*4137952dSVesa Jääskeläinen case PKCS11_CKO_CERTIFICATE: 1089*4137952dSVesa Jääskeläinen rc = create_certificate_attributes(&attrs, temp); 1090*4137952dSVesa Jääskeläinen break; 109163f89caaSJens Wiklander case PKCS11_CKO_SECRET_KEY: 1092196bcd93SRuchika Gupta rc = sanitize_symm_key_attributes(&temp, function); 1093196bcd93SRuchika Gupta if (rc) 1094196bcd93SRuchika Gupta goto out; 109563f89caaSJens Wiklander rc = create_symm_key_attributes(&attrs, temp); 109663f89caaSJens Wiklander break; 109763f89caaSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 10989cf1afceSVesa Jääskeläinen rc = create_pub_key_attributes(&attrs, temp, function); 109963f89caaSJens Wiklander break; 110063f89caaSJens Wiklander case PKCS11_CKO_PRIVATE_KEY: 110163f89caaSJens Wiklander rc = create_priv_key_attributes(&attrs, temp); 110263f89caaSJens Wiklander break; 110363f89caaSJens Wiklander default: 110463f89caaSJens Wiklander DMSG("Invalid object class %#"PRIx32"/%s", 110563f89caaSJens Wiklander get_class(temp), id2str_class(get_class(temp))); 110663f89caaSJens Wiklander 110763f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 110863f89caaSJens Wiklander break; 110963f89caaSJens Wiklander } 111063f89caaSJens Wiklander if (rc) 111163f89caaSJens Wiklander goto out; 111263f89caaSJens Wiklander 111390c47fe2SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_LOCAL, NULL, NULL) != 1114002f6b93SEtienne Carriere PKCS11_RV_NOT_FOUND) { 1115002f6b93SEtienne Carriere rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 111663f89caaSJens Wiklander goto out; 1117002f6b93SEtienne Carriere } 111863f89caaSJens Wiklander 111990c47fe2SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_KEY_GEN_MECHANISM, NULL, NULL) != 1120002f6b93SEtienne Carriere PKCS11_RV_NOT_FOUND) { 1121002f6b93SEtienne Carriere rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 112263f89caaSJens Wiklander goto out; 1123002f6b93SEtienne Carriere } 112463f89caaSJens Wiklander 112563f89caaSJens Wiklander switch (function) { 1126fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 1127013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 1128fa247a2aSRuchika Gupta local = PKCS11_TRUE; 1129fa247a2aSRuchika Gupta break; 113063f89caaSJens Wiklander case PKCS11_FUNCTION_IMPORT: 113148799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 1132e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 113363f89caaSJens Wiklander default: 113463f89caaSJens Wiklander local = PKCS11_FALSE; 113563f89caaSJens Wiklander break; 113663f89caaSJens Wiklander } 113763f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_LOCAL, &local, sizeof(local)); 113863f89caaSJens Wiklander if (rc) 113963f89caaSJens Wiklander goto out; 114063f89caaSJens Wiklander 114163f89caaSJens Wiklander switch (get_class(attrs)) { 114263f89caaSJens Wiklander case PKCS11_CKO_SECRET_KEY: 114363f89caaSJens Wiklander case PKCS11_CKO_PRIVATE_KEY: 114463f89caaSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 114563f89caaSJens Wiklander always_sensitive = PKCS11_FALSE; 114663f89caaSJens Wiklander never_extract = PKCS11_FALSE; 114763f89caaSJens Wiklander 1148fa247a2aSRuchika Gupta switch (function) { 114948799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 115048799892SRuchika Gupta always_sensitive = 115148799892SRuchika Gupta get_bool(parent, PKCS11_CKA_ALWAYS_SENSITIVE) && 115248799892SRuchika Gupta get_bool(attrs, PKCS11_CKA_SENSITIVE); 115348799892SRuchika Gupta never_extract = 115448799892SRuchika Gupta get_bool(parent, PKCS11_CKA_NEVER_EXTRACTABLE) && 115548799892SRuchika Gupta !get_bool(attrs, PKCS11_CKA_EXTRACTABLE); 115648799892SRuchika Gupta break; 1157e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 1158e3f0cb56SRuchika Gupta always_sensitive = PKCS11_FALSE; 1159e3f0cb56SRuchika Gupta never_extract = PKCS11_FALSE; 1160e3f0cb56SRuchika Gupta extractable = PKCS11_TRUE; 1161e3f0cb56SRuchika Gupta 1162e3f0cb56SRuchika Gupta /* 1163e3f0cb56SRuchika Gupta * Check if template passed by user has CKA_EXTRACTABLE. 1164e3f0cb56SRuchika Gupta * If not, by default value of CKA_EXTRACTABLE is set as 1165e3f0cb56SRuchika Gupta * TRUE. 1166e3f0cb56SRuchika Gupta */ 1167e3f0cb56SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_EXTRACTABLE, 1168e3f0cb56SRuchika Gupta NULL, 1169e3f0cb56SRuchika Gupta NULL) == PKCS11_RV_NOT_FOUND) { 1170e3f0cb56SRuchika Gupta rc = set_attribute(&attrs, 1171e3f0cb56SRuchika Gupta PKCS11_CKA_EXTRACTABLE, 1172e3f0cb56SRuchika Gupta &extractable, 1173e3f0cb56SRuchika Gupta sizeof(extractable)); 1174e3f0cb56SRuchika Gupta if (rc) 1175e3f0cb56SRuchika Gupta goto out; 1176e3f0cb56SRuchika Gupta } 1177e3f0cb56SRuchika Gupta break; 1178fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 1179013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 1180fa247a2aSRuchika Gupta always_sensitive = get_bool(attrs, 1181fa247a2aSRuchika Gupta PKCS11_CKA_SENSITIVE); 1182fa247a2aSRuchika Gupta never_extract = !get_bool(attrs, 1183fa247a2aSRuchika Gupta PKCS11_CKA_EXTRACTABLE); 1184fa247a2aSRuchika Gupta break; 1185fa247a2aSRuchika Gupta default: 1186fa247a2aSRuchika Gupta break; 1187fa247a2aSRuchika Gupta } 1188fa247a2aSRuchika Gupta 118963f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_ALWAYS_SENSITIVE, 119063f89caaSJens Wiklander &always_sensitive, sizeof(always_sensitive)); 119163f89caaSJens Wiklander if (rc) 119263f89caaSJens Wiklander goto out; 119363f89caaSJens Wiklander 119463f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_NEVER_EXTRACTABLE, 119563f89caaSJens Wiklander &never_extract, sizeof(never_extract)); 119663f89caaSJens Wiklander if (rc) 119763f89caaSJens Wiklander goto out; 119863f89caaSJens Wiklander 119963f89caaSJens Wiklander /* Keys mandate attribute PKCS11_CKA_KEY_GEN_MECHANISM */ 1200fa247a2aSRuchika Gupta if (local) 1201fa247a2aSRuchika Gupta mechanism_id = mecha; 1202fa247a2aSRuchika Gupta else 120363f89caaSJens Wiklander mechanism_id = PKCS11_CK_UNAVAILABLE_INFORMATION; 1204fa247a2aSRuchika Gupta 120563f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_KEY_GEN_MECHANISM, 120663f89caaSJens Wiklander &mechanism_id, sizeof(mechanism_id)); 120763f89caaSJens Wiklander if (rc) 120863f89caaSJens Wiklander goto out; 120963f89caaSJens Wiklander break; 121063f89caaSJens Wiklander 121163f89caaSJens Wiklander default: 121263f89caaSJens Wiklander break; 121363f89caaSJens Wiklander } 121463f89caaSJens Wiklander 121563f89caaSJens Wiklander *out = attrs; 121663f89caaSJens Wiklander 121763f89caaSJens Wiklander #ifdef DEBUG 121863f89caaSJens Wiklander trace_attributes("object", attrs); 121963f89caaSJens Wiklander #endif 122063f89caaSJens Wiklander 122163f89caaSJens Wiklander out: 122263f89caaSJens Wiklander TEE_Free(temp); 122363f89caaSJens Wiklander if (rc) 122463f89caaSJens Wiklander TEE_Free(attrs); 122563f89caaSJens Wiklander 122663f89caaSJens Wiklander return rc; 122763f89caaSJens Wiklander } 122863f89caaSJens Wiklander 122963f89caaSJens Wiklander static enum pkcs11_rc check_attrs_misc_integrity(struct obj_attrs *head) 123063f89caaSJens Wiklander { 123163f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_NEVER_EXTRACTABLE) && 123263f89caaSJens Wiklander get_bool(head, PKCS11_CKA_EXTRACTABLE)) { 123363f89caaSJens Wiklander DMSG("Never/Extractable attributes mismatch %d/%d", 123463f89caaSJens Wiklander get_bool(head, PKCS11_CKA_NEVER_EXTRACTABLE), 123563f89caaSJens Wiklander get_bool(head, PKCS11_CKA_EXTRACTABLE)); 123663f89caaSJens Wiklander 123763f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 123863f89caaSJens Wiklander } 123963f89caaSJens Wiklander 124063f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_ALWAYS_SENSITIVE) && 124163f89caaSJens Wiklander !get_bool(head, PKCS11_CKA_SENSITIVE)) { 124263f89caaSJens Wiklander DMSG("Sensitive/always attributes mismatch %d/%d", 124363f89caaSJens Wiklander get_bool(head, PKCS11_CKA_SENSITIVE), 124463f89caaSJens Wiklander get_bool(head, PKCS11_CKA_ALWAYS_SENSITIVE)); 124563f89caaSJens Wiklander 124663f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 124763f89caaSJens Wiklander } 124863f89caaSJens Wiklander 124963f89caaSJens Wiklander return PKCS11_CKR_OK; 125063f89caaSJens Wiklander } 125163f89caaSJens Wiklander 125289735787SRuchika Gupta bool object_is_private(struct obj_attrs *head) 125389735787SRuchika Gupta { 125465fb9092SVesa Jääskeläinen return get_bool(head, PKCS11_CKA_PRIVATE); 125589735787SRuchika Gupta } 125689735787SRuchika Gupta 12572d25a9bcSRuchika Gupta bool object_is_token(struct obj_attrs *head) 12582d25a9bcSRuchika Gupta { 12592d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_TOKEN); 12602d25a9bcSRuchika Gupta } 12612d25a9bcSRuchika Gupta 12622d25a9bcSRuchika Gupta bool object_is_modifiable(struct obj_attrs *head) 12632d25a9bcSRuchika Gupta { 12642d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_MODIFIABLE); 12652d25a9bcSRuchika Gupta } 12662d25a9bcSRuchika Gupta 12672d25a9bcSRuchika Gupta bool object_is_copyable(struct obj_attrs *head) 12682d25a9bcSRuchika Gupta { 12692d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_COPYABLE); 12702d25a9bcSRuchika Gupta } 12712d25a9bcSRuchika Gupta 127263f89caaSJens Wiklander /* 1273512cbf1dSJens Wiklander * Check access to object against authentication to token 1274512cbf1dSJens Wiklander */ 1275512cbf1dSJens Wiklander enum pkcs11_rc check_access_attrs_against_token(struct pkcs11_session *session, 1276512cbf1dSJens Wiklander struct obj_attrs *head) 1277512cbf1dSJens Wiklander { 1278512cbf1dSJens Wiklander bool private = true; 1279512cbf1dSJens Wiklander 1280512cbf1dSJens Wiklander switch (get_class(head)) { 1281512cbf1dSJens Wiklander case PKCS11_CKO_SECRET_KEY: 128265fb9092SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1283512cbf1dSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 1284512cbf1dSJens Wiklander case PKCS11_CKO_DATA: 1285*4137952dSVesa Jääskeläinen case PKCS11_CKO_CERTIFICATE: 128665fb9092SVesa Jääskeläinen private = object_is_private(head); 1287512cbf1dSJens Wiklander break; 1288512cbf1dSJens Wiklander default: 1289512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1290512cbf1dSJens Wiklander } 1291512cbf1dSJens Wiklander 12925db0fef4SRuchika Gupta if (private && (pkcs11_session_is_public(session) || 12935db0fef4SRuchika Gupta pkcs11_session_is_so(session))) { 12945db0fef4SRuchika Gupta DMSG("Private object access from a public or SO session"); 1295512cbf1dSJens Wiklander 129612f1ba86SRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 1297512cbf1dSJens Wiklander } 1298512cbf1dSJens Wiklander 1299512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1300512cbf1dSJens Wiklander } 1301512cbf1dSJens Wiklander 1302512cbf1dSJens Wiklander /* 130363f89caaSJens Wiklander * Check the attributes of a to-be-created object matches the token state 130463f89caaSJens Wiklander */ 130563f89caaSJens Wiklander enum pkcs11_rc check_created_attrs_against_token(struct pkcs11_session *session, 130663f89caaSJens Wiklander struct obj_attrs *head) 130763f89caaSJens Wiklander { 130863f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 130963f89caaSJens Wiklander 131063f89caaSJens Wiklander rc = check_attrs_misc_integrity(head); 131163f89caaSJens Wiklander if (rc) 131263f89caaSJens Wiklander return rc; 131363f89caaSJens Wiklander 131463f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_TRUSTED) && 131563f89caaSJens Wiklander !pkcs11_session_is_so(session)) { 131663f89caaSJens Wiklander DMSG("Can't create trusted object"); 131763f89caaSJens Wiklander 131863f89caaSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 131963f89caaSJens Wiklander } 132063f89caaSJens Wiklander 132163f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_TOKEN) && 132263f89caaSJens Wiklander !pkcs11_session_is_read_write(session)) { 132363f89caaSJens Wiklander DMSG("Can't create persistent object"); 132463f89caaSJens Wiklander 132563f89caaSJens Wiklander return PKCS11_CKR_SESSION_READ_ONLY; 132663f89caaSJens Wiklander } 132763f89caaSJens Wiklander 132863f89caaSJens Wiklander /* 132963f89caaSJens Wiklander * TODO: START_DATE and END_DATE: complies with current time? 133063f89caaSJens Wiklander */ 133163f89caaSJens Wiklander return PKCS11_CKR_OK; 133263f89caaSJens Wiklander } 133363f89caaSJens Wiklander 133463f89caaSJens Wiklander #define DMSG_BAD_BBOOL(attr, proc, head) \ 133563f89caaSJens Wiklander do { \ 133663f89caaSJens Wiklander uint32_t __maybe_unused _attr = (attr); \ 133763f89caaSJens Wiklander uint8_t __maybe_unused _bvalue = 0; \ 133863f89caaSJens Wiklander enum pkcs11_rc __maybe_unused _rc = PKCS11_CKR_OK; \ 133963f89caaSJens Wiklander \ 134063f89caaSJens Wiklander _rc = get_attribute((head), _attr, &_bvalue, NULL); \ 134163f89caaSJens Wiklander DMSG("%s issue for %s: %sfound, value %"PRIu8, \ 134263f89caaSJens Wiklander id2str_attr(_attr), id2str_proc((proc)), \ 134363f89caaSJens Wiklander _rc ? "not " : "", _bvalue); \ 134463f89caaSJens Wiklander } while (0) 134563f89caaSJens Wiklander 134663f89caaSJens Wiklander static bool __maybe_unused check_attr_bval(uint32_t proc_id __maybe_unused, 134763f89caaSJens Wiklander struct obj_attrs *head, 134863f89caaSJens Wiklander uint32_t attribute, bool val) 134963f89caaSJens Wiklander { 135063f89caaSJens Wiklander uint8_t bbool = 0; 135163f89caaSJens Wiklander uint32_t sz = sizeof(bbool); 135263f89caaSJens Wiklander 135363f89caaSJens Wiklander if (!get_attribute(head, attribute, &bbool, &sz) && !!bbool == val) 135463f89caaSJens Wiklander return true; 135563f89caaSJens Wiklander 135663f89caaSJens Wiklander DMSG_BAD_BBOOL(attribute, proc_id, head); 135763f89caaSJens Wiklander return false; 135863f89caaSJens Wiklander } 135963f89caaSJens Wiklander 136063f89caaSJens Wiklander /* 136163f89caaSJens Wiklander * Check the attributes of a new secret match the processing/mechanism 136263f89caaSJens Wiklander * used to create it. 136363f89caaSJens Wiklander * 136463f89caaSJens Wiklander * @proc_id - PKCS11_CKM_xxx 136563f89caaSJens Wiklander * @head - head of the attributes of the to-be-created object. 136663f89caaSJens Wiklander */ 136763f89caaSJens Wiklander enum pkcs11_rc check_created_attrs_against_processing(uint32_t proc_id, 136863f89caaSJens Wiklander struct obj_attrs *head) 136963f89caaSJens Wiklander { 137063f89caaSJens Wiklander /* 137163f89caaSJens Wiklander * Processings that do not create secrets are not expected to call 137263f89caaSJens Wiklander * this function which would panic. 137363f89caaSJens Wiklander */ 137463f89caaSJens Wiklander switch (proc_id) { 137563f89caaSJens Wiklander case PKCS11_PROCESSING_IMPORT: 1376e3f0cb56SRuchika Gupta case PKCS11_CKM_AES_ECB: 1377e3f0cb56SRuchika Gupta case PKCS11_CKM_AES_CBC: 137848799892SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 137948799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 138063f89caaSJens Wiklander assert(check_attr_bval(proc_id, head, PKCS11_CKA_LOCAL, false)); 138163f89caaSJens Wiklander break; 1382fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1383fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 138402b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 138586922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 1386fa247a2aSRuchika Gupta assert(check_attr_bval(proc_id, head, PKCS11_CKA_LOCAL, true)); 1387fa247a2aSRuchika Gupta break; 138863f89caaSJens Wiklander default: 138963f89caaSJens Wiklander TEE_Panic(proc_id); 139063f89caaSJens Wiklander break; 139163f89caaSJens Wiklander } 139263f89caaSJens Wiklander 1393fa247a2aSRuchika Gupta switch (proc_id) { 1394fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1395fa247a2aSRuchika Gupta assert(get_key_type(head) == PKCS11_CKK_GENERIC_SECRET); 1396fa247a2aSRuchika Gupta break; 1397fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 1398fa247a2aSRuchika Gupta assert(get_key_type(head) == PKCS11_CKK_AES); 1399fa247a2aSRuchika Gupta break; 140002b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 140102b16804SVesa Jääskeläinen assert(get_key_type(head) == PKCS11_CKK_EC); 140202b16804SVesa Jääskeläinen break; 140386922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 140486922832SVesa Jääskeläinen assert(get_key_type(head) == PKCS11_CKK_RSA); 140586922832SVesa Jääskeläinen break; 1406fa247a2aSRuchika Gupta case PKCS11_PROCESSING_IMPORT: 1407fa247a2aSRuchika Gupta default: 1408fa247a2aSRuchika Gupta break; 1409fa247a2aSRuchika Gupta } 1410fa247a2aSRuchika Gupta 141163f89caaSJens Wiklander return PKCS11_CKR_OK; 141263f89caaSJens Wiklander } 1413512cbf1dSJens Wiklander 14142d0cd829SRuchika Gupta /* Return min and max key size supported for a key_type in bytes */ 1415512cbf1dSJens Wiklander static void get_key_min_max_sizes(enum pkcs11_key_type key_type, 1416512cbf1dSJens Wiklander uint32_t *min_key_size, 1417512cbf1dSJens Wiklander uint32_t *max_key_size) 1418512cbf1dSJens Wiklander { 1419512cbf1dSJens Wiklander enum pkcs11_mechanism_id mechanism = PKCS11_CKM_UNDEFINED_ID; 1420512cbf1dSJens Wiklander 1421512cbf1dSJens Wiklander switch (key_type) { 1422fa247a2aSRuchika Gupta case PKCS11_CKK_GENERIC_SECRET: 1423fa247a2aSRuchika Gupta mechanism = PKCS11_CKM_GENERIC_SECRET_KEY_GEN; 1424fa247a2aSRuchika Gupta break; 1425512cbf1dSJens Wiklander case PKCS11_CKK_AES: 1426512cbf1dSJens Wiklander mechanism = PKCS11_CKM_AES_KEY_GEN; 1427512cbf1dSJens Wiklander break; 14281f45c9cfSRuchika Gupta case PKCS11_CKK_MD5_HMAC: 14291f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_MD5_HMAC; 14301f45c9cfSRuchika Gupta break; 14311f45c9cfSRuchika Gupta case PKCS11_CKK_SHA_1_HMAC: 14321f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA_1_HMAC; 14331f45c9cfSRuchika Gupta break; 14341f45c9cfSRuchika Gupta case PKCS11_CKK_SHA224_HMAC: 14351f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA224_HMAC; 14361f45c9cfSRuchika Gupta break; 1437a339a354SEtienne Carriere case PKCS11_CKK_SHA256_HMAC: 1438a339a354SEtienne Carriere mechanism = PKCS11_CKM_SHA256_HMAC; 1439a339a354SEtienne Carriere break; 14401f45c9cfSRuchika Gupta case PKCS11_CKK_SHA384_HMAC: 14411f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA384_HMAC; 14421f45c9cfSRuchika Gupta break; 14431f45c9cfSRuchika Gupta case PKCS11_CKK_SHA512_HMAC: 14441f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA512_HMAC; 14451f45c9cfSRuchika Gupta break; 1446db28c542SVesa Jääskeläinen case PKCS11_CKK_EC: 1447db28c542SVesa Jääskeläinen mechanism = PKCS11_CKM_EC_KEY_PAIR_GEN; 1448db28c542SVesa Jääskeläinen break; 144986922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 145086922832SVesa Jääskeläinen mechanism = PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN; 145186922832SVesa Jääskeläinen break; 1452512cbf1dSJens Wiklander default: 1453512cbf1dSJens Wiklander TEE_Panic(key_type); 1454512cbf1dSJens Wiklander break; 1455512cbf1dSJens Wiklander } 1456512cbf1dSJens Wiklander 14572d0cd829SRuchika Gupta mechanism_supported_key_sizes_bytes(mechanism, min_key_size, 1458512cbf1dSJens Wiklander max_key_size); 1459512cbf1dSJens Wiklander } 1460512cbf1dSJens Wiklander 1461512cbf1dSJens Wiklander enum pkcs11_rc check_created_attrs(struct obj_attrs *key1, 1462512cbf1dSJens Wiklander struct obj_attrs *key2) 1463512cbf1dSJens Wiklander { 1464512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 1465512cbf1dSJens Wiklander struct obj_attrs *secret = NULL; 1466013934d8SVesa Jääskeläinen struct obj_attrs *private = NULL; 1467013934d8SVesa Jääskeläinen struct obj_attrs *public = NULL; 1468512cbf1dSJens Wiklander uint32_t max_key_size = 0; 1469512cbf1dSJens Wiklander uint32_t min_key_size = 0; 1470512cbf1dSJens Wiklander uint32_t key_length = 0; 1471512cbf1dSJens Wiklander 1472512cbf1dSJens Wiklander switch (get_class(key1)) { 1473512cbf1dSJens Wiklander case PKCS11_CKO_SECRET_KEY: 1474512cbf1dSJens Wiklander secret = key1; 1475512cbf1dSJens Wiklander break; 1476013934d8SVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 1477013934d8SVesa Jääskeläinen public = key1; 1478013934d8SVesa Jääskeläinen break; 1479013934d8SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1480013934d8SVesa Jääskeläinen private = key1; 1481013934d8SVesa Jääskeläinen break; 1482512cbf1dSJens Wiklander default: 1483512cbf1dSJens Wiklander return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 1484512cbf1dSJens Wiklander } 1485512cbf1dSJens Wiklander 1486013934d8SVesa Jääskeläinen if (key2) { 1487013934d8SVesa Jääskeläinen switch (get_class(key2)) { 1488013934d8SVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 1489013934d8SVesa Jääskeläinen public = key2; 1490013934d8SVesa Jääskeläinen if (private == key1) 1491013934d8SVesa Jääskeläinen break; 1492013934d8SVesa Jääskeläinen 1493013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1494013934d8SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1495013934d8SVesa Jääskeläinen private = key2; 1496013934d8SVesa Jääskeläinen if (public == key1) 1497013934d8SVesa Jääskeläinen break; 1498013934d8SVesa Jääskeläinen 1499013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1500013934d8SVesa Jääskeläinen default: 1501512cbf1dSJens Wiklander return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 1502013934d8SVesa Jääskeläinen } 1503013934d8SVesa Jääskeläinen 1504013934d8SVesa Jääskeläinen if (get_key_type(private) != get_key_type(public)) 1505013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1506013934d8SVesa Jääskeläinen } 1507512cbf1dSJens Wiklander 1508512cbf1dSJens Wiklander if (secret) { 1509512cbf1dSJens Wiklander switch (get_key_type(secret)) { 1510512cbf1dSJens Wiklander case PKCS11_CKK_AES: 1511512cbf1dSJens Wiklander case PKCS11_CKK_GENERIC_SECRET: 1512512cbf1dSJens Wiklander case PKCS11_CKK_MD5_HMAC: 1513512cbf1dSJens Wiklander case PKCS11_CKK_SHA_1_HMAC: 1514512cbf1dSJens Wiklander case PKCS11_CKK_SHA224_HMAC: 1515512cbf1dSJens Wiklander case PKCS11_CKK_SHA256_HMAC: 1516512cbf1dSJens Wiklander case PKCS11_CKK_SHA384_HMAC: 1517512cbf1dSJens Wiklander case PKCS11_CKK_SHA512_HMAC: 1518512cbf1dSJens Wiklander break; 1519512cbf1dSJens Wiklander default: 1520512cbf1dSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1521512cbf1dSJens Wiklander } 1522512cbf1dSJens Wiklander 1523512cbf1dSJens Wiklander /* Get key size */ 1524512cbf1dSJens Wiklander rc = get_u32_attribute(secret, PKCS11_CKA_VALUE_LEN, 1525512cbf1dSJens Wiklander &key_length); 1526512cbf1dSJens Wiklander if (rc) 1527d1d44372SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCOMPLETE; 1528512cbf1dSJens Wiklander } 1529013934d8SVesa Jääskeläinen if (public) { 1530013934d8SVesa Jääskeläinen switch (get_key_type(public)) { 153186922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 153286922832SVesa Jääskeläinen /* Get key size */ 153386922832SVesa Jääskeläinen rc = get_u32_attribute(public, PKCS11_CKA_MODULUS_BITS, 153486922832SVesa Jääskeläinen &key_length); 153586922832SVesa Jääskeläinen if (rc) 153686922832SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 153786922832SVesa Jääskeläinen key_length = ROUNDUP(key_length, 8) / 8; 153886922832SVesa Jääskeläinen break; 153902b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 154002b16804SVesa Jääskeläinen break; 1541013934d8SVesa Jääskeläinen default: 1542013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1543013934d8SVesa Jääskeläinen } 1544013934d8SVesa Jääskeläinen } 1545013934d8SVesa Jääskeläinen if (private) { 1546013934d8SVesa Jääskeläinen switch (get_key_type(private)) { 154786922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 154802b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 154902b16804SVesa Jääskeläinen break; 1550013934d8SVesa Jääskeläinen default: 1551013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1552013934d8SVesa Jääskeläinen } 1553013934d8SVesa Jääskeläinen } 1554512cbf1dSJens Wiklander 155502b16804SVesa Jääskeläinen /* 155602b16804SVesa Jääskeläinen * Check key size for symmetric keys and RSA keys 155702b16804SVesa Jääskeläinen * EC is bound to domains, no need to check here. 155802b16804SVesa Jääskeläinen */ 155902b16804SVesa Jääskeläinen switch (get_key_type(key1)) { 156002b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 156102b16804SVesa Jääskeläinen return PKCS11_CKR_OK; 156202b16804SVesa Jääskeläinen default: 156302b16804SVesa Jääskeläinen break; 156402b16804SVesa Jääskeläinen } 156502b16804SVesa Jääskeläinen 1566512cbf1dSJens Wiklander get_key_min_max_sizes(get_key_type(key1), &min_key_size, &max_key_size); 1567512cbf1dSJens Wiklander if (key_length < min_key_size || key_length > max_key_size) { 1568512cbf1dSJens Wiklander EMSG("Length %"PRIu32" vs range [%"PRIu32" %"PRIu32"]", 1569512cbf1dSJens Wiklander key_length, min_key_size, max_key_size); 1570512cbf1dSJens Wiklander 1571512cbf1dSJens Wiklander return PKCS11_CKR_KEY_SIZE_RANGE; 1572512cbf1dSJens Wiklander } 1573512cbf1dSJens Wiklander 157449ed60abSRuchika Gupta if (secret && get_key_type(secret) == PKCS11_CKK_AES) { 157549ed60abSRuchika Gupta if (key_length != 16 && key_length != 24 && key_length != 32) 157649ed60abSRuchika Gupta return PKCS11_CKR_KEY_SIZE_RANGE; 157749ed60abSRuchika Gupta } 157849ed60abSRuchika Gupta 1579512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1580512cbf1dSJens Wiklander } 1581512cbf1dSJens Wiklander 1582512cbf1dSJens Wiklander /* Check processing ID against attribute ALLOWED_MECHANISMS if any */ 1583512cbf1dSJens Wiklander static bool parent_key_complies_allowed_processings(uint32_t proc_id, 1584512cbf1dSJens Wiklander struct obj_attrs *head) 1585512cbf1dSJens Wiklander { 1586512cbf1dSJens Wiklander char *attr = NULL; 1587512cbf1dSJens Wiklander uint32_t size = 0; 1588512cbf1dSJens Wiklander uint32_t proc = 0; 1589512cbf1dSJens Wiklander size_t count = 0; 15906a760c9eSEtienne Carriere enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 1591512cbf1dSJens Wiklander 15926a760c9eSEtienne Carriere rc = get_attribute_ptr(head, PKCS11_CKA_ALLOWED_MECHANISMS, 15936a760c9eSEtienne Carriere (void *)&attr, &size); 15946a760c9eSEtienne Carriere if (rc == PKCS11_RV_NOT_FOUND) 1595512cbf1dSJens Wiklander return true; 15966a760c9eSEtienne Carriere if (rc) { 15976a760c9eSEtienne Carriere EMSG("unexpected attributes state"); 15986a760c9eSEtienne Carriere TEE_Panic(TEE_ERROR_BAD_STATE); 1599512cbf1dSJens Wiklander } 1600512cbf1dSJens Wiklander 1601512cbf1dSJens Wiklander for (count = size / sizeof(uint32_t); count; count--) { 1602512cbf1dSJens Wiklander TEE_MemMove(&proc, attr, sizeof(uint32_t)); 1603512cbf1dSJens Wiklander attr += sizeof(uint32_t); 1604512cbf1dSJens Wiklander 1605512cbf1dSJens Wiklander if (proc == proc_id) 1606512cbf1dSJens Wiklander return true; 1607512cbf1dSJens Wiklander } 1608512cbf1dSJens Wiklander 1609512cbf1dSJens Wiklander DMSG("can't find %s in allowed list", id2str_proc(proc_id)); 1610512cbf1dSJens Wiklander return false; 1611512cbf1dSJens Wiklander } 1612512cbf1dSJens Wiklander 1613512cbf1dSJens Wiklander static enum pkcs11_attr_id func_to_attr(enum processing_func func) 1614512cbf1dSJens Wiklander { 1615512cbf1dSJens Wiklander switch (func) { 1616512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 1617512cbf1dSJens Wiklander return PKCS11_CKA_ENCRYPT; 1618512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 1619512cbf1dSJens Wiklander return PKCS11_CKA_DECRYPT; 1620512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN: 1621512cbf1dSJens Wiklander return PKCS11_CKA_SIGN; 1622512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY: 1623512cbf1dSJens Wiklander return PKCS11_CKA_VERIFY; 1624512cbf1dSJens Wiklander case PKCS11_FUNCTION_WRAP: 1625512cbf1dSJens Wiklander return PKCS11_CKA_WRAP; 1626512cbf1dSJens Wiklander case PKCS11_FUNCTION_UNWRAP: 1627512cbf1dSJens Wiklander return PKCS11_CKA_UNWRAP; 1628512cbf1dSJens Wiklander case PKCS11_FUNCTION_DERIVE: 1629512cbf1dSJens Wiklander return PKCS11_CKA_DERIVE; 1630512cbf1dSJens Wiklander default: 1631512cbf1dSJens Wiklander return PKCS11_CKA_UNDEFINED_ID; 1632512cbf1dSJens Wiklander } 1633512cbf1dSJens Wiklander } 1634512cbf1dSJens Wiklander 1635512cbf1dSJens Wiklander enum pkcs11_rc 1636512cbf1dSJens Wiklander check_parent_attrs_against_processing(enum pkcs11_mechanism_id proc_id, 1637512cbf1dSJens Wiklander enum processing_func function, 1638512cbf1dSJens Wiklander struct obj_attrs *head) 1639512cbf1dSJens Wiklander { 1640512cbf1dSJens Wiklander enum pkcs11_class_id key_class = get_class(head); 1641512cbf1dSJens Wiklander enum pkcs11_key_type key_type = get_key_type(head); 1642512cbf1dSJens Wiklander enum pkcs11_attr_id attr = func_to_attr(function); 1643512cbf1dSJens Wiklander 1644512cbf1dSJens Wiklander if (!get_bool(head, attr)) { 1645512cbf1dSJens Wiklander DMSG("%s not permitted", id2str_attr(attr)); 1646512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1647512cbf1dSJens Wiklander } 1648512cbf1dSJens Wiklander 1649512cbf1dSJens Wiklander /* Check processing complies with parent key family */ 1650512cbf1dSJens Wiklander switch (proc_id) { 1651512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 1652512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 1653512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 1654512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 1655512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 16560ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC: 16570ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC_GENERAL: 1658512cbf1dSJens Wiklander if (key_class == PKCS11_CKO_SECRET_KEY && 1659512cbf1dSJens Wiklander key_type == PKCS11_CKK_AES) 1660512cbf1dSJens Wiklander break; 1661512cbf1dSJens Wiklander 1662512cbf1dSJens Wiklander DMSG("%s invalid key %s/%s", id2str_proc(proc_id), 1663512cbf1dSJens Wiklander id2str_class(key_class), id2str_key_type(key_type)); 1664512cbf1dSJens Wiklander 16655f80f270SRuchika Gupta if (function == PKCS11_FUNCTION_WRAP) 16665f80f270SRuchika Gupta return PKCS11_CKR_WRAPPING_KEY_TYPE_INCONSISTENT; 1667e3f0cb56SRuchika Gupta else if (function == PKCS11_FUNCTION_UNWRAP) 1668e3f0cb56SRuchika Gupta return PKCS11_CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT; 16695f80f270SRuchika Gupta else 1670512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1671512cbf1dSJens Wiklander 1672c3033708SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 1673c3033708SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 1674c3033708SRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY && 1675c3033708SRuchika Gupta key_type != PKCS11_CKK_AES) 1676c3033708SRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1677c3033708SRuchika Gupta 1678c3033708SRuchika Gupta if (get_bool(head, PKCS11_CKA_ENCRYPT)) { 1679c3033708SRuchika Gupta /* 1680c3033708SRuchika Gupta * Intentionally refuse to proceed despite 1681c3033708SRuchika Gupta * PKCS#11 specifications v2.40 and v3.0 not expecting 1682c3033708SRuchika Gupta * this behavior to avoid potential security issue 1683c3033708SRuchika Gupta * where keys derived by these mechanisms can be 1684c3033708SRuchika Gupta * revealed by doing data encryption using parent key. 1685c3033708SRuchika Gupta */ 1686c3033708SRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED; 1687c3033708SRuchika Gupta } 1688c3033708SRuchika Gupta 1689c3033708SRuchika Gupta break; 1690689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 1691689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 1692689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 1693689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 1694689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 1695689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 169670b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 169770b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 169870b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 169970b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 170070b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 170170b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 1702689f4e5bSRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY) 1703689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1704689f4e5bSRuchika Gupta 1705689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_GENERIC_SECRET) 1706689f4e5bSRuchika Gupta break; 1707689f4e5bSRuchika Gupta 1708689f4e5bSRuchika Gupta switch (proc_id) { 1709689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 171070b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 1711689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_MD5_HMAC) 1712689f4e5bSRuchika Gupta break; 1713689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1714689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 171570b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 1716689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA_1_HMAC) 1717689f4e5bSRuchika Gupta break; 1718689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1719689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 172070b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 1721689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA224_HMAC) 1722689f4e5bSRuchika Gupta break; 1723689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1724689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 172570b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 1726689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA256_HMAC) 1727689f4e5bSRuchika Gupta break; 1728689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1729689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 173070b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 1731689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA384_HMAC) 1732689f4e5bSRuchika Gupta break; 1733689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1734689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 173570b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 1736689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA512_HMAC) 1737689f4e5bSRuchika Gupta break; 1738689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1739689f4e5bSRuchika Gupta default: 1740689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1741689f4e5bSRuchika Gupta } 1742689f4e5bSRuchika Gupta break; 1743689f4e5bSRuchika Gupta 1744fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 1745fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 1746fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 1747fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 1748fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 1749fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 1750fb279d8bSVesa Jääskeläinen if (key_type != PKCS11_CKK_EC) { 1751fb279d8bSVesa Jääskeläinen EMSG("Invalid key %s for mechanism %s", 1752fb279d8bSVesa Jääskeläinen id2str_type(key_type, key_class), 1753fb279d8bSVesa Jääskeläinen id2str_proc(proc_id)); 1754fb279d8bSVesa Jääskeläinen 1755fb279d8bSVesa Jääskeläinen return PKCS11_CKR_KEY_TYPE_INCONSISTENT; 1756fb279d8bSVesa Jääskeläinen } 1757fb279d8bSVesa Jääskeläinen if (key_class != PKCS11_CKO_PUBLIC_KEY && 1758fb279d8bSVesa Jääskeläinen key_class != PKCS11_CKO_PRIVATE_KEY) { 1759fb279d8bSVesa Jääskeläinen EMSG("Invalid key class for mechanism %s", 1760fb279d8bSVesa Jääskeläinen id2str_proc(proc_id)); 1761fb279d8bSVesa Jääskeläinen 1762fb279d8bSVesa Jääskeläinen return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1763fb279d8bSVesa Jääskeläinen } 1764fb279d8bSVesa Jääskeläinen break; 17650442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 17660442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 17670442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 17680442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 17690442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 17700442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 17710442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 1772dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 1773d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 1774d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 1775d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 1776d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 1777d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 1778d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 17790442c956SVesa Jääskeläinen if (key_type != PKCS11_CKK_RSA) { 17800442c956SVesa Jääskeläinen EMSG("Invalid key %s for mechanism %s", 17810442c956SVesa Jääskeläinen id2str_type(key_type, key_class), 17820442c956SVesa Jääskeläinen id2str_proc(proc_id)); 17830442c956SVesa Jääskeläinen 17840442c956SVesa Jääskeläinen return PKCS11_CKR_KEY_TYPE_INCONSISTENT; 17850442c956SVesa Jääskeläinen } 17860442c956SVesa Jääskeläinen if (key_class != PKCS11_CKO_PUBLIC_KEY && 17870442c956SVesa Jääskeläinen key_class != PKCS11_CKO_PRIVATE_KEY) { 17880442c956SVesa Jääskeläinen EMSG("Invalid key class for mechanism %s", 17890442c956SVesa Jääskeläinen id2str_proc(proc_id)); 17900442c956SVesa Jääskeläinen 17910442c956SVesa Jääskeläinen return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 17920442c956SVesa Jääskeläinen } 17930442c956SVesa Jääskeläinen break; 1794512cbf1dSJens Wiklander default: 1795512cbf1dSJens Wiklander DMSG("Invalid processing %#"PRIx32"/%s", proc_id, 1796512cbf1dSJens Wiklander id2str_proc(proc_id)); 1797512cbf1dSJens Wiklander 1798512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_INVALID; 1799512cbf1dSJens Wiklander } 1800512cbf1dSJens Wiklander 1801512cbf1dSJens Wiklander if (!parent_key_complies_allowed_processings(proc_id, head)) { 1802512cbf1dSJens Wiklander DMSG("Allowed mechanism failed"); 1803512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1804512cbf1dSJens Wiklander } 1805512cbf1dSJens Wiklander 1806512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1807512cbf1dSJens Wiklander } 1808783c1515SRuchika Gupta 1809783c1515SRuchika Gupta bool attribute_is_exportable(struct pkcs11_attribute_head *req_attr, 1810783c1515SRuchika Gupta struct pkcs11_object *obj) 1811783c1515SRuchika Gupta { 1812783c1515SRuchika Gupta uint8_t boolval = 0; 1813783c1515SRuchika Gupta uint32_t boolsize = 0; 1814783c1515SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 1815783c1515SRuchika Gupta enum pkcs11_class_id key_class = get_class(obj->attributes); 1816783c1515SRuchika Gupta 1817783c1515SRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY && 1818783c1515SRuchika Gupta key_class != PKCS11_CKO_PRIVATE_KEY) 1819783c1515SRuchika Gupta return true; 1820783c1515SRuchika Gupta 1821783c1515SRuchika Gupta switch (req_attr->id) { 1822783c1515SRuchika Gupta case PKCS11_CKA_PRIVATE_EXPONENT: 1823783c1515SRuchika Gupta case PKCS11_CKA_PRIME_1: 1824783c1515SRuchika Gupta case PKCS11_CKA_PRIME_2: 1825783c1515SRuchika Gupta case PKCS11_CKA_EXPONENT_1: 1826783c1515SRuchika Gupta case PKCS11_CKA_EXPONENT_2: 1827783c1515SRuchika Gupta case PKCS11_CKA_COEFFICIENT: 1828783c1515SRuchika Gupta case PKCS11_CKA_VALUE: 1829783c1515SRuchika Gupta boolsize = sizeof(boolval); 1830783c1515SRuchika Gupta rc = get_attribute(obj->attributes, PKCS11_CKA_EXTRACTABLE, 1831783c1515SRuchika Gupta &boolval, &boolsize); 1832783c1515SRuchika Gupta if (rc || boolval == PKCS11_FALSE) 1833783c1515SRuchika Gupta return false; 1834783c1515SRuchika Gupta 1835783c1515SRuchika Gupta boolsize = sizeof(boolval); 1836783c1515SRuchika Gupta rc = get_attribute(obj->attributes, PKCS11_CKA_SENSITIVE, 1837783c1515SRuchika Gupta &boolval, &boolsize); 1838783c1515SRuchika Gupta if (rc || boolval == PKCS11_TRUE) 1839783c1515SRuchika Gupta return false; 1840783c1515SRuchika Gupta break; 1841783c1515SRuchika Gupta default: 1842783c1515SRuchika Gupta break; 1843783c1515SRuchika Gupta } 1844783c1515SRuchika Gupta 1845783c1515SRuchika Gupta return true; 1846783c1515SRuchika Gupta } 18472d25a9bcSRuchika Gupta 18482d25a9bcSRuchika Gupta static bool attr_is_modifiable_any_key(struct pkcs11_attribute_head *attr) 18492d25a9bcSRuchika Gupta { 18502d25a9bcSRuchika Gupta switch (attr->id) { 18512d25a9bcSRuchika Gupta case PKCS11_CKA_ID: 18522d25a9bcSRuchika Gupta case PKCS11_CKA_START_DATE: 18532d25a9bcSRuchika Gupta case PKCS11_CKA_END_DATE: 18542d25a9bcSRuchika Gupta case PKCS11_CKA_DERIVE: 18552d25a9bcSRuchika Gupta return true; 18562d25a9bcSRuchika Gupta default: 18572d25a9bcSRuchika Gupta return false; 18582d25a9bcSRuchika Gupta } 18592d25a9bcSRuchika Gupta } 18602d25a9bcSRuchika Gupta 18612d25a9bcSRuchika Gupta static bool attr_is_modifiable_secret_key(struct pkcs11_attribute_head *attr, 18622d25a9bcSRuchika Gupta struct pkcs11_session *session, 18632d25a9bcSRuchika Gupta struct pkcs11_object *obj) 18642d25a9bcSRuchika Gupta { 18652d25a9bcSRuchika Gupta switch (attr->id) { 18662d25a9bcSRuchika Gupta case PKCS11_CKA_ENCRYPT: 18672d25a9bcSRuchika Gupta case PKCS11_CKA_DECRYPT: 18682d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN: 18692d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY: 18702d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP: 18712d25a9bcSRuchika Gupta case PKCS11_CKA_UNWRAP: 18722d25a9bcSRuchika Gupta return true; 18732d25a9bcSRuchika Gupta /* Can't be modified once set to CK_FALSE - 12 in Table 10 */ 18742d25a9bcSRuchika Gupta case PKCS11_CKA_EXTRACTABLE: 18752d25a9bcSRuchika Gupta return get_bool(obj->attributes, attr->id); 18762d25a9bcSRuchika Gupta /* Can't be modified once set to CK_TRUE - 11 in Table 10 */ 18772d25a9bcSRuchika Gupta case PKCS11_CKA_SENSITIVE: 18782d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP_WITH_TRUSTED: 18792d25a9bcSRuchika Gupta return !get_bool(obj->attributes, attr->id); 18802d25a9bcSRuchika Gupta /* Change in CKA_TRUSTED can only be done by SO */ 18812d25a9bcSRuchika Gupta case PKCS11_CKA_TRUSTED: 18822d25a9bcSRuchika Gupta return pkcs11_session_is_so(session); 18832d25a9bcSRuchika Gupta case PKCS11_CKA_NEVER_EXTRACTABLE: 18842d25a9bcSRuchika Gupta case PKCS11_CKA_ALWAYS_SENSITIVE: 18852d25a9bcSRuchika Gupta return false; 18862d25a9bcSRuchika Gupta default: 18872d25a9bcSRuchika Gupta return false; 18882d25a9bcSRuchika Gupta } 18892d25a9bcSRuchika Gupta } 18902d25a9bcSRuchika Gupta 18912d25a9bcSRuchika Gupta static bool attr_is_modifiable_public_key(struct pkcs11_attribute_head *attr, 18922d25a9bcSRuchika Gupta struct pkcs11_session *session, 18932d25a9bcSRuchika Gupta struct pkcs11_object *obj __unused) 18942d25a9bcSRuchika Gupta { 18952d25a9bcSRuchika Gupta switch (attr->id) { 18962d25a9bcSRuchika Gupta case PKCS11_CKA_SUBJECT: 18972d25a9bcSRuchika Gupta case PKCS11_CKA_ENCRYPT: 18982d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY: 18992d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY_RECOVER: 19002d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP: 19012d25a9bcSRuchika Gupta return true; 19022d25a9bcSRuchika Gupta case PKCS11_CKA_TRUSTED: 19032d25a9bcSRuchika Gupta /* Change in CKA_TRUSTED can only be done by SO */ 19042d25a9bcSRuchika Gupta return pkcs11_session_is_so(session); 19052d25a9bcSRuchika Gupta default: 19062d25a9bcSRuchika Gupta return false; 19072d25a9bcSRuchika Gupta } 19082d25a9bcSRuchika Gupta } 19092d25a9bcSRuchika Gupta 19102d25a9bcSRuchika Gupta static bool attr_is_modifiable_private_key(struct pkcs11_attribute_head *attr, 19112d25a9bcSRuchika Gupta struct pkcs11_session *sess __unused, 19122d25a9bcSRuchika Gupta struct pkcs11_object *obj) 19132d25a9bcSRuchika Gupta { 19142d25a9bcSRuchika Gupta switch (attr->id) { 19152d25a9bcSRuchika Gupta case PKCS11_CKA_SUBJECT: 19162d25a9bcSRuchika Gupta case PKCS11_CKA_DECRYPT: 19172d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN: 19182d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN_RECOVER: 19192d25a9bcSRuchika Gupta case PKCS11_CKA_UNWRAP: 19202d25a9bcSRuchika Gupta /* 19212d25a9bcSRuchika Gupta * TBD: Revisit if we don't support PKCS11_CKA_PUBLIC_KEY_INFO 19222d25a9bcSRuchika Gupta * Specification mentions that if this attribute is 19232d25a9bcSRuchika Gupta * supplied as part of a template for C_CreateObject, C_CopyObject or 19242d25a9bcSRuchika Gupta * C_SetAttributeValue for a private key, the token MUST verify 19252d25a9bcSRuchika Gupta * correspondence between the private key data and the public key data 19262d25a9bcSRuchika Gupta * as supplied in CKA_PUBLIC_KEY_INFO. This needs to be 19272d25a9bcSRuchika Gupta * taken care of when this object type will be implemented 19282d25a9bcSRuchika Gupta */ 19292d25a9bcSRuchika Gupta case PKCS11_CKA_PUBLIC_KEY_INFO: 19302d25a9bcSRuchika Gupta return true; 19312d25a9bcSRuchika Gupta /* Can't be modified once set to CK_FALSE - 12 in Table 10 */ 19322d25a9bcSRuchika Gupta case PKCS11_CKA_EXTRACTABLE: 19332d25a9bcSRuchika Gupta return get_bool(obj->attributes, attr->id); 19342d25a9bcSRuchika Gupta /* Can't be modified once set to CK_TRUE - 11 in Table 10 */ 19352d25a9bcSRuchika Gupta case PKCS11_CKA_SENSITIVE: 19362d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP_WITH_TRUSTED: 19372d25a9bcSRuchika Gupta return !get_bool(obj->attributes, attr->id); 19382d25a9bcSRuchika Gupta case PKCS11_CKA_NEVER_EXTRACTABLE: 19392d25a9bcSRuchika Gupta case PKCS11_CKA_ALWAYS_SENSITIVE: 19402d25a9bcSRuchika Gupta return false; 19412d25a9bcSRuchika Gupta default: 19422d25a9bcSRuchika Gupta return false; 19432d25a9bcSRuchika Gupta } 19442d25a9bcSRuchika Gupta } 19452d25a9bcSRuchika Gupta 1946*4137952dSVesa Jääskeläinen static bool attr_is_modifiable_certificate(struct pkcs11_attribute_head *attr, 1947*4137952dSVesa Jääskeläinen struct pkcs11_session *session, 1948*4137952dSVesa Jääskeläinen struct pkcs11_object *obj) 1949*4137952dSVesa Jääskeläinen { 1950*4137952dSVesa Jääskeläinen uint8_t boolval = 0; 1951*4137952dSVesa Jääskeläinen uint32_t boolsize = 0; 1952*4137952dSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 1953*4137952dSVesa Jääskeläinen 1954*4137952dSVesa Jääskeläinen /* Trusted certificates cannot be modified. */ 1955*4137952dSVesa Jääskeläinen rc = get_attribute(obj->attributes, PKCS11_CKA_TRUSTED, 1956*4137952dSVesa Jääskeläinen &boolval, &boolsize); 1957*4137952dSVesa Jääskeläinen if (rc || boolval == PKCS11_TRUE) 1958*4137952dSVesa Jääskeläinen return false; 1959*4137952dSVesa Jääskeläinen 1960*4137952dSVesa Jääskeläinen /* Common certificate attributes */ 1961*4137952dSVesa Jääskeläinen switch (attr->id) { 1962*4137952dSVesa Jääskeläinen case PKCS11_CKA_TRUSTED: 1963*4137952dSVesa Jääskeläinen /* 1964*4137952dSVesa Jääskeläinen * The CKA_TRUSTED attribute cannot be set to CK_TRUE by an 1965*4137952dSVesa Jääskeläinen * application. It MUST be set by a token initialization 1966*4137952dSVesa Jääskeläinen * application or by the token’s SO. 1967*4137952dSVesa Jääskeläinen */ 1968*4137952dSVesa Jääskeläinen return pkcs11_session_is_so(session); 1969*4137952dSVesa Jääskeläinen case PKCS11_CKA_CERTIFICATE_TYPE: 1970*4137952dSVesa Jääskeläinen case PKCS11_CKA_CERTIFICATE_CATEGORY: 1971*4137952dSVesa Jääskeläinen return false; 1972*4137952dSVesa Jääskeläinen default: 1973*4137952dSVesa Jääskeläinen break; 1974*4137952dSVesa Jääskeläinen } 1975*4137952dSVesa Jääskeläinen 1976*4137952dSVesa Jääskeläinen /* Certificate type specific attributes */ 1977*4137952dSVesa Jääskeläinen switch (get_certificate_type(obj->attributes)) { 1978*4137952dSVesa Jääskeläinen case PKCS11_CKC_X_509: 1979*4137952dSVesa Jääskeläinen /* 1980*4137952dSVesa Jääskeläinen * Only the CKA_ID, CKA_ISSUER, and CKA_SERIAL_NUMBER 1981*4137952dSVesa Jääskeläinen * attributes may be modified after the object is created. 1982*4137952dSVesa Jääskeläinen */ 1983*4137952dSVesa Jääskeläinen switch (attr->id) { 1984*4137952dSVesa Jääskeläinen case PKCS11_CKA_ID: 1985*4137952dSVesa Jääskeläinen case PKCS11_CKA_ISSUER: 1986*4137952dSVesa Jääskeläinen case PKCS11_CKA_SERIAL_NUMBER: 1987*4137952dSVesa Jääskeläinen return true; 1988*4137952dSVesa Jääskeläinen default: 1989*4137952dSVesa Jääskeläinen break; 1990*4137952dSVesa Jääskeläinen } 1991*4137952dSVesa Jääskeläinen break; 1992*4137952dSVesa Jääskeläinen default: 1993*4137952dSVesa Jääskeläinen /* Unsupported certificate type */ 1994*4137952dSVesa Jääskeläinen break; 1995*4137952dSVesa Jääskeläinen } 1996*4137952dSVesa Jääskeläinen 1997*4137952dSVesa Jääskeläinen return false; 1998*4137952dSVesa Jääskeläinen } 1999*4137952dSVesa Jääskeläinen 20002d25a9bcSRuchika Gupta static bool attribute_is_modifiable(struct pkcs11_session *session, 20012d25a9bcSRuchika Gupta struct pkcs11_attribute_head *req_attr, 20022d25a9bcSRuchika Gupta struct pkcs11_object *obj, 20032d25a9bcSRuchika Gupta enum pkcs11_class_id class, 20042d25a9bcSRuchika Gupta enum processing_func function) 20052d25a9bcSRuchika Gupta { 20062d25a9bcSRuchika Gupta /* Check modifiable attributes common to any object */ 20072d25a9bcSRuchika Gupta switch (req_attr->id) { 20082d25a9bcSRuchika Gupta case PKCS11_CKA_LABEL: 20092d25a9bcSRuchika Gupta return true; 20102d25a9bcSRuchika Gupta case PKCS11_CKA_TOKEN: 20112d25a9bcSRuchika Gupta case PKCS11_CKA_MODIFIABLE: 20122d25a9bcSRuchika Gupta case PKCS11_CKA_DESTROYABLE: 20132d25a9bcSRuchika Gupta case PKCS11_CKA_PRIVATE: 20142d25a9bcSRuchika Gupta return function == PKCS11_FUNCTION_COPY; 20152d25a9bcSRuchika Gupta case PKCS11_CKA_COPYABLE: 20162d25a9bcSRuchika Gupta /* 20172d25a9bcSRuchika Gupta * Specification mentions that if the attribute value is false 20182d25a9bcSRuchika Gupta * it can't be set to true. Reading this we assume that it 20192d25a9bcSRuchika Gupta * should be possible to modify this attribute even though this 20202d25a9bcSRuchika Gupta * is not marked as modifiable in Table 10 if done in right 20212d25a9bcSRuchika Gupta * direction i.e from TRUE -> FALSE. 20222d25a9bcSRuchika Gupta */ 20232d25a9bcSRuchika Gupta return get_bool(obj->attributes, req_attr->id); 20242d25a9bcSRuchika Gupta default: 20252d25a9bcSRuchika Gupta break; 20262d25a9bcSRuchika Gupta } 20272d25a9bcSRuchika Gupta 20282d25a9bcSRuchika Gupta /* Attribute checking based on class type */ 20292d25a9bcSRuchika Gupta switch (class) { 20302d25a9bcSRuchika Gupta case PKCS11_CKO_SECRET_KEY: 20312d25a9bcSRuchika Gupta case PKCS11_CKO_PUBLIC_KEY: 20322d25a9bcSRuchika Gupta case PKCS11_CKO_PRIVATE_KEY: 20332d25a9bcSRuchika Gupta if (attr_is_modifiable_any_key(req_attr)) 20342d25a9bcSRuchika Gupta return true; 20352d25a9bcSRuchika Gupta if (class == PKCS11_CKO_SECRET_KEY && 20362d25a9bcSRuchika Gupta attr_is_modifiable_secret_key(req_attr, session, obj)) 20372d25a9bcSRuchika Gupta return true; 20382d25a9bcSRuchika Gupta if (class == PKCS11_CKO_PUBLIC_KEY && 20392d25a9bcSRuchika Gupta attr_is_modifiable_public_key(req_attr, session, obj)) 20402d25a9bcSRuchika Gupta return true; 20412d25a9bcSRuchika Gupta if (class == PKCS11_CKO_PRIVATE_KEY && 20422d25a9bcSRuchika Gupta attr_is_modifiable_private_key(req_attr, session, obj)) 20432d25a9bcSRuchika Gupta return true; 20442d25a9bcSRuchika Gupta break; 20452d25a9bcSRuchika Gupta case PKCS11_CKO_DATA: 20462d25a9bcSRuchika Gupta /* None of the data object attributes are modifiable */ 20472d25a9bcSRuchika Gupta return false; 2048*4137952dSVesa Jääskeläinen case PKCS11_CKO_CERTIFICATE: 2049*4137952dSVesa Jääskeläinen return attr_is_modifiable_certificate(req_attr, session, obj); 20502d25a9bcSRuchika Gupta default: 20512d25a9bcSRuchika Gupta break; 20522d25a9bcSRuchika Gupta } 20532d25a9bcSRuchika Gupta 20542d25a9bcSRuchika Gupta return false; 20552d25a9bcSRuchika Gupta } 20562d25a9bcSRuchika Gupta 20572d25a9bcSRuchika Gupta enum pkcs11_rc check_attrs_against_modification(struct pkcs11_session *session, 20582d25a9bcSRuchika Gupta struct obj_attrs *head, 20592d25a9bcSRuchika Gupta struct pkcs11_object *obj, 20602d25a9bcSRuchika Gupta enum processing_func function) 20612d25a9bcSRuchika Gupta { 20622d25a9bcSRuchika Gupta enum pkcs11_class_id class = PKCS11_CKO_UNDEFINED_ID; 20632d25a9bcSRuchika Gupta char *cur = NULL; 20642d25a9bcSRuchika Gupta char *end = NULL; 20652d25a9bcSRuchika Gupta size_t len = 0; 20662d25a9bcSRuchika Gupta 20672d25a9bcSRuchika Gupta class = get_class(obj->attributes); 20682d25a9bcSRuchika Gupta 20692d25a9bcSRuchika Gupta cur = (char *)head + sizeof(struct obj_attrs); 20702d25a9bcSRuchika Gupta end = cur + head->attrs_size; 20712d25a9bcSRuchika Gupta 20722d25a9bcSRuchika Gupta for (; cur < end; cur += len) { 20732d25a9bcSRuchika Gupta /* Structure aligned copy of the pkcs11_ref in the object */ 20742d25a9bcSRuchika Gupta struct pkcs11_attribute_head cli_ref = { }; 20752d25a9bcSRuchika Gupta 20762d25a9bcSRuchika Gupta TEE_MemMove(&cli_ref, cur, sizeof(cli_ref)); 20772d25a9bcSRuchika Gupta len = sizeof(cli_ref) + cli_ref.size; 20782d25a9bcSRuchika Gupta 20792d25a9bcSRuchika Gupta /* 20802d25a9bcSRuchika Gupta * Check 1 - Check if attribute belongs to the object 20812d25a9bcSRuchika Gupta * The obj->attributes has all the attributes in 20822d25a9bcSRuchika Gupta * it which are allowed for an object. 20832d25a9bcSRuchika Gupta */ 20842d25a9bcSRuchika Gupta if (get_attribute_ptr(obj->attributes, cli_ref.id, NULL, 20852d25a9bcSRuchika Gupta NULL) == PKCS11_RV_NOT_FOUND) 20862d25a9bcSRuchika Gupta return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 20872d25a9bcSRuchika Gupta 20882d25a9bcSRuchika Gupta /* Check 2 - Is attribute modifiable */ 20892d25a9bcSRuchika Gupta if (!attribute_is_modifiable(session, &cli_ref, obj, class, 20902d25a9bcSRuchika Gupta function)) 20912d25a9bcSRuchika Gupta return PKCS11_CKR_ATTRIBUTE_READ_ONLY; 20922d25a9bcSRuchika Gupta 20932d25a9bcSRuchika Gupta /* 20942d25a9bcSRuchika Gupta * Checks for modification in PKCS11_CKA_TOKEN and 20952d25a9bcSRuchika Gupta * PKCS11_CKA_PRIVATE are required for PKCS11_FUNCTION_COPY 20962d25a9bcSRuchika Gupta * only, so skip them for PKCS11_FUNCTION_MODIFY. 20972d25a9bcSRuchika Gupta */ 20982d25a9bcSRuchika Gupta if (function == PKCS11_FUNCTION_MODIFY) 20992d25a9bcSRuchika Gupta continue; 21002d25a9bcSRuchika Gupta 21012d25a9bcSRuchika Gupta /* 21022d25a9bcSRuchika Gupta * An attempt to copy an object to a token will fail for 21032d25a9bcSRuchika Gupta * RO session 21042d25a9bcSRuchika Gupta */ 21052d25a9bcSRuchika Gupta if (cli_ref.id == PKCS11_CKA_TOKEN && 21062d25a9bcSRuchika Gupta get_bool(head, PKCS11_CKA_TOKEN)) { 21072d25a9bcSRuchika Gupta if (!pkcs11_session_is_read_write(session)) { 21082d25a9bcSRuchika Gupta DMSG("Can't copy to token in a RO session"); 21092d25a9bcSRuchika Gupta return PKCS11_CKR_SESSION_READ_ONLY; 21102d25a9bcSRuchika Gupta } 21112d25a9bcSRuchika Gupta } 21122d25a9bcSRuchika Gupta 21132d25a9bcSRuchika Gupta if (cli_ref.id == PKCS11_CKA_PRIVATE) { 21142d25a9bcSRuchika Gupta bool parent_priv = 21152d25a9bcSRuchika Gupta get_bool(obj->attributes, cli_ref.id); 21162d25a9bcSRuchika Gupta bool obj_priv = get_bool(head, cli_ref.id); 21172d25a9bcSRuchika Gupta 21182d25a9bcSRuchika Gupta /* 21192d25a9bcSRuchika Gupta * If PKCS11_CKA_PRIVATE is being set to TRUE from 21202d25a9bcSRuchika Gupta * FALSE, user has to be logged in 21212d25a9bcSRuchika Gupta */ 21222d25a9bcSRuchika Gupta if (!parent_priv && obj_priv) { 21232d25a9bcSRuchika Gupta if ((pkcs11_session_is_public(session) || 21242d25a9bcSRuchika Gupta pkcs11_session_is_so(session))) 21252d25a9bcSRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 21262d25a9bcSRuchika Gupta } 2127df017b2bSRuchika Gupta 2128df017b2bSRuchika Gupta /* 2129df017b2bSRuchika Gupta * Restriction added - Even for Copy, do not allow 2130df017b2bSRuchika Gupta * modification of CKA_PRIVATE from TRUE to FALSE 2131df017b2bSRuchika Gupta */ 2132df017b2bSRuchika Gupta if (parent_priv && !obj_priv) 2133df017b2bSRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 21342d25a9bcSRuchika Gupta } 21352d25a9bcSRuchika Gupta } 21362d25a9bcSRuchika Gupta 21372d25a9bcSRuchika Gupta return PKCS11_CKR_OK; 21382d25a9bcSRuchika Gupta } 21398c499324SRuchika Gupta 21408c499324SRuchika Gupta static enum pkcs11_rc set_secret_key_data(struct obj_attrs **head, void *data, 21418c499324SRuchika Gupta size_t key_size) 21428c499324SRuchika Gupta { 21438c499324SRuchika Gupta uint32_t size = sizeof(uint32_t); 21448c499324SRuchika Gupta uint32_t key_length = 0; 21458c499324SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 21468c499324SRuchika Gupta 21478c499324SRuchika Gupta /* Get key size if present in template */ 21488c499324SRuchika Gupta rc = get_attribute(*head, PKCS11_CKA_VALUE_LEN, &key_length, &size); 21498c499324SRuchika Gupta if (rc && rc != PKCS11_RV_NOT_FOUND) 21508c499324SRuchika Gupta return rc; 21518c499324SRuchika Gupta 21528c499324SRuchika Gupta if (key_length) { 21538c499324SRuchika Gupta if (key_size < key_length) 21548c499324SRuchika Gupta return PKCS11_CKR_DATA_LEN_RANGE; 21558c499324SRuchika Gupta } else { 21568c499324SRuchika Gupta key_length = key_size; 21578c499324SRuchika Gupta rc = set_attribute(head, PKCS11_CKA_VALUE_LEN, &key_length, 21588c499324SRuchika Gupta sizeof(uint32_t)); 21598c499324SRuchika Gupta if (rc) 21608c499324SRuchika Gupta return rc; 21618c499324SRuchika Gupta } 21628c499324SRuchika Gupta 21638c499324SRuchika Gupta /* Now we can check the VALUE_LEN field */ 21648c499324SRuchika Gupta rc = check_created_attrs(*head, NULL); 21658c499324SRuchika Gupta if (rc) 21668c499324SRuchika Gupta return rc; 21678c499324SRuchika Gupta 21688c499324SRuchika Gupta /* Remove the default empty value attribute if found */ 21698c499324SRuchika Gupta rc = remove_empty_attribute(head, PKCS11_CKA_VALUE); 21708c499324SRuchika Gupta if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND) 21718c499324SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 21728c499324SRuchika Gupta 21738c499324SRuchika Gupta return add_attribute(head, PKCS11_CKA_VALUE, data, key_length); 21748c499324SRuchika Gupta } 21758c499324SRuchika Gupta 21768c499324SRuchika Gupta enum pkcs11_rc set_key_data(struct obj_attrs **head, void *data, 21778c499324SRuchika Gupta size_t key_size) 21788c499324SRuchika Gupta { 21798c499324SRuchika Gupta switch (get_class(*head)) { 21808c499324SRuchika Gupta case PKCS11_CKO_SECRET_KEY: 21818c499324SRuchika Gupta return set_secret_key_data(head, data, key_size); 21828c499324SRuchika Gupta default: 21838c499324SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 21848c499324SRuchika Gupta } 21858c499324SRuchika Gupta } 21865e1d94ebSVesa Jääskeläinen 21875f80f270SRuchika Gupta enum pkcs11_rc get_key_data_to_wrap(struct obj_attrs *head, void **data, 21885f80f270SRuchika Gupta uint32_t *sz) 21895f80f270SRuchika Gupta { 21905f80f270SRuchika Gupta switch (get_class(head)) { 21915f80f270SRuchika Gupta case PKCS11_CKO_SECRET_KEY: 21925f80f270SRuchika Gupta if (get_attribute_ptr(head, PKCS11_CKA_VALUE, data, sz)) 21935f80f270SRuchika Gupta return PKCS11_CKR_ARGUMENTS_BAD; 21945f80f270SRuchika Gupta break; 21955f80f270SRuchika Gupta default: 21965f80f270SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 21975f80f270SRuchika Gupta } 21985f80f270SRuchika Gupta 21995f80f270SRuchika Gupta return PKCS11_CKR_OK; 22005f80f270SRuchika Gupta } 22015f80f270SRuchika Gupta 22025e1d94ebSVesa Jääskeläinen enum pkcs11_rc add_missing_attribute_id(struct obj_attrs **pub_head, 22035e1d94ebSVesa Jääskeläinen struct obj_attrs **priv_head) 22045e1d94ebSVesa Jääskeläinen { 22055e1d94ebSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 22065e1d94ebSVesa Jääskeläinen void *id1 = NULL; 22075e1d94ebSVesa Jääskeläinen uint32_t id1_size = 0; 22085e1d94ebSVesa Jääskeläinen void *id2 = NULL; 22095e1d94ebSVesa Jääskeläinen uint32_t id2_size = 0; 22105e1d94ebSVesa Jääskeläinen 22115e1d94ebSVesa Jääskeläinen assert(pub_head); 22125e1d94ebSVesa Jääskeläinen assert(priv_head); 22135e1d94ebSVesa Jääskeläinen 22145e1d94ebSVesa Jääskeläinen rc = get_attribute_ptr(*pub_head, PKCS11_CKA_ID, &id1, &id1_size); 22155e1d94ebSVesa Jääskeläinen if (rc) { 22165e1d94ebSVesa Jääskeläinen if (rc != PKCS11_RV_NOT_FOUND) 22175e1d94ebSVesa Jääskeläinen return rc; 22185e1d94ebSVesa Jääskeläinen id1 = NULL; 22195e1d94ebSVesa Jääskeläinen } else if (!id1_size) { 22205e1d94ebSVesa Jääskeläinen id1 = NULL; 22215e1d94ebSVesa Jääskeläinen } 22225e1d94ebSVesa Jääskeläinen 22235e1d94ebSVesa Jääskeläinen rc = get_attribute_ptr(*priv_head, PKCS11_CKA_ID, &id2, &id2_size); 22245e1d94ebSVesa Jääskeläinen if (rc) { 22255e1d94ebSVesa Jääskeläinen if (rc != PKCS11_RV_NOT_FOUND) 22265e1d94ebSVesa Jääskeläinen return rc; 22275e1d94ebSVesa Jääskeläinen id2 = NULL; 22285e1d94ebSVesa Jääskeläinen } else if (!id2_size) { 22295e1d94ebSVesa Jääskeläinen id2 = NULL; 22305e1d94ebSVesa Jääskeläinen } 22315e1d94ebSVesa Jääskeläinen 22325e1d94ebSVesa Jääskeläinen /* Both have value -- let them be what caller has specified them */ 22335e1d94ebSVesa Jääskeläinen if (id1 && id2) 22345e1d94ebSVesa Jääskeläinen return PKCS11_CKR_OK; 22355e1d94ebSVesa Jääskeläinen 22365e1d94ebSVesa Jääskeläinen /* Both are empty -- leave empty values */ 22375e1d94ebSVesa Jääskeläinen if (!id1 && !id2) 22385e1d94ebSVesa Jääskeläinen return PKCS11_CKR_OK; 22395e1d94ebSVesa Jääskeläinen 22405e1d94ebSVesa Jääskeläinen /* Cross copy CKA_ID value */ 22415e1d94ebSVesa Jääskeläinen if (id1) 22425e1d94ebSVesa Jääskeläinen return set_attribute(priv_head, PKCS11_CKA_ID, id1, id1_size); 22435e1d94ebSVesa Jääskeläinen else 22445e1d94ebSVesa Jääskeläinen return set_attribute(pub_head, PKCS11_CKA_ID, id2, id2_size); 22455e1d94ebSVesa Jääskeläinen } 2246