163f89caaSJens Wiklander // SPDX-License-Identifier: BSD-2-Clause 263f89caaSJens Wiklander /* 363f89caaSJens Wiklander * Copyright (c) 2017-2020, Linaro Limited 463f89caaSJens Wiklander */ 563f89caaSJens Wiklander 663f89caaSJens Wiklander #include <assert.h> 763f89caaSJens Wiklander #include <inttypes.h> 863f89caaSJens Wiklander #include <pkcs11_ta.h> 963f89caaSJens Wiklander #include <stdlib.h> 1063f89caaSJens Wiklander #include <string_ext.h> 1163f89caaSJens Wiklander #include <tee_internal_api_extensions.h> 1263f89caaSJens Wiklander #include <tee_internal_api.h> 136a760c9eSEtienne Carriere #include <trace.h> 1463f89caaSJens Wiklander #include <util.h> 1563f89caaSJens Wiklander 1663f89caaSJens Wiklander #include "attributes.h" 1763f89caaSJens Wiklander #include "handle.h" 1863f89caaSJens Wiklander #include "pkcs11_attributes.h" 1963f89caaSJens Wiklander #include "pkcs11_helpers.h" 2063f89caaSJens Wiklander #include "pkcs11_token.h" 2163f89caaSJens Wiklander #include "sanitize_object.h" 2263f89caaSJens Wiklander #include "serializer.h" 2363f89caaSJens Wiklander #include "token_capabilities.h" 2463f89caaSJens Wiklander 25512cbf1dSJens Wiklander static uint32_t pkcs11_func2ckfm(enum processing_func function) 26512cbf1dSJens Wiklander { 27512cbf1dSJens Wiklander switch (function) { 28512cbf1dSJens Wiklander case PKCS11_FUNCTION_DIGEST: 29512cbf1dSJens Wiklander return PKCS11_CKFM_DIGEST; 30512cbf1dSJens Wiklander case PKCS11_FUNCTION_GENERATE: 31512cbf1dSJens Wiklander return PKCS11_CKFM_GENERATE; 32512cbf1dSJens Wiklander case PKCS11_FUNCTION_GENERATE_PAIR: 33512cbf1dSJens Wiklander return PKCS11_CKFM_GENERATE_KEY_PAIR; 34512cbf1dSJens Wiklander case PKCS11_FUNCTION_DERIVE: 35512cbf1dSJens Wiklander return PKCS11_CKFM_DERIVE; 36512cbf1dSJens Wiklander case PKCS11_FUNCTION_WRAP: 37512cbf1dSJens Wiklander return PKCS11_CKFM_WRAP; 38512cbf1dSJens Wiklander case PKCS11_FUNCTION_UNWRAP: 39512cbf1dSJens Wiklander return PKCS11_CKFM_UNWRAP; 40512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 41512cbf1dSJens Wiklander return PKCS11_CKFM_ENCRYPT; 42512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 43512cbf1dSJens Wiklander return PKCS11_CKFM_DECRYPT; 44512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN: 45512cbf1dSJens Wiklander return PKCS11_CKFM_SIGN; 46512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY: 47512cbf1dSJens Wiklander return PKCS11_CKFM_VERIFY; 48512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN_RECOVER: 49512cbf1dSJens Wiklander return PKCS11_CKFM_SIGN_RECOVER; 50512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY_RECOVER: 51512cbf1dSJens Wiklander return PKCS11_CKFM_VERIFY_RECOVER; 52512cbf1dSJens Wiklander default: 53512cbf1dSJens Wiklander return 0; 54512cbf1dSJens Wiklander } 55512cbf1dSJens Wiklander } 56512cbf1dSJens Wiklander 57512cbf1dSJens Wiklander enum pkcs11_rc 58512cbf1dSJens Wiklander check_mechanism_against_processing(struct pkcs11_session *session, 59512cbf1dSJens Wiklander enum pkcs11_mechanism_id mechanism_type, 60512cbf1dSJens Wiklander enum processing_func function, 61512cbf1dSJens Wiklander enum processing_step step) 62512cbf1dSJens Wiklander { 63512cbf1dSJens Wiklander bool allowed = false; 64512cbf1dSJens Wiklander 65512cbf1dSJens Wiklander switch (step) { 66512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_INIT: 67512cbf1dSJens Wiklander switch (function) { 68512cbf1dSJens Wiklander case PKCS11_FUNCTION_IMPORT: 69512cbf1dSJens Wiklander case PKCS11_FUNCTION_COPY: 70512cbf1dSJens Wiklander case PKCS11_FUNCTION_MODIFY: 71512cbf1dSJens Wiklander case PKCS11_FUNCTION_DESTROY: 72512cbf1dSJens Wiklander return PKCS11_CKR_OK; 73512cbf1dSJens Wiklander default: 74512cbf1dSJens Wiklander break; 75512cbf1dSJens Wiklander } 76512cbf1dSJens Wiklander /* 77512cbf1dSJens Wiklander * Check that the returned PKCS11_CKFM_* flag from 78512cbf1dSJens Wiklander * pkcs11_func2ckfm() is among the ones from 79512cbf1dSJens Wiklander * mechanism_supported_flags(). 80512cbf1dSJens Wiklander */ 81512cbf1dSJens Wiklander allowed = mechanism_supported_flags(mechanism_type) & 82512cbf1dSJens Wiklander pkcs11_func2ckfm(function); 83512cbf1dSJens Wiklander break; 84512cbf1dSJens Wiklander 85512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_ONESHOT: 860460a039SRuchika Gupta if (session->processing->always_authen && 870460a039SRuchika Gupta !session->processing->relogged) 880460a039SRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 890460a039SRuchika Gupta 902364aa69SRuchika Gupta if (session->processing->step == PKCS11_FUNC_STEP_UPDATE || 912364aa69SRuchika Gupta session->processing->step == PKCS11_FUNC_STEP_FINAL) { 922364aa69SRuchika Gupta EMSG("Cannot perform one-shot on active processing"); 930460a039SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE; 940460a039SRuchika Gupta } 950460a039SRuchika Gupta 960460a039SRuchika Gupta allowed = true; 970460a039SRuchika Gupta break; 980460a039SRuchika Gupta 99512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_UPDATE: 100512cbf1dSJens Wiklander if (session->processing->always_authen && 101512cbf1dSJens Wiklander !session->processing->relogged) 102512cbf1dSJens Wiklander return PKCS11_CKR_USER_NOT_LOGGED_IN; 103512cbf1dSJens Wiklander 1042364aa69SRuchika Gupta if (session->processing->step == PKCS11_FUNC_STEP_ONESHOT || 1052364aa69SRuchika Gupta session->processing->step == PKCS11_FUNC_STEP_FINAL) { 1062364aa69SRuchika Gupta EMSG("Cannot perform update on finalized processing"); 1072364aa69SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE; 1082364aa69SRuchika Gupta } 1092364aa69SRuchika Gupta 110512cbf1dSJens Wiklander allowed = !mechanism_is_one_shot_only(mechanism_type); 111512cbf1dSJens Wiklander break; 112512cbf1dSJens Wiklander 1139e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE_KEY: 1149e91a619SVesa Jääskeläinen assert(function == PKCS11_FUNCTION_DIGEST); 1159e91a619SVesa Jääskeläinen 1169e91a619SVesa Jääskeläinen if (session->processing->always_authen && 1179e91a619SVesa Jääskeläinen !session->processing->relogged) 1189e91a619SVesa Jääskeläinen return PKCS11_CKR_USER_NOT_LOGGED_IN; 1199e91a619SVesa Jääskeläinen 1209e91a619SVesa Jääskeläinen allowed = true; 1219e91a619SVesa Jääskeläinen break; 1229e91a619SVesa Jääskeläinen 123512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_FINAL: 124512cbf1dSJens Wiklander if (session->processing->always_authen && 125512cbf1dSJens Wiklander !session->processing->relogged) 126512cbf1dSJens Wiklander return PKCS11_CKR_USER_NOT_LOGGED_IN; 127512cbf1dSJens Wiklander 1282364aa69SRuchika Gupta if (session->processing->step == PKCS11_FUNC_STEP_ONESHOT) { 1292364aa69SRuchika Gupta EMSG("Cannot perform final on oneshot processing"); 1302364aa69SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE; 1312364aa69SRuchika Gupta } 132512cbf1dSJens Wiklander return PKCS11_CKR_OK; 133512cbf1dSJens Wiklander 134512cbf1dSJens Wiklander default: 135512cbf1dSJens Wiklander TEE_Panic(step); 136512cbf1dSJens Wiklander break; 137512cbf1dSJens Wiklander } 138512cbf1dSJens Wiklander 139512cbf1dSJens Wiklander if (!allowed) { 140512cbf1dSJens Wiklander EMSG("Processing %#x/%s not permitted (%u/%u)", 141512cbf1dSJens Wiklander (unsigned int)mechanism_type, id2str_proc(mechanism_type), 142512cbf1dSJens Wiklander function, step); 143df705578SRuchika Gupta return PKCS11_CKR_MECHANISM_INVALID; 144512cbf1dSJens Wiklander } 145512cbf1dSJens Wiklander 146512cbf1dSJens Wiklander return PKCS11_CKR_OK; 147512cbf1dSJens Wiklander } 148512cbf1dSJens Wiklander 14963f89caaSJens Wiklander /* 15063f89caaSJens Wiklander * Object default boolean attributes as per PKCS#11 15163f89caaSJens Wiklander */ 15263f89caaSJens Wiklander static uint8_t *pkcs11_object_default_boolprop(uint32_t attribute) 15363f89caaSJens Wiklander { 15463f89caaSJens Wiklander static const uint8_t bool_true = 1; 15563f89caaSJens Wiklander static const uint8_t bool_false; 15663f89caaSJens Wiklander 15763f89caaSJens Wiklander switch (attribute) { 15863f89caaSJens Wiklander /* As per PKCS#11 default value */ 15963f89caaSJens Wiklander case PKCS11_CKA_MODIFIABLE: 16063f89caaSJens Wiklander case PKCS11_CKA_COPYABLE: 16163f89caaSJens Wiklander case PKCS11_CKA_DESTROYABLE: 16263f89caaSJens Wiklander return (uint8_t *)&bool_true; 16363f89caaSJens Wiklander case PKCS11_CKA_TOKEN: 16463f89caaSJens Wiklander case PKCS11_CKA_PRIVATE: 16539fc24faSEtienne Carriere case PKCS11_CKA_WRAP_WITH_TRUSTED: 16639fc24faSEtienne Carriere case PKCS11_CKA_ALWAYS_AUTHENTICATE: 16763f89caaSJens Wiklander case PKCS11_CKA_SENSITIVE: 16863f89caaSJens Wiklander return (uint8_t *)&bool_false; 16963f89caaSJens Wiklander /* Token specific default value */ 17063f89caaSJens Wiklander case PKCS11_CKA_SIGN: 17163f89caaSJens Wiklander case PKCS11_CKA_VERIFY: 17263f89caaSJens Wiklander case PKCS11_CKA_DERIVE: 17363f89caaSJens Wiklander case PKCS11_CKA_ENCRYPT: 17463f89caaSJens Wiklander case PKCS11_CKA_DECRYPT: 17563f89caaSJens Wiklander case PKCS11_CKA_SIGN_RECOVER: 17663f89caaSJens Wiklander case PKCS11_CKA_VERIFY_RECOVER: 17763f89caaSJens Wiklander case PKCS11_CKA_WRAP: 17863f89caaSJens Wiklander case PKCS11_CKA_UNWRAP: 17963f89caaSJens Wiklander case PKCS11_CKA_EXTRACTABLE: 18063f89caaSJens Wiklander case PKCS11_CKA_TRUSTED: 18163f89caaSJens Wiklander return (uint8_t *)&bool_false; 18263f89caaSJens Wiklander default: 18363f89caaSJens Wiklander DMSG("No default for boolprop attribute %#"PRIx32, attribute); 18463f89caaSJens Wiklander return NULL; 18563f89caaSJens Wiklander } 18663f89caaSJens Wiklander } 18763f89caaSJens Wiklander 18863f89caaSJens Wiklander /* 18963f89caaSJens Wiklander * Object expects several boolean attributes to be set to a default value 19063f89caaSJens Wiklander * or to a validate client configuration value. This function append the input 19163f89caaSJens Wiklander * attribute (id/size/value) in the serialized object. 19263f89caaSJens Wiklander */ 19363f89caaSJens Wiklander static enum pkcs11_rc pkcs11_import_object_boolprop(struct obj_attrs **out, 19463f89caaSJens Wiklander struct obj_attrs *templ, 19563f89caaSJens Wiklander uint32_t attribute) 19663f89caaSJens Wiklander { 19763f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 19863f89caaSJens Wiklander uint8_t bbool = 0; 19963f89caaSJens Wiklander uint32_t size = sizeof(uint8_t); 20063f89caaSJens Wiklander void *attr = NULL; 20163f89caaSJens Wiklander 20263f89caaSJens Wiklander rc = get_attribute(templ, attribute, &bbool, &size); 20363f89caaSJens Wiklander if (rc) { 20463f89caaSJens Wiklander if (rc != PKCS11_RV_NOT_FOUND) 20563f89caaSJens Wiklander return rc; 20663f89caaSJens Wiklander attr = pkcs11_object_default_boolprop(attribute); 20763f89caaSJens Wiklander if (!attr) 20863f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCOMPLETE; 20963f89caaSJens Wiklander } else { 21063f89caaSJens Wiklander attr = &bbool; 21163f89caaSJens Wiklander } 21263f89caaSJens Wiklander 21363f89caaSJens Wiklander /* Boolean attributes are 1byte in the ABI, no alignment issue */ 21463f89caaSJens Wiklander return add_attribute(out, attribute, attr, sizeof(uint8_t)); 21563f89caaSJens Wiklander } 21663f89caaSJens Wiklander 21763f89caaSJens Wiklander static enum pkcs11_rc set_mandatory_boolprops(struct obj_attrs **out, 21863f89caaSJens Wiklander struct obj_attrs *temp, 21963f89caaSJens Wiklander uint32_t const *bp, 22063f89caaSJens Wiklander size_t bp_count) 22163f89caaSJens Wiklander { 22263f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 22363f89caaSJens Wiklander size_t n = 0; 22463f89caaSJens Wiklander 22563f89caaSJens Wiklander for (n = 0; n < bp_count; n++) { 22663f89caaSJens Wiklander rc = pkcs11_import_object_boolprop(out, temp, bp[n]); 22763f89caaSJens Wiklander if (rc) 22863f89caaSJens Wiklander return rc; 22963f89caaSJens Wiklander } 23063f89caaSJens Wiklander 23163f89caaSJens Wiklander return rc; 23263f89caaSJens Wiklander } 23363f89caaSJens Wiklander 23463f89caaSJens Wiklander static enum pkcs11_rc set_mandatory_attributes(struct obj_attrs **out, 23563f89caaSJens Wiklander struct obj_attrs *temp, 23616df60c7SEtienne Carriere uint32_t const *attrs, 23716df60c7SEtienne Carriere size_t attrs_count) 23863f89caaSJens Wiklander { 23963f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 24063f89caaSJens Wiklander size_t n = 0; 24163f89caaSJens Wiklander 24216df60c7SEtienne Carriere for (n = 0; n < attrs_count; n++) { 24363f89caaSJens Wiklander uint32_t size = 0; 24463f89caaSJens Wiklander void *value = NULL; 24563f89caaSJens Wiklander 24616df60c7SEtienne Carriere if (get_attribute_ptr(temp, attrs[n], &value, &size)) 24763f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCOMPLETE; 24863f89caaSJens Wiklander 24916df60c7SEtienne Carriere rc = add_attribute(out, attrs[n], value, size); 25063f89caaSJens Wiklander if (rc) 25163f89caaSJens Wiklander return rc; 25263f89caaSJens Wiklander } 25363f89caaSJens Wiklander 25463f89caaSJens Wiklander return rc; 25563f89caaSJens Wiklander } 25663f89caaSJens Wiklander 25763f89caaSJens Wiklander static enum pkcs11_rc get_default_value(enum pkcs11_attr_id id, void **value, 25863f89caaSJens Wiklander uint32_t *size) 25963f89caaSJens Wiklander { 26063f89caaSJens Wiklander /* should have been taken care of already */ 26163f89caaSJens Wiklander assert(!pkcs11_attr_is_boolean(id)); 26263f89caaSJens Wiklander 26363f89caaSJens Wiklander /* All other attributes have an empty default value */ 26463f89caaSJens Wiklander *value = NULL; 26563f89caaSJens Wiklander *size = 0; 26663f89caaSJens Wiklander return PKCS11_CKR_OK; 26763f89caaSJens Wiklander } 26863f89caaSJens Wiklander 2694eb88651SRuchika Gupta static enum pkcs11_rc set_optional_attributes_with_def(struct obj_attrs **out, 27063f89caaSJens Wiklander struct obj_attrs *temp, 27116df60c7SEtienne Carriere uint32_t const *attrs, 27216df60c7SEtienne Carriere size_t attrs_count, 2734eb88651SRuchika Gupta bool default_to_null) 27463f89caaSJens Wiklander { 27563f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 27663f89caaSJens Wiklander size_t n = 0; 27763f89caaSJens Wiklander 27816df60c7SEtienne Carriere for (n = 0; n < attrs_count; n++) { 27963f89caaSJens Wiklander uint32_t size = 0; 28063f89caaSJens Wiklander void *value = NULL; 28163f89caaSJens Wiklander 28216df60c7SEtienne Carriere rc = get_attribute_ptr(temp, attrs[n], &value, &size); 2834eb88651SRuchika Gupta if (rc == PKCS11_RV_NOT_FOUND) { 2844eb88651SRuchika Gupta if (default_to_null) { 28516df60c7SEtienne Carriere rc = get_default_value(attrs[n], &value, &size); 2864eb88651SRuchika Gupta } else { 2874eb88651SRuchika Gupta rc = PKCS11_CKR_OK; 2884eb88651SRuchika Gupta continue; 2894eb88651SRuchika Gupta } 2904eb88651SRuchika Gupta } 29163f89caaSJens Wiklander if (rc) 29263f89caaSJens Wiklander return rc; 29363f89caaSJens Wiklander 29416df60c7SEtienne Carriere rc = add_attribute(out, attrs[n], value, size); 29563f89caaSJens Wiklander if (rc) 29663f89caaSJens Wiklander return rc; 29763f89caaSJens Wiklander } 29863f89caaSJens Wiklander 29963f89caaSJens Wiklander return rc; 30063f89caaSJens Wiklander } 30163f89caaSJens Wiklander 3024eb88651SRuchika Gupta static enum pkcs11_rc set_attributes_opt_or_null(struct obj_attrs **out, 3034eb88651SRuchika Gupta struct obj_attrs *temp, 30416df60c7SEtienne Carriere uint32_t const *attrs, 30516df60c7SEtienne Carriere size_t attrs_count) 3064eb88651SRuchika Gupta { 30716df60c7SEtienne Carriere return set_optional_attributes_with_def(out, temp, attrs, attrs_count, 30816df60c7SEtienne Carriere true /* defaults to empty */); 3094eb88651SRuchika Gupta } 3104eb88651SRuchika Gupta 3114eb88651SRuchika Gupta static enum pkcs11_rc set_optional_attributes(struct obj_attrs **out, 3124eb88651SRuchika Gupta struct obj_attrs *temp, 31316df60c7SEtienne Carriere uint32_t const *attrs, 31416df60c7SEtienne Carriere size_t attrs_count) 3154eb88651SRuchika Gupta { 31616df60c7SEtienne Carriere return set_optional_attributes_with_def(out, temp, attrs, attrs_count, 31716df60c7SEtienne Carriere false /* no default value */); 3184eb88651SRuchika Gupta } 3194eb88651SRuchika Gupta 32063f89caaSJens Wiklander /* 32163f89caaSJens Wiklander * Below are listed the mandated or optional expected attributes for 32263f89caaSJens Wiklander * PKCS#11 storage objects. 32363f89caaSJens Wiklander * 32463f89caaSJens Wiklander * Note: boolprops (mandated boolean attributes) PKCS11_CKA_ALWAYS_SENSITIVE, 32563f89caaSJens Wiklander * and PKCS11_CKA_NEVER_EXTRACTABLE are set by the token, not provided 32663f89caaSJens Wiklander * in the client template. 32763f89caaSJens Wiklander */ 32863f89caaSJens Wiklander 32963f89caaSJens Wiklander /* PKCS#11 specification for any object (session/token) of the storage */ 3304eb88651SRuchika Gupta static const uint32_t any_object_boolprops[] = { 33163f89caaSJens Wiklander PKCS11_CKA_TOKEN, PKCS11_CKA_PRIVATE, 33263f89caaSJens Wiklander PKCS11_CKA_MODIFIABLE, PKCS11_CKA_COPYABLE, PKCS11_CKA_DESTROYABLE, 33363f89caaSJens Wiklander }; 33463f89caaSJens Wiklander 3354eb88651SRuchika Gupta static const uint32_t any_object_opt_or_null[] = { 33663f89caaSJens Wiklander PKCS11_CKA_LABEL, 33763f89caaSJens Wiklander }; 33863f89caaSJens Wiklander 3394eb88651SRuchika Gupta /* PKCS#11 specification for raw data object (+any_object_xxx) */ 3404eb88651SRuchika Gupta const uint32_t raw_data_opt_or_null[] = { 34163f89caaSJens Wiklander PKCS11_CKA_OBJECT_ID, PKCS11_CKA_APPLICATION, PKCS11_CKA_VALUE, 34263f89caaSJens Wiklander }; 34363f89caaSJens Wiklander 3444eb88651SRuchika Gupta /* PKCS#11 specification for any key object (+any_object_xxx) */ 3454eb88651SRuchika Gupta static const uint32_t any_key_boolprops[] = { 34663f89caaSJens Wiklander PKCS11_CKA_DERIVE, 34763f89caaSJens Wiklander }; 34863f89caaSJens Wiklander 3494eb88651SRuchika Gupta static const uint32_t any_key_opt_or_null[] = { 35063f89caaSJens Wiklander PKCS11_CKA_ID, 35163f89caaSJens Wiklander PKCS11_CKA_START_DATE, PKCS11_CKA_END_DATE, 3524eb88651SRuchika Gupta }; 3534eb88651SRuchika Gupta 3544eb88651SRuchika Gupta static const uint32_t any_key_optional[] = { 35563f89caaSJens Wiklander PKCS11_CKA_ALLOWED_MECHANISMS, 35663f89caaSJens Wiklander }; 35763f89caaSJens Wiklander 3584eb88651SRuchika Gupta /* PKCS#11 specification for any symmetric key (+any_key_xxx) */ 3594eb88651SRuchika Gupta static const uint32_t symm_key_boolprops[] = { 36063f89caaSJens Wiklander PKCS11_CKA_ENCRYPT, PKCS11_CKA_DECRYPT, 36163f89caaSJens Wiklander PKCS11_CKA_SIGN, PKCS11_CKA_VERIFY, 36263f89caaSJens Wiklander PKCS11_CKA_WRAP, PKCS11_CKA_UNWRAP, 36363f89caaSJens Wiklander PKCS11_CKA_SENSITIVE, PKCS11_CKA_EXTRACTABLE, 36463f89caaSJens Wiklander PKCS11_CKA_WRAP_WITH_TRUSTED, PKCS11_CKA_TRUSTED, 36563f89caaSJens Wiklander }; 36663f89caaSJens Wiklander 3674eb88651SRuchika Gupta static const uint32_t symm_key_opt_or_null[] = { 36863f89caaSJens Wiklander PKCS11_CKA_WRAP_TEMPLATE, PKCS11_CKA_UNWRAP_TEMPLATE, 3690ac5c695SRuchika Gupta PKCS11_CKA_DERIVE_TEMPLATE, PKCS11_CKA_VALUE, 3700ac5c695SRuchika Gupta }; 3710ac5c695SRuchika Gupta 3720ac5c695SRuchika Gupta static const uint32_t symm_key_optional[] = { 3730ac5c695SRuchika Gupta PKCS11_CKA_VALUE_LEN, 37463f89caaSJens Wiklander }; 37563f89caaSJens Wiklander 3764eb88651SRuchika Gupta /* PKCS#11 specification for any asymmetric public key (+any_key_xxx) */ 3774eb88651SRuchika Gupta static const uint32_t public_key_boolprops[] = { 37863f89caaSJens Wiklander PKCS11_CKA_ENCRYPT, PKCS11_CKA_VERIFY, PKCS11_CKA_VERIFY_RECOVER, 37963f89caaSJens Wiklander PKCS11_CKA_WRAP, 38063f89caaSJens Wiklander PKCS11_CKA_TRUSTED, 38163f89caaSJens Wiklander }; 38263f89caaSJens Wiklander 3834eb88651SRuchika Gupta static const uint32_t public_key_mandated[] = { 38463f89caaSJens Wiklander }; 38563f89caaSJens Wiklander 3864eb88651SRuchika Gupta static const uint32_t public_key_opt_or_null[] = { 387edd95148SVesa Jääskeläinen PKCS11_CKA_SUBJECT, PKCS11_CKA_WRAP_TEMPLATE, 388edd95148SVesa Jääskeläinen PKCS11_CKA_PUBLIC_KEY_INFO, 38963f89caaSJens Wiklander }; 39063f89caaSJens Wiklander 3914eb88651SRuchika Gupta /* PKCS#11 specification for any asymmetric private key (+any_key_xxx) */ 3924eb88651SRuchika Gupta static const uint32_t private_key_boolprops[] = { 39363f89caaSJens Wiklander PKCS11_CKA_DECRYPT, PKCS11_CKA_SIGN, PKCS11_CKA_SIGN_RECOVER, 39463f89caaSJens Wiklander PKCS11_CKA_UNWRAP, 39563f89caaSJens Wiklander PKCS11_CKA_SENSITIVE, PKCS11_CKA_EXTRACTABLE, 39663f89caaSJens Wiklander PKCS11_CKA_WRAP_WITH_TRUSTED, PKCS11_CKA_ALWAYS_AUTHENTICATE, 39763f89caaSJens Wiklander }; 39863f89caaSJens Wiklander 3994eb88651SRuchika Gupta static const uint32_t private_key_mandated[] = { 40063f89caaSJens Wiklander }; 40163f89caaSJens Wiklander 4024eb88651SRuchika Gupta static const uint32_t private_key_opt_or_null[] = { 403edd95148SVesa Jääskeläinen PKCS11_CKA_SUBJECT, PKCS11_CKA_UNWRAP_TEMPLATE, 404edd95148SVesa Jääskeläinen PKCS11_CKA_PUBLIC_KEY_INFO, 40563f89caaSJens Wiklander }; 40663f89caaSJens Wiklander 4074eb88651SRuchika Gupta /* PKCS#11 specification for any RSA key (+public/private_key_xxx) */ 4089cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_gen_mand[] = { 40963f89caaSJens Wiklander PKCS11_CKA_MODULUS_BITS, 41063f89caaSJens Wiklander }; 41163f89caaSJens Wiklander 4129cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_create_mand[] = { 41363f89caaSJens Wiklander PKCS11_CKA_MODULUS, PKCS11_CKA_PUBLIC_EXPONENT, 41463f89caaSJens Wiklander }; 41563f89caaSJens Wiklander 4169cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_gen_opt_or_null[] = { 4179cf1afceSVesa Jääskeläinen PKCS11_CKA_PUBLIC_EXPONENT, 4189cf1afceSVesa Jääskeläinen }; 4199cf1afceSVesa Jääskeläinen 4209cf1afceSVesa Jääskeläinen static const uint32_t rsa_priv_key_opt_or_null[] = { 42163f89caaSJens Wiklander PKCS11_CKA_MODULUS, PKCS11_CKA_PUBLIC_EXPONENT, 42263f89caaSJens Wiklander PKCS11_CKA_PRIVATE_EXPONENT, 42363f89caaSJens Wiklander PKCS11_CKA_PRIME_1, PKCS11_CKA_PRIME_2, 42463f89caaSJens Wiklander PKCS11_CKA_EXPONENT_1, PKCS11_CKA_EXPONENT_2, PKCS11_CKA_COEFFICIENT, 42563f89caaSJens Wiklander }; 42663f89caaSJens Wiklander 4274eb88651SRuchika Gupta /* PKCS#11 specification for any EC key (+public/private_key_xxx) */ 4284eb88651SRuchika Gupta static const uint32_t ec_public_key_mandated[] = { 42963f89caaSJens Wiklander PKCS11_CKA_EC_PARAMS, 43063f89caaSJens Wiklander }; 43163f89caaSJens Wiklander 4324eb88651SRuchika Gupta static const uint32_t ec_public_key_opt_or_null[] = { 43363f89caaSJens Wiklander PKCS11_CKA_EC_POINT, 43463f89caaSJens Wiklander }; 43563f89caaSJens Wiklander 4364eb88651SRuchika Gupta static const uint32_t ec_private_key_mandated[] = { 43763f89caaSJens Wiklander }; 43863f89caaSJens Wiklander 4394eb88651SRuchika Gupta static const uint32_t ec_private_key_opt_or_null[] = { 44002b16804SVesa Jääskeläinen PKCS11_CKA_EC_PARAMS, 44163f89caaSJens Wiklander PKCS11_CKA_VALUE, 44263f89caaSJens Wiklander }; 44363f89caaSJens Wiklander 44463f89caaSJens Wiklander static enum pkcs11_rc create_storage_attributes(struct obj_attrs **out, 44563f89caaSJens Wiklander struct obj_attrs *temp) 44663f89caaSJens Wiklander { 44763f89caaSJens Wiklander enum pkcs11_class_id class = PKCS11_CKO_UNDEFINED_ID; 44863f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 44963f89caaSJens Wiklander 45063f89caaSJens Wiklander rc = init_attributes_head(out); 45163f89caaSJens Wiklander if (rc) 45263f89caaSJens Wiklander return rc; 45363f89caaSJens Wiklander 45463f89caaSJens Wiklander /* Object class is mandatory */ 45563f89caaSJens Wiklander class = get_class(temp); 45663f89caaSJens Wiklander if (class == PKCS11_CKO_UNDEFINED_ID) { 45763f89caaSJens Wiklander EMSG("Class attribute not found"); 45863f89caaSJens Wiklander 45963f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 46063f89caaSJens Wiklander } 46163f89caaSJens Wiklander rc = add_attribute(out, PKCS11_CKA_CLASS, &class, sizeof(uint32_t)); 46263f89caaSJens Wiklander if (rc) 46363f89caaSJens Wiklander return rc; 46463f89caaSJens Wiklander 4654eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, any_object_boolprops, 4664eb88651SRuchika Gupta ARRAY_SIZE(any_object_boolprops)); 46763f89caaSJens Wiklander if (rc) 46863f89caaSJens Wiklander return rc; 46963f89caaSJens Wiklander 4704eb88651SRuchika Gupta return set_attributes_opt_or_null(out, temp, any_object_opt_or_null, 4714eb88651SRuchika Gupta ARRAY_SIZE(any_object_opt_or_null)); 47263f89caaSJens Wiklander } 47363f89caaSJens Wiklander 47463f89caaSJens Wiklander static enum pkcs11_rc create_genkey_attributes(struct obj_attrs **out, 47563f89caaSJens Wiklander struct obj_attrs *temp) 47663f89caaSJens Wiklander { 47763f89caaSJens Wiklander uint32_t type = PKCS11_CKO_UNDEFINED_ID; 47863f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 47963f89caaSJens Wiklander 48063f89caaSJens Wiklander rc = create_storage_attributes(out, temp); 48163f89caaSJens Wiklander if (rc) 48263f89caaSJens Wiklander return rc; 48363f89caaSJens Wiklander 48463f89caaSJens Wiklander type = get_key_type(temp); 48563f89caaSJens Wiklander if (type == PKCS11_CKK_UNDEFINED_ID) { 48663f89caaSJens Wiklander EMSG("Key type attribute not found"); 48763f89caaSJens Wiklander 48863f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 48963f89caaSJens Wiklander } 49063f89caaSJens Wiklander rc = add_attribute(out, PKCS11_CKA_KEY_TYPE, &type, sizeof(uint32_t)); 49163f89caaSJens Wiklander if (rc) 49263f89caaSJens Wiklander return rc; 49363f89caaSJens Wiklander 4944eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, any_key_boolprops, 4954eb88651SRuchika Gupta ARRAY_SIZE(any_key_boolprops)); 49663f89caaSJens Wiklander if (rc) 49763f89caaSJens Wiklander return rc; 49863f89caaSJens Wiklander 4994eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, any_key_opt_or_null, 5004eb88651SRuchika Gupta ARRAY_SIZE(any_key_opt_or_null)); 5014eb88651SRuchika Gupta if (rc) 5024eb88651SRuchika Gupta return rc; 5034eb88651SRuchika Gupta 5044eb88651SRuchika Gupta return set_optional_attributes(out, temp, any_key_optional, 5054eb88651SRuchika Gupta ARRAY_SIZE(any_key_optional)); 5064eb88651SRuchika Gupta 50763f89caaSJens Wiklander } 50863f89caaSJens Wiklander 50963f89caaSJens Wiklander static enum pkcs11_rc create_symm_key_attributes(struct obj_attrs **out, 51063f89caaSJens Wiklander struct obj_attrs *temp) 51163f89caaSJens Wiklander { 51263f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 51363f89caaSJens Wiklander 51463f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_SECRET_KEY); 51563f89caaSJens Wiklander 51663f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 51763f89caaSJens Wiklander if (rc) 51863f89caaSJens Wiklander return rc; 51963f89caaSJens Wiklander 52063f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_SECRET_KEY); 52163f89caaSJens Wiklander 52263f89caaSJens Wiklander switch (get_key_type(*out)) { 52363f89caaSJens Wiklander case PKCS11_CKK_GENERIC_SECRET: 52463f89caaSJens Wiklander case PKCS11_CKK_AES: 52563f89caaSJens Wiklander case PKCS11_CKK_MD5_HMAC: 52663f89caaSJens Wiklander case PKCS11_CKK_SHA_1_HMAC: 52763f89caaSJens Wiklander case PKCS11_CKK_SHA256_HMAC: 52863f89caaSJens Wiklander case PKCS11_CKK_SHA384_HMAC: 52963f89caaSJens Wiklander case PKCS11_CKK_SHA512_HMAC: 53063f89caaSJens Wiklander case PKCS11_CKK_SHA224_HMAC: 53163f89caaSJens Wiklander break; 53263f89caaSJens Wiklander default: 53363f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 53463f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 53563f89caaSJens Wiklander 53663f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 53763f89caaSJens Wiklander } 53863f89caaSJens Wiklander 5394eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, symm_key_boolprops, 5404eb88651SRuchika Gupta ARRAY_SIZE(symm_key_boolprops)); 54163f89caaSJens Wiklander if (rc) 54263f89caaSJens Wiklander return rc; 54363f89caaSJens Wiklander 5440ac5c695SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, symm_key_opt_or_null, 5454eb88651SRuchika Gupta ARRAY_SIZE(symm_key_opt_or_null)); 5460ac5c695SRuchika Gupta if (rc) 5470ac5c695SRuchika Gupta return rc; 5480ac5c695SRuchika Gupta 5490ac5c695SRuchika Gupta return set_optional_attributes(out, temp, symm_key_optional, 5500ac5c695SRuchika Gupta ARRAY_SIZE(symm_key_optional)); 55163f89caaSJens Wiklander } 55263f89caaSJens Wiklander 55363f89caaSJens Wiklander static enum pkcs11_rc create_data_attributes(struct obj_attrs **out, 55463f89caaSJens Wiklander struct obj_attrs *temp) 55563f89caaSJens Wiklander { 55663f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 55763f89caaSJens Wiklander 55863f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_DATA); 55963f89caaSJens Wiklander 56063f89caaSJens Wiklander rc = create_storage_attributes(out, temp); 56163f89caaSJens Wiklander if (rc) 56263f89caaSJens Wiklander return rc; 56363f89caaSJens Wiklander 56463f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_DATA); 56563f89caaSJens Wiklander 5664eb88651SRuchika Gupta return set_attributes_opt_or_null(out, temp, raw_data_opt_or_null, 5674eb88651SRuchika Gupta ARRAY_SIZE(raw_data_opt_or_null)); 56863f89caaSJens Wiklander } 56963f89caaSJens Wiklander 57063f89caaSJens Wiklander static enum pkcs11_rc create_pub_key_attributes(struct obj_attrs **out, 5719cf1afceSVesa Jääskeläinen struct obj_attrs *temp, 5729cf1afceSVesa Jääskeläinen enum processing_func function) 57363f89caaSJens Wiklander { 57463f89caaSJens Wiklander uint32_t const *mandated = NULL; 5759cf1afceSVesa Jääskeläinen uint32_t const *oon = NULL; 57663f89caaSJens Wiklander size_t mandated_count = 0; 5779cf1afceSVesa Jääskeläinen size_t oon_count = 0; 57863f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 57963f89caaSJens Wiklander 58063f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_PUBLIC_KEY); 58163f89caaSJens Wiklander 58263f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 58363f89caaSJens Wiklander if (rc) 58463f89caaSJens Wiklander return rc; 58563f89caaSJens Wiklander 58663f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_PUBLIC_KEY); 58763f89caaSJens Wiklander 5884eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, public_key_boolprops, 5894eb88651SRuchika Gupta ARRAY_SIZE(public_key_boolprops)); 59063f89caaSJens Wiklander if (rc) 59163f89caaSJens Wiklander return rc; 59263f89caaSJens Wiklander 5934eb88651SRuchika Gupta rc = set_mandatory_attributes(out, temp, public_key_mandated, 5944eb88651SRuchika Gupta ARRAY_SIZE(public_key_mandated)); 59563f89caaSJens Wiklander if (rc) 59663f89caaSJens Wiklander return rc; 59763f89caaSJens Wiklander 5984eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, 5994eb88651SRuchika Gupta public_key_opt_or_null, 6004eb88651SRuchika Gupta ARRAY_SIZE(public_key_opt_or_null)); 60163f89caaSJens Wiklander if (rc) 60263f89caaSJens Wiklander return rc; 60363f89caaSJens Wiklander 60463f89caaSJens Wiklander switch (get_key_type(*out)) { 60563f89caaSJens Wiklander case PKCS11_CKK_RSA: 6069cf1afceSVesa Jääskeläinen switch (function) { 6079cf1afceSVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 6089cf1afceSVesa Jääskeläinen mandated = rsa_pub_key_gen_mand; 6099cf1afceSVesa Jääskeläinen oon = rsa_pub_key_gen_opt_or_null; 6109cf1afceSVesa Jääskeläinen mandated_count = ARRAY_SIZE(rsa_pub_key_gen_mand); 6119cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(rsa_pub_key_gen_opt_or_null); 6129cf1afceSVesa Jääskeläinen break; 6139cf1afceSVesa Jääskeläinen case PKCS11_FUNCTION_IMPORT: 6149cf1afceSVesa Jääskeläinen mandated = rsa_pub_key_create_mand; 6159cf1afceSVesa Jääskeläinen mandated_count = ARRAY_SIZE(rsa_pub_key_create_mand); 6169cf1afceSVesa Jääskeläinen break; 6179cf1afceSVesa Jääskeläinen default: 6189cf1afceSVesa Jääskeläinen EMSG("Unsupported function %#"PRIx32"/%s", function, 6199cf1afceSVesa Jääskeläinen id2str_function(function)); 6209cf1afceSVesa Jääskeläinen 6219cf1afceSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 6229cf1afceSVesa Jääskeläinen } 62363f89caaSJens Wiklander break; 62463f89caaSJens Wiklander case PKCS11_CKK_EC: 6254eb88651SRuchika Gupta mandated = ec_public_key_mandated; 6269cf1afceSVesa Jääskeläinen oon = ec_public_key_opt_or_null; 6274eb88651SRuchika Gupta mandated_count = ARRAY_SIZE(ec_public_key_mandated); 6289cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(ec_public_key_opt_or_null); 62963f89caaSJens Wiklander break; 63063f89caaSJens Wiklander default: 63163f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 63263f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 63363f89caaSJens Wiklander 63463f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 63563f89caaSJens Wiklander } 63663f89caaSJens Wiklander 63763f89caaSJens Wiklander rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 63863f89caaSJens Wiklander if (rc) 63963f89caaSJens Wiklander return rc; 64063f89caaSJens Wiklander 6419cf1afceSVesa Jääskeläinen return set_attributes_opt_or_null(out, temp, oon, oon_count); 64263f89caaSJens Wiklander } 64363f89caaSJens Wiklander 64463f89caaSJens Wiklander static enum pkcs11_rc create_priv_key_attributes(struct obj_attrs **out, 64563f89caaSJens Wiklander struct obj_attrs *temp) 64663f89caaSJens Wiklander { 64763f89caaSJens Wiklander uint32_t const *mandated = NULL; 6489cf1afceSVesa Jääskeläinen uint32_t const *oon = NULL; 64963f89caaSJens Wiklander size_t mandated_count = 0; 6509cf1afceSVesa Jääskeläinen size_t oon_count = 0; 65163f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 65263f89caaSJens Wiklander 65363f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_PRIVATE_KEY); 65463f89caaSJens Wiklander 65563f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 65663f89caaSJens Wiklander if (rc) 65763f89caaSJens Wiklander return rc; 65863f89caaSJens Wiklander 65963f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_PRIVATE_KEY); 66063f89caaSJens Wiklander 6614eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, private_key_boolprops, 6624eb88651SRuchika Gupta ARRAY_SIZE(private_key_boolprops)); 66363f89caaSJens Wiklander if (rc) 66463f89caaSJens Wiklander return rc; 66563f89caaSJens Wiklander 6664eb88651SRuchika Gupta rc = set_mandatory_attributes(out, temp, private_key_mandated, 6674eb88651SRuchika Gupta ARRAY_SIZE(private_key_mandated)); 66863f89caaSJens Wiklander if (rc) 66963f89caaSJens Wiklander return rc; 67063f89caaSJens Wiklander 6714eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, private_key_opt_or_null, 6724eb88651SRuchika Gupta ARRAY_SIZE(private_key_opt_or_null)); 67363f89caaSJens Wiklander if (rc) 67463f89caaSJens Wiklander return rc; 67563f89caaSJens Wiklander 67663f89caaSJens Wiklander switch (get_key_type(*out)) { 67763f89caaSJens Wiklander case PKCS11_CKK_RSA: 6789cf1afceSVesa Jääskeläinen oon = rsa_priv_key_opt_or_null; 6799cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(rsa_priv_key_opt_or_null); 68063f89caaSJens Wiklander break; 68163f89caaSJens Wiklander case PKCS11_CKK_EC: 6824eb88651SRuchika Gupta mandated = ec_private_key_mandated; 6839cf1afceSVesa Jääskeläinen oon = ec_private_key_opt_or_null; 6844eb88651SRuchika Gupta mandated_count = ARRAY_SIZE(ec_private_key_mandated); 6859cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(ec_private_key_opt_or_null); 68663f89caaSJens Wiklander break; 68763f89caaSJens Wiklander default: 68863f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 68963f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 69063f89caaSJens Wiklander 69163f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 69263f89caaSJens Wiklander } 69363f89caaSJens Wiklander 69463f89caaSJens Wiklander rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 69563f89caaSJens Wiklander if (rc) 69663f89caaSJens Wiklander return rc; 69763f89caaSJens Wiklander 6989cf1afceSVesa Jääskeläinen return set_attributes_opt_or_null(out, temp, oon, oon_count); 69963f89caaSJens Wiklander } 70063f89caaSJens Wiklander 701196bcd93SRuchika Gupta static enum pkcs11_rc 702196bcd93SRuchika Gupta sanitize_symm_key_attributes(struct obj_attrs **temp, 703196bcd93SRuchika Gupta enum processing_func function) 704196bcd93SRuchika Gupta { 705196bcd93SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK; 706196bcd93SRuchika Gupta uint32_t a_size = 0; 707196bcd93SRuchika Gupta 708196bcd93SRuchika Gupta assert(get_class(*temp) == PKCS11_CKO_SECRET_KEY); 709196bcd93SRuchika Gupta 710196bcd93SRuchika Gupta rc = get_attribute_ptr(*temp, PKCS11_CKA_VALUE, NULL, &a_size); 711196bcd93SRuchika Gupta 712196bcd93SRuchika Gupta switch (get_key_type(*temp)) { 713196bcd93SRuchika Gupta case PKCS11_CKK_GENERIC_SECRET: 714196bcd93SRuchika Gupta case PKCS11_CKK_AES: 715196bcd93SRuchika Gupta case PKCS11_CKK_MD5_HMAC: 716196bcd93SRuchika Gupta case PKCS11_CKK_SHA_1_HMAC: 717196bcd93SRuchika Gupta case PKCS11_CKK_SHA256_HMAC: 718196bcd93SRuchika Gupta case PKCS11_CKK_SHA384_HMAC: 719196bcd93SRuchika Gupta case PKCS11_CKK_SHA512_HMAC: 720196bcd93SRuchika Gupta case PKCS11_CKK_SHA224_HMAC: 721196bcd93SRuchika Gupta switch (function) { 722196bcd93SRuchika Gupta case PKCS11_FUNCTION_IMPORT: 723196bcd93SRuchika Gupta /* CKA_VALUE is a mandatory with C_CreateObject */ 724196bcd93SRuchika Gupta if (rc || a_size == 0) 725196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 726196bcd93SRuchika Gupta 727196bcd93SRuchika Gupta if (get_attribute_ptr(*temp, PKCS11_CKA_VALUE_LEN, NULL, 728196bcd93SRuchika Gupta NULL) != PKCS11_RV_NOT_FOUND) 729196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 730196bcd93SRuchika Gupta 731196bcd93SRuchika Gupta return add_attribute(temp, PKCS11_CKA_VALUE_LEN, 732196bcd93SRuchika Gupta &a_size, sizeof(uint32_t)); 733196bcd93SRuchika Gupta case PKCS11_FUNCTION_GENERATE: 734196bcd93SRuchika Gupta if (rc != PKCS11_RV_NOT_FOUND) 735196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 736196bcd93SRuchika Gupta break; 737196bcd93SRuchika Gupta default: 738196bcd93SRuchika Gupta break; 739196bcd93SRuchika Gupta } 740196bcd93SRuchika Gupta break; 741196bcd93SRuchika Gupta default: 742196bcd93SRuchika Gupta EMSG("Invalid key type %#"PRIx32"/%s", 743196bcd93SRuchika Gupta get_key_type(*temp), id2str_key_type(get_key_type(*temp))); 744196bcd93SRuchika Gupta 745196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 746196bcd93SRuchika Gupta } 747196bcd93SRuchika Gupta 748196bcd93SRuchika Gupta return PKCS11_CKR_OK; 749196bcd93SRuchika Gupta } 750196bcd93SRuchika Gupta 75163f89caaSJens Wiklander /* 75263f89caaSJens Wiklander * Create an attribute list for a new object from a template and a parent 75363f89caaSJens Wiklander * object (optional) for an object generation function (generate, copy, 75463f89caaSJens Wiklander * derive...). 75563f89caaSJens Wiklander * 75663f89caaSJens Wiklander * PKCS#11 directives on the supplied template and expected return value: 75763f89caaSJens Wiklander * - template has an invalid attribute ID: ATTRIBUTE_TYPE_INVALID 75863f89caaSJens Wiklander * - template has an invalid value for an attribute: ATTRIBUTE_VALID_INVALID 75963f89caaSJens Wiklander * - template has value for a read-only attribute: ATTRIBUTE_READ_ONLY 76063f89caaSJens Wiklander * - template+default+parent => still miss an attribute: TEMPLATE_INCONSISTENT 76163f89caaSJens Wiklander * 76263f89caaSJens Wiklander * INFO on PKCS11_CMD_COPY_OBJECT: 76363f89caaSJens Wiklander * - parent PKCS11_CKA_COPYIABLE=false => return ACTION_PROHIBITED. 76463f89caaSJens Wiklander * - template can specify PKCS11_CKA_TOKEN, PKCS11_CKA_PRIVATE, 76563f89caaSJens Wiklander * PKCS11_CKA_MODIFIABLE, PKCS11_CKA_DESTROYABLE. 76663f89caaSJens Wiklander * - SENSITIVE can change from false to true, not from true to false. 76763f89caaSJens Wiklander * - LOCAL is the parent LOCAL 76863f89caaSJens Wiklander */ 76963f89caaSJens Wiklander enum pkcs11_rc 77063f89caaSJens Wiklander create_attributes_from_template(struct obj_attrs **out, void *template, 77163f89caaSJens Wiklander size_t template_size, 77248799892SRuchika Gupta struct obj_attrs *parent, 77363f89caaSJens Wiklander enum processing_func function, 7744cfce748SRuchika Gupta enum pkcs11_mechanism_id mecha, 77502b16804SVesa Jääskeläinen enum pkcs11_class_id template_class) 77663f89caaSJens Wiklander { 77763f89caaSJens Wiklander struct obj_attrs *temp = NULL; 77863f89caaSJens Wiklander struct obj_attrs *attrs = NULL; 77963f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 78063f89caaSJens Wiklander uint8_t local = 0; 78163f89caaSJens Wiklander uint8_t always_sensitive = 0; 78263f89caaSJens Wiklander uint8_t never_extract = 0; 783e3f0cb56SRuchika Gupta uint8_t extractable = 0; 784fa247a2aSRuchika Gupta uint32_t class = PKCS11_UNDEFINED_ID; 785fa247a2aSRuchika Gupta uint32_t type = PKCS11_UNDEFINED_ID; 78663f89caaSJens Wiklander uint32_t mechanism_id = PKCS11_CKM_UNDEFINED_ID; 787e3f0cb56SRuchika Gupta struct obj_attrs *req_attrs = NULL; 788e3f0cb56SRuchika Gupta uint32_t size = 0; 789e3f0cb56SRuchika Gupta uint32_t indirect_template = PKCS11_CKA_UNDEFINED_ID; 79063f89caaSJens Wiklander 79163f89caaSJens Wiklander #ifdef DEBUG /* Sanity: check function argument */ 79263f89caaSJens Wiklander trace_attributes_from_api_head("template", template, template_size); 79363f89caaSJens Wiklander switch (function) { 794fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 795013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 79663f89caaSJens Wiklander case PKCS11_FUNCTION_IMPORT: 7972d25a9bcSRuchika Gupta case PKCS11_FUNCTION_MODIFY: 79848799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 799e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 8002d25a9bcSRuchika Gupta case PKCS11_FUNCTION_COPY: 80163f89caaSJens Wiklander break; 80263f89caaSJens Wiklander default: 80363f89caaSJens Wiklander TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 80463f89caaSJens Wiklander } 80563f89caaSJens Wiklander #endif 80663f89caaSJens Wiklander 807dcad3409SRuchika Gupta /* 808dcad3409SRuchika Gupta * For PKCS11_FUNCTION_GENERATE, find the class and type 809dcad3409SRuchika Gupta * based on the mechanism. These will be passed as hint 810dcad3409SRuchika Gupta * sanitize_client_object() and added in temp if not 811dcad3409SRuchika Gupta * already present 812dcad3409SRuchika Gupta */ 813dcad3409SRuchika Gupta if (function == PKCS11_FUNCTION_GENERATE) { 814fa247a2aSRuchika Gupta switch (mecha) { 815fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 816fa247a2aSRuchika Gupta class = PKCS11_CKO_SECRET_KEY; 817fa247a2aSRuchika Gupta type = PKCS11_CKK_GENERIC_SECRET; 818fa247a2aSRuchika Gupta break; 819fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 820fa247a2aSRuchika Gupta class = PKCS11_CKO_SECRET_KEY; 821fa247a2aSRuchika Gupta type = PKCS11_CKK_AES; 822fa247a2aSRuchika Gupta break; 823fa247a2aSRuchika Gupta default: 824dcad3409SRuchika Gupta TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 825fa247a2aSRuchika Gupta } 826fa247a2aSRuchika Gupta } 827fa247a2aSRuchika Gupta 8282d25a9bcSRuchika Gupta /* 829013934d8SVesa Jääskeläinen * For PKCS11_FUNCTION_GENERATE_PAIR, find the class and type 830013934d8SVesa Jääskeläinen * based on the mechanism. These will be passed as hint 831013934d8SVesa Jääskeläinen * sanitize_client_object() and added in temp if not 832013934d8SVesa Jääskeläinen * already present 833013934d8SVesa Jääskeläinen */ 834013934d8SVesa Jääskeläinen if (function == PKCS11_FUNCTION_GENERATE_PAIR) { 835013934d8SVesa Jääskeläinen switch (mecha) { 83602b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 83702b16804SVesa Jääskeläinen class = template_class; 83802b16804SVesa Jääskeläinen type = PKCS11_CKK_EC; 83902b16804SVesa Jääskeläinen break; 84086922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 84186922832SVesa Jääskeläinen class = template_class; 84286922832SVesa Jääskeläinen type = PKCS11_CKK_RSA; 84386922832SVesa Jääskeläinen break; 844013934d8SVesa Jääskeläinen default: 845013934d8SVesa Jääskeläinen TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 846013934d8SVesa Jääskeläinen } 847013934d8SVesa Jääskeläinen } 848013934d8SVesa Jääskeläinen 849013934d8SVesa Jääskeläinen /* 8502d25a9bcSRuchika Gupta * Check and remove duplicates if any and create a new temporary 8512d25a9bcSRuchika Gupta * template 8522d25a9bcSRuchika Gupta */ 853dcad3409SRuchika Gupta rc = sanitize_client_object(&temp, template, template_size, class, 854dcad3409SRuchika Gupta type); 855dcad3409SRuchika Gupta if (rc) 856dcad3409SRuchika Gupta goto out; 857dcad3409SRuchika Gupta 858dcad3409SRuchika Gupta /* 8592d25a9bcSRuchika Gupta * For function type modify and copy return the created template 8602d25a9bcSRuchika Gupta * from here. Rest of the code below is for creating objects 8612d25a9bcSRuchika Gupta * or generating keys. 8622d25a9bcSRuchika Gupta */ 8632d25a9bcSRuchika Gupta switch (function) { 8642d25a9bcSRuchika Gupta case PKCS11_FUNCTION_MODIFY: 8652d25a9bcSRuchika Gupta case PKCS11_FUNCTION_COPY: 8662d25a9bcSRuchika Gupta *out = temp; 8672d25a9bcSRuchika Gupta return rc; 868e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 869e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 870e3f0cb56SRuchika Gupta if (function == PKCS11_FUNCTION_UNWRAP) 871e3f0cb56SRuchika Gupta indirect_template = PKCS11_CKA_UNWRAP_TEMPLATE; 872e3f0cb56SRuchika Gupta else 873e3f0cb56SRuchika Gupta indirect_template = PKCS11_CKA_DERIVE_TEMPLATE; 874e3f0cb56SRuchika Gupta 875e3f0cb56SRuchika Gupta rc = get_attribute_ptr(parent, indirect_template, 876e3f0cb56SRuchika Gupta (void *)&req_attrs, &size); 877e3f0cb56SRuchika Gupta if (rc == PKCS11_CKR_OK && size != 0) { 878e3f0cb56SRuchika Gupta rc = attributes_match_add_reference(&temp, req_attrs); 879e3f0cb56SRuchika Gupta if (rc) 880e3f0cb56SRuchika Gupta goto out; 881e3f0cb56SRuchika Gupta } 882e3f0cb56SRuchika Gupta break; 8832d25a9bcSRuchika Gupta default: 8842d25a9bcSRuchika Gupta break; 8852d25a9bcSRuchika Gupta } 8862d25a9bcSRuchika Gupta 8872d25a9bcSRuchika Gupta /* 888dcad3409SRuchika Gupta * Check if class and type in temp are consistent with the mechanism 889dcad3409SRuchika Gupta */ 890fa247a2aSRuchika Gupta switch (mecha) { 891fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 892fa247a2aSRuchika Gupta if (get_class(temp) != PKCS11_CKO_SECRET_KEY || 893fa247a2aSRuchika Gupta get_key_type(temp) != PKCS11_CKK_GENERIC_SECRET) { 894fa247a2aSRuchika Gupta rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 895fa247a2aSRuchika Gupta goto out; 896fa247a2aSRuchika Gupta } 897fa247a2aSRuchika Gupta break; 898fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 899fa247a2aSRuchika Gupta if (get_class(temp) != PKCS11_CKO_SECRET_KEY || 900fa247a2aSRuchika Gupta get_key_type(temp) != PKCS11_CKK_AES) { 901fa247a2aSRuchika Gupta rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 902fa247a2aSRuchika Gupta goto out; 903fa247a2aSRuchika Gupta } 904fa247a2aSRuchika Gupta break; 90502b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 90602b16804SVesa Jääskeläinen if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && 90702b16804SVesa Jääskeläinen get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || 90802b16804SVesa Jääskeläinen get_key_type(temp) != PKCS11_CKK_EC) { 90902b16804SVesa Jääskeläinen rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 91002b16804SVesa Jääskeläinen goto out; 91102b16804SVesa Jääskeläinen } 91202b16804SVesa Jääskeläinen break; 91386922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 91486922832SVesa Jääskeläinen if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && 91586922832SVesa Jääskeläinen get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || 91686922832SVesa Jääskeläinen get_key_type(temp) != PKCS11_CKK_RSA) { 91786922832SVesa Jääskeläinen rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 91886922832SVesa Jääskeläinen goto out; 91986922832SVesa Jääskeläinen } 92086922832SVesa Jääskeläinen break; 921fa247a2aSRuchika Gupta default: 922fa247a2aSRuchika Gupta break; 923fa247a2aSRuchika Gupta } 92463f89caaSJens Wiklander 92563f89caaSJens Wiklander if (!sanitize_consistent_class_and_type(temp)) { 92663f89caaSJens Wiklander EMSG("Inconsistent class/type"); 92763f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 92863f89caaSJens Wiklander goto out; 92963f89caaSJens Wiklander } 93063f89caaSJens Wiklander 931e3f0cb56SRuchika Gupta /* 932e3f0cb56SRuchika Gupta * TBD - Add a check to see if temp contains any attribute which 933e3f0cb56SRuchika Gupta * is not consistent with the object class or type and return error. 934e3f0cb56SRuchika Gupta * In current implementation such attributes are ignored and not 935e3f0cb56SRuchika Gupta * added to final object while PKCS#11 specification expects a 936e3f0cb56SRuchika Gupta * failure and an error code be returned. 937e3f0cb56SRuchika Gupta */ 938e3f0cb56SRuchika Gupta 93963f89caaSJens Wiklander switch (get_class(temp)) { 94063f89caaSJens Wiklander case PKCS11_CKO_DATA: 94163f89caaSJens Wiklander rc = create_data_attributes(&attrs, temp); 94263f89caaSJens Wiklander break; 94363f89caaSJens Wiklander case PKCS11_CKO_SECRET_KEY: 944196bcd93SRuchika Gupta rc = sanitize_symm_key_attributes(&temp, function); 945196bcd93SRuchika Gupta if (rc) 946196bcd93SRuchika Gupta goto out; 94763f89caaSJens Wiklander rc = create_symm_key_attributes(&attrs, temp); 94863f89caaSJens Wiklander break; 94963f89caaSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 9509cf1afceSVesa Jääskeläinen rc = create_pub_key_attributes(&attrs, temp, function); 95163f89caaSJens Wiklander break; 95263f89caaSJens Wiklander case PKCS11_CKO_PRIVATE_KEY: 95363f89caaSJens Wiklander rc = create_priv_key_attributes(&attrs, temp); 95463f89caaSJens Wiklander break; 95563f89caaSJens Wiklander default: 95663f89caaSJens Wiklander DMSG("Invalid object class %#"PRIx32"/%s", 95763f89caaSJens Wiklander get_class(temp), id2str_class(get_class(temp))); 95863f89caaSJens Wiklander 95963f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 96063f89caaSJens Wiklander break; 96163f89caaSJens Wiklander } 96263f89caaSJens Wiklander if (rc) 96363f89caaSJens Wiklander goto out; 96463f89caaSJens Wiklander 96590c47fe2SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_LOCAL, NULL, NULL) != 966002f6b93SEtienne Carriere PKCS11_RV_NOT_FOUND) { 967002f6b93SEtienne Carriere rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 96863f89caaSJens Wiklander goto out; 969002f6b93SEtienne Carriere } 97063f89caaSJens Wiklander 97190c47fe2SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_KEY_GEN_MECHANISM, NULL, NULL) != 972002f6b93SEtienne Carriere PKCS11_RV_NOT_FOUND) { 973002f6b93SEtienne Carriere rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 97463f89caaSJens Wiklander goto out; 975002f6b93SEtienne Carriere } 97663f89caaSJens Wiklander 97763f89caaSJens Wiklander switch (function) { 978fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 979013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 980fa247a2aSRuchika Gupta local = PKCS11_TRUE; 981fa247a2aSRuchika Gupta break; 98263f89caaSJens Wiklander case PKCS11_FUNCTION_IMPORT: 98348799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 984e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 98563f89caaSJens Wiklander default: 98663f89caaSJens Wiklander local = PKCS11_FALSE; 98763f89caaSJens Wiklander break; 98863f89caaSJens Wiklander } 98963f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_LOCAL, &local, sizeof(local)); 99063f89caaSJens Wiklander if (rc) 99163f89caaSJens Wiklander goto out; 99263f89caaSJens Wiklander 99363f89caaSJens Wiklander switch (get_class(attrs)) { 99463f89caaSJens Wiklander case PKCS11_CKO_SECRET_KEY: 99563f89caaSJens Wiklander case PKCS11_CKO_PRIVATE_KEY: 99663f89caaSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 99763f89caaSJens Wiklander always_sensitive = PKCS11_FALSE; 99863f89caaSJens Wiklander never_extract = PKCS11_FALSE; 99963f89caaSJens Wiklander 1000fa247a2aSRuchika Gupta switch (function) { 100148799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 100248799892SRuchika Gupta always_sensitive = 100348799892SRuchika Gupta get_bool(parent, PKCS11_CKA_ALWAYS_SENSITIVE) && 100448799892SRuchika Gupta get_bool(attrs, PKCS11_CKA_SENSITIVE); 100548799892SRuchika Gupta never_extract = 100648799892SRuchika Gupta get_bool(parent, PKCS11_CKA_NEVER_EXTRACTABLE) && 100748799892SRuchika Gupta !get_bool(attrs, PKCS11_CKA_EXTRACTABLE); 100848799892SRuchika Gupta break; 1009e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 1010e3f0cb56SRuchika Gupta always_sensitive = PKCS11_FALSE; 1011e3f0cb56SRuchika Gupta never_extract = PKCS11_FALSE; 1012e3f0cb56SRuchika Gupta extractable = PKCS11_TRUE; 1013e3f0cb56SRuchika Gupta 1014e3f0cb56SRuchika Gupta /* 1015e3f0cb56SRuchika Gupta * Check if template passed by user has CKA_EXTRACTABLE. 1016e3f0cb56SRuchika Gupta * If not, by default value of CKA_EXTRACTABLE is set as 1017e3f0cb56SRuchika Gupta * TRUE. 1018e3f0cb56SRuchika Gupta */ 1019e3f0cb56SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_EXTRACTABLE, 1020e3f0cb56SRuchika Gupta NULL, 1021e3f0cb56SRuchika Gupta NULL) == PKCS11_RV_NOT_FOUND) { 1022e3f0cb56SRuchika Gupta rc = set_attribute(&attrs, 1023e3f0cb56SRuchika Gupta PKCS11_CKA_EXTRACTABLE, 1024e3f0cb56SRuchika Gupta &extractable, 1025e3f0cb56SRuchika Gupta sizeof(extractable)); 1026e3f0cb56SRuchika Gupta if (rc) 1027e3f0cb56SRuchika Gupta goto out; 1028e3f0cb56SRuchika Gupta } 1029e3f0cb56SRuchika Gupta break; 1030fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 1031013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 1032fa247a2aSRuchika Gupta always_sensitive = get_bool(attrs, 1033fa247a2aSRuchika Gupta PKCS11_CKA_SENSITIVE); 1034fa247a2aSRuchika Gupta never_extract = !get_bool(attrs, 1035fa247a2aSRuchika Gupta PKCS11_CKA_EXTRACTABLE); 1036fa247a2aSRuchika Gupta break; 1037fa247a2aSRuchika Gupta default: 1038fa247a2aSRuchika Gupta break; 1039fa247a2aSRuchika Gupta } 1040fa247a2aSRuchika Gupta 104163f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_ALWAYS_SENSITIVE, 104263f89caaSJens Wiklander &always_sensitive, sizeof(always_sensitive)); 104363f89caaSJens Wiklander if (rc) 104463f89caaSJens Wiklander goto out; 104563f89caaSJens Wiklander 104663f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_NEVER_EXTRACTABLE, 104763f89caaSJens Wiklander &never_extract, sizeof(never_extract)); 104863f89caaSJens Wiklander if (rc) 104963f89caaSJens Wiklander goto out; 105063f89caaSJens Wiklander 105163f89caaSJens Wiklander /* Keys mandate attribute PKCS11_CKA_KEY_GEN_MECHANISM */ 1052fa247a2aSRuchika Gupta if (local) 1053fa247a2aSRuchika Gupta mechanism_id = mecha; 1054fa247a2aSRuchika Gupta else 105563f89caaSJens Wiklander mechanism_id = PKCS11_CK_UNAVAILABLE_INFORMATION; 1056fa247a2aSRuchika Gupta 105763f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_KEY_GEN_MECHANISM, 105863f89caaSJens Wiklander &mechanism_id, sizeof(mechanism_id)); 105963f89caaSJens Wiklander if (rc) 106063f89caaSJens Wiklander goto out; 106163f89caaSJens Wiklander break; 106263f89caaSJens Wiklander 106363f89caaSJens Wiklander default: 106463f89caaSJens Wiklander break; 106563f89caaSJens Wiklander } 106663f89caaSJens Wiklander 106763f89caaSJens Wiklander *out = attrs; 106863f89caaSJens Wiklander 106963f89caaSJens Wiklander #ifdef DEBUG 107063f89caaSJens Wiklander trace_attributes("object", attrs); 107163f89caaSJens Wiklander #endif 107263f89caaSJens Wiklander 107363f89caaSJens Wiklander out: 107463f89caaSJens Wiklander TEE_Free(temp); 107563f89caaSJens Wiklander if (rc) 107663f89caaSJens Wiklander TEE_Free(attrs); 107763f89caaSJens Wiklander 107863f89caaSJens Wiklander return rc; 107963f89caaSJens Wiklander } 108063f89caaSJens Wiklander 108163f89caaSJens Wiklander static enum pkcs11_rc check_attrs_misc_integrity(struct obj_attrs *head) 108263f89caaSJens Wiklander { 108363f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_NEVER_EXTRACTABLE) && 108463f89caaSJens Wiklander get_bool(head, PKCS11_CKA_EXTRACTABLE)) { 108563f89caaSJens Wiklander DMSG("Never/Extractable attributes mismatch %d/%d", 108663f89caaSJens Wiklander get_bool(head, PKCS11_CKA_NEVER_EXTRACTABLE), 108763f89caaSJens Wiklander get_bool(head, PKCS11_CKA_EXTRACTABLE)); 108863f89caaSJens Wiklander 108963f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 109063f89caaSJens Wiklander } 109163f89caaSJens Wiklander 109263f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_ALWAYS_SENSITIVE) && 109363f89caaSJens Wiklander !get_bool(head, PKCS11_CKA_SENSITIVE)) { 109463f89caaSJens Wiklander DMSG("Sensitive/always attributes mismatch %d/%d", 109563f89caaSJens Wiklander get_bool(head, PKCS11_CKA_SENSITIVE), 109663f89caaSJens Wiklander get_bool(head, PKCS11_CKA_ALWAYS_SENSITIVE)); 109763f89caaSJens Wiklander 109863f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 109963f89caaSJens Wiklander } 110063f89caaSJens Wiklander 110163f89caaSJens Wiklander return PKCS11_CKR_OK; 110263f89caaSJens Wiklander } 110363f89caaSJens Wiklander 110489735787SRuchika Gupta bool object_is_private(struct obj_attrs *head) 110589735787SRuchika Gupta { 110665fb9092SVesa Jääskeläinen return get_bool(head, PKCS11_CKA_PRIVATE); 110789735787SRuchika Gupta } 110889735787SRuchika Gupta 11092d25a9bcSRuchika Gupta bool object_is_token(struct obj_attrs *head) 11102d25a9bcSRuchika Gupta { 11112d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_TOKEN); 11122d25a9bcSRuchika Gupta } 11132d25a9bcSRuchika Gupta 11142d25a9bcSRuchika Gupta bool object_is_modifiable(struct obj_attrs *head) 11152d25a9bcSRuchika Gupta { 11162d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_MODIFIABLE); 11172d25a9bcSRuchika Gupta } 11182d25a9bcSRuchika Gupta 11192d25a9bcSRuchika Gupta bool object_is_copyable(struct obj_attrs *head) 11202d25a9bcSRuchika Gupta { 11212d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_COPYABLE); 11222d25a9bcSRuchika Gupta } 11232d25a9bcSRuchika Gupta 112463f89caaSJens Wiklander /* 1125512cbf1dSJens Wiklander * Check access to object against authentication to token 1126512cbf1dSJens Wiklander */ 1127512cbf1dSJens Wiklander enum pkcs11_rc check_access_attrs_against_token(struct pkcs11_session *session, 1128512cbf1dSJens Wiklander struct obj_attrs *head) 1129512cbf1dSJens Wiklander { 1130512cbf1dSJens Wiklander bool private = true; 1131512cbf1dSJens Wiklander 1132512cbf1dSJens Wiklander switch (get_class(head)) { 1133512cbf1dSJens Wiklander case PKCS11_CKO_SECRET_KEY: 113465fb9092SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1135512cbf1dSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 1136512cbf1dSJens Wiklander case PKCS11_CKO_DATA: 113765fb9092SVesa Jääskeläinen private = object_is_private(head); 1138512cbf1dSJens Wiklander break; 1139512cbf1dSJens Wiklander default: 1140512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1141512cbf1dSJens Wiklander } 1142512cbf1dSJens Wiklander 11435db0fef4SRuchika Gupta if (private && (pkcs11_session_is_public(session) || 11445db0fef4SRuchika Gupta pkcs11_session_is_so(session))) { 11455db0fef4SRuchika Gupta DMSG("Private object access from a public or SO session"); 1146512cbf1dSJens Wiklander 114712f1ba86SRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 1148512cbf1dSJens Wiklander } 1149512cbf1dSJens Wiklander 1150512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1151512cbf1dSJens Wiklander } 1152512cbf1dSJens Wiklander 1153512cbf1dSJens Wiklander /* 115463f89caaSJens Wiklander * Check the attributes of a to-be-created object matches the token state 115563f89caaSJens Wiklander */ 115663f89caaSJens Wiklander enum pkcs11_rc check_created_attrs_against_token(struct pkcs11_session *session, 115763f89caaSJens Wiklander struct obj_attrs *head) 115863f89caaSJens Wiklander { 115963f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 116063f89caaSJens Wiklander 116163f89caaSJens Wiklander rc = check_attrs_misc_integrity(head); 116263f89caaSJens Wiklander if (rc) 116363f89caaSJens Wiklander return rc; 116463f89caaSJens Wiklander 116563f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_TRUSTED) && 116663f89caaSJens Wiklander !pkcs11_session_is_so(session)) { 116763f89caaSJens Wiklander DMSG("Can't create trusted object"); 116863f89caaSJens Wiklander 116963f89caaSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 117063f89caaSJens Wiklander } 117163f89caaSJens Wiklander 117263f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_TOKEN) && 117363f89caaSJens Wiklander !pkcs11_session_is_read_write(session)) { 117463f89caaSJens Wiklander DMSG("Can't create persistent object"); 117563f89caaSJens Wiklander 117663f89caaSJens Wiklander return PKCS11_CKR_SESSION_READ_ONLY; 117763f89caaSJens Wiklander } 117863f89caaSJens Wiklander 117963f89caaSJens Wiklander /* 118063f89caaSJens Wiklander * TODO: START_DATE and END_DATE: complies with current time? 118163f89caaSJens Wiklander */ 118263f89caaSJens Wiklander return PKCS11_CKR_OK; 118363f89caaSJens Wiklander } 118463f89caaSJens Wiklander 118563f89caaSJens Wiklander #define DMSG_BAD_BBOOL(attr, proc, head) \ 118663f89caaSJens Wiklander do { \ 118763f89caaSJens Wiklander uint32_t __maybe_unused _attr = (attr); \ 118863f89caaSJens Wiklander uint8_t __maybe_unused _bvalue = 0; \ 118963f89caaSJens Wiklander enum pkcs11_rc __maybe_unused _rc = PKCS11_CKR_OK; \ 119063f89caaSJens Wiklander \ 119163f89caaSJens Wiklander _rc = get_attribute((head), _attr, &_bvalue, NULL); \ 119263f89caaSJens Wiklander DMSG("%s issue for %s: %sfound, value %"PRIu8, \ 119363f89caaSJens Wiklander id2str_attr(_attr), id2str_proc((proc)), \ 119463f89caaSJens Wiklander _rc ? "not " : "", _bvalue); \ 119563f89caaSJens Wiklander } while (0) 119663f89caaSJens Wiklander 119763f89caaSJens Wiklander static bool __maybe_unused check_attr_bval(uint32_t proc_id __maybe_unused, 119863f89caaSJens Wiklander struct obj_attrs *head, 119963f89caaSJens Wiklander uint32_t attribute, bool val) 120063f89caaSJens Wiklander { 120163f89caaSJens Wiklander uint8_t bbool = 0; 120263f89caaSJens Wiklander uint32_t sz = sizeof(bbool); 120363f89caaSJens Wiklander 120463f89caaSJens Wiklander if (!get_attribute(head, attribute, &bbool, &sz) && !!bbool == val) 120563f89caaSJens Wiklander return true; 120663f89caaSJens Wiklander 120763f89caaSJens Wiklander DMSG_BAD_BBOOL(attribute, proc_id, head); 120863f89caaSJens Wiklander return false; 120963f89caaSJens Wiklander } 121063f89caaSJens Wiklander 121163f89caaSJens Wiklander /* 121263f89caaSJens Wiklander * Check the attributes of a new secret match the processing/mechanism 121363f89caaSJens Wiklander * used to create it. 121463f89caaSJens Wiklander * 121563f89caaSJens Wiklander * @proc_id - PKCS11_CKM_xxx 121663f89caaSJens Wiklander * @head - head of the attributes of the to-be-created object. 121763f89caaSJens Wiklander */ 121863f89caaSJens Wiklander enum pkcs11_rc check_created_attrs_against_processing(uint32_t proc_id, 121963f89caaSJens Wiklander struct obj_attrs *head) 122063f89caaSJens Wiklander { 122163f89caaSJens Wiklander /* 122263f89caaSJens Wiklander * Processings that do not create secrets are not expected to call 122363f89caaSJens Wiklander * this function which would panic. 122463f89caaSJens Wiklander */ 122563f89caaSJens Wiklander switch (proc_id) { 122663f89caaSJens Wiklander case PKCS11_PROCESSING_IMPORT: 1227e3f0cb56SRuchika Gupta case PKCS11_CKM_AES_ECB: 1228e3f0cb56SRuchika Gupta case PKCS11_CKM_AES_CBC: 122948799892SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 123048799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 123163f89caaSJens Wiklander assert(check_attr_bval(proc_id, head, PKCS11_CKA_LOCAL, false)); 123263f89caaSJens Wiklander break; 1233fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1234fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 123502b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 123686922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 1237fa247a2aSRuchika Gupta assert(check_attr_bval(proc_id, head, PKCS11_CKA_LOCAL, true)); 1238fa247a2aSRuchika Gupta break; 123963f89caaSJens Wiklander default: 124063f89caaSJens Wiklander TEE_Panic(proc_id); 124163f89caaSJens Wiklander break; 124263f89caaSJens Wiklander } 124363f89caaSJens Wiklander 1244fa247a2aSRuchika Gupta switch (proc_id) { 1245fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1246fa247a2aSRuchika Gupta assert(get_key_type(head) == PKCS11_CKK_GENERIC_SECRET); 1247fa247a2aSRuchika Gupta break; 1248fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 1249fa247a2aSRuchika Gupta assert(get_key_type(head) == PKCS11_CKK_AES); 1250fa247a2aSRuchika Gupta break; 125102b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 125202b16804SVesa Jääskeläinen assert(get_key_type(head) == PKCS11_CKK_EC); 125302b16804SVesa Jääskeläinen break; 125486922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 125586922832SVesa Jääskeläinen assert(get_key_type(head) == PKCS11_CKK_RSA); 125686922832SVesa Jääskeläinen break; 1257fa247a2aSRuchika Gupta case PKCS11_PROCESSING_IMPORT: 1258fa247a2aSRuchika Gupta default: 1259fa247a2aSRuchika Gupta break; 1260fa247a2aSRuchika Gupta } 1261fa247a2aSRuchika Gupta 126263f89caaSJens Wiklander return PKCS11_CKR_OK; 126363f89caaSJens Wiklander } 1264512cbf1dSJens Wiklander 12652d0cd829SRuchika Gupta /* Return min and max key size supported for a key_type in bytes */ 1266512cbf1dSJens Wiklander static void get_key_min_max_sizes(enum pkcs11_key_type key_type, 1267512cbf1dSJens Wiklander uint32_t *min_key_size, 1268512cbf1dSJens Wiklander uint32_t *max_key_size) 1269512cbf1dSJens Wiklander { 1270512cbf1dSJens Wiklander enum pkcs11_mechanism_id mechanism = PKCS11_CKM_UNDEFINED_ID; 1271512cbf1dSJens Wiklander 1272512cbf1dSJens Wiklander switch (key_type) { 1273fa247a2aSRuchika Gupta case PKCS11_CKK_GENERIC_SECRET: 1274fa247a2aSRuchika Gupta mechanism = PKCS11_CKM_GENERIC_SECRET_KEY_GEN; 1275fa247a2aSRuchika Gupta break; 1276512cbf1dSJens Wiklander case PKCS11_CKK_AES: 1277512cbf1dSJens Wiklander mechanism = PKCS11_CKM_AES_KEY_GEN; 1278512cbf1dSJens Wiklander break; 12791f45c9cfSRuchika Gupta case PKCS11_CKK_MD5_HMAC: 12801f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_MD5_HMAC; 12811f45c9cfSRuchika Gupta break; 12821f45c9cfSRuchika Gupta case PKCS11_CKK_SHA_1_HMAC: 12831f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA_1_HMAC; 12841f45c9cfSRuchika Gupta break; 12851f45c9cfSRuchika Gupta case PKCS11_CKK_SHA224_HMAC: 12861f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA224_HMAC; 12871f45c9cfSRuchika Gupta break; 1288a339a354SEtienne Carriere case PKCS11_CKK_SHA256_HMAC: 1289a339a354SEtienne Carriere mechanism = PKCS11_CKM_SHA256_HMAC; 1290a339a354SEtienne Carriere break; 12911f45c9cfSRuchika Gupta case PKCS11_CKK_SHA384_HMAC: 12921f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA384_HMAC; 12931f45c9cfSRuchika Gupta break; 12941f45c9cfSRuchika Gupta case PKCS11_CKK_SHA512_HMAC: 12951f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA512_HMAC; 12961f45c9cfSRuchika Gupta break; 1297db28c542SVesa Jääskeläinen case PKCS11_CKK_EC: 1298db28c542SVesa Jääskeläinen mechanism = PKCS11_CKM_EC_KEY_PAIR_GEN; 1299db28c542SVesa Jääskeläinen break; 130086922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 130186922832SVesa Jääskeläinen mechanism = PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN; 130286922832SVesa Jääskeläinen break; 1303512cbf1dSJens Wiklander default: 1304512cbf1dSJens Wiklander TEE_Panic(key_type); 1305512cbf1dSJens Wiklander break; 1306512cbf1dSJens Wiklander } 1307512cbf1dSJens Wiklander 13082d0cd829SRuchika Gupta mechanism_supported_key_sizes_bytes(mechanism, min_key_size, 1309512cbf1dSJens Wiklander max_key_size); 1310512cbf1dSJens Wiklander } 1311512cbf1dSJens Wiklander 1312512cbf1dSJens Wiklander enum pkcs11_rc check_created_attrs(struct obj_attrs *key1, 1313512cbf1dSJens Wiklander struct obj_attrs *key2) 1314512cbf1dSJens Wiklander { 1315512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 1316512cbf1dSJens Wiklander struct obj_attrs *secret = NULL; 1317013934d8SVesa Jääskeläinen struct obj_attrs *private = NULL; 1318013934d8SVesa Jääskeläinen struct obj_attrs *public = NULL; 1319512cbf1dSJens Wiklander uint32_t max_key_size = 0; 1320512cbf1dSJens Wiklander uint32_t min_key_size = 0; 1321512cbf1dSJens Wiklander uint32_t key_length = 0; 1322512cbf1dSJens Wiklander 1323512cbf1dSJens Wiklander switch (get_class(key1)) { 1324512cbf1dSJens Wiklander case PKCS11_CKO_SECRET_KEY: 1325512cbf1dSJens Wiklander secret = key1; 1326512cbf1dSJens Wiklander break; 1327013934d8SVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 1328013934d8SVesa Jääskeläinen public = key1; 1329013934d8SVesa Jääskeläinen break; 1330013934d8SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1331013934d8SVesa Jääskeläinen private = key1; 1332013934d8SVesa Jääskeläinen break; 1333512cbf1dSJens Wiklander default: 1334512cbf1dSJens Wiklander return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 1335512cbf1dSJens Wiklander } 1336512cbf1dSJens Wiklander 1337013934d8SVesa Jääskeläinen if (key2) { 1338013934d8SVesa Jääskeläinen switch (get_class(key2)) { 1339013934d8SVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 1340013934d8SVesa Jääskeläinen public = key2; 1341013934d8SVesa Jääskeläinen if (private == key1) 1342013934d8SVesa Jääskeläinen break; 1343013934d8SVesa Jääskeläinen 1344013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1345013934d8SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1346013934d8SVesa Jääskeläinen private = key2; 1347013934d8SVesa Jääskeläinen if (public == key1) 1348013934d8SVesa Jääskeläinen break; 1349013934d8SVesa Jääskeläinen 1350013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1351013934d8SVesa Jääskeläinen default: 1352512cbf1dSJens Wiklander return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 1353013934d8SVesa Jääskeläinen } 1354013934d8SVesa Jääskeläinen 1355013934d8SVesa Jääskeläinen if (get_key_type(private) != get_key_type(public)) 1356013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1357013934d8SVesa Jääskeläinen } 1358512cbf1dSJens Wiklander 1359512cbf1dSJens Wiklander if (secret) { 1360512cbf1dSJens Wiklander switch (get_key_type(secret)) { 1361512cbf1dSJens Wiklander case PKCS11_CKK_AES: 1362512cbf1dSJens Wiklander case PKCS11_CKK_GENERIC_SECRET: 1363512cbf1dSJens Wiklander case PKCS11_CKK_MD5_HMAC: 1364512cbf1dSJens Wiklander case PKCS11_CKK_SHA_1_HMAC: 1365512cbf1dSJens Wiklander case PKCS11_CKK_SHA224_HMAC: 1366512cbf1dSJens Wiklander case PKCS11_CKK_SHA256_HMAC: 1367512cbf1dSJens Wiklander case PKCS11_CKK_SHA384_HMAC: 1368512cbf1dSJens Wiklander case PKCS11_CKK_SHA512_HMAC: 1369512cbf1dSJens Wiklander break; 1370512cbf1dSJens Wiklander default: 1371512cbf1dSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1372512cbf1dSJens Wiklander } 1373512cbf1dSJens Wiklander 1374512cbf1dSJens Wiklander /* Get key size */ 1375512cbf1dSJens Wiklander rc = get_u32_attribute(secret, PKCS11_CKA_VALUE_LEN, 1376512cbf1dSJens Wiklander &key_length); 1377512cbf1dSJens Wiklander if (rc) 1378d1d44372SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCOMPLETE; 1379512cbf1dSJens Wiklander } 1380013934d8SVesa Jääskeläinen if (public) { 1381013934d8SVesa Jääskeläinen switch (get_key_type(public)) { 138286922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 138386922832SVesa Jääskeläinen /* Get key size */ 138486922832SVesa Jääskeläinen rc = get_u32_attribute(public, PKCS11_CKA_MODULUS_BITS, 138586922832SVesa Jääskeläinen &key_length); 138686922832SVesa Jääskeläinen if (rc) 138786922832SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 138886922832SVesa Jääskeläinen key_length = ROUNDUP(key_length, 8) / 8; 138986922832SVesa Jääskeläinen break; 139002b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 139102b16804SVesa Jääskeläinen break; 1392013934d8SVesa Jääskeläinen default: 1393013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1394013934d8SVesa Jääskeläinen } 1395013934d8SVesa Jääskeläinen } 1396013934d8SVesa Jääskeläinen if (private) { 1397013934d8SVesa Jääskeläinen switch (get_key_type(private)) { 139886922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 139902b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 140002b16804SVesa Jääskeläinen break; 1401013934d8SVesa Jääskeläinen default: 1402013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1403013934d8SVesa Jääskeläinen } 1404013934d8SVesa Jääskeläinen } 1405512cbf1dSJens Wiklander 140602b16804SVesa Jääskeläinen /* 140702b16804SVesa Jääskeläinen * Check key size for symmetric keys and RSA keys 140802b16804SVesa Jääskeläinen * EC is bound to domains, no need to check here. 140902b16804SVesa Jääskeläinen */ 141002b16804SVesa Jääskeläinen switch (get_key_type(key1)) { 141102b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 141202b16804SVesa Jääskeläinen return PKCS11_CKR_OK; 141302b16804SVesa Jääskeläinen default: 141402b16804SVesa Jääskeläinen break; 141502b16804SVesa Jääskeläinen } 141602b16804SVesa Jääskeläinen 1417512cbf1dSJens Wiklander get_key_min_max_sizes(get_key_type(key1), &min_key_size, &max_key_size); 1418512cbf1dSJens Wiklander if (key_length < min_key_size || key_length > max_key_size) { 1419512cbf1dSJens Wiklander EMSG("Length %"PRIu32" vs range [%"PRIu32" %"PRIu32"]", 1420512cbf1dSJens Wiklander key_length, min_key_size, max_key_size); 1421512cbf1dSJens Wiklander 1422512cbf1dSJens Wiklander return PKCS11_CKR_KEY_SIZE_RANGE; 1423512cbf1dSJens Wiklander } 1424512cbf1dSJens Wiklander 142549ed60abSRuchika Gupta if (secret && get_key_type(secret) == PKCS11_CKK_AES) { 142649ed60abSRuchika Gupta if (key_length != 16 && key_length != 24 && key_length != 32) 142749ed60abSRuchika Gupta return PKCS11_CKR_KEY_SIZE_RANGE; 142849ed60abSRuchika Gupta } 142949ed60abSRuchika Gupta 1430512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1431512cbf1dSJens Wiklander } 1432512cbf1dSJens Wiklander 1433512cbf1dSJens Wiklander /* Check processing ID against attribute ALLOWED_MECHANISMS if any */ 1434512cbf1dSJens Wiklander static bool parent_key_complies_allowed_processings(uint32_t proc_id, 1435512cbf1dSJens Wiklander struct obj_attrs *head) 1436512cbf1dSJens Wiklander { 1437512cbf1dSJens Wiklander char *attr = NULL; 1438512cbf1dSJens Wiklander uint32_t size = 0; 1439512cbf1dSJens Wiklander uint32_t proc = 0; 1440512cbf1dSJens Wiklander size_t count = 0; 14416a760c9eSEtienne Carriere enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 1442512cbf1dSJens Wiklander 14436a760c9eSEtienne Carriere rc = get_attribute_ptr(head, PKCS11_CKA_ALLOWED_MECHANISMS, 14446a760c9eSEtienne Carriere (void *)&attr, &size); 14456a760c9eSEtienne Carriere if (rc == PKCS11_RV_NOT_FOUND) 1446512cbf1dSJens Wiklander return true; 14476a760c9eSEtienne Carriere if (rc) { 14486a760c9eSEtienne Carriere EMSG("unexpected attributes state"); 14496a760c9eSEtienne Carriere TEE_Panic(TEE_ERROR_BAD_STATE); 1450512cbf1dSJens Wiklander } 1451512cbf1dSJens Wiklander 1452512cbf1dSJens Wiklander for (count = size / sizeof(uint32_t); count; count--) { 1453512cbf1dSJens Wiklander TEE_MemMove(&proc, attr, sizeof(uint32_t)); 1454512cbf1dSJens Wiklander attr += sizeof(uint32_t); 1455512cbf1dSJens Wiklander 1456512cbf1dSJens Wiklander if (proc == proc_id) 1457512cbf1dSJens Wiklander return true; 1458512cbf1dSJens Wiklander } 1459512cbf1dSJens Wiklander 1460512cbf1dSJens Wiklander DMSG("can't find %s in allowed list", id2str_proc(proc_id)); 1461512cbf1dSJens Wiklander return false; 1462512cbf1dSJens Wiklander } 1463512cbf1dSJens Wiklander 1464512cbf1dSJens Wiklander static enum pkcs11_attr_id func_to_attr(enum processing_func func) 1465512cbf1dSJens Wiklander { 1466512cbf1dSJens Wiklander switch (func) { 1467512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 1468512cbf1dSJens Wiklander return PKCS11_CKA_ENCRYPT; 1469512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 1470512cbf1dSJens Wiklander return PKCS11_CKA_DECRYPT; 1471512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN: 1472512cbf1dSJens Wiklander return PKCS11_CKA_SIGN; 1473512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY: 1474512cbf1dSJens Wiklander return PKCS11_CKA_VERIFY; 1475512cbf1dSJens Wiklander case PKCS11_FUNCTION_WRAP: 1476512cbf1dSJens Wiklander return PKCS11_CKA_WRAP; 1477512cbf1dSJens Wiklander case PKCS11_FUNCTION_UNWRAP: 1478512cbf1dSJens Wiklander return PKCS11_CKA_UNWRAP; 1479512cbf1dSJens Wiklander case PKCS11_FUNCTION_DERIVE: 1480512cbf1dSJens Wiklander return PKCS11_CKA_DERIVE; 1481512cbf1dSJens Wiklander default: 1482512cbf1dSJens Wiklander return PKCS11_CKA_UNDEFINED_ID; 1483512cbf1dSJens Wiklander } 1484512cbf1dSJens Wiklander } 1485512cbf1dSJens Wiklander 1486512cbf1dSJens Wiklander enum pkcs11_rc 1487512cbf1dSJens Wiklander check_parent_attrs_against_processing(enum pkcs11_mechanism_id proc_id, 1488512cbf1dSJens Wiklander enum processing_func function, 1489512cbf1dSJens Wiklander struct obj_attrs *head) 1490512cbf1dSJens Wiklander { 1491512cbf1dSJens Wiklander enum pkcs11_class_id key_class = get_class(head); 1492512cbf1dSJens Wiklander enum pkcs11_key_type key_type = get_key_type(head); 1493512cbf1dSJens Wiklander enum pkcs11_attr_id attr = func_to_attr(function); 1494512cbf1dSJens Wiklander 1495512cbf1dSJens Wiklander if (!get_bool(head, attr)) { 1496512cbf1dSJens Wiklander DMSG("%s not permitted", id2str_attr(attr)); 1497512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1498512cbf1dSJens Wiklander } 1499512cbf1dSJens Wiklander 1500512cbf1dSJens Wiklander /* Check processing complies with parent key family */ 1501512cbf1dSJens Wiklander switch (proc_id) { 1502512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 1503512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 1504512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC_PAD: 1505512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 1506512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 1507*0ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC: 1508*0ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC_GENERAL: 1509512cbf1dSJens Wiklander if (key_class == PKCS11_CKO_SECRET_KEY && 1510512cbf1dSJens Wiklander key_type == PKCS11_CKK_AES) 1511512cbf1dSJens Wiklander break; 1512512cbf1dSJens Wiklander 1513512cbf1dSJens Wiklander DMSG("%s invalid key %s/%s", id2str_proc(proc_id), 1514512cbf1dSJens Wiklander id2str_class(key_class), id2str_key_type(key_type)); 1515512cbf1dSJens Wiklander 15165f80f270SRuchika Gupta if (function == PKCS11_FUNCTION_WRAP) 15175f80f270SRuchika Gupta return PKCS11_CKR_WRAPPING_KEY_TYPE_INCONSISTENT; 1518e3f0cb56SRuchika Gupta else if (function == PKCS11_FUNCTION_UNWRAP) 1519e3f0cb56SRuchika Gupta return PKCS11_CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT; 15205f80f270SRuchika Gupta else 1521512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1522512cbf1dSJens Wiklander 1523c3033708SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 1524c3033708SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 1525c3033708SRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY && 1526c3033708SRuchika Gupta key_type != PKCS11_CKK_AES) 1527c3033708SRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1528c3033708SRuchika Gupta 1529c3033708SRuchika Gupta if (get_bool(head, PKCS11_CKA_ENCRYPT)) { 1530c3033708SRuchika Gupta /* 1531c3033708SRuchika Gupta * Intentionally refuse to proceed despite 1532c3033708SRuchika Gupta * PKCS#11 specifications v2.40 and v3.0 not expecting 1533c3033708SRuchika Gupta * this behavior to avoid potential security issue 1534c3033708SRuchika Gupta * where keys derived by these mechanisms can be 1535c3033708SRuchika Gupta * revealed by doing data encryption using parent key. 1536c3033708SRuchika Gupta */ 1537c3033708SRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED; 1538c3033708SRuchika Gupta } 1539c3033708SRuchika Gupta 1540c3033708SRuchika Gupta break; 1541689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 1542689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 1543689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 1544689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 1545689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 1546689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 154770b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 154870b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 154970b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 155070b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 155170b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 155270b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 1553689f4e5bSRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY) 1554689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1555689f4e5bSRuchika Gupta 1556689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_GENERIC_SECRET) 1557689f4e5bSRuchika Gupta break; 1558689f4e5bSRuchika Gupta 1559689f4e5bSRuchika Gupta switch (proc_id) { 1560689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 156170b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 1562689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_MD5_HMAC) 1563689f4e5bSRuchika Gupta break; 1564689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1565689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 156670b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 1567689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA_1_HMAC) 1568689f4e5bSRuchika Gupta break; 1569689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1570689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 157170b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 1572689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA224_HMAC) 1573689f4e5bSRuchika Gupta break; 1574689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1575689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 157670b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 1577689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA256_HMAC) 1578689f4e5bSRuchika Gupta break; 1579689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1580689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 158170b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 1582689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA384_HMAC) 1583689f4e5bSRuchika Gupta break; 1584689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1585689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 158670b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 1587689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA512_HMAC) 1588689f4e5bSRuchika Gupta break; 1589689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1590689f4e5bSRuchika Gupta default: 1591689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1592689f4e5bSRuchika Gupta } 1593689f4e5bSRuchika Gupta break; 1594689f4e5bSRuchika Gupta 1595fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 1596fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 1597fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 1598fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 1599fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 1600fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 1601fb279d8bSVesa Jääskeläinen if (key_type != PKCS11_CKK_EC) { 1602fb279d8bSVesa Jääskeläinen EMSG("Invalid key %s for mechanism %s", 1603fb279d8bSVesa Jääskeläinen id2str_type(key_type, key_class), 1604fb279d8bSVesa Jääskeläinen id2str_proc(proc_id)); 1605fb279d8bSVesa Jääskeläinen 1606fb279d8bSVesa Jääskeläinen return PKCS11_CKR_KEY_TYPE_INCONSISTENT; 1607fb279d8bSVesa Jääskeläinen } 1608fb279d8bSVesa Jääskeläinen if (key_class != PKCS11_CKO_PUBLIC_KEY && 1609fb279d8bSVesa Jääskeläinen key_class != PKCS11_CKO_PRIVATE_KEY) { 1610fb279d8bSVesa Jääskeläinen EMSG("Invalid key class for mechanism %s", 1611fb279d8bSVesa Jääskeläinen id2str_proc(proc_id)); 1612fb279d8bSVesa Jääskeläinen 1613fb279d8bSVesa Jääskeläinen return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1614fb279d8bSVesa Jääskeläinen } 1615fb279d8bSVesa Jääskeläinen break; 16160442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 16170442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 16180442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 16190442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 16200442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 16210442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 16220442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 1623dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 1624d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 1625d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 1626d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 1627d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 1628d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 1629d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 16300442c956SVesa Jääskeläinen if (key_type != PKCS11_CKK_RSA) { 16310442c956SVesa Jääskeläinen EMSG("Invalid key %s for mechanism %s", 16320442c956SVesa Jääskeläinen id2str_type(key_type, key_class), 16330442c956SVesa Jääskeläinen id2str_proc(proc_id)); 16340442c956SVesa Jääskeläinen 16350442c956SVesa Jääskeläinen return PKCS11_CKR_KEY_TYPE_INCONSISTENT; 16360442c956SVesa Jääskeläinen } 16370442c956SVesa Jääskeläinen if (key_class != PKCS11_CKO_PUBLIC_KEY && 16380442c956SVesa Jääskeläinen key_class != PKCS11_CKO_PRIVATE_KEY) { 16390442c956SVesa Jääskeläinen EMSG("Invalid key class for mechanism %s", 16400442c956SVesa Jääskeläinen id2str_proc(proc_id)); 16410442c956SVesa Jääskeläinen 16420442c956SVesa Jääskeläinen return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 16430442c956SVesa Jääskeläinen } 16440442c956SVesa Jääskeläinen break; 1645512cbf1dSJens Wiklander default: 1646512cbf1dSJens Wiklander DMSG("Invalid processing %#"PRIx32"/%s", proc_id, 1647512cbf1dSJens Wiklander id2str_proc(proc_id)); 1648512cbf1dSJens Wiklander 1649512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_INVALID; 1650512cbf1dSJens Wiklander } 1651512cbf1dSJens Wiklander 1652512cbf1dSJens Wiklander if (!parent_key_complies_allowed_processings(proc_id, head)) { 1653512cbf1dSJens Wiklander DMSG("Allowed mechanism failed"); 1654512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1655512cbf1dSJens Wiklander } 1656512cbf1dSJens Wiklander 1657512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1658512cbf1dSJens Wiklander } 1659783c1515SRuchika Gupta 1660783c1515SRuchika Gupta bool attribute_is_exportable(struct pkcs11_attribute_head *req_attr, 1661783c1515SRuchika Gupta struct pkcs11_object *obj) 1662783c1515SRuchika Gupta { 1663783c1515SRuchika Gupta uint8_t boolval = 0; 1664783c1515SRuchika Gupta uint32_t boolsize = 0; 1665783c1515SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 1666783c1515SRuchika Gupta enum pkcs11_class_id key_class = get_class(obj->attributes); 1667783c1515SRuchika Gupta 1668783c1515SRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY && 1669783c1515SRuchika Gupta key_class != PKCS11_CKO_PRIVATE_KEY) 1670783c1515SRuchika Gupta return true; 1671783c1515SRuchika Gupta 1672783c1515SRuchika Gupta switch (req_attr->id) { 1673783c1515SRuchika Gupta case PKCS11_CKA_PRIVATE_EXPONENT: 1674783c1515SRuchika Gupta case PKCS11_CKA_PRIME_1: 1675783c1515SRuchika Gupta case PKCS11_CKA_PRIME_2: 1676783c1515SRuchika Gupta case PKCS11_CKA_EXPONENT_1: 1677783c1515SRuchika Gupta case PKCS11_CKA_EXPONENT_2: 1678783c1515SRuchika Gupta case PKCS11_CKA_COEFFICIENT: 1679783c1515SRuchika Gupta case PKCS11_CKA_VALUE: 1680783c1515SRuchika Gupta boolsize = sizeof(boolval); 1681783c1515SRuchika Gupta rc = get_attribute(obj->attributes, PKCS11_CKA_EXTRACTABLE, 1682783c1515SRuchika Gupta &boolval, &boolsize); 1683783c1515SRuchika Gupta if (rc || boolval == PKCS11_FALSE) 1684783c1515SRuchika Gupta return false; 1685783c1515SRuchika Gupta 1686783c1515SRuchika Gupta boolsize = sizeof(boolval); 1687783c1515SRuchika Gupta rc = get_attribute(obj->attributes, PKCS11_CKA_SENSITIVE, 1688783c1515SRuchika Gupta &boolval, &boolsize); 1689783c1515SRuchika Gupta if (rc || boolval == PKCS11_TRUE) 1690783c1515SRuchika Gupta return false; 1691783c1515SRuchika Gupta break; 1692783c1515SRuchika Gupta default: 1693783c1515SRuchika Gupta break; 1694783c1515SRuchika Gupta } 1695783c1515SRuchika Gupta 1696783c1515SRuchika Gupta return true; 1697783c1515SRuchika Gupta } 16982d25a9bcSRuchika Gupta 16992d25a9bcSRuchika Gupta static bool attr_is_modifiable_any_key(struct pkcs11_attribute_head *attr) 17002d25a9bcSRuchika Gupta { 17012d25a9bcSRuchika Gupta switch (attr->id) { 17022d25a9bcSRuchika Gupta case PKCS11_CKA_ID: 17032d25a9bcSRuchika Gupta case PKCS11_CKA_START_DATE: 17042d25a9bcSRuchika Gupta case PKCS11_CKA_END_DATE: 17052d25a9bcSRuchika Gupta case PKCS11_CKA_DERIVE: 17062d25a9bcSRuchika Gupta return true; 17072d25a9bcSRuchika Gupta default: 17082d25a9bcSRuchika Gupta return false; 17092d25a9bcSRuchika Gupta } 17102d25a9bcSRuchika Gupta } 17112d25a9bcSRuchika Gupta 17122d25a9bcSRuchika Gupta static bool attr_is_modifiable_secret_key(struct pkcs11_attribute_head *attr, 17132d25a9bcSRuchika Gupta struct pkcs11_session *session, 17142d25a9bcSRuchika Gupta struct pkcs11_object *obj) 17152d25a9bcSRuchika Gupta { 17162d25a9bcSRuchika Gupta switch (attr->id) { 17172d25a9bcSRuchika Gupta case PKCS11_CKA_ENCRYPT: 17182d25a9bcSRuchika Gupta case PKCS11_CKA_DECRYPT: 17192d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN: 17202d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY: 17212d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP: 17222d25a9bcSRuchika Gupta case PKCS11_CKA_UNWRAP: 17232d25a9bcSRuchika Gupta return true; 17242d25a9bcSRuchika Gupta /* Can't be modified once set to CK_FALSE - 12 in Table 10 */ 17252d25a9bcSRuchika Gupta case PKCS11_CKA_EXTRACTABLE: 17262d25a9bcSRuchika Gupta return get_bool(obj->attributes, attr->id); 17272d25a9bcSRuchika Gupta /* Can't be modified once set to CK_TRUE - 11 in Table 10 */ 17282d25a9bcSRuchika Gupta case PKCS11_CKA_SENSITIVE: 17292d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP_WITH_TRUSTED: 17302d25a9bcSRuchika Gupta return !get_bool(obj->attributes, attr->id); 17312d25a9bcSRuchika Gupta /* Change in CKA_TRUSTED can only be done by SO */ 17322d25a9bcSRuchika Gupta case PKCS11_CKA_TRUSTED: 17332d25a9bcSRuchika Gupta return pkcs11_session_is_so(session); 17342d25a9bcSRuchika Gupta case PKCS11_CKA_NEVER_EXTRACTABLE: 17352d25a9bcSRuchika Gupta case PKCS11_CKA_ALWAYS_SENSITIVE: 17362d25a9bcSRuchika Gupta return false; 17372d25a9bcSRuchika Gupta default: 17382d25a9bcSRuchika Gupta return false; 17392d25a9bcSRuchika Gupta } 17402d25a9bcSRuchika Gupta } 17412d25a9bcSRuchika Gupta 17422d25a9bcSRuchika Gupta static bool attr_is_modifiable_public_key(struct pkcs11_attribute_head *attr, 17432d25a9bcSRuchika Gupta struct pkcs11_session *session, 17442d25a9bcSRuchika Gupta struct pkcs11_object *obj __unused) 17452d25a9bcSRuchika Gupta { 17462d25a9bcSRuchika Gupta switch (attr->id) { 17472d25a9bcSRuchika Gupta case PKCS11_CKA_SUBJECT: 17482d25a9bcSRuchika Gupta case PKCS11_CKA_ENCRYPT: 17492d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY: 17502d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY_RECOVER: 17512d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP: 17522d25a9bcSRuchika Gupta return true; 17532d25a9bcSRuchika Gupta case PKCS11_CKA_TRUSTED: 17542d25a9bcSRuchika Gupta /* Change in CKA_TRUSTED can only be done by SO */ 17552d25a9bcSRuchika Gupta return pkcs11_session_is_so(session); 17562d25a9bcSRuchika Gupta default: 17572d25a9bcSRuchika Gupta return false; 17582d25a9bcSRuchika Gupta } 17592d25a9bcSRuchika Gupta } 17602d25a9bcSRuchika Gupta 17612d25a9bcSRuchika Gupta static bool attr_is_modifiable_private_key(struct pkcs11_attribute_head *attr, 17622d25a9bcSRuchika Gupta struct pkcs11_session *sess __unused, 17632d25a9bcSRuchika Gupta struct pkcs11_object *obj) 17642d25a9bcSRuchika Gupta { 17652d25a9bcSRuchika Gupta switch (attr->id) { 17662d25a9bcSRuchika Gupta case PKCS11_CKA_SUBJECT: 17672d25a9bcSRuchika Gupta case PKCS11_CKA_DECRYPT: 17682d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN: 17692d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN_RECOVER: 17702d25a9bcSRuchika Gupta case PKCS11_CKA_UNWRAP: 17712d25a9bcSRuchika Gupta /* 17722d25a9bcSRuchika Gupta * TBD: Revisit if we don't support PKCS11_CKA_PUBLIC_KEY_INFO 17732d25a9bcSRuchika Gupta * Specification mentions that if this attribute is 17742d25a9bcSRuchika Gupta * supplied as part of a template for C_CreateObject, C_CopyObject or 17752d25a9bcSRuchika Gupta * C_SetAttributeValue for a private key, the token MUST verify 17762d25a9bcSRuchika Gupta * correspondence between the private key data and the public key data 17772d25a9bcSRuchika Gupta * as supplied in CKA_PUBLIC_KEY_INFO. This needs to be 17782d25a9bcSRuchika Gupta * taken care of when this object type will be implemented 17792d25a9bcSRuchika Gupta */ 17802d25a9bcSRuchika Gupta case PKCS11_CKA_PUBLIC_KEY_INFO: 17812d25a9bcSRuchika Gupta return true; 17822d25a9bcSRuchika Gupta /* Can't be modified once set to CK_FALSE - 12 in Table 10 */ 17832d25a9bcSRuchika Gupta case PKCS11_CKA_EXTRACTABLE: 17842d25a9bcSRuchika Gupta return get_bool(obj->attributes, attr->id); 17852d25a9bcSRuchika Gupta /* Can't be modified once set to CK_TRUE - 11 in Table 10 */ 17862d25a9bcSRuchika Gupta case PKCS11_CKA_SENSITIVE: 17872d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP_WITH_TRUSTED: 17882d25a9bcSRuchika Gupta return !get_bool(obj->attributes, attr->id); 17892d25a9bcSRuchika Gupta case PKCS11_CKA_NEVER_EXTRACTABLE: 17902d25a9bcSRuchika Gupta case PKCS11_CKA_ALWAYS_SENSITIVE: 17912d25a9bcSRuchika Gupta return false; 17922d25a9bcSRuchika Gupta default: 17932d25a9bcSRuchika Gupta return false; 17942d25a9bcSRuchika Gupta } 17952d25a9bcSRuchika Gupta } 17962d25a9bcSRuchika Gupta 17972d25a9bcSRuchika Gupta static bool attribute_is_modifiable(struct pkcs11_session *session, 17982d25a9bcSRuchika Gupta struct pkcs11_attribute_head *req_attr, 17992d25a9bcSRuchika Gupta struct pkcs11_object *obj, 18002d25a9bcSRuchika Gupta enum pkcs11_class_id class, 18012d25a9bcSRuchika Gupta enum processing_func function) 18022d25a9bcSRuchika Gupta { 18032d25a9bcSRuchika Gupta /* Check modifiable attributes common to any object */ 18042d25a9bcSRuchika Gupta switch (req_attr->id) { 18052d25a9bcSRuchika Gupta case PKCS11_CKA_LABEL: 18062d25a9bcSRuchika Gupta return true; 18072d25a9bcSRuchika Gupta case PKCS11_CKA_TOKEN: 18082d25a9bcSRuchika Gupta case PKCS11_CKA_MODIFIABLE: 18092d25a9bcSRuchika Gupta case PKCS11_CKA_DESTROYABLE: 18102d25a9bcSRuchika Gupta case PKCS11_CKA_PRIVATE: 18112d25a9bcSRuchika Gupta return function == PKCS11_FUNCTION_COPY; 18122d25a9bcSRuchika Gupta case PKCS11_CKA_COPYABLE: 18132d25a9bcSRuchika Gupta /* 18142d25a9bcSRuchika Gupta * Specification mentions that if the attribute value is false 18152d25a9bcSRuchika Gupta * it can't be set to true. Reading this we assume that it 18162d25a9bcSRuchika Gupta * should be possible to modify this attribute even though this 18172d25a9bcSRuchika Gupta * is not marked as modifiable in Table 10 if done in right 18182d25a9bcSRuchika Gupta * direction i.e from TRUE -> FALSE. 18192d25a9bcSRuchika Gupta */ 18202d25a9bcSRuchika Gupta return get_bool(obj->attributes, req_attr->id); 18212d25a9bcSRuchika Gupta default: 18222d25a9bcSRuchika Gupta break; 18232d25a9bcSRuchika Gupta } 18242d25a9bcSRuchika Gupta 18252d25a9bcSRuchika Gupta /* Attribute checking based on class type */ 18262d25a9bcSRuchika Gupta switch (class) { 18272d25a9bcSRuchika Gupta case PKCS11_CKO_SECRET_KEY: 18282d25a9bcSRuchika Gupta case PKCS11_CKO_PUBLIC_KEY: 18292d25a9bcSRuchika Gupta case PKCS11_CKO_PRIVATE_KEY: 18302d25a9bcSRuchika Gupta if (attr_is_modifiable_any_key(req_attr)) 18312d25a9bcSRuchika Gupta return true; 18322d25a9bcSRuchika Gupta if (class == PKCS11_CKO_SECRET_KEY && 18332d25a9bcSRuchika Gupta attr_is_modifiable_secret_key(req_attr, session, obj)) 18342d25a9bcSRuchika Gupta return true; 18352d25a9bcSRuchika Gupta if (class == PKCS11_CKO_PUBLIC_KEY && 18362d25a9bcSRuchika Gupta attr_is_modifiable_public_key(req_attr, session, obj)) 18372d25a9bcSRuchika Gupta return true; 18382d25a9bcSRuchika Gupta if (class == PKCS11_CKO_PRIVATE_KEY && 18392d25a9bcSRuchika Gupta attr_is_modifiable_private_key(req_attr, session, obj)) 18402d25a9bcSRuchika Gupta return true; 18412d25a9bcSRuchika Gupta break; 18422d25a9bcSRuchika Gupta case PKCS11_CKO_DATA: 18432d25a9bcSRuchika Gupta /* None of the data object attributes are modifiable */ 18442d25a9bcSRuchika Gupta return false; 18452d25a9bcSRuchika Gupta default: 18462d25a9bcSRuchika Gupta break; 18472d25a9bcSRuchika Gupta } 18482d25a9bcSRuchika Gupta 18492d25a9bcSRuchika Gupta return false; 18502d25a9bcSRuchika Gupta } 18512d25a9bcSRuchika Gupta 18522d25a9bcSRuchika Gupta enum pkcs11_rc check_attrs_against_modification(struct pkcs11_session *session, 18532d25a9bcSRuchika Gupta struct obj_attrs *head, 18542d25a9bcSRuchika Gupta struct pkcs11_object *obj, 18552d25a9bcSRuchika Gupta enum processing_func function) 18562d25a9bcSRuchika Gupta { 18572d25a9bcSRuchika Gupta enum pkcs11_class_id class = PKCS11_CKO_UNDEFINED_ID; 18582d25a9bcSRuchika Gupta char *cur = NULL; 18592d25a9bcSRuchika Gupta char *end = NULL; 18602d25a9bcSRuchika Gupta size_t len = 0; 18612d25a9bcSRuchika Gupta 18622d25a9bcSRuchika Gupta class = get_class(obj->attributes); 18632d25a9bcSRuchika Gupta 18642d25a9bcSRuchika Gupta cur = (char *)head + sizeof(struct obj_attrs); 18652d25a9bcSRuchika Gupta end = cur + head->attrs_size; 18662d25a9bcSRuchika Gupta 18672d25a9bcSRuchika Gupta for (; cur < end; cur += len) { 18682d25a9bcSRuchika Gupta /* Structure aligned copy of the pkcs11_ref in the object */ 18692d25a9bcSRuchika Gupta struct pkcs11_attribute_head cli_ref = { }; 18702d25a9bcSRuchika Gupta 18712d25a9bcSRuchika Gupta TEE_MemMove(&cli_ref, cur, sizeof(cli_ref)); 18722d25a9bcSRuchika Gupta len = sizeof(cli_ref) + cli_ref.size; 18732d25a9bcSRuchika Gupta 18742d25a9bcSRuchika Gupta /* 18752d25a9bcSRuchika Gupta * Check 1 - Check if attribute belongs to the object 18762d25a9bcSRuchika Gupta * The obj->attributes has all the attributes in 18772d25a9bcSRuchika Gupta * it which are allowed for an object. 18782d25a9bcSRuchika Gupta */ 18792d25a9bcSRuchika Gupta if (get_attribute_ptr(obj->attributes, cli_ref.id, NULL, 18802d25a9bcSRuchika Gupta NULL) == PKCS11_RV_NOT_FOUND) 18812d25a9bcSRuchika Gupta return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 18822d25a9bcSRuchika Gupta 18832d25a9bcSRuchika Gupta /* Check 2 - Is attribute modifiable */ 18842d25a9bcSRuchika Gupta if (!attribute_is_modifiable(session, &cli_ref, obj, class, 18852d25a9bcSRuchika Gupta function)) 18862d25a9bcSRuchika Gupta return PKCS11_CKR_ATTRIBUTE_READ_ONLY; 18872d25a9bcSRuchika Gupta 18882d25a9bcSRuchika Gupta /* 18892d25a9bcSRuchika Gupta * Checks for modification in PKCS11_CKA_TOKEN and 18902d25a9bcSRuchika Gupta * PKCS11_CKA_PRIVATE are required for PKCS11_FUNCTION_COPY 18912d25a9bcSRuchika Gupta * only, so skip them for PKCS11_FUNCTION_MODIFY. 18922d25a9bcSRuchika Gupta */ 18932d25a9bcSRuchika Gupta if (function == PKCS11_FUNCTION_MODIFY) 18942d25a9bcSRuchika Gupta continue; 18952d25a9bcSRuchika Gupta 18962d25a9bcSRuchika Gupta /* 18972d25a9bcSRuchika Gupta * An attempt to copy an object to a token will fail for 18982d25a9bcSRuchika Gupta * RO session 18992d25a9bcSRuchika Gupta */ 19002d25a9bcSRuchika Gupta if (cli_ref.id == PKCS11_CKA_TOKEN && 19012d25a9bcSRuchika Gupta get_bool(head, PKCS11_CKA_TOKEN)) { 19022d25a9bcSRuchika Gupta if (!pkcs11_session_is_read_write(session)) { 19032d25a9bcSRuchika Gupta DMSG("Can't copy to token in a RO session"); 19042d25a9bcSRuchika Gupta return PKCS11_CKR_SESSION_READ_ONLY; 19052d25a9bcSRuchika Gupta } 19062d25a9bcSRuchika Gupta } 19072d25a9bcSRuchika Gupta 19082d25a9bcSRuchika Gupta if (cli_ref.id == PKCS11_CKA_PRIVATE) { 19092d25a9bcSRuchika Gupta bool parent_priv = 19102d25a9bcSRuchika Gupta get_bool(obj->attributes, cli_ref.id); 19112d25a9bcSRuchika Gupta bool obj_priv = get_bool(head, cli_ref.id); 19122d25a9bcSRuchika Gupta 19132d25a9bcSRuchika Gupta /* 19142d25a9bcSRuchika Gupta * If PKCS11_CKA_PRIVATE is being set to TRUE from 19152d25a9bcSRuchika Gupta * FALSE, user has to be logged in 19162d25a9bcSRuchika Gupta */ 19172d25a9bcSRuchika Gupta if (!parent_priv && obj_priv) { 19182d25a9bcSRuchika Gupta if ((pkcs11_session_is_public(session) || 19192d25a9bcSRuchika Gupta pkcs11_session_is_so(session))) 19202d25a9bcSRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 19212d25a9bcSRuchika Gupta } 1922df017b2bSRuchika Gupta 1923df017b2bSRuchika Gupta /* 1924df017b2bSRuchika Gupta * Restriction added - Even for Copy, do not allow 1925df017b2bSRuchika Gupta * modification of CKA_PRIVATE from TRUE to FALSE 1926df017b2bSRuchika Gupta */ 1927df017b2bSRuchika Gupta if (parent_priv && !obj_priv) 1928df017b2bSRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 19292d25a9bcSRuchika Gupta } 19302d25a9bcSRuchika Gupta } 19312d25a9bcSRuchika Gupta 19322d25a9bcSRuchika Gupta return PKCS11_CKR_OK; 19332d25a9bcSRuchika Gupta } 19348c499324SRuchika Gupta 19358c499324SRuchika Gupta static enum pkcs11_rc set_secret_key_data(struct obj_attrs **head, void *data, 19368c499324SRuchika Gupta size_t key_size) 19378c499324SRuchika Gupta { 19388c499324SRuchika Gupta uint32_t size = sizeof(uint32_t); 19398c499324SRuchika Gupta uint32_t key_length = 0; 19408c499324SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 19418c499324SRuchika Gupta 19428c499324SRuchika Gupta /* Get key size if present in template */ 19438c499324SRuchika Gupta rc = get_attribute(*head, PKCS11_CKA_VALUE_LEN, &key_length, &size); 19448c499324SRuchika Gupta if (rc && rc != PKCS11_RV_NOT_FOUND) 19458c499324SRuchika Gupta return rc; 19468c499324SRuchika Gupta 19478c499324SRuchika Gupta if (key_length) { 19488c499324SRuchika Gupta if (key_size < key_length) 19498c499324SRuchika Gupta return PKCS11_CKR_DATA_LEN_RANGE; 19508c499324SRuchika Gupta } else { 19518c499324SRuchika Gupta key_length = key_size; 19528c499324SRuchika Gupta rc = set_attribute(head, PKCS11_CKA_VALUE_LEN, &key_length, 19538c499324SRuchika Gupta sizeof(uint32_t)); 19548c499324SRuchika Gupta if (rc) 19558c499324SRuchika Gupta return rc; 19568c499324SRuchika Gupta } 19578c499324SRuchika Gupta 19588c499324SRuchika Gupta /* Now we can check the VALUE_LEN field */ 19598c499324SRuchika Gupta rc = check_created_attrs(*head, NULL); 19608c499324SRuchika Gupta if (rc) 19618c499324SRuchika Gupta return rc; 19628c499324SRuchika Gupta 19638c499324SRuchika Gupta /* Remove the default empty value attribute if found */ 19648c499324SRuchika Gupta rc = remove_empty_attribute(head, PKCS11_CKA_VALUE); 19658c499324SRuchika Gupta if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND) 19668c499324SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 19678c499324SRuchika Gupta 19688c499324SRuchika Gupta return add_attribute(head, PKCS11_CKA_VALUE, data, key_length); 19698c499324SRuchika Gupta } 19708c499324SRuchika Gupta 19718c499324SRuchika Gupta enum pkcs11_rc set_key_data(struct obj_attrs **head, void *data, 19728c499324SRuchika Gupta size_t key_size) 19738c499324SRuchika Gupta { 19748c499324SRuchika Gupta switch (get_class(*head)) { 19758c499324SRuchika Gupta case PKCS11_CKO_SECRET_KEY: 19768c499324SRuchika Gupta return set_secret_key_data(head, data, key_size); 19778c499324SRuchika Gupta default: 19788c499324SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 19798c499324SRuchika Gupta } 19808c499324SRuchika Gupta } 19815e1d94ebSVesa Jääskeläinen 19825f80f270SRuchika Gupta enum pkcs11_rc get_key_data_to_wrap(struct obj_attrs *head, void **data, 19835f80f270SRuchika Gupta uint32_t *sz) 19845f80f270SRuchika Gupta { 19855f80f270SRuchika Gupta switch (get_class(head)) { 19865f80f270SRuchika Gupta case PKCS11_CKO_SECRET_KEY: 19875f80f270SRuchika Gupta if (get_attribute_ptr(head, PKCS11_CKA_VALUE, data, sz)) 19885f80f270SRuchika Gupta return PKCS11_CKR_ARGUMENTS_BAD; 19895f80f270SRuchika Gupta break; 19905f80f270SRuchika Gupta default: 19915f80f270SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 19925f80f270SRuchika Gupta } 19935f80f270SRuchika Gupta 19945f80f270SRuchika Gupta return PKCS11_CKR_OK; 19955f80f270SRuchika Gupta } 19965f80f270SRuchika Gupta 19975e1d94ebSVesa Jääskeläinen enum pkcs11_rc add_missing_attribute_id(struct obj_attrs **pub_head, 19985e1d94ebSVesa Jääskeläinen struct obj_attrs **priv_head) 19995e1d94ebSVesa Jääskeläinen { 20005e1d94ebSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 20015e1d94ebSVesa Jääskeläinen void *id1 = NULL; 20025e1d94ebSVesa Jääskeläinen uint32_t id1_size = 0; 20035e1d94ebSVesa Jääskeläinen void *id2 = NULL; 20045e1d94ebSVesa Jääskeläinen uint32_t id2_size = 0; 20055e1d94ebSVesa Jääskeläinen 20065e1d94ebSVesa Jääskeläinen assert(pub_head); 20075e1d94ebSVesa Jääskeläinen assert(priv_head); 20085e1d94ebSVesa Jääskeläinen 20095e1d94ebSVesa Jääskeläinen rc = get_attribute_ptr(*pub_head, PKCS11_CKA_ID, &id1, &id1_size); 20105e1d94ebSVesa Jääskeläinen if (rc) { 20115e1d94ebSVesa Jääskeläinen if (rc != PKCS11_RV_NOT_FOUND) 20125e1d94ebSVesa Jääskeläinen return rc; 20135e1d94ebSVesa Jääskeläinen id1 = NULL; 20145e1d94ebSVesa Jääskeläinen } else if (!id1_size) { 20155e1d94ebSVesa Jääskeläinen id1 = NULL; 20165e1d94ebSVesa Jääskeläinen } 20175e1d94ebSVesa Jääskeläinen 20185e1d94ebSVesa Jääskeläinen rc = get_attribute_ptr(*priv_head, PKCS11_CKA_ID, &id2, &id2_size); 20195e1d94ebSVesa Jääskeläinen if (rc) { 20205e1d94ebSVesa Jääskeläinen if (rc != PKCS11_RV_NOT_FOUND) 20215e1d94ebSVesa Jääskeläinen return rc; 20225e1d94ebSVesa Jääskeläinen id2 = NULL; 20235e1d94ebSVesa Jääskeläinen } else if (!id2_size) { 20245e1d94ebSVesa Jääskeläinen id2 = NULL; 20255e1d94ebSVesa Jääskeläinen } 20265e1d94ebSVesa Jääskeläinen 20275e1d94ebSVesa Jääskeläinen /* Both have value -- let them be what caller has specified them */ 20285e1d94ebSVesa Jääskeläinen if (id1 && id2) 20295e1d94ebSVesa Jääskeläinen return PKCS11_CKR_OK; 20305e1d94ebSVesa Jääskeläinen 20315e1d94ebSVesa Jääskeläinen /* Both are empty -- leave empty values */ 20325e1d94ebSVesa Jääskeläinen if (!id1 && !id2) 20335e1d94ebSVesa Jääskeläinen return PKCS11_CKR_OK; 20345e1d94ebSVesa Jääskeläinen 20355e1d94ebSVesa Jääskeläinen /* Cross copy CKA_ID value */ 20365e1d94ebSVesa Jääskeläinen if (id1) 20375e1d94ebSVesa Jääskeläinen return set_attribute(priv_head, PKCS11_CKA_ID, id1, id1_size); 20385e1d94ebSVesa Jääskeläinen else 20395e1d94ebSVesa Jääskeläinen return set_attribute(pub_head, PKCS11_CKA_ID, id2, id2_size); 20405e1d94ebSVesa Jääskeläinen } 2041