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 900460a039SRuchika Gupta if (session->processing->updated) { 910460a039SRuchika Gupta EMSG("Cannot perform one-shot on updated processing"); 920460a039SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE; 930460a039SRuchika Gupta } 940460a039SRuchika Gupta 950460a039SRuchika Gupta allowed = true; 960460a039SRuchika Gupta break; 970460a039SRuchika Gupta 98512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_UPDATE: 99512cbf1dSJens Wiklander if (session->processing->always_authen && 100512cbf1dSJens Wiklander !session->processing->relogged) 101512cbf1dSJens Wiklander return PKCS11_CKR_USER_NOT_LOGGED_IN; 102512cbf1dSJens Wiklander 103512cbf1dSJens Wiklander allowed = !mechanism_is_one_shot_only(mechanism_type); 104512cbf1dSJens Wiklander break; 105512cbf1dSJens Wiklander 1069e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE_KEY: 1079e91a619SVesa Jääskeläinen assert(function == PKCS11_FUNCTION_DIGEST); 1089e91a619SVesa Jääskeläinen 1099e91a619SVesa Jääskeläinen if (session->processing->always_authen && 1109e91a619SVesa Jääskeläinen !session->processing->relogged) 1119e91a619SVesa Jääskeläinen return PKCS11_CKR_USER_NOT_LOGGED_IN; 1129e91a619SVesa Jääskeläinen 1139e91a619SVesa Jääskeläinen allowed = true; 1149e91a619SVesa Jääskeläinen break; 1159e91a619SVesa Jääskeläinen 116512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_FINAL: 117512cbf1dSJens Wiklander if (session->processing->always_authen && 118512cbf1dSJens Wiklander !session->processing->relogged) 119512cbf1dSJens Wiklander return PKCS11_CKR_USER_NOT_LOGGED_IN; 120512cbf1dSJens Wiklander 121512cbf1dSJens Wiklander return PKCS11_CKR_OK; 122512cbf1dSJens Wiklander 123512cbf1dSJens Wiklander default: 124512cbf1dSJens Wiklander TEE_Panic(step); 125512cbf1dSJens Wiklander break; 126512cbf1dSJens Wiklander } 127512cbf1dSJens Wiklander 128512cbf1dSJens Wiklander if (!allowed) { 129512cbf1dSJens Wiklander EMSG("Processing %#x/%s not permitted (%u/%u)", 130512cbf1dSJens Wiklander (unsigned int)mechanism_type, id2str_proc(mechanism_type), 131512cbf1dSJens Wiklander function, step); 132df705578SRuchika Gupta return PKCS11_CKR_MECHANISM_INVALID; 133512cbf1dSJens Wiklander } 134512cbf1dSJens Wiklander 135512cbf1dSJens Wiklander return PKCS11_CKR_OK; 136512cbf1dSJens Wiklander } 137512cbf1dSJens Wiklander 13863f89caaSJens Wiklander /* 13963f89caaSJens Wiklander * Object default boolean attributes as per PKCS#11 14063f89caaSJens Wiklander */ 14163f89caaSJens Wiklander static uint8_t *pkcs11_object_default_boolprop(uint32_t attribute) 14263f89caaSJens Wiklander { 14363f89caaSJens Wiklander static const uint8_t bool_true = 1; 14463f89caaSJens Wiklander static const uint8_t bool_false; 14563f89caaSJens Wiklander 14663f89caaSJens Wiklander switch (attribute) { 14763f89caaSJens Wiklander /* As per PKCS#11 default value */ 14863f89caaSJens Wiklander case PKCS11_CKA_MODIFIABLE: 14963f89caaSJens Wiklander case PKCS11_CKA_COPYABLE: 15063f89caaSJens Wiklander case PKCS11_CKA_DESTROYABLE: 15163f89caaSJens Wiklander return (uint8_t *)&bool_true; 15263f89caaSJens Wiklander case PKCS11_CKA_TOKEN: 15363f89caaSJens Wiklander case PKCS11_CKA_PRIVATE: 15439fc24faSEtienne Carriere case PKCS11_CKA_WRAP_WITH_TRUSTED: 15539fc24faSEtienne Carriere case PKCS11_CKA_ALWAYS_AUTHENTICATE: 15663f89caaSJens Wiklander case PKCS11_CKA_SENSITIVE: 15763f89caaSJens Wiklander return (uint8_t *)&bool_false; 15863f89caaSJens Wiklander /* Token specific default value */ 15963f89caaSJens Wiklander case PKCS11_CKA_SIGN: 16063f89caaSJens Wiklander case PKCS11_CKA_VERIFY: 16163f89caaSJens Wiklander case PKCS11_CKA_DERIVE: 16263f89caaSJens Wiklander case PKCS11_CKA_ENCRYPT: 16363f89caaSJens Wiklander case PKCS11_CKA_DECRYPT: 16463f89caaSJens Wiklander case PKCS11_CKA_SIGN_RECOVER: 16563f89caaSJens Wiklander case PKCS11_CKA_VERIFY_RECOVER: 16663f89caaSJens Wiklander case PKCS11_CKA_WRAP: 16763f89caaSJens Wiklander case PKCS11_CKA_UNWRAP: 16863f89caaSJens Wiklander case PKCS11_CKA_EXTRACTABLE: 16963f89caaSJens Wiklander case PKCS11_CKA_TRUSTED: 17063f89caaSJens Wiklander return (uint8_t *)&bool_false; 17163f89caaSJens Wiklander default: 17263f89caaSJens Wiklander DMSG("No default for boolprop attribute %#"PRIx32, attribute); 17363f89caaSJens Wiklander return NULL; 17463f89caaSJens Wiklander } 17563f89caaSJens Wiklander } 17663f89caaSJens Wiklander 17763f89caaSJens Wiklander /* 17863f89caaSJens Wiklander * Object expects several boolean attributes to be set to a default value 17963f89caaSJens Wiklander * or to a validate client configuration value. This function append the input 18063f89caaSJens Wiklander * attribute (id/size/value) in the serialized object. 18163f89caaSJens Wiklander */ 18263f89caaSJens Wiklander static enum pkcs11_rc pkcs11_import_object_boolprop(struct obj_attrs **out, 18363f89caaSJens Wiklander struct obj_attrs *templ, 18463f89caaSJens Wiklander uint32_t attribute) 18563f89caaSJens Wiklander { 18663f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 18763f89caaSJens Wiklander uint8_t bbool = 0; 18863f89caaSJens Wiklander uint32_t size = sizeof(uint8_t); 18963f89caaSJens Wiklander void *attr = NULL; 19063f89caaSJens Wiklander 19163f89caaSJens Wiklander rc = get_attribute(templ, attribute, &bbool, &size); 19263f89caaSJens Wiklander if (rc) { 19363f89caaSJens Wiklander if (rc != PKCS11_RV_NOT_FOUND) 19463f89caaSJens Wiklander return rc; 19563f89caaSJens Wiklander attr = pkcs11_object_default_boolprop(attribute); 19663f89caaSJens Wiklander if (!attr) 19763f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCOMPLETE; 19863f89caaSJens Wiklander } else { 19963f89caaSJens Wiklander attr = &bbool; 20063f89caaSJens Wiklander } 20163f89caaSJens Wiklander 20263f89caaSJens Wiklander /* Boolean attributes are 1byte in the ABI, no alignment issue */ 20363f89caaSJens Wiklander return add_attribute(out, attribute, attr, sizeof(uint8_t)); 20463f89caaSJens Wiklander } 20563f89caaSJens Wiklander 20663f89caaSJens Wiklander static enum pkcs11_rc set_mandatory_boolprops(struct obj_attrs **out, 20763f89caaSJens Wiklander struct obj_attrs *temp, 20863f89caaSJens Wiklander uint32_t const *bp, 20963f89caaSJens Wiklander size_t bp_count) 21063f89caaSJens Wiklander { 21163f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 21263f89caaSJens Wiklander size_t n = 0; 21363f89caaSJens Wiklander 21463f89caaSJens Wiklander for (n = 0; n < bp_count; n++) { 21563f89caaSJens Wiklander rc = pkcs11_import_object_boolprop(out, temp, bp[n]); 21663f89caaSJens Wiklander if (rc) 21763f89caaSJens Wiklander return rc; 21863f89caaSJens Wiklander } 21963f89caaSJens Wiklander 22063f89caaSJens Wiklander return rc; 22163f89caaSJens Wiklander } 22263f89caaSJens Wiklander 22363f89caaSJens Wiklander static enum pkcs11_rc set_mandatory_attributes(struct obj_attrs **out, 22463f89caaSJens Wiklander struct obj_attrs *temp, 22516df60c7SEtienne Carriere uint32_t const *attrs, 22616df60c7SEtienne Carriere size_t attrs_count) 22763f89caaSJens Wiklander { 22863f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 22963f89caaSJens Wiklander size_t n = 0; 23063f89caaSJens Wiklander 23116df60c7SEtienne Carriere for (n = 0; n < attrs_count; n++) { 23263f89caaSJens Wiklander uint32_t size = 0; 23363f89caaSJens Wiklander void *value = NULL; 23463f89caaSJens Wiklander 23516df60c7SEtienne Carriere if (get_attribute_ptr(temp, attrs[n], &value, &size)) 23663f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCOMPLETE; 23763f89caaSJens Wiklander 23816df60c7SEtienne Carriere rc = add_attribute(out, attrs[n], value, size); 23963f89caaSJens Wiklander if (rc) 24063f89caaSJens Wiklander return rc; 24163f89caaSJens Wiklander } 24263f89caaSJens Wiklander 24363f89caaSJens Wiklander return rc; 24463f89caaSJens Wiklander } 24563f89caaSJens Wiklander 24663f89caaSJens Wiklander static enum pkcs11_rc get_default_value(enum pkcs11_attr_id id, void **value, 24763f89caaSJens Wiklander uint32_t *size) 24863f89caaSJens Wiklander { 24963f89caaSJens Wiklander /* should have been taken care of already */ 25063f89caaSJens Wiklander assert(!pkcs11_attr_is_boolean(id)); 25163f89caaSJens Wiklander 25263f89caaSJens Wiklander /* All other attributes have an empty default value */ 25363f89caaSJens Wiklander *value = NULL; 25463f89caaSJens Wiklander *size = 0; 25563f89caaSJens Wiklander return PKCS11_CKR_OK; 25663f89caaSJens Wiklander } 25763f89caaSJens Wiklander 2584eb88651SRuchika Gupta static enum pkcs11_rc set_optional_attributes_with_def(struct obj_attrs **out, 25963f89caaSJens Wiklander struct obj_attrs *temp, 26016df60c7SEtienne Carriere uint32_t const *attrs, 26116df60c7SEtienne Carriere size_t attrs_count, 2624eb88651SRuchika Gupta bool default_to_null) 26363f89caaSJens Wiklander { 26463f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 26563f89caaSJens Wiklander size_t n = 0; 26663f89caaSJens Wiklander 26716df60c7SEtienne Carriere for (n = 0; n < attrs_count; n++) { 26863f89caaSJens Wiklander uint32_t size = 0; 26963f89caaSJens Wiklander void *value = NULL; 27063f89caaSJens Wiklander 27116df60c7SEtienne Carriere rc = get_attribute_ptr(temp, attrs[n], &value, &size); 2724eb88651SRuchika Gupta if (rc == PKCS11_RV_NOT_FOUND) { 2734eb88651SRuchika Gupta if (default_to_null) { 27416df60c7SEtienne Carriere rc = get_default_value(attrs[n], &value, &size); 2754eb88651SRuchika Gupta } else { 2764eb88651SRuchika Gupta rc = PKCS11_CKR_OK; 2774eb88651SRuchika Gupta continue; 2784eb88651SRuchika Gupta } 2794eb88651SRuchika Gupta } 28063f89caaSJens Wiklander if (rc) 28163f89caaSJens Wiklander return rc; 28263f89caaSJens Wiklander 28316df60c7SEtienne Carriere rc = add_attribute(out, attrs[n], value, size); 28463f89caaSJens Wiklander if (rc) 28563f89caaSJens Wiklander return rc; 28663f89caaSJens Wiklander } 28763f89caaSJens Wiklander 28863f89caaSJens Wiklander return rc; 28963f89caaSJens Wiklander } 29063f89caaSJens Wiklander 2914eb88651SRuchika Gupta static enum pkcs11_rc set_attributes_opt_or_null(struct obj_attrs **out, 2924eb88651SRuchika Gupta struct obj_attrs *temp, 29316df60c7SEtienne Carriere uint32_t const *attrs, 29416df60c7SEtienne Carriere size_t attrs_count) 2954eb88651SRuchika Gupta { 29616df60c7SEtienne Carriere return set_optional_attributes_with_def(out, temp, attrs, attrs_count, 29716df60c7SEtienne Carriere true /* defaults to empty */); 2984eb88651SRuchika Gupta } 2994eb88651SRuchika Gupta 3004eb88651SRuchika Gupta static enum pkcs11_rc set_optional_attributes(struct obj_attrs **out, 3014eb88651SRuchika Gupta struct obj_attrs *temp, 30216df60c7SEtienne Carriere uint32_t const *attrs, 30316df60c7SEtienne Carriere size_t attrs_count) 3044eb88651SRuchika Gupta { 30516df60c7SEtienne Carriere return set_optional_attributes_with_def(out, temp, attrs, attrs_count, 30616df60c7SEtienne Carriere false /* no default value */); 3074eb88651SRuchika Gupta } 3084eb88651SRuchika Gupta 30963f89caaSJens Wiklander /* 31063f89caaSJens Wiklander * Below are listed the mandated or optional expected attributes for 31163f89caaSJens Wiklander * PKCS#11 storage objects. 31263f89caaSJens Wiklander * 31363f89caaSJens Wiklander * Note: boolprops (mandated boolean attributes) PKCS11_CKA_ALWAYS_SENSITIVE, 31463f89caaSJens Wiklander * and PKCS11_CKA_NEVER_EXTRACTABLE are set by the token, not provided 31563f89caaSJens Wiklander * in the client template. 31663f89caaSJens Wiklander */ 31763f89caaSJens Wiklander 31863f89caaSJens Wiklander /* PKCS#11 specification for any object (session/token) of the storage */ 3194eb88651SRuchika Gupta static const uint32_t any_object_boolprops[] = { 32063f89caaSJens Wiklander PKCS11_CKA_TOKEN, PKCS11_CKA_PRIVATE, 32163f89caaSJens Wiklander PKCS11_CKA_MODIFIABLE, PKCS11_CKA_COPYABLE, PKCS11_CKA_DESTROYABLE, 32263f89caaSJens Wiklander }; 32363f89caaSJens Wiklander 3244eb88651SRuchika Gupta static const uint32_t any_object_opt_or_null[] = { 32563f89caaSJens Wiklander PKCS11_CKA_LABEL, 32663f89caaSJens Wiklander }; 32763f89caaSJens Wiklander 3284eb88651SRuchika Gupta /* PKCS#11 specification for raw data object (+any_object_xxx) */ 3294eb88651SRuchika Gupta const uint32_t raw_data_opt_or_null[] = { 33063f89caaSJens Wiklander PKCS11_CKA_OBJECT_ID, PKCS11_CKA_APPLICATION, PKCS11_CKA_VALUE, 33163f89caaSJens Wiklander }; 33263f89caaSJens Wiklander 3334eb88651SRuchika Gupta /* PKCS#11 specification for any key object (+any_object_xxx) */ 3344eb88651SRuchika Gupta static const uint32_t any_key_boolprops[] = { 33563f89caaSJens Wiklander PKCS11_CKA_DERIVE, 33663f89caaSJens Wiklander }; 33763f89caaSJens Wiklander 3384eb88651SRuchika Gupta static const uint32_t any_key_opt_or_null[] = { 33963f89caaSJens Wiklander PKCS11_CKA_ID, 34063f89caaSJens Wiklander PKCS11_CKA_START_DATE, PKCS11_CKA_END_DATE, 3414eb88651SRuchika Gupta }; 3424eb88651SRuchika Gupta 3434eb88651SRuchika Gupta static const uint32_t any_key_optional[] = { 34463f89caaSJens Wiklander PKCS11_CKA_ALLOWED_MECHANISMS, 34563f89caaSJens Wiklander }; 34663f89caaSJens Wiklander 3474eb88651SRuchika Gupta /* PKCS#11 specification for any symmetric key (+any_key_xxx) */ 3484eb88651SRuchika Gupta static const uint32_t symm_key_boolprops[] = { 34963f89caaSJens Wiklander PKCS11_CKA_ENCRYPT, PKCS11_CKA_DECRYPT, 35063f89caaSJens Wiklander PKCS11_CKA_SIGN, PKCS11_CKA_VERIFY, 35163f89caaSJens Wiklander PKCS11_CKA_WRAP, PKCS11_CKA_UNWRAP, 35263f89caaSJens Wiklander PKCS11_CKA_SENSITIVE, PKCS11_CKA_EXTRACTABLE, 35363f89caaSJens Wiklander PKCS11_CKA_WRAP_WITH_TRUSTED, PKCS11_CKA_TRUSTED, 35463f89caaSJens Wiklander }; 35563f89caaSJens Wiklander 3564eb88651SRuchika Gupta static const uint32_t symm_key_opt_or_null[] = { 35763f89caaSJens Wiklander PKCS11_CKA_WRAP_TEMPLATE, PKCS11_CKA_UNWRAP_TEMPLATE, 3580ac5c695SRuchika Gupta PKCS11_CKA_DERIVE_TEMPLATE, PKCS11_CKA_VALUE, 3590ac5c695SRuchika Gupta }; 3600ac5c695SRuchika Gupta 3610ac5c695SRuchika Gupta static const uint32_t symm_key_optional[] = { 3620ac5c695SRuchika Gupta PKCS11_CKA_VALUE_LEN, 36363f89caaSJens Wiklander }; 36463f89caaSJens Wiklander 3654eb88651SRuchika Gupta /* PKCS#11 specification for any asymmetric public key (+any_key_xxx) */ 3664eb88651SRuchika Gupta static const uint32_t public_key_boolprops[] = { 36763f89caaSJens Wiklander PKCS11_CKA_ENCRYPT, PKCS11_CKA_VERIFY, PKCS11_CKA_VERIFY_RECOVER, 36863f89caaSJens Wiklander PKCS11_CKA_WRAP, 36963f89caaSJens Wiklander PKCS11_CKA_TRUSTED, 37063f89caaSJens Wiklander }; 37163f89caaSJens Wiklander 3724eb88651SRuchika Gupta static const uint32_t public_key_mandated[] = { 37363f89caaSJens Wiklander }; 37463f89caaSJens Wiklander 3754eb88651SRuchika Gupta static const uint32_t public_key_opt_or_null[] = { 376edd95148SVesa Jääskeläinen PKCS11_CKA_SUBJECT, PKCS11_CKA_WRAP_TEMPLATE, 377edd95148SVesa Jääskeläinen PKCS11_CKA_PUBLIC_KEY_INFO, 37863f89caaSJens Wiklander }; 37963f89caaSJens Wiklander 3804eb88651SRuchika Gupta /* PKCS#11 specification for any asymmetric private key (+any_key_xxx) */ 3814eb88651SRuchika Gupta static const uint32_t private_key_boolprops[] = { 38263f89caaSJens Wiklander PKCS11_CKA_DECRYPT, PKCS11_CKA_SIGN, PKCS11_CKA_SIGN_RECOVER, 38363f89caaSJens Wiklander PKCS11_CKA_UNWRAP, 38463f89caaSJens Wiklander PKCS11_CKA_SENSITIVE, PKCS11_CKA_EXTRACTABLE, 38563f89caaSJens Wiklander PKCS11_CKA_WRAP_WITH_TRUSTED, PKCS11_CKA_ALWAYS_AUTHENTICATE, 38663f89caaSJens Wiklander }; 38763f89caaSJens Wiklander 3884eb88651SRuchika Gupta static const uint32_t private_key_mandated[] = { 38963f89caaSJens Wiklander }; 39063f89caaSJens Wiklander 3914eb88651SRuchika Gupta static const uint32_t private_key_opt_or_null[] = { 392edd95148SVesa Jääskeläinen PKCS11_CKA_SUBJECT, PKCS11_CKA_UNWRAP_TEMPLATE, 393edd95148SVesa Jääskeläinen PKCS11_CKA_PUBLIC_KEY_INFO, 39463f89caaSJens Wiklander }; 39563f89caaSJens Wiklander 3964eb88651SRuchika Gupta /* PKCS#11 specification for any RSA key (+public/private_key_xxx) */ 397*9cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_gen_mand[] = { 39863f89caaSJens Wiklander PKCS11_CKA_MODULUS_BITS, 39963f89caaSJens Wiklander }; 40063f89caaSJens Wiklander 401*9cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_create_mand[] = { 40263f89caaSJens Wiklander PKCS11_CKA_MODULUS, PKCS11_CKA_PUBLIC_EXPONENT, 40363f89caaSJens Wiklander }; 40463f89caaSJens Wiklander 405*9cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_gen_opt_or_null[] = { 406*9cf1afceSVesa Jääskeläinen PKCS11_CKA_PUBLIC_EXPONENT, 407*9cf1afceSVesa Jääskeläinen }; 408*9cf1afceSVesa Jääskeläinen 409*9cf1afceSVesa Jääskeläinen static const uint32_t rsa_priv_key_opt_or_null[] = { 41063f89caaSJens Wiklander PKCS11_CKA_MODULUS, PKCS11_CKA_PUBLIC_EXPONENT, 41163f89caaSJens Wiklander PKCS11_CKA_PRIVATE_EXPONENT, 41263f89caaSJens Wiklander PKCS11_CKA_PRIME_1, PKCS11_CKA_PRIME_2, 41363f89caaSJens Wiklander PKCS11_CKA_EXPONENT_1, PKCS11_CKA_EXPONENT_2, PKCS11_CKA_COEFFICIENT, 41463f89caaSJens Wiklander }; 41563f89caaSJens Wiklander 4164eb88651SRuchika Gupta /* PKCS#11 specification for any EC key (+public/private_key_xxx) */ 4174eb88651SRuchika Gupta static const uint32_t ec_public_key_mandated[] = { 41863f89caaSJens Wiklander PKCS11_CKA_EC_PARAMS, 41963f89caaSJens Wiklander }; 42063f89caaSJens Wiklander 4214eb88651SRuchika Gupta static const uint32_t ec_public_key_opt_or_null[] = { 42263f89caaSJens Wiklander PKCS11_CKA_EC_POINT, 42363f89caaSJens Wiklander }; 42463f89caaSJens Wiklander 4254eb88651SRuchika Gupta static const uint32_t ec_private_key_mandated[] = { 42663f89caaSJens Wiklander }; 42763f89caaSJens Wiklander 4284eb88651SRuchika Gupta static const uint32_t ec_private_key_opt_or_null[] = { 42902b16804SVesa Jääskeläinen PKCS11_CKA_EC_PARAMS, 43063f89caaSJens Wiklander PKCS11_CKA_VALUE, 43163f89caaSJens Wiklander }; 43263f89caaSJens Wiklander 43363f89caaSJens Wiklander static enum pkcs11_rc create_storage_attributes(struct obj_attrs **out, 43463f89caaSJens Wiklander struct obj_attrs *temp) 43563f89caaSJens Wiklander { 43663f89caaSJens Wiklander enum pkcs11_class_id class = PKCS11_CKO_UNDEFINED_ID; 43763f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 43863f89caaSJens Wiklander 43963f89caaSJens Wiklander rc = init_attributes_head(out); 44063f89caaSJens Wiklander if (rc) 44163f89caaSJens Wiklander return rc; 44263f89caaSJens Wiklander 44363f89caaSJens Wiklander /* Object class is mandatory */ 44463f89caaSJens Wiklander class = get_class(temp); 44563f89caaSJens Wiklander if (class == PKCS11_CKO_UNDEFINED_ID) { 44663f89caaSJens Wiklander EMSG("Class attribute not found"); 44763f89caaSJens Wiklander 44863f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 44963f89caaSJens Wiklander } 45063f89caaSJens Wiklander rc = add_attribute(out, PKCS11_CKA_CLASS, &class, sizeof(uint32_t)); 45163f89caaSJens Wiklander if (rc) 45263f89caaSJens Wiklander return rc; 45363f89caaSJens Wiklander 4544eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, any_object_boolprops, 4554eb88651SRuchika Gupta ARRAY_SIZE(any_object_boolprops)); 45663f89caaSJens Wiklander if (rc) 45763f89caaSJens Wiklander return rc; 45863f89caaSJens Wiklander 4594eb88651SRuchika Gupta return set_attributes_opt_or_null(out, temp, any_object_opt_or_null, 4604eb88651SRuchika Gupta ARRAY_SIZE(any_object_opt_or_null)); 46163f89caaSJens Wiklander } 46263f89caaSJens Wiklander 46363f89caaSJens Wiklander static enum pkcs11_rc create_genkey_attributes(struct obj_attrs **out, 46463f89caaSJens Wiklander struct obj_attrs *temp) 46563f89caaSJens Wiklander { 46663f89caaSJens Wiklander uint32_t type = PKCS11_CKO_UNDEFINED_ID; 46763f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 46863f89caaSJens Wiklander 46963f89caaSJens Wiklander rc = create_storage_attributes(out, temp); 47063f89caaSJens Wiklander if (rc) 47163f89caaSJens Wiklander return rc; 47263f89caaSJens Wiklander 47363f89caaSJens Wiklander type = get_key_type(temp); 47463f89caaSJens Wiklander if (type == PKCS11_CKK_UNDEFINED_ID) { 47563f89caaSJens Wiklander EMSG("Key type attribute not found"); 47663f89caaSJens Wiklander 47763f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 47863f89caaSJens Wiklander } 47963f89caaSJens Wiklander rc = add_attribute(out, PKCS11_CKA_KEY_TYPE, &type, sizeof(uint32_t)); 48063f89caaSJens Wiklander if (rc) 48163f89caaSJens Wiklander return rc; 48263f89caaSJens Wiklander 4834eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, any_key_boolprops, 4844eb88651SRuchika Gupta ARRAY_SIZE(any_key_boolprops)); 48563f89caaSJens Wiklander if (rc) 48663f89caaSJens Wiklander return rc; 48763f89caaSJens Wiklander 4884eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, any_key_opt_or_null, 4894eb88651SRuchika Gupta ARRAY_SIZE(any_key_opt_or_null)); 4904eb88651SRuchika Gupta if (rc) 4914eb88651SRuchika Gupta return rc; 4924eb88651SRuchika Gupta 4934eb88651SRuchika Gupta return set_optional_attributes(out, temp, any_key_optional, 4944eb88651SRuchika Gupta ARRAY_SIZE(any_key_optional)); 4954eb88651SRuchika Gupta 49663f89caaSJens Wiklander } 49763f89caaSJens Wiklander 49863f89caaSJens Wiklander static enum pkcs11_rc create_symm_key_attributes(struct obj_attrs **out, 49963f89caaSJens Wiklander struct obj_attrs *temp) 50063f89caaSJens Wiklander { 50163f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 50263f89caaSJens Wiklander 50363f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_SECRET_KEY); 50463f89caaSJens Wiklander 50563f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 50663f89caaSJens Wiklander if (rc) 50763f89caaSJens Wiklander return rc; 50863f89caaSJens Wiklander 50963f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_SECRET_KEY); 51063f89caaSJens Wiklander 51163f89caaSJens Wiklander switch (get_key_type(*out)) { 51263f89caaSJens Wiklander case PKCS11_CKK_GENERIC_SECRET: 51363f89caaSJens Wiklander case PKCS11_CKK_AES: 51463f89caaSJens Wiklander case PKCS11_CKK_MD5_HMAC: 51563f89caaSJens Wiklander case PKCS11_CKK_SHA_1_HMAC: 51663f89caaSJens Wiklander case PKCS11_CKK_SHA256_HMAC: 51763f89caaSJens Wiklander case PKCS11_CKK_SHA384_HMAC: 51863f89caaSJens Wiklander case PKCS11_CKK_SHA512_HMAC: 51963f89caaSJens Wiklander case PKCS11_CKK_SHA224_HMAC: 52063f89caaSJens Wiklander break; 52163f89caaSJens Wiklander default: 52263f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 52363f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 52463f89caaSJens Wiklander 52563f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 52663f89caaSJens Wiklander } 52763f89caaSJens Wiklander 5284eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, symm_key_boolprops, 5294eb88651SRuchika Gupta ARRAY_SIZE(symm_key_boolprops)); 53063f89caaSJens Wiklander if (rc) 53163f89caaSJens Wiklander return rc; 53263f89caaSJens Wiklander 5330ac5c695SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, symm_key_opt_or_null, 5344eb88651SRuchika Gupta ARRAY_SIZE(symm_key_opt_or_null)); 5350ac5c695SRuchika Gupta if (rc) 5360ac5c695SRuchika Gupta return rc; 5370ac5c695SRuchika Gupta 5380ac5c695SRuchika Gupta return set_optional_attributes(out, temp, symm_key_optional, 5390ac5c695SRuchika Gupta ARRAY_SIZE(symm_key_optional)); 54063f89caaSJens Wiklander } 54163f89caaSJens Wiklander 54263f89caaSJens Wiklander static enum pkcs11_rc create_data_attributes(struct obj_attrs **out, 54363f89caaSJens Wiklander struct obj_attrs *temp) 54463f89caaSJens Wiklander { 54563f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 54663f89caaSJens Wiklander 54763f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_DATA); 54863f89caaSJens Wiklander 54963f89caaSJens Wiklander rc = create_storage_attributes(out, temp); 55063f89caaSJens Wiklander if (rc) 55163f89caaSJens Wiklander return rc; 55263f89caaSJens Wiklander 55363f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_DATA); 55463f89caaSJens Wiklander 5554eb88651SRuchika Gupta return set_attributes_opt_or_null(out, temp, raw_data_opt_or_null, 5564eb88651SRuchika Gupta ARRAY_SIZE(raw_data_opt_or_null)); 55763f89caaSJens Wiklander } 55863f89caaSJens Wiklander 55963f89caaSJens Wiklander static enum pkcs11_rc create_pub_key_attributes(struct obj_attrs **out, 560*9cf1afceSVesa Jääskeläinen struct obj_attrs *temp, 561*9cf1afceSVesa Jääskeläinen enum processing_func function) 56263f89caaSJens Wiklander { 56363f89caaSJens Wiklander uint32_t const *mandated = NULL; 564*9cf1afceSVesa Jääskeläinen uint32_t const *oon = NULL; 56563f89caaSJens Wiklander size_t mandated_count = 0; 566*9cf1afceSVesa Jääskeläinen size_t oon_count = 0; 56763f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 56863f89caaSJens Wiklander 56963f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_PUBLIC_KEY); 57063f89caaSJens Wiklander 57163f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 57263f89caaSJens Wiklander if (rc) 57363f89caaSJens Wiklander return rc; 57463f89caaSJens Wiklander 57563f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_PUBLIC_KEY); 57663f89caaSJens Wiklander 5774eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, public_key_boolprops, 5784eb88651SRuchika Gupta ARRAY_SIZE(public_key_boolprops)); 57963f89caaSJens Wiklander if (rc) 58063f89caaSJens Wiklander return rc; 58163f89caaSJens Wiklander 5824eb88651SRuchika Gupta rc = set_mandatory_attributes(out, temp, public_key_mandated, 5834eb88651SRuchika Gupta ARRAY_SIZE(public_key_mandated)); 58463f89caaSJens Wiklander if (rc) 58563f89caaSJens Wiklander return rc; 58663f89caaSJens Wiklander 5874eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, 5884eb88651SRuchika Gupta public_key_opt_or_null, 5894eb88651SRuchika Gupta ARRAY_SIZE(public_key_opt_or_null)); 59063f89caaSJens Wiklander if (rc) 59163f89caaSJens Wiklander return rc; 59263f89caaSJens Wiklander 59363f89caaSJens Wiklander switch (get_key_type(*out)) { 59463f89caaSJens Wiklander case PKCS11_CKK_RSA: 595*9cf1afceSVesa Jääskeläinen switch (function) { 596*9cf1afceSVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 597*9cf1afceSVesa Jääskeläinen mandated = rsa_pub_key_gen_mand; 598*9cf1afceSVesa Jääskeläinen oon = rsa_pub_key_gen_opt_or_null; 599*9cf1afceSVesa Jääskeläinen mandated_count = ARRAY_SIZE(rsa_pub_key_gen_mand); 600*9cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(rsa_pub_key_gen_opt_or_null); 601*9cf1afceSVesa Jääskeläinen break; 602*9cf1afceSVesa Jääskeläinen case PKCS11_FUNCTION_IMPORT: 603*9cf1afceSVesa Jääskeläinen mandated = rsa_pub_key_create_mand; 604*9cf1afceSVesa Jääskeläinen mandated_count = ARRAY_SIZE(rsa_pub_key_create_mand); 605*9cf1afceSVesa Jääskeläinen break; 606*9cf1afceSVesa Jääskeläinen default: 607*9cf1afceSVesa Jääskeläinen EMSG("Unsupported function %#"PRIx32"/%s", function, 608*9cf1afceSVesa Jääskeläinen id2str_function(function)); 609*9cf1afceSVesa Jääskeläinen 610*9cf1afceSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 611*9cf1afceSVesa Jääskeläinen } 61263f89caaSJens Wiklander break; 61363f89caaSJens Wiklander case PKCS11_CKK_EC: 6144eb88651SRuchika Gupta mandated = ec_public_key_mandated; 615*9cf1afceSVesa Jääskeläinen oon = ec_public_key_opt_or_null; 6164eb88651SRuchika Gupta mandated_count = ARRAY_SIZE(ec_public_key_mandated); 617*9cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(ec_public_key_opt_or_null); 61863f89caaSJens Wiklander break; 61963f89caaSJens Wiklander default: 62063f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 62163f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 62263f89caaSJens Wiklander 62363f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 62463f89caaSJens Wiklander } 62563f89caaSJens Wiklander 62663f89caaSJens Wiklander rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 62763f89caaSJens Wiklander if (rc) 62863f89caaSJens Wiklander return rc; 62963f89caaSJens Wiklander 630*9cf1afceSVesa Jääskeläinen return set_attributes_opt_or_null(out, temp, oon, oon_count); 63163f89caaSJens Wiklander } 63263f89caaSJens Wiklander 63363f89caaSJens Wiklander static enum pkcs11_rc create_priv_key_attributes(struct obj_attrs **out, 63463f89caaSJens Wiklander struct obj_attrs *temp) 63563f89caaSJens Wiklander { 63663f89caaSJens Wiklander uint32_t const *mandated = NULL; 637*9cf1afceSVesa Jääskeläinen uint32_t const *oon = NULL; 63863f89caaSJens Wiklander size_t mandated_count = 0; 639*9cf1afceSVesa Jääskeläinen size_t oon_count = 0; 64063f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 64163f89caaSJens Wiklander 64263f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_PRIVATE_KEY); 64363f89caaSJens Wiklander 64463f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 64563f89caaSJens Wiklander if (rc) 64663f89caaSJens Wiklander return rc; 64763f89caaSJens Wiklander 64863f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_PRIVATE_KEY); 64963f89caaSJens Wiklander 6504eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, private_key_boolprops, 6514eb88651SRuchika Gupta ARRAY_SIZE(private_key_boolprops)); 65263f89caaSJens Wiklander if (rc) 65363f89caaSJens Wiklander return rc; 65463f89caaSJens Wiklander 6554eb88651SRuchika Gupta rc = set_mandatory_attributes(out, temp, private_key_mandated, 6564eb88651SRuchika Gupta ARRAY_SIZE(private_key_mandated)); 65763f89caaSJens Wiklander if (rc) 65863f89caaSJens Wiklander return rc; 65963f89caaSJens Wiklander 6604eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, private_key_opt_or_null, 6614eb88651SRuchika Gupta ARRAY_SIZE(private_key_opt_or_null)); 66263f89caaSJens Wiklander if (rc) 66363f89caaSJens Wiklander return rc; 66463f89caaSJens Wiklander 66563f89caaSJens Wiklander switch (get_key_type(*out)) { 66663f89caaSJens Wiklander case PKCS11_CKK_RSA: 667*9cf1afceSVesa Jääskeläinen oon = rsa_priv_key_opt_or_null; 668*9cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(rsa_priv_key_opt_or_null); 66963f89caaSJens Wiklander break; 67063f89caaSJens Wiklander case PKCS11_CKK_EC: 6714eb88651SRuchika Gupta mandated = ec_private_key_mandated; 672*9cf1afceSVesa Jääskeläinen oon = ec_private_key_opt_or_null; 6734eb88651SRuchika Gupta mandated_count = ARRAY_SIZE(ec_private_key_mandated); 674*9cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(ec_private_key_opt_or_null); 67563f89caaSJens Wiklander break; 67663f89caaSJens Wiklander default: 67763f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 67863f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 67963f89caaSJens Wiklander 68063f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 68163f89caaSJens Wiklander } 68263f89caaSJens Wiklander 68363f89caaSJens Wiklander rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 68463f89caaSJens Wiklander if (rc) 68563f89caaSJens Wiklander return rc; 68663f89caaSJens Wiklander 687*9cf1afceSVesa Jääskeläinen return set_attributes_opt_or_null(out, temp, oon, oon_count); 68863f89caaSJens Wiklander } 68963f89caaSJens Wiklander 690196bcd93SRuchika Gupta static enum pkcs11_rc 691196bcd93SRuchika Gupta sanitize_symm_key_attributes(struct obj_attrs **temp, 692196bcd93SRuchika Gupta enum processing_func function) 693196bcd93SRuchika Gupta { 694196bcd93SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK; 695196bcd93SRuchika Gupta uint32_t a_size = 0; 696196bcd93SRuchika Gupta 697196bcd93SRuchika Gupta assert(get_class(*temp) == PKCS11_CKO_SECRET_KEY); 698196bcd93SRuchika Gupta 699196bcd93SRuchika Gupta rc = get_attribute_ptr(*temp, PKCS11_CKA_VALUE, NULL, &a_size); 700196bcd93SRuchika Gupta 701196bcd93SRuchika Gupta switch (get_key_type(*temp)) { 702196bcd93SRuchika Gupta case PKCS11_CKK_GENERIC_SECRET: 703196bcd93SRuchika Gupta case PKCS11_CKK_AES: 704196bcd93SRuchika Gupta case PKCS11_CKK_MD5_HMAC: 705196bcd93SRuchika Gupta case PKCS11_CKK_SHA_1_HMAC: 706196bcd93SRuchika Gupta case PKCS11_CKK_SHA256_HMAC: 707196bcd93SRuchika Gupta case PKCS11_CKK_SHA384_HMAC: 708196bcd93SRuchika Gupta case PKCS11_CKK_SHA512_HMAC: 709196bcd93SRuchika Gupta case PKCS11_CKK_SHA224_HMAC: 710196bcd93SRuchika Gupta switch (function) { 711196bcd93SRuchika Gupta case PKCS11_FUNCTION_IMPORT: 712196bcd93SRuchika Gupta /* CKA_VALUE is a mandatory with C_CreateObject */ 713196bcd93SRuchika Gupta if (rc || a_size == 0) 714196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 715196bcd93SRuchika Gupta 716196bcd93SRuchika Gupta if (get_attribute_ptr(*temp, PKCS11_CKA_VALUE_LEN, NULL, 717196bcd93SRuchika Gupta NULL) != PKCS11_RV_NOT_FOUND) 718196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 719196bcd93SRuchika Gupta 720196bcd93SRuchika Gupta return add_attribute(temp, PKCS11_CKA_VALUE_LEN, 721196bcd93SRuchika Gupta &a_size, sizeof(uint32_t)); 722196bcd93SRuchika Gupta case PKCS11_FUNCTION_GENERATE: 723196bcd93SRuchika Gupta if (rc != PKCS11_RV_NOT_FOUND) 724196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 725196bcd93SRuchika Gupta break; 726196bcd93SRuchika Gupta default: 727196bcd93SRuchika Gupta break; 728196bcd93SRuchika Gupta } 729196bcd93SRuchika Gupta break; 730196bcd93SRuchika Gupta default: 731196bcd93SRuchika Gupta EMSG("Invalid key type %#"PRIx32"/%s", 732196bcd93SRuchika Gupta get_key_type(*temp), id2str_key_type(get_key_type(*temp))); 733196bcd93SRuchika Gupta 734196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 735196bcd93SRuchika Gupta } 736196bcd93SRuchika Gupta 737196bcd93SRuchika Gupta return PKCS11_CKR_OK; 738196bcd93SRuchika Gupta } 739196bcd93SRuchika Gupta 74063f89caaSJens Wiklander /* 74163f89caaSJens Wiklander * Create an attribute list for a new object from a template and a parent 74263f89caaSJens Wiklander * object (optional) for an object generation function (generate, copy, 74363f89caaSJens Wiklander * derive...). 74463f89caaSJens Wiklander * 74563f89caaSJens Wiklander * PKCS#11 directives on the supplied template and expected return value: 74663f89caaSJens Wiklander * - template has an invalid attribute ID: ATTRIBUTE_TYPE_INVALID 74763f89caaSJens Wiklander * - template has an invalid value for an attribute: ATTRIBUTE_VALID_INVALID 74863f89caaSJens Wiklander * - template has value for a read-only attribute: ATTRIBUTE_READ_ONLY 74963f89caaSJens Wiklander * - template+default+parent => still miss an attribute: TEMPLATE_INCONSISTENT 75063f89caaSJens Wiklander * 75163f89caaSJens Wiklander * INFO on PKCS11_CMD_COPY_OBJECT: 75263f89caaSJens Wiklander * - parent PKCS11_CKA_COPYIABLE=false => return ACTION_PROHIBITED. 75363f89caaSJens Wiklander * - template can specify PKCS11_CKA_TOKEN, PKCS11_CKA_PRIVATE, 75463f89caaSJens Wiklander * PKCS11_CKA_MODIFIABLE, PKCS11_CKA_DESTROYABLE. 75563f89caaSJens Wiklander * - SENSITIVE can change from false to true, not from true to false. 75663f89caaSJens Wiklander * - LOCAL is the parent LOCAL 75763f89caaSJens Wiklander */ 75863f89caaSJens Wiklander enum pkcs11_rc 75963f89caaSJens Wiklander create_attributes_from_template(struct obj_attrs **out, void *template, 76063f89caaSJens Wiklander size_t template_size, 76148799892SRuchika Gupta struct obj_attrs *parent, 76263f89caaSJens Wiklander enum processing_func function, 7634cfce748SRuchika Gupta enum pkcs11_mechanism_id mecha, 76402b16804SVesa Jääskeläinen enum pkcs11_class_id template_class) 76563f89caaSJens Wiklander { 76663f89caaSJens Wiklander struct obj_attrs *temp = NULL; 76763f89caaSJens Wiklander struct obj_attrs *attrs = NULL; 76863f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 76963f89caaSJens Wiklander uint8_t local = 0; 77063f89caaSJens Wiklander uint8_t always_sensitive = 0; 77163f89caaSJens Wiklander uint8_t never_extract = 0; 772e3f0cb56SRuchika Gupta uint8_t extractable = 0; 773fa247a2aSRuchika Gupta uint32_t class = PKCS11_UNDEFINED_ID; 774fa247a2aSRuchika Gupta uint32_t type = PKCS11_UNDEFINED_ID; 77563f89caaSJens Wiklander uint32_t mechanism_id = PKCS11_CKM_UNDEFINED_ID; 776e3f0cb56SRuchika Gupta struct obj_attrs *req_attrs = NULL; 777e3f0cb56SRuchika Gupta uint32_t size = 0; 778e3f0cb56SRuchika Gupta uint32_t indirect_template = PKCS11_CKA_UNDEFINED_ID; 77963f89caaSJens Wiklander 78063f89caaSJens Wiklander #ifdef DEBUG /* Sanity: check function argument */ 78163f89caaSJens Wiklander trace_attributes_from_api_head("template", template, template_size); 78263f89caaSJens Wiklander switch (function) { 783fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 784013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 78563f89caaSJens Wiklander case PKCS11_FUNCTION_IMPORT: 7862d25a9bcSRuchika Gupta case PKCS11_FUNCTION_MODIFY: 78748799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 788e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 7892d25a9bcSRuchika Gupta case PKCS11_FUNCTION_COPY: 79063f89caaSJens Wiklander break; 79163f89caaSJens Wiklander default: 79263f89caaSJens Wiklander TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 79363f89caaSJens Wiklander } 79463f89caaSJens Wiklander #endif 79563f89caaSJens Wiklander 796dcad3409SRuchika Gupta /* 797dcad3409SRuchika Gupta * For PKCS11_FUNCTION_GENERATE, find the class and type 798dcad3409SRuchika Gupta * based on the mechanism. These will be passed as hint 799dcad3409SRuchika Gupta * sanitize_client_object() and added in temp if not 800dcad3409SRuchika Gupta * already present 801dcad3409SRuchika Gupta */ 802dcad3409SRuchika Gupta if (function == PKCS11_FUNCTION_GENERATE) { 803fa247a2aSRuchika Gupta switch (mecha) { 804fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 805fa247a2aSRuchika Gupta class = PKCS11_CKO_SECRET_KEY; 806fa247a2aSRuchika Gupta type = PKCS11_CKK_GENERIC_SECRET; 807fa247a2aSRuchika Gupta break; 808fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 809fa247a2aSRuchika Gupta class = PKCS11_CKO_SECRET_KEY; 810fa247a2aSRuchika Gupta type = PKCS11_CKK_AES; 811fa247a2aSRuchika Gupta break; 812fa247a2aSRuchika Gupta default: 813dcad3409SRuchika Gupta TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 814fa247a2aSRuchika Gupta } 815fa247a2aSRuchika Gupta } 816fa247a2aSRuchika Gupta 8172d25a9bcSRuchika Gupta /* 818013934d8SVesa Jääskeläinen * For PKCS11_FUNCTION_GENERATE_PAIR, find the class and type 819013934d8SVesa Jääskeläinen * based on the mechanism. These will be passed as hint 820013934d8SVesa Jääskeläinen * sanitize_client_object() and added in temp if not 821013934d8SVesa Jääskeläinen * already present 822013934d8SVesa Jääskeläinen */ 823013934d8SVesa Jääskeläinen if (function == PKCS11_FUNCTION_GENERATE_PAIR) { 824013934d8SVesa Jääskeläinen switch (mecha) { 82502b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 82602b16804SVesa Jääskeläinen class = template_class; 82702b16804SVesa Jääskeläinen type = PKCS11_CKK_EC; 82802b16804SVesa Jääskeläinen break; 82986922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 83086922832SVesa Jääskeläinen class = template_class; 83186922832SVesa Jääskeläinen type = PKCS11_CKK_RSA; 83286922832SVesa Jääskeläinen break; 833013934d8SVesa Jääskeläinen default: 834013934d8SVesa Jääskeläinen TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 835013934d8SVesa Jääskeläinen } 836013934d8SVesa Jääskeläinen } 837013934d8SVesa Jääskeläinen 838013934d8SVesa Jääskeläinen /* 8392d25a9bcSRuchika Gupta * Check and remove duplicates if any and create a new temporary 8402d25a9bcSRuchika Gupta * template 8412d25a9bcSRuchika Gupta */ 842dcad3409SRuchika Gupta rc = sanitize_client_object(&temp, template, template_size, class, 843dcad3409SRuchika Gupta type); 844dcad3409SRuchika Gupta if (rc) 845dcad3409SRuchika Gupta goto out; 846dcad3409SRuchika Gupta 847dcad3409SRuchika Gupta /* 8482d25a9bcSRuchika Gupta * For function type modify and copy return the created template 8492d25a9bcSRuchika Gupta * from here. Rest of the code below is for creating objects 8502d25a9bcSRuchika Gupta * or generating keys. 8512d25a9bcSRuchika Gupta */ 8522d25a9bcSRuchika Gupta switch (function) { 8532d25a9bcSRuchika Gupta case PKCS11_FUNCTION_MODIFY: 8542d25a9bcSRuchika Gupta case PKCS11_FUNCTION_COPY: 8552d25a9bcSRuchika Gupta *out = temp; 8562d25a9bcSRuchika Gupta return rc; 857e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 858e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 859e3f0cb56SRuchika Gupta if (function == PKCS11_FUNCTION_UNWRAP) 860e3f0cb56SRuchika Gupta indirect_template = PKCS11_CKA_UNWRAP_TEMPLATE; 861e3f0cb56SRuchika Gupta else 862e3f0cb56SRuchika Gupta indirect_template = PKCS11_CKA_DERIVE_TEMPLATE; 863e3f0cb56SRuchika Gupta 864e3f0cb56SRuchika Gupta rc = get_attribute_ptr(parent, indirect_template, 865e3f0cb56SRuchika Gupta (void *)&req_attrs, &size); 866e3f0cb56SRuchika Gupta if (rc == PKCS11_CKR_OK && size != 0) { 867e3f0cb56SRuchika Gupta rc = attributes_match_add_reference(&temp, req_attrs); 868e3f0cb56SRuchika Gupta if (rc) 869e3f0cb56SRuchika Gupta goto out; 870e3f0cb56SRuchika Gupta } 871e3f0cb56SRuchika Gupta break; 8722d25a9bcSRuchika Gupta default: 8732d25a9bcSRuchika Gupta break; 8742d25a9bcSRuchika Gupta } 8752d25a9bcSRuchika Gupta 8762d25a9bcSRuchika Gupta /* 877dcad3409SRuchika Gupta * Check if class and type in temp are consistent with the mechanism 878dcad3409SRuchika Gupta */ 879fa247a2aSRuchika Gupta switch (mecha) { 880fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 881fa247a2aSRuchika Gupta if (get_class(temp) != PKCS11_CKO_SECRET_KEY || 882fa247a2aSRuchika Gupta get_key_type(temp) != PKCS11_CKK_GENERIC_SECRET) { 883fa247a2aSRuchika Gupta rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 884fa247a2aSRuchika Gupta goto out; 885fa247a2aSRuchika Gupta } 886fa247a2aSRuchika Gupta break; 887fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 888fa247a2aSRuchika Gupta if (get_class(temp) != PKCS11_CKO_SECRET_KEY || 889fa247a2aSRuchika Gupta get_key_type(temp) != PKCS11_CKK_AES) { 890fa247a2aSRuchika Gupta rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 891fa247a2aSRuchika Gupta goto out; 892fa247a2aSRuchika Gupta } 893fa247a2aSRuchika Gupta break; 89402b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 89502b16804SVesa Jääskeläinen if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && 89602b16804SVesa Jääskeläinen get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || 89702b16804SVesa Jääskeläinen get_key_type(temp) != PKCS11_CKK_EC) { 89802b16804SVesa Jääskeläinen rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 89902b16804SVesa Jääskeläinen goto out; 90002b16804SVesa Jääskeläinen } 90102b16804SVesa Jääskeläinen break; 90286922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 90386922832SVesa Jääskeläinen if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && 90486922832SVesa Jääskeläinen get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || 90586922832SVesa Jääskeläinen get_key_type(temp) != PKCS11_CKK_RSA) { 90686922832SVesa Jääskeläinen rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 90786922832SVesa Jääskeläinen goto out; 90886922832SVesa Jääskeläinen } 90986922832SVesa Jääskeläinen break; 910fa247a2aSRuchika Gupta default: 911fa247a2aSRuchika Gupta break; 912fa247a2aSRuchika Gupta } 91363f89caaSJens Wiklander 91463f89caaSJens Wiklander if (!sanitize_consistent_class_and_type(temp)) { 91563f89caaSJens Wiklander EMSG("Inconsistent class/type"); 91663f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 91763f89caaSJens Wiklander goto out; 91863f89caaSJens Wiklander } 91963f89caaSJens Wiklander 920e3f0cb56SRuchika Gupta /* 921e3f0cb56SRuchika Gupta * TBD - Add a check to see if temp contains any attribute which 922e3f0cb56SRuchika Gupta * is not consistent with the object class or type and return error. 923e3f0cb56SRuchika Gupta * In current implementation such attributes are ignored and not 924e3f0cb56SRuchika Gupta * added to final object while PKCS#11 specification expects a 925e3f0cb56SRuchika Gupta * failure and an error code be returned. 926e3f0cb56SRuchika Gupta */ 927e3f0cb56SRuchika Gupta 92863f89caaSJens Wiklander switch (get_class(temp)) { 92963f89caaSJens Wiklander case PKCS11_CKO_DATA: 93063f89caaSJens Wiklander rc = create_data_attributes(&attrs, temp); 93163f89caaSJens Wiklander break; 93263f89caaSJens Wiklander case PKCS11_CKO_SECRET_KEY: 933196bcd93SRuchika Gupta rc = sanitize_symm_key_attributes(&temp, function); 934196bcd93SRuchika Gupta if (rc) 935196bcd93SRuchika Gupta goto out; 93663f89caaSJens Wiklander rc = create_symm_key_attributes(&attrs, temp); 93763f89caaSJens Wiklander break; 93863f89caaSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 939*9cf1afceSVesa Jääskeläinen rc = create_pub_key_attributes(&attrs, temp, function); 94063f89caaSJens Wiklander break; 94163f89caaSJens Wiklander case PKCS11_CKO_PRIVATE_KEY: 94263f89caaSJens Wiklander rc = create_priv_key_attributes(&attrs, temp); 94363f89caaSJens Wiklander break; 94463f89caaSJens Wiklander default: 94563f89caaSJens Wiklander DMSG("Invalid object class %#"PRIx32"/%s", 94663f89caaSJens Wiklander get_class(temp), id2str_class(get_class(temp))); 94763f89caaSJens Wiklander 94863f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 94963f89caaSJens Wiklander break; 95063f89caaSJens Wiklander } 95163f89caaSJens Wiklander if (rc) 95263f89caaSJens Wiklander goto out; 95363f89caaSJens Wiklander 95490c47fe2SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_LOCAL, NULL, NULL) != 955002f6b93SEtienne Carriere PKCS11_RV_NOT_FOUND) { 956002f6b93SEtienne Carriere rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 95763f89caaSJens Wiklander goto out; 958002f6b93SEtienne Carriere } 95963f89caaSJens Wiklander 96090c47fe2SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_KEY_GEN_MECHANISM, NULL, NULL) != 961002f6b93SEtienne Carriere PKCS11_RV_NOT_FOUND) { 962002f6b93SEtienne Carriere rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 96363f89caaSJens Wiklander goto out; 964002f6b93SEtienne Carriere } 96563f89caaSJens Wiklander 96663f89caaSJens Wiklander switch (function) { 967fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 968013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 969fa247a2aSRuchika Gupta local = PKCS11_TRUE; 970fa247a2aSRuchika Gupta break; 97163f89caaSJens Wiklander case PKCS11_FUNCTION_IMPORT: 97248799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 973e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 97463f89caaSJens Wiklander default: 97563f89caaSJens Wiklander local = PKCS11_FALSE; 97663f89caaSJens Wiklander break; 97763f89caaSJens Wiklander } 97863f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_LOCAL, &local, sizeof(local)); 97963f89caaSJens Wiklander if (rc) 98063f89caaSJens Wiklander goto out; 98163f89caaSJens Wiklander 98263f89caaSJens Wiklander switch (get_class(attrs)) { 98363f89caaSJens Wiklander case PKCS11_CKO_SECRET_KEY: 98463f89caaSJens Wiklander case PKCS11_CKO_PRIVATE_KEY: 98563f89caaSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 98663f89caaSJens Wiklander always_sensitive = PKCS11_FALSE; 98763f89caaSJens Wiklander never_extract = PKCS11_FALSE; 98863f89caaSJens Wiklander 989fa247a2aSRuchika Gupta switch (function) { 99048799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 99148799892SRuchika Gupta always_sensitive = 99248799892SRuchika Gupta get_bool(parent, PKCS11_CKA_ALWAYS_SENSITIVE) && 99348799892SRuchika Gupta get_bool(attrs, PKCS11_CKA_SENSITIVE); 99448799892SRuchika Gupta never_extract = 99548799892SRuchika Gupta get_bool(parent, PKCS11_CKA_NEVER_EXTRACTABLE) && 99648799892SRuchika Gupta !get_bool(attrs, PKCS11_CKA_EXTRACTABLE); 99748799892SRuchika Gupta break; 998e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 999e3f0cb56SRuchika Gupta always_sensitive = PKCS11_FALSE; 1000e3f0cb56SRuchika Gupta never_extract = PKCS11_FALSE; 1001e3f0cb56SRuchika Gupta extractable = PKCS11_TRUE; 1002e3f0cb56SRuchika Gupta 1003e3f0cb56SRuchika Gupta /* 1004e3f0cb56SRuchika Gupta * Check if template passed by user has CKA_EXTRACTABLE. 1005e3f0cb56SRuchika Gupta * If not, by default value of CKA_EXTRACTABLE is set as 1006e3f0cb56SRuchika Gupta * TRUE. 1007e3f0cb56SRuchika Gupta */ 1008e3f0cb56SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_EXTRACTABLE, 1009e3f0cb56SRuchika Gupta NULL, 1010e3f0cb56SRuchika Gupta NULL) == PKCS11_RV_NOT_FOUND) { 1011e3f0cb56SRuchika Gupta rc = set_attribute(&attrs, 1012e3f0cb56SRuchika Gupta PKCS11_CKA_EXTRACTABLE, 1013e3f0cb56SRuchika Gupta &extractable, 1014e3f0cb56SRuchika Gupta sizeof(extractable)); 1015e3f0cb56SRuchika Gupta if (rc) 1016e3f0cb56SRuchika Gupta goto out; 1017e3f0cb56SRuchika Gupta } 1018e3f0cb56SRuchika Gupta break; 1019fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 1020013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 1021fa247a2aSRuchika Gupta always_sensitive = get_bool(attrs, 1022fa247a2aSRuchika Gupta PKCS11_CKA_SENSITIVE); 1023fa247a2aSRuchika Gupta never_extract = !get_bool(attrs, 1024fa247a2aSRuchika Gupta PKCS11_CKA_EXTRACTABLE); 1025fa247a2aSRuchika Gupta break; 1026fa247a2aSRuchika Gupta default: 1027fa247a2aSRuchika Gupta break; 1028fa247a2aSRuchika Gupta } 1029fa247a2aSRuchika Gupta 103063f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_ALWAYS_SENSITIVE, 103163f89caaSJens Wiklander &always_sensitive, sizeof(always_sensitive)); 103263f89caaSJens Wiklander if (rc) 103363f89caaSJens Wiklander goto out; 103463f89caaSJens Wiklander 103563f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_NEVER_EXTRACTABLE, 103663f89caaSJens Wiklander &never_extract, sizeof(never_extract)); 103763f89caaSJens Wiklander if (rc) 103863f89caaSJens Wiklander goto out; 103963f89caaSJens Wiklander 104063f89caaSJens Wiklander /* Keys mandate attribute PKCS11_CKA_KEY_GEN_MECHANISM */ 1041fa247a2aSRuchika Gupta if (local) 1042fa247a2aSRuchika Gupta mechanism_id = mecha; 1043fa247a2aSRuchika Gupta else 104463f89caaSJens Wiklander mechanism_id = PKCS11_CK_UNAVAILABLE_INFORMATION; 1045fa247a2aSRuchika Gupta 104663f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_KEY_GEN_MECHANISM, 104763f89caaSJens Wiklander &mechanism_id, sizeof(mechanism_id)); 104863f89caaSJens Wiklander if (rc) 104963f89caaSJens Wiklander goto out; 105063f89caaSJens Wiklander break; 105163f89caaSJens Wiklander 105263f89caaSJens Wiklander default: 105363f89caaSJens Wiklander break; 105463f89caaSJens Wiklander } 105563f89caaSJens Wiklander 105663f89caaSJens Wiklander *out = attrs; 105763f89caaSJens Wiklander 105863f89caaSJens Wiklander #ifdef DEBUG 105963f89caaSJens Wiklander trace_attributes("object", attrs); 106063f89caaSJens Wiklander #endif 106163f89caaSJens Wiklander 106263f89caaSJens Wiklander out: 106363f89caaSJens Wiklander TEE_Free(temp); 106463f89caaSJens Wiklander if (rc) 106563f89caaSJens Wiklander TEE_Free(attrs); 106663f89caaSJens Wiklander 106763f89caaSJens Wiklander return rc; 106863f89caaSJens Wiklander } 106963f89caaSJens Wiklander 107063f89caaSJens Wiklander static enum pkcs11_rc check_attrs_misc_integrity(struct obj_attrs *head) 107163f89caaSJens Wiklander { 107263f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_NEVER_EXTRACTABLE) && 107363f89caaSJens Wiklander get_bool(head, PKCS11_CKA_EXTRACTABLE)) { 107463f89caaSJens Wiklander DMSG("Never/Extractable attributes mismatch %d/%d", 107563f89caaSJens Wiklander get_bool(head, PKCS11_CKA_NEVER_EXTRACTABLE), 107663f89caaSJens Wiklander get_bool(head, PKCS11_CKA_EXTRACTABLE)); 107763f89caaSJens Wiklander 107863f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 107963f89caaSJens Wiklander } 108063f89caaSJens Wiklander 108163f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_ALWAYS_SENSITIVE) && 108263f89caaSJens Wiklander !get_bool(head, PKCS11_CKA_SENSITIVE)) { 108363f89caaSJens Wiklander DMSG("Sensitive/always attributes mismatch %d/%d", 108463f89caaSJens Wiklander get_bool(head, PKCS11_CKA_SENSITIVE), 108563f89caaSJens Wiklander get_bool(head, PKCS11_CKA_ALWAYS_SENSITIVE)); 108663f89caaSJens Wiklander 108763f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 108863f89caaSJens Wiklander } 108963f89caaSJens Wiklander 109063f89caaSJens Wiklander return PKCS11_CKR_OK; 109163f89caaSJens Wiklander } 109263f89caaSJens Wiklander 109389735787SRuchika Gupta bool object_is_private(struct obj_attrs *head) 109489735787SRuchika Gupta { 109565fb9092SVesa Jääskeläinen return get_bool(head, PKCS11_CKA_PRIVATE); 109689735787SRuchika Gupta } 109789735787SRuchika Gupta 10982d25a9bcSRuchika Gupta bool object_is_token(struct obj_attrs *head) 10992d25a9bcSRuchika Gupta { 11002d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_TOKEN); 11012d25a9bcSRuchika Gupta } 11022d25a9bcSRuchika Gupta 11032d25a9bcSRuchika Gupta bool object_is_modifiable(struct obj_attrs *head) 11042d25a9bcSRuchika Gupta { 11052d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_MODIFIABLE); 11062d25a9bcSRuchika Gupta } 11072d25a9bcSRuchika Gupta 11082d25a9bcSRuchika Gupta bool object_is_copyable(struct obj_attrs *head) 11092d25a9bcSRuchika Gupta { 11102d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_COPYABLE); 11112d25a9bcSRuchika Gupta } 11122d25a9bcSRuchika Gupta 111363f89caaSJens Wiklander /* 1114512cbf1dSJens Wiklander * Check access to object against authentication to token 1115512cbf1dSJens Wiklander */ 1116512cbf1dSJens Wiklander enum pkcs11_rc check_access_attrs_against_token(struct pkcs11_session *session, 1117512cbf1dSJens Wiklander struct obj_attrs *head) 1118512cbf1dSJens Wiklander { 1119512cbf1dSJens Wiklander bool private = true; 1120512cbf1dSJens Wiklander 1121512cbf1dSJens Wiklander switch (get_class(head)) { 1122512cbf1dSJens Wiklander case PKCS11_CKO_SECRET_KEY: 112365fb9092SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1124512cbf1dSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 1125512cbf1dSJens Wiklander case PKCS11_CKO_DATA: 112665fb9092SVesa Jääskeläinen private = object_is_private(head); 1127512cbf1dSJens Wiklander break; 1128512cbf1dSJens Wiklander default: 1129512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1130512cbf1dSJens Wiklander } 1131512cbf1dSJens Wiklander 11325db0fef4SRuchika Gupta if (private && (pkcs11_session_is_public(session) || 11335db0fef4SRuchika Gupta pkcs11_session_is_so(session))) { 11345db0fef4SRuchika Gupta DMSG("Private object access from a public or SO session"); 1135512cbf1dSJens Wiklander 113612f1ba86SRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 1137512cbf1dSJens Wiklander } 1138512cbf1dSJens Wiklander 1139512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1140512cbf1dSJens Wiklander } 1141512cbf1dSJens Wiklander 1142512cbf1dSJens Wiklander /* 114363f89caaSJens Wiklander * Check the attributes of a to-be-created object matches the token state 114463f89caaSJens Wiklander */ 114563f89caaSJens Wiklander enum pkcs11_rc check_created_attrs_against_token(struct pkcs11_session *session, 114663f89caaSJens Wiklander struct obj_attrs *head) 114763f89caaSJens Wiklander { 114863f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 114963f89caaSJens Wiklander 115063f89caaSJens Wiklander rc = check_attrs_misc_integrity(head); 115163f89caaSJens Wiklander if (rc) 115263f89caaSJens Wiklander return rc; 115363f89caaSJens Wiklander 115463f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_TRUSTED) && 115563f89caaSJens Wiklander !pkcs11_session_is_so(session)) { 115663f89caaSJens Wiklander DMSG("Can't create trusted object"); 115763f89caaSJens Wiklander 115863f89caaSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 115963f89caaSJens Wiklander } 116063f89caaSJens Wiklander 116163f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_TOKEN) && 116263f89caaSJens Wiklander !pkcs11_session_is_read_write(session)) { 116363f89caaSJens Wiklander DMSG("Can't create persistent object"); 116463f89caaSJens Wiklander 116563f89caaSJens Wiklander return PKCS11_CKR_SESSION_READ_ONLY; 116663f89caaSJens Wiklander } 116763f89caaSJens Wiklander 116863f89caaSJens Wiklander /* 116963f89caaSJens Wiklander * TODO: START_DATE and END_DATE: complies with current time? 117063f89caaSJens Wiklander */ 117163f89caaSJens Wiklander return PKCS11_CKR_OK; 117263f89caaSJens Wiklander } 117363f89caaSJens Wiklander 117463f89caaSJens Wiklander #define DMSG_BAD_BBOOL(attr, proc, head) \ 117563f89caaSJens Wiklander do { \ 117663f89caaSJens Wiklander uint32_t __maybe_unused _attr = (attr); \ 117763f89caaSJens Wiklander uint8_t __maybe_unused _bvalue = 0; \ 117863f89caaSJens Wiklander enum pkcs11_rc __maybe_unused _rc = PKCS11_CKR_OK; \ 117963f89caaSJens Wiklander \ 118063f89caaSJens Wiklander _rc = get_attribute((head), _attr, &_bvalue, NULL); \ 118163f89caaSJens Wiklander DMSG("%s issue for %s: %sfound, value %"PRIu8, \ 118263f89caaSJens Wiklander id2str_attr(_attr), id2str_proc((proc)), \ 118363f89caaSJens Wiklander _rc ? "not " : "", _bvalue); \ 118463f89caaSJens Wiklander } while (0) 118563f89caaSJens Wiklander 118663f89caaSJens Wiklander static bool __maybe_unused check_attr_bval(uint32_t proc_id __maybe_unused, 118763f89caaSJens Wiklander struct obj_attrs *head, 118863f89caaSJens Wiklander uint32_t attribute, bool val) 118963f89caaSJens Wiklander { 119063f89caaSJens Wiklander uint8_t bbool = 0; 119163f89caaSJens Wiklander uint32_t sz = sizeof(bbool); 119263f89caaSJens Wiklander 119363f89caaSJens Wiklander if (!get_attribute(head, attribute, &bbool, &sz) && !!bbool == val) 119463f89caaSJens Wiklander return true; 119563f89caaSJens Wiklander 119663f89caaSJens Wiklander DMSG_BAD_BBOOL(attribute, proc_id, head); 119763f89caaSJens Wiklander return false; 119863f89caaSJens Wiklander } 119963f89caaSJens Wiklander 120063f89caaSJens Wiklander /* 120163f89caaSJens Wiklander * Check the attributes of a new secret match the processing/mechanism 120263f89caaSJens Wiklander * used to create it. 120363f89caaSJens Wiklander * 120463f89caaSJens Wiklander * @proc_id - PKCS11_CKM_xxx 120563f89caaSJens Wiklander * @head - head of the attributes of the to-be-created object. 120663f89caaSJens Wiklander */ 120763f89caaSJens Wiklander enum pkcs11_rc check_created_attrs_against_processing(uint32_t proc_id, 120863f89caaSJens Wiklander struct obj_attrs *head) 120963f89caaSJens Wiklander { 121063f89caaSJens Wiklander /* 121163f89caaSJens Wiklander * Processings that do not create secrets are not expected to call 121263f89caaSJens Wiklander * this function which would panic. 121363f89caaSJens Wiklander */ 121463f89caaSJens Wiklander switch (proc_id) { 121563f89caaSJens Wiklander case PKCS11_PROCESSING_IMPORT: 1216e3f0cb56SRuchika Gupta case PKCS11_CKM_AES_ECB: 1217e3f0cb56SRuchika Gupta case PKCS11_CKM_AES_CBC: 121848799892SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 121948799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 122063f89caaSJens Wiklander assert(check_attr_bval(proc_id, head, PKCS11_CKA_LOCAL, false)); 122163f89caaSJens Wiklander break; 1222fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1223fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 122402b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 122586922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 1226fa247a2aSRuchika Gupta assert(check_attr_bval(proc_id, head, PKCS11_CKA_LOCAL, true)); 1227fa247a2aSRuchika Gupta break; 122863f89caaSJens Wiklander default: 122963f89caaSJens Wiklander TEE_Panic(proc_id); 123063f89caaSJens Wiklander break; 123163f89caaSJens Wiklander } 123263f89caaSJens Wiklander 1233fa247a2aSRuchika Gupta switch (proc_id) { 1234fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1235fa247a2aSRuchika Gupta assert(get_key_type(head) == PKCS11_CKK_GENERIC_SECRET); 1236fa247a2aSRuchika Gupta break; 1237fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 1238fa247a2aSRuchika Gupta assert(get_key_type(head) == PKCS11_CKK_AES); 1239fa247a2aSRuchika Gupta break; 124002b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 124102b16804SVesa Jääskeläinen assert(get_key_type(head) == PKCS11_CKK_EC); 124202b16804SVesa Jääskeläinen break; 124386922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 124486922832SVesa Jääskeläinen assert(get_key_type(head) == PKCS11_CKK_RSA); 124586922832SVesa Jääskeläinen break; 1246fa247a2aSRuchika Gupta case PKCS11_PROCESSING_IMPORT: 1247fa247a2aSRuchika Gupta default: 1248fa247a2aSRuchika Gupta break; 1249fa247a2aSRuchika Gupta } 1250fa247a2aSRuchika Gupta 125163f89caaSJens Wiklander return PKCS11_CKR_OK; 125263f89caaSJens Wiklander } 1253512cbf1dSJens Wiklander 12542d0cd829SRuchika Gupta /* Return min and max key size supported for a key_type in bytes */ 1255512cbf1dSJens Wiklander static void get_key_min_max_sizes(enum pkcs11_key_type key_type, 1256512cbf1dSJens Wiklander uint32_t *min_key_size, 1257512cbf1dSJens Wiklander uint32_t *max_key_size) 1258512cbf1dSJens Wiklander { 1259512cbf1dSJens Wiklander enum pkcs11_mechanism_id mechanism = PKCS11_CKM_UNDEFINED_ID; 1260512cbf1dSJens Wiklander 1261512cbf1dSJens Wiklander switch (key_type) { 1262fa247a2aSRuchika Gupta case PKCS11_CKK_GENERIC_SECRET: 1263fa247a2aSRuchika Gupta mechanism = PKCS11_CKM_GENERIC_SECRET_KEY_GEN; 1264fa247a2aSRuchika Gupta break; 1265512cbf1dSJens Wiklander case PKCS11_CKK_AES: 1266512cbf1dSJens Wiklander mechanism = PKCS11_CKM_AES_KEY_GEN; 1267512cbf1dSJens Wiklander break; 12681f45c9cfSRuchika Gupta case PKCS11_CKK_MD5_HMAC: 12691f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_MD5_HMAC; 12701f45c9cfSRuchika Gupta break; 12711f45c9cfSRuchika Gupta case PKCS11_CKK_SHA_1_HMAC: 12721f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA_1_HMAC; 12731f45c9cfSRuchika Gupta break; 12741f45c9cfSRuchika Gupta case PKCS11_CKK_SHA224_HMAC: 12751f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA224_HMAC; 12761f45c9cfSRuchika Gupta break; 1277a339a354SEtienne Carriere case PKCS11_CKK_SHA256_HMAC: 1278a339a354SEtienne Carriere mechanism = PKCS11_CKM_SHA256_HMAC; 1279a339a354SEtienne Carriere break; 12801f45c9cfSRuchika Gupta case PKCS11_CKK_SHA384_HMAC: 12811f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA384_HMAC; 12821f45c9cfSRuchika Gupta break; 12831f45c9cfSRuchika Gupta case PKCS11_CKK_SHA512_HMAC: 12841f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA512_HMAC; 12851f45c9cfSRuchika Gupta break; 1286db28c542SVesa Jääskeläinen case PKCS11_CKK_EC: 1287db28c542SVesa Jääskeläinen mechanism = PKCS11_CKM_EC_KEY_PAIR_GEN; 1288db28c542SVesa Jääskeläinen break; 128986922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 129086922832SVesa Jääskeläinen mechanism = PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN; 129186922832SVesa Jääskeläinen break; 1292512cbf1dSJens Wiklander default: 1293512cbf1dSJens Wiklander TEE_Panic(key_type); 1294512cbf1dSJens Wiklander break; 1295512cbf1dSJens Wiklander } 1296512cbf1dSJens Wiklander 12972d0cd829SRuchika Gupta mechanism_supported_key_sizes_bytes(mechanism, min_key_size, 1298512cbf1dSJens Wiklander max_key_size); 1299512cbf1dSJens Wiklander } 1300512cbf1dSJens Wiklander 1301512cbf1dSJens Wiklander enum pkcs11_rc check_created_attrs(struct obj_attrs *key1, 1302512cbf1dSJens Wiklander struct obj_attrs *key2) 1303512cbf1dSJens Wiklander { 1304512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 1305512cbf1dSJens Wiklander struct obj_attrs *secret = NULL; 1306013934d8SVesa Jääskeläinen struct obj_attrs *private = NULL; 1307013934d8SVesa Jääskeläinen struct obj_attrs *public = NULL; 1308512cbf1dSJens Wiklander uint32_t max_key_size = 0; 1309512cbf1dSJens Wiklander uint32_t min_key_size = 0; 1310512cbf1dSJens Wiklander uint32_t key_length = 0; 1311512cbf1dSJens Wiklander 1312512cbf1dSJens Wiklander switch (get_class(key1)) { 1313512cbf1dSJens Wiklander case PKCS11_CKO_SECRET_KEY: 1314512cbf1dSJens Wiklander secret = key1; 1315512cbf1dSJens Wiklander break; 1316013934d8SVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 1317013934d8SVesa Jääskeläinen public = key1; 1318013934d8SVesa Jääskeläinen break; 1319013934d8SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1320013934d8SVesa Jääskeläinen private = key1; 1321013934d8SVesa Jääskeläinen break; 1322512cbf1dSJens Wiklander default: 1323512cbf1dSJens Wiklander return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 1324512cbf1dSJens Wiklander } 1325512cbf1dSJens Wiklander 1326013934d8SVesa Jääskeläinen if (key2) { 1327013934d8SVesa Jääskeläinen switch (get_class(key2)) { 1328013934d8SVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 1329013934d8SVesa Jääskeläinen public = key2; 1330013934d8SVesa Jääskeläinen if (private == key1) 1331013934d8SVesa Jääskeläinen break; 1332013934d8SVesa Jääskeläinen 1333013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1334013934d8SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1335013934d8SVesa Jääskeläinen private = key2; 1336013934d8SVesa Jääskeläinen if (public == key1) 1337013934d8SVesa Jääskeläinen break; 1338013934d8SVesa Jääskeläinen 1339013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1340013934d8SVesa Jääskeläinen default: 1341512cbf1dSJens Wiklander return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 1342013934d8SVesa Jääskeläinen } 1343013934d8SVesa Jääskeläinen 1344013934d8SVesa Jääskeläinen if (get_key_type(private) != get_key_type(public)) 1345013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1346013934d8SVesa Jääskeläinen } 1347512cbf1dSJens Wiklander 1348512cbf1dSJens Wiklander if (secret) { 1349512cbf1dSJens Wiklander switch (get_key_type(secret)) { 1350512cbf1dSJens Wiklander case PKCS11_CKK_AES: 1351512cbf1dSJens Wiklander case PKCS11_CKK_GENERIC_SECRET: 1352512cbf1dSJens Wiklander case PKCS11_CKK_MD5_HMAC: 1353512cbf1dSJens Wiklander case PKCS11_CKK_SHA_1_HMAC: 1354512cbf1dSJens Wiklander case PKCS11_CKK_SHA224_HMAC: 1355512cbf1dSJens Wiklander case PKCS11_CKK_SHA256_HMAC: 1356512cbf1dSJens Wiklander case PKCS11_CKK_SHA384_HMAC: 1357512cbf1dSJens Wiklander case PKCS11_CKK_SHA512_HMAC: 1358512cbf1dSJens Wiklander break; 1359512cbf1dSJens Wiklander default: 1360512cbf1dSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1361512cbf1dSJens Wiklander } 1362512cbf1dSJens Wiklander 1363512cbf1dSJens Wiklander /* Get key size */ 1364512cbf1dSJens Wiklander rc = get_u32_attribute(secret, PKCS11_CKA_VALUE_LEN, 1365512cbf1dSJens Wiklander &key_length); 1366512cbf1dSJens Wiklander if (rc) 1367d1d44372SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCOMPLETE; 1368512cbf1dSJens Wiklander } 1369013934d8SVesa Jääskeläinen if (public) { 1370013934d8SVesa Jääskeläinen switch (get_key_type(public)) { 137186922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 137286922832SVesa Jääskeläinen /* Get key size */ 137386922832SVesa Jääskeläinen rc = get_u32_attribute(public, PKCS11_CKA_MODULUS_BITS, 137486922832SVesa Jääskeläinen &key_length); 137586922832SVesa Jääskeläinen if (rc) 137686922832SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 137786922832SVesa Jääskeläinen key_length = ROUNDUP(key_length, 8) / 8; 137886922832SVesa Jääskeläinen break; 137902b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 138002b16804SVesa Jääskeläinen break; 1381013934d8SVesa Jääskeläinen default: 1382013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1383013934d8SVesa Jääskeläinen } 1384013934d8SVesa Jääskeläinen } 1385013934d8SVesa Jääskeläinen if (private) { 1386013934d8SVesa Jääskeläinen switch (get_key_type(private)) { 138786922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 138802b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 138902b16804SVesa Jääskeläinen break; 1390013934d8SVesa Jääskeläinen default: 1391013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1392013934d8SVesa Jääskeläinen } 1393013934d8SVesa Jääskeläinen } 1394512cbf1dSJens Wiklander 139502b16804SVesa Jääskeläinen /* 139602b16804SVesa Jääskeläinen * Check key size for symmetric keys and RSA keys 139702b16804SVesa Jääskeläinen * EC is bound to domains, no need to check here. 139802b16804SVesa Jääskeläinen */ 139902b16804SVesa Jääskeläinen switch (get_key_type(key1)) { 140002b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 140102b16804SVesa Jääskeläinen return PKCS11_CKR_OK; 140202b16804SVesa Jääskeläinen default: 140302b16804SVesa Jääskeläinen break; 140402b16804SVesa Jääskeläinen } 140502b16804SVesa Jääskeläinen 1406512cbf1dSJens Wiklander get_key_min_max_sizes(get_key_type(key1), &min_key_size, &max_key_size); 1407512cbf1dSJens Wiklander if (key_length < min_key_size || key_length > max_key_size) { 1408512cbf1dSJens Wiklander EMSG("Length %"PRIu32" vs range [%"PRIu32" %"PRIu32"]", 1409512cbf1dSJens Wiklander key_length, min_key_size, max_key_size); 1410512cbf1dSJens Wiklander 1411512cbf1dSJens Wiklander return PKCS11_CKR_KEY_SIZE_RANGE; 1412512cbf1dSJens Wiklander } 1413512cbf1dSJens Wiklander 141449ed60abSRuchika Gupta if (secret && get_key_type(secret) == PKCS11_CKK_AES) { 141549ed60abSRuchika Gupta if (key_length != 16 && key_length != 24 && key_length != 32) 141649ed60abSRuchika Gupta return PKCS11_CKR_KEY_SIZE_RANGE; 141749ed60abSRuchika Gupta } 141849ed60abSRuchika Gupta 1419512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1420512cbf1dSJens Wiklander } 1421512cbf1dSJens Wiklander 1422512cbf1dSJens Wiklander /* Check processing ID against attribute ALLOWED_MECHANISMS if any */ 1423512cbf1dSJens Wiklander static bool parent_key_complies_allowed_processings(uint32_t proc_id, 1424512cbf1dSJens Wiklander struct obj_attrs *head) 1425512cbf1dSJens Wiklander { 1426512cbf1dSJens Wiklander char *attr = NULL; 1427512cbf1dSJens Wiklander uint32_t size = 0; 1428512cbf1dSJens Wiklander uint32_t proc = 0; 1429512cbf1dSJens Wiklander size_t count = 0; 14306a760c9eSEtienne Carriere enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 1431512cbf1dSJens Wiklander 14326a760c9eSEtienne Carriere rc = get_attribute_ptr(head, PKCS11_CKA_ALLOWED_MECHANISMS, 14336a760c9eSEtienne Carriere (void *)&attr, &size); 14346a760c9eSEtienne Carriere if (rc == PKCS11_RV_NOT_FOUND) 1435512cbf1dSJens Wiklander return true; 14366a760c9eSEtienne Carriere if (rc) { 14376a760c9eSEtienne Carriere EMSG("unexpected attributes state"); 14386a760c9eSEtienne Carriere TEE_Panic(TEE_ERROR_BAD_STATE); 1439512cbf1dSJens Wiklander } 1440512cbf1dSJens Wiklander 1441512cbf1dSJens Wiklander for (count = size / sizeof(uint32_t); count; count--) { 1442512cbf1dSJens Wiklander TEE_MemMove(&proc, attr, sizeof(uint32_t)); 1443512cbf1dSJens Wiklander attr += sizeof(uint32_t); 1444512cbf1dSJens Wiklander 1445512cbf1dSJens Wiklander if (proc == proc_id) 1446512cbf1dSJens Wiklander return true; 1447512cbf1dSJens Wiklander } 1448512cbf1dSJens Wiklander 1449512cbf1dSJens Wiklander DMSG("can't find %s in allowed list", id2str_proc(proc_id)); 1450512cbf1dSJens Wiklander return false; 1451512cbf1dSJens Wiklander } 1452512cbf1dSJens Wiklander 1453512cbf1dSJens Wiklander static enum pkcs11_attr_id func_to_attr(enum processing_func func) 1454512cbf1dSJens Wiklander { 1455512cbf1dSJens Wiklander switch (func) { 1456512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 1457512cbf1dSJens Wiklander return PKCS11_CKA_ENCRYPT; 1458512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 1459512cbf1dSJens Wiklander return PKCS11_CKA_DECRYPT; 1460512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN: 1461512cbf1dSJens Wiklander return PKCS11_CKA_SIGN; 1462512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY: 1463512cbf1dSJens Wiklander return PKCS11_CKA_VERIFY; 1464512cbf1dSJens Wiklander case PKCS11_FUNCTION_WRAP: 1465512cbf1dSJens Wiklander return PKCS11_CKA_WRAP; 1466512cbf1dSJens Wiklander case PKCS11_FUNCTION_UNWRAP: 1467512cbf1dSJens Wiklander return PKCS11_CKA_UNWRAP; 1468512cbf1dSJens Wiklander case PKCS11_FUNCTION_DERIVE: 1469512cbf1dSJens Wiklander return PKCS11_CKA_DERIVE; 1470512cbf1dSJens Wiklander default: 1471512cbf1dSJens Wiklander return PKCS11_CKA_UNDEFINED_ID; 1472512cbf1dSJens Wiklander } 1473512cbf1dSJens Wiklander } 1474512cbf1dSJens Wiklander 1475512cbf1dSJens Wiklander enum pkcs11_rc 1476512cbf1dSJens Wiklander check_parent_attrs_against_processing(enum pkcs11_mechanism_id proc_id, 1477512cbf1dSJens Wiklander enum processing_func function, 1478512cbf1dSJens Wiklander struct obj_attrs *head) 1479512cbf1dSJens Wiklander { 1480512cbf1dSJens Wiklander enum pkcs11_class_id key_class = get_class(head); 1481512cbf1dSJens Wiklander enum pkcs11_key_type key_type = get_key_type(head); 1482512cbf1dSJens Wiklander enum pkcs11_attr_id attr = func_to_attr(function); 1483512cbf1dSJens Wiklander 1484512cbf1dSJens Wiklander if (!get_bool(head, attr)) { 1485512cbf1dSJens Wiklander DMSG("%s not permitted", id2str_attr(attr)); 1486512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1487512cbf1dSJens Wiklander } 1488512cbf1dSJens Wiklander 1489512cbf1dSJens Wiklander /* Check processing complies with parent key family */ 1490512cbf1dSJens Wiklander switch (proc_id) { 1491512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 1492512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 1493512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 1494512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 1495512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 1496512cbf1dSJens Wiklander if (key_class == PKCS11_CKO_SECRET_KEY && 1497512cbf1dSJens Wiklander key_type == PKCS11_CKK_AES) 1498512cbf1dSJens Wiklander break; 1499512cbf1dSJens Wiklander 1500512cbf1dSJens Wiklander DMSG("%s invalid key %s/%s", id2str_proc(proc_id), 1501512cbf1dSJens Wiklander id2str_class(key_class), id2str_key_type(key_type)); 1502512cbf1dSJens Wiklander 15035f80f270SRuchika Gupta if (function == PKCS11_FUNCTION_WRAP) 15045f80f270SRuchika Gupta return PKCS11_CKR_WRAPPING_KEY_TYPE_INCONSISTENT; 1505e3f0cb56SRuchika Gupta else if (function == PKCS11_FUNCTION_UNWRAP) 1506e3f0cb56SRuchika Gupta return PKCS11_CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT; 15075f80f270SRuchika Gupta else 1508512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1509512cbf1dSJens Wiklander 1510c3033708SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 1511c3033708SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 1512c3033708SRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY && 1513c3033708SRuchika Gupta key_type != PKCS11_CKK_AES) 1514c3033708SRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1515c3033708SRuchika Gupta 1516c3033708SRuchika Gupta if (get_bool(head, PKCS11_CKA_ENCRYPT)) { 1517c3033708SRuchika Gupta /* 1518c3033708SRuchika Gupta * Intentionally refuse to proceed despite 1519c3033708SRuchika Gupta * PKCS#11 specifications v2.40 and v3.0 not expecting 1520c3033708SRuchika Gupta * this behavior to avoid potential security issue 1521c3033708SRuchika Gupta * where keys derived by these mechanisms can be 1522c3033708SRuchika Gupta * revealed by doing data encryption using parent key. 1523c3033708SRuchika Gupta */ 1524c3033708SRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED; 1525c3033708SRuchika Gupta } 1526c3033708SRuchika Gupta 1527c3033708SRuchika Gupta break; 1528689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 1529689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 1530689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 1531689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 1532689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 1533689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 1534689f4e5bSRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY) 1535689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1536689f4e5bSRuchika Gupta 1537689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_GENERIC_SECRET) 1538689f4e5bSRuchika Gupta break; 1539689f4e5bSRuchika Gupta 1540689f4e5bSRuchika Gupta switch (proc_id) { 1541689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 1542689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_MD5_HMAC) 1543689f4e5bSRuchika Gupta break; 1544689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1545689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 1546689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA_1_HMAC) 1547689f4e5bSRuchika Gupta break; 1548689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1549689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 1550689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA224_HMAC) 1551689f4e5bSRuchika Gupta break; 1552689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1553689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 1554689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA256_HMAC) 1555689f4e5bSRuchika Gupta break; 1556689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1557689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 1558689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA384_HMAC) 1559689f4e5bSRuchika Gupta break; 1560689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1561689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 1562689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA512_HMAC) 1563689f4e5bSRuchika Gupta break; 1564689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1565689f4e5bSRuchika Gupta default: 1566689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1567689f4e5bSRuchika Gupta } 1568689f4e5bSRuchika Gupta break; 1569689f4e5bSRuchika Gupta 1570fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 1571fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 1572fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 1573fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 1574fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 1575fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 1576fb279d8bSVesa Jääskeläinen if (key_type != PKCS11_CKK_EC) { 1577fb279d8bSVesa Jääskeläinen EMSG("Invalid key %s for mechanism %s", 1578fb279d8bSVesa Jääskeläinen id2str_type(key_type, key_class), 1579fb279d8bSVesa Jääskeläinen id2str_proc(proc_id)); 1580fb279d8bSVesa Jääskeläinen 1581fb279d8bSVesa Jääskeläinen return PKCS11_CKR_KEY_TYPE_INCONSISTENT; 1582fb279d8bSVesa Jääskeläinen } 1583fb279d8bSVesa Jääskeläinen if (key_class != PKCS11_CKO_PUBLIC_KEY && 1584fb279d8bSVesa Jääskeläinen key_class != PKCS11_CKO_PRIVATE_KEY) { 1585fb279d8bSVesa Jääskeläinen EMSG("Invalid key class for mechanism %s", 1586fb279d8bSVesa Jääskeläinen id2str_proc(proc_id)); 1587fb279d8bSVesa Jääskeläinen 1588fb279d8bSVesa Jääskeläinen return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1589fb279d8bSVesa Jääskeläinen } 1590fb279d8bSVesa Jääskeläinen break; 15910442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 15920442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 15930442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 15940442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 15950442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 15960442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 15970442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 1598dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 1599d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 1600d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 1601d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 1602d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 1603d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 1604d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 16050442c956SVesa Jääskeläinen if (key_type != PKCS11_CKK_RSA) { 16060442c956SVesa Jääskeläinen EMSG("Invalid key %s for mechanism %s", 16070442c956SVesa Jääskeläinen id2str_type(key_type, key_class), 16080442c956SVesa Jääskeläinen id2str_proc(proc_id)); 16090442c956SVesa Jääskeläinen 16100442c956SVesa Jääskeläinen return PKCS11_CKR_KEY_TYPE_INCONSISTENT; 16110442c956SVesa Jääskeläinen } 16120442c956SVesa Jääskeläinen if (key_class != PKCS11_CKO_PUBLIC_KEY && 16130442c956SVesa Jääskeläinen key_class != PKCS11_CKO_PRIVATE_KEY) { 16140442c956SVesa Jääskeläinen EMSG("Invalid key class for mechanism %s", 16150442c956SVesa Jääskeläinen id2str_proc(proc_id)); 16160442c956SVesa Jääskeläinen 16170442c956SVesa Jääskeläinen return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 16180442c956SVesa Jääskeläinen } 16190442c956SVesa Jääskeläinen break; 1620512cbf1dSJens Wiklander default: 1621512cbf1dSJens Wiklander DMSG("Invalid processing %#"PRIx32"/%s", proc_id, 1622512cbf1dSJens Wiklander id2str_proc(proc_id)); 1623512cbf1dSJens Wiklander 1624512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_INVALID; 1625512cbf1dSJens Wiklander } 1626512cbf1dSJens Wiklander 1627512cbf1dSJens Wiklander if (!parent_key_complies_allowed_processings(proc_id, head)) { 1628512cbf1dSJens Wiklander DMSG("Allowed mechanism failed"); 1629512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1630512cbf1dSJens Wiklander } 1631512cbf1dSJens Wiklander 1632512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1633512cbf1dSJens Wiklander } 1634783c1515SRuchika Gupta 1635783c1515SRuchika Gupta bool attribute_is_exportable(struct pkcs11_attribute_head *req_attr, 1636783c1515SRuchika Gupta struct pkcs11_object *obj) 1637783c1515SRuchika Gupta { 1638783c1515SRuchika Gupta uint8_t boolval = 0; 1639783c1515SRuchika Gupta uint32_t boolsize = 0; 1640783c1515SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 1641783c1515SRuchika Gupta enum pkcs11_class_id key_class = get_class(obj->attributes); 1642783c1515SRuchika Gupta 1643783c1515SRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY && 1644783c1515SRuchika Gupta key_class != PKCS11_CKO_PRIVATE_KEY) 1645783c1515SRuchika Gupta return true; 1646783c1515SRuchika Gupta 1647783c1515SRuchika Gupta switch (req_attr->id) { 1648783c1515SRuchika Gupta case PKCS11_CKA_PRIVATE_EXPONENT: 1649783c1515SRuchika Gupta case PKCS11_CKA_PRIME_1: 1650783c1515SRuchika Gupta case PKCS11_CKA_PRIME_2: 1651783c1515SRuchika Gupta case PKCS11_CKA_EXPONENT_1: 1652783c1515SRuchika Gupta case PKCS11_CKA_EXPONENT_2: 1653783c1515SRuchika Gupta case PKCS11_CKA_COEFFICIENT: 1654783c1515SRuchika Gupta case PKCS11_CKA_VALUE: 1655783c1515SRuchika Gupta boolsize = sizeof(boolval); 1656783c1515SRuchika Gupta rc = get_attribute(obj->attributes, PKCS11_CKA_EXTRACTABLE, 1657783c1515SRuchika Gupta &boolval, &boolsize); 1658783c1515SRuchika Gupta if (rc || boolval == PKCS11_FALSE) 1659783c1515SRuchika Gupta return false; 1660783c1515SRuchika Gupta 1661783c1515SRuchika Gupta boolsize = sizeof(boolval); 1662783c1515SRuchika Gupta rc = get_attribute(obj->attributes, PKCS11_CKA_SENSITIVE, 1663783c1515SRuchika Gupta &boolval, &boolsize); 1664783c1515SRuchika Gupta if (rc || boolval == PKCS11_TRUE) 1665783c1515SRuchika Gupta return false; 1666783c1515SRuchika Gupta break; 1667783c1515SRuchika Gupta default: 1668783c1515SRuchika Gupta break; 1669783c1515SRuchika Gupta } 1670783c1515SRuchika Gupta 1671783c1515SRuchika Gupta return true; 1672783c1515SRuchika Gupta } 16732d25a9bcSRuchika Gupta 16742d25a9bcSRuchika Gupta static bool attr_is_modifiable_any_key(struct pkcs11_attribute_head *attr) 16752d25a9bcSRuchika Gupta { 16762d25a9bcSRuchika Gupta switch (attr->id) { 16772d25a9bcSRuchika Gupta case PKCS11_CKA_ID: 16782d25a9bcSRuchika Gupta case PKCS11_CKA_START_DATE: 16792d25a9bcSRuchika Gupta case PKCS11_CKA_END_DATE: 16802d25a9bcSRuchika Gupta case PKCS11_CKA_DERIVE: 16812d25a9bcSRuchika Gupta return true; 16822d25a9bcSRuchika Gupta default: 16832d25a9bcSRuchika Gupta return false; 16842d25a9bcSRuchika Gupta } 16852d25a9bcSRuchika Gupta } 16862d25a9bcSRuchika Gupta 16872d25a9bcSRuchika Gupta static bool attr_is_modifiable_secret_key(struct pkcs11_attribute_head *attr, 16882d25a9bcSRuchika Gupta struct pkcs11_session *session, 16892d25a9bcSRuchika Gupta struct pkcs11_object *obj) 16902d25a9bcSRuchika Gupta { 16912d25a9bcSRuchika Gupta switch (attr->id) { 16922d25a9bcSRuchika Gupta case PKCS11_CKA_ENCRYPT: 16932d25a9bcSRuchika Gupta case PKCS11_CKA_DECRYPT: 16942d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN: 16952d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY: 16962d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP: 16972d25a9bcSRuchika Gupta case PKCS11_CKA_UNWRAP: 16982d25a9bcSRuchika Gupta return true; 16992d25a9bcSRuchika Gupta /* Can't be modified once set to CK_FALSE - 12 in Table 10 */ 17002d25a9bcSRuchika Gupta case PKCS11_CKA_EXTRACTABLE: 17012d25a9bcSRuchika Gupta return get_bool(obj->attributes, attr->id); 17022d25a9bcSRuchika Gupta /* Can't be modified once set to CK_TRUE - 11 in Table 10 */ 17032d25a9bcSRuchika Gupta case PKCS11_CKA_SENSITIVE: 17042d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP_WITH_TRUSTED: 17052d25a9bcSRuchika Gupta return !get_bool(obj->attributes, attr->id); 17062d25a9bcSRuchika Gupta /* Change in CKA_TRUSTED can only be done by SO */ 17072d25a9bcSRuchika Gupta case PKCS11_CKA_TRUSTED: 17082d25a9bcSRuchika Gupta return pkcs11_session_is_so(session); 17092d25a9bcSRuchika Gupta case PKCS11_CKA_NEVER_EXTRACTABLE: 17102d25a9bcSRuchika Gupta case PKCS11_CKA_ALWAYS_SENSITIVE: 17112d25a9bcSRuchika Gupta return false; 17122d25a9bcSRuchika Gupta default: 17132d25a9bcSRuchika Gupta return false; 17142d25a9bcSRuchika Gupta } 17152d25a9bcSRuchika Gupta } 17162d25a9bcSRuchika Gupta 17172d25a9bcSRuchika Gupta static bool attr_is_modifiable_public_key(struct pkcs11_attribute_head *attr, 17182d25a9bcSRuchika Gupta struct pkcs11_session *session, 17192d25a9bcSRuchika Gupta struct pkcs11_object *obj __unused) 17202d25a9bcSRuchika Gupta { 17212d25a9bcSRuchika Gupta switch (attr->id) { 17222d25a9bcSRuchika Gupta case PKCS11_CKA_SUBJECT: 17232d25a9bcSRuchika Gupta case PKCS11_CKA_ENCRYPT: 17242d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY: 17252d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY_RECOVER: 17262d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP: 17272d25a9bcSRuchika Gupta return true; 17282d25a9bcSRuchika Gupta case PKCS11_CKA_TRUSTED: 17292d25a9bcSRuchika Gupta /* Change in CKA_TRUSTED can only be done by SO */ 17302d25a9bcSRuchika Gupta return pkcs11_session_is_so(session); 17312d25a9bcSRuchika Gupta default: 17322d25a9bcSRuchika Gupta return false; 17332d25a9bcSRuchika Gupta } 17342d25a9bcSRuchika Gupta } 17352d25a9bcSRuchika Gupta 17362d25a9bcSRuchika Gupta static bool attr_is_modifiable_private_key(struct pkcs11_attribute_head *attr, 17372d25a9bcSRuchika Gupta struct pkcs11_session *sess __unused, 17382d25a9bcSRuchika Gupta struct pkcs11_object *obj) 17392d25a9bcSRuchika Gupta { 17402d25a9bcSRuchika Gupta switch (attr->id) { 17412d25a9bcSRuchika Gupta case PKCS11_CKA_SUBJECT: 17422d25a9bcSRuchika Gupta case PKCS11_CKA_DECRYPT: 17432d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN: 17442d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN_RECOVER: 17452d25a9bcSRuchika Gupta case PKCS11_CKA_UNWRAP: 17462d25a9bcSRuchika Gupta /* 17472d25a9bcSRuchika Gupta * TBD: Revisit if we don't support PKCS11_CKA_PUBLIC_KEY_INFO 17482d25a9bcSRuchika Gupta * Specification mentions that if this attribute is 17492d25a9bcSRuchika Gupta * supplied as part of a template for C_CreateObject, C_CopyObject or 17502d25a9bcSRuchika Gupta * C_SetAttributeValue for a private key, the token MUST verify 17512d25a9bcSRuchika Gupta * correspondence between the private key data and the public key data 17522d25a9bcSRuchika Gupta * as supplied in CKA_PUBLIC_KEY_INFO. This needs to be 17532d25a9bcSRuchika Gupta * taken care of when this object type will be implemented 17542d25a9bcSRuchika Gupta */ 17552d25a9bcSRuchika Gupta case PKCS11_CKA_PUBLIC_KEY_INFO: 17562d25a9bcSRuchika Gupta return true; 17572d25a9bcSRuchika Gupta /* Can't be modified once set to CK_FALSE - 12 in Table 10 */ 17582d25a9bcSRuchika Gupta case PKCS11_CKA_EXTRACTABLE: 17592d25a9bcSRuchika Gupta return get_bool(obj->attributes, attr->id); 17602d25a9bcSRuchika Gupta /* Can't be modified once set to CK_TRUE - 11 in Table 10 */ 17612d25a9bcSRuchika Gupta case PKCS11_CKA_SENSITIVE: 17622d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP_WITH_TRUSTED: 17632d25a9bcSRuchika Gupta return !get_bool(obj->attributes, attr->id); 17642d25a9bcSRuchika Gupta case PKCS11_CKA_NEVER_EXTRACTABLE: 17652d25a9bcSRuchika Gupta case PKCS11_CKA_ALWAYS_SENSITIVE: 17662d25a9bcSRuchika Gupta return false; 17672d25a9bcSRuchika Gupta default: 17682d25a9bcSRuchika Gupta return false; 17692d25a9bcSRuchika Gupta } 17702d25a9bcSRuchika Gupta } 17712d25a9bcSRuchika Gupta 17722d25a9bcSRuchika Gupta static bool attribute_is_modifiable(struct pkcs11_session *session, 17732d25a9bcSRuchika Gupta struct pkcs11_attribute_head *req_attr, 17742d25a9bcSRuchika Gupta struct pkcs11_object *obj, 17752d25a9bcSRuchika Gupta enum pkcs11_class_id class, 17762d25a9bcSRuchika Gupta enum processing_func function) 17772d25a9bcSRuchika Gupta { 17782d25a9bcSRuchika Gupta /* Check modifiable attributes common to any object */ 17792d25a9bcSRuchika Gupta switch (req_attr->id) { 17802d25a9bcSRuchika Gupta case PKCS11_CKA_LABEL: 17812d25a9bcSRuchika Gupta return true; 17822d25a9bcSRuchika Gupta case PKCS11_CKA_TOKEN: 17832d25a9bcSRuchika Gupta case PKCS11_CKA_MODIFIABLE: 17842d25a9bcSRuchika Gupta case PKCS11_CKA_DESTROYABLE: 17852d25a9bcSRuchika Gupta case PKCS11_CKA_PRIVATE: 17862d25a9bcSRuchika Gupta return function == PKCS11_FUNCTION_COPY; 17872d25a9bcSRuchika Gupta case PKCS11_CKA_COPYABLE: 17882d25a9bcSRuchika Gupta /* 17892d25a9bcSRuchika Gupta * Specification mentions that if the attribute value is false 17902d25a9bcSRuchika Gupta * it can't be set to true. Reading this we assume that it 17912d25a9bcSRuchika Gupta * should be possible to modify this attribute even though this 17922d25a9bcSRuchika Gupta * is not marked as modifiable in Table 10 if done in right 17932d25a9bcSRuchika Gupta * direction i.e from TRUE -> FALSE. 17942d25a9bcSRuchika Gupta */ 17952d25a9bcSRuchika Gupta return get_bool(obj->attributes, req_attr->id); 17962d25a9bcSRuchika Gupta default: 17972d25a9bcSRuchika Gupta break; 17982d25a9bcSRuchika Gupta } 17992d25a9bcSRuchika Gupta 18002d25a9bcSRuchika Gupta /* Attribute checking based on class type */ 18012d25a9bcSRuchika Gupta switch (class) { 18022d25a9bcSRuchika Gupta case PKCS11_CKO_SECRET_KEY: 18032d25a9bcSRuchika Gupta case PKCS11_CKO_PUBLIC_KEY: 18042d25a9bcSRuchika Gupta case PKCS11_CKO_PRIVATE_KEY: 18052d25a9bcSRuchika Gupta if (attr_is_modifiable_any_key(req_attr)) 18062d25a9bcSRuchika Gupta return true; 18072d25a9bcSRuchika Gupta if (class == PKCS11_CKO_SECRET_KEY && 18082d25a9bcSRuchika Gupta attr_is_modifiable_secret_key(req_attr, session, obj)) 18092d25a9bcSRuchika Gupta return true; 18102d25a9bcSRuchika Gupta if (class == PKCS11_CKO_PUBLIC_KEY && 18112d25a9bcSRuchika Gupta attr_is_modifiable_public_key(req_attr, session, obj)) 18122d25a9bcSRuchika Gupta return true; 18132d25a9bcSRuchika Gupta if (class == PKCS11_CKO_PRIVATE_KEY && 18142d25a9bcSRuchika Gupta attr_is_modifiable_private_key(req_attr, session, obj)) 18152d25a9bcSRuchika Gupta return true; 18162d25a9bcSRuchika Gupta break; 18172d25a9bcSRuchika Gupta case PKCS11_CKO_DATA: 18182d25a9bcSRuchika Gupta /* None of the data object attributes are modifiable */ 18192d25a9bcSRuchika Gupta return false; 18202d25a9bcSRuchika Gupta default: 18212d25a9bcSRuchika Gupta break; 18222d25a9bcSRuchika Gupta } 18232d25a9bcSRuchika Gupta 18242d25a9bcSRuchika Gupta return false; 18252d25a9bcSRuchika Gupta } 18262d25a9bcSRuchika Gupta 18272d25a9bcSRuchika Gupta enum pkcs11_rc check_attrs_against_modification(struct pkcs11_session *session, 18282d25a9bcSRuchika Gupta struct obj_attrs *head, 18292d25a9bcSRuchika Gupta struct pkcs11_object *obj, 18302d25a9bcSRuchika Gupta enum processing_func function) 18312d25a9bcSRuchika Gupta { 18322d25a9bcSRuchika Gupta enum pkcs11_class_id class = PKCS11_CKO_UNDEFINED_ID; 18332d25a9bcSRuchika Gupta char *cur = NULL; 18342d25a9bcSRuchika Gupta char *end = NULL; 18352d25a9bcSRuchika Gupta size_t len = 0; 18362d25a9bcSRuchika Gupta 18372d25a9bcSRuchika Gupta class = get_class(obj->attributes); 18382d25a9bcSRuchika Gupta 18392d25a9bcSRuchika Gupta cur = (char *)head + sizeof(struct obj_attrs); 18402d25a9bcSRuchika Gupta end = cur + head->attrs_size; 18412d25a9bcSRuchika Gupta 18422d25a9bcSRuchika Gupta for (; cur < end; cur += len) { 18432d25a9bcSRuchika Gupta /* Structure aligned copy of the pkcs11_ref in the object */ 18442d25a9bcSRuchika Gupta struct pkcs11_attribute_head cli_ref = { }; 18452d25a9bcSRuchika Gupta 18462d25a9bcSRuchika Gupta TEE_MemMove(&cli_ref, cur, sizeof(cli_ref)); 18472d25a9bcSRuchika Gupta len = sizeof(cli_ref) + cli_ref.size; 18482d25a9bcSRuchika Gupta 18492d25a9bcSRuchika Gupta /* 18502d25a9bcSRuchika Gupta * Check 1 - Check if attribute belongs to the object 18512d25a9bcSRuchika Gupta * The obj->attributes has all the attributes in 18522d25a9bcSRuchika Gupta * it which are allowed for an object. 18532d25a9bcSRuchika Gupta */ 18542d25a9bcSRuchika Gupta if (get_attribute_ptr(obj->attributes, cli_ref.id, NULL, 18552d25a9bcSRuchika Gupta NULL) == PKCS11_RV_NOT_FOUND) 18562d25a9bcSRuchika Gupta return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 18572d25a9bcSRuchika Gupta 18582d25a9bcSRuchika Gupta /* Check 2 - Is attribute modifiable */ 18592d25a9bcSRuchika Gupta if (!attribute_is_modifiable(session, &cli_ref, obj, class, 18602d25a9bcSRuchika Gupta function)) 18612d25a9bcSRuchika Gupta return PKCS11_CKR_ATTRIBUTE_READ_ONLY; 18622d25a9bcSRuchika Gupta 18632d25a9bcSRuchika Gupta /* 18642d25a9bcSRuchika Gupta * Checks for modification in PKCS11_CKA_TOKEN and 18652d25a9bcSRuchika Gupta * PKCS11_CKA_PRIVATE are required for PKCS11_FUNCTION_COPY 18662d25a9bcSRuchika Gupta * only, so skip them for PKCS11_FUNCTION_MODIFY. 18672d25a9bcSRuchika Gupta */ 18682d25a9bcSRuchika Gupta if (function == PKCS11_FUNCTION_MODIFY) 18692d25a9bcSRuchika Gupta continue; 18702d25a9bcSRuchika Gupta 18712d25a9bcSRuchika Gupta /* 18722d25a9bcSRuchika Gupta * An attempt to copy an object to a token will fail for 18732d25a9bcSRuchika Gupta * RO session 18742d25a9bcSRuchika Gupta */ 18752d25a9bcSRuchika Gupta if (cli_ref.id == PKCS11_CKA_TOKEN && 18762d25a9bcSRuchika Gupta get_bool(head, PKCS11_CKA_TOKEN)) { 18772d25a9bcSRuchika Gupta if (!pkcs11_session_is_read_write(session)) { 18782d25a9bcSRuchika Gupta DMSG("Can't copy to token in a RO session"); 18792d25a9bcSRuchika Gupta return PKCS11_CKR_SESSION_READ_ONLY; 18802d25a9bcSRuchika Gupta } 18812d25a9bcSRuchika Gupta } 18822d25a9bcSRuchika Gupta 18832d25a9bcSRuchika Gupta if (cli_ref.id == PKCS11_CKA_PRIVATE) { 18842d25a9bcSRuchika Gupta bool parent_priv = 18852d25a9bcSRuchika Gupta get_bool(obj->attributes, cli_ref.id); 18862d25a9bcSRuchika Gupta bool obj_priv = get_bool(head, cli_ref.id); 18872d25a9bcSRuchika Gupta 18882d25a9bcSRuchika Gupta /* 18892d25a9bcSRuchika Gupta * If PKCS11_CKA_PRIVATE is being set to TRUE from 18902d25a9bcSRuchika Gupta * FALSE, user has to be logged in 18912d25a9bcSRuchika Gupta */ 18922d25a9bcSRuchika Gupta if (!parent_priv && obj_priv) { 18932d25a9bcSRuchika Gupta if ((pkcs11_session_is_public(session) || 18942d25a9bcSRuchika Gupta pkcs11_session_is_so(session))) 18952d25a9bcSRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 18962d25a9bcSRuchika Gupta } 1897df017b2bSRuchika Gupta 1898df017b2bSRuchika Gupta /* 1899df017b2bSRuchika Gupta * Restriction added - Even for Copy, do not allow 1900df017b2bSRuchika Gupta * modification of CKA_PRIVATE from TRUE to FALSE 1901df017b2bSRuchika Gupta */ 1902df017b2bSRuchika Gupta if (parent_priv && !obj_priv) 1903df017b2bSRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 19042d25a9bcSRuchika Gupta } 19052d25a9bcSRuchika Gupta } 19062d25a9bcSRuchika Gupta 19072d25a9bcSRuchika Gupta return PKCS11_CKR_OK; 19082d25a9bcSRuchika Gupta } 19098c499324SRuchika Gupta 19108c499324SRuchika Gupta static enum pkcs11_rc set_secret_key_data(struct obj_attrs **head, void *data, 19118c499324SRuchika Gupta size_t key_size) 19128c499324SRuchika Gupta { 19138c499324SRuchika Gupta uint32_t size = sizeof(uint32_t); 19148c499324SRuchika Gupta uint32_t key_length = 0; 19158c499324SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 19168c499324SRuchika Gupta 19178c499324SRuchika Gupta /* Get key size if present in template */ 19188c499324SRuchika Gupta rc = get_attribute(*head, PKCS11_CKA_VALUE_LEN, &key_length, &size); 19198c499324SRuchika Gupta if (rc && rc != PKCS11_RV_NOT_FOUND) 19208c499324SRuchika Gupta return rc; 19218c499324SRuchika Gupta 19228c499324SRuchika Gupta if (key_length) { 19238c499324SRuchika Gupta if (key_size < key_length) 19248c499324SRuchika Gupta return PKCS11_CKR_DATA_LEN_RANGE; 19258c499324SRuchika Gupta } else { 19268c499324SRuchika Gupta key_length = key_size; 19278c499324SRuchika Gupta rc = set_attribute(head, PKCS11_CKA_VALUE_LEN, &key_length, 19288c499324SRuchika Gupta sizeof(uint32_t)); 19298c499324SRuchika Gupta if (rc) 19308c499324SRuchika Gupta return rc; 19318c499324SRuchika Gupta } 19328c499324SRuchika Gupta 19338c499324SRuchika Gupta /* Now we can check the VALUE_LEN field */ 19348c499324SRuchika Gupta rc = check_created_attrs(*head, NULL); 19358c499324SRuchika Gupta if (rc) 19368c499324SRuchika Gupta return rc; 19378c499324SRuchika Gupta 19388c499324SRuchika Gupta /* Remove the default empty value attribute if found */ 19398c499324SRuchika Gupta rc = remove_empty_attribute(head, PKCS11_CKA_VALUE); 19408c499324SRuchika Gupta if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND) 19418c499324SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 19428c499324SRuchika Gupta 19438c499324SRuchika Gupta return add_attribute(head, PKCS11_CKA_VALUE, data, key_length); 19448c499324SRuchika Gupta } 19458c499324SRuchika Gupta 19468c499324SRuchika Gupta enum pkcs11_rc set_key_data(struct obj_attrs **head, void *data, 19478c499324SRuchika Gupta size_t key_size) 19488c499324SRuchika Gupta { 19498c499324SRuchika Gupta switch (get_class(*head)) { 19508c499324SRuchika Gupta case PKCS11_CKO_SECRET_KEY: 19518c499324SRuchika Gupta return set_secret_key_data(head, data, key_size); 19528c499324SRuchika Gupta default: 19538c499324SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 19548c499324SRuchika Gupta } 19558c499324SRuchika Gupta } 19565e1d94ebSVesa Jääskeläinen 19575f80f270SRuchika Gupta enum pkcs11_rc get_key_data_to_wrap(struct obj_attrs *head, void **data, 19585f80f270SRuchika Gupta uint32_t *sz) 19595f80f270SRuchika Gupta { 19605f80f270SRuchika Gupta switch (get_class(head)) { 19615f80f270SRuchika Gupta case PKCS11_CKO_SECRET_KEY: 19625f80f270SRuchika Gupta if (get_attribute_ptr(head, PKCS11_CKA_VALUE, data, sz)) 19635f80f270SRuchika Gupta return PKCS11_CKR_ARGUMENTS_BAD; 19645f80f270SRuchika Gupta break; 19655f80f270SRuchika Gupta default: 19665f80f270SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 19675f80f270SRuchika Gupta } 19685f80f270SRuchika Gupta 19695f80f270SRuchika Gupta return PKCS11_CKR_OK; 19705f80f270SRuchika Gupta } 19715f80f270SRuchika Gupta 19725e1d94ebSVesa Jääskeläinen enum pkcs11_rc add_missing_attribute_id(struct obj_attrs **pub_head, 19735e1d94ebSVesa Jääskeläinen struct obj_attrs **priv_head) 19745e1d94ebSVesa Jääskeläinen { 19755e1d94ebSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 19765e1d94ebSVesa Jääskeläinen void *id1 = NULL; 19775e1d94ebSVesa Jääskeläinen uint32_t id1_size = 0; 19785e1d94ebSVesa Jääskeläinen void *id2 = NULL; 19795e1d94ebSVesa Jääskeläinen uint32_t id2_size = 0; 19805e1d94ebSVesa Jääskeläinen 19815e1d94ebSVesa Jääskeläinen assert(pub_head); 19825e1d94ebSVesa Jääskeläinen assert(priv_head); 19835e1d94ebSVesa Jääskeläinen 19845e1d94ebSVesa Jääskeläinen rc = get_attribute_ptr(*pub_head, PKCS11_CKA_ID, &id1, &id1_size); 19855e1d94ebSVesa Jääskeläinen if (rc) { 19865e1d94ebSVesa Jääskeläinen if (rc != PKCS11_RV_NOT_FOUND) 19875e1d94ebSVesa Jääskeläinen return rc; 19885e1d94ebSVesa Jääskeläinen id1 = NULL; 19895e1d94ebSVesa Jääskeläinen } else if (!id1_size) { 19905e1d94ebSVesa Jääskeläinen id1 = NULL; 19915e1d94ebSVesa Jääskeläinen } 19925e1d94ebSVesa Jääskeläinen 19935e1d94ebSVesa Jääskeläinen rc = get_attribute_ptr(*priv_head, PKCS11_CKA_ID, &id2, &id2_size); 19945e1d94ebSVesa Jääskeläinen if (rc) { 19955e1d94ebSVesa Jääskeläinen if (rc != PKCS11_RV_NOT_FOUND) 19965e1d94ebSVesa Jääskeläinen return rc; 19975e1d94ebSVesa Jääskeläinen id2 = NULL; 19985e1d94ebSVesa Jääskeläinen } else if (!id2_size) { 19995e1d94ebSVesa Jääskeläinen id2 = NULL; 20005e1d94ebSVesa Jääskeläinen } 20015e1d94ebSVesa Jääskeläinen 20025e1d94ebSVesa Jääskeläinen /* Both have value -- let them be what caller has specified them */ 20035e1d94ebSVesa Jääskeläinen if (id1 && id2) 20045e1d94ebSVesa Jääskeläinen return PKCS11_CKR_OK; 20055e1d94ebSVesa Jääskeläinen 20065e1d94ebSVesa Jääskeläinen /* Both are empty -- leave empty values */ 20075e1d94ebSVesa Jääskeläinen if (!id1 && !id2) 20085e1d94ebSVesa Jääskeläinen return PKCS11_CKR_OK; 20095e1d94ebSVesa Jääskeläinen 20105e1d94ebSVesa Jääskeläinen /* Cross copy CKA_ID value */ 20115e1d94ebSVesa Jääskeläinen if (id1) 20125e1d94ebSVesa Jääskeläinen return set_attribute(priv_head, PKCS11_CKA_ID, id1, id1_size); 20135e1d94ebSVesa Jääskeläinen else 20145e1d94ebSVesa Jääskeläinen return set_attribute(pub_head, PKCS11_CKA_ID, id2, id2_size); 20155e1d94ebSVesa Jääskeläinen } 2016