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> 845d40bdaSValerii Chubar #include <mbedtls/pk.h> 963f89caaSJens Wiklander #include <pkcs11_ta.h> 1063f89caaSJens Wiklander #include <stdlib.h> 1163f89caaSJens Wiklander #include <string_ext.h> 1263f89caaSJens Wiklander #include <tee_internal_api_extensions.h> 1363f89caaSJens Wiklander #include <tee_internal_api.h> 146a760c9eSEtienne Carriere #include <trace.h> 1563f89caaSJens Wiklander #include <util.h> 1663f89caaSJens Wiklander 1763f89caaSJens Wiklander #include "attributes.h" 1863f89caaSJens Wiklander #include "handle.h" 1963f89caaSJens Wiklander #include "pkcs11_attributes.h" 2063f89caaSJens Wiklander #include "pkcs11_helpers.h" 2163f89caaSJens Wiklander #include "pkcs11_token.h" 2263f89caaSJens Wiklander #include "sanitize_object.h" 2363f89caaSJens Wiklander #include "serializer.h" 2463f89caaSJens Wiklander #include "token_capabilities.h" 2563f89caaSJens Wiklander 26512cbf1dSJens Wiklander static uint32_t pkcs11_func2ckfm(enum processing_func function) 27512cbf1dSJens Wiklander { 28512cbf1dSJens Wiklander switch (function) { 29512cbf1dSJens Wiklander case PKCS11_FUNCTION_DIGEST: 30512cbf1dSJens Wiklander return PKCS11_CKFM_DIGEST; 31512cbf1dSJens Wiklander case PKCS11_FUNCTION_GENERATE: 32512cbf1dSJens Wiklander return PKCS11_CKFM_GENERATE; 33512cbf1dSJens Wiklander case PKCS11_FUNCTION_GENERATE_PAIR: 34512cbf1dSJens Wiklander return PKCS11_CKFM_GENERATE_KEY_PAIR; 35512cbf1dSJens Wiklander case PKCS11_FUNCTION_DERIVE: 36512cbf1dSJens Wiklander return PKCS11_CKFM_DERIVE; 37512cbf1dSJens Wiklander case PKCS11_FUNCTION_WRAP: 38512cbf1dSJens Wiklander return PKCS11_CKFM_WRAP; 39512cbf1dSJens Wiklander case PKCS11_FUNCTION_UNWRAP: 40512cbf1dSJens Wiklander return PKCS11_CKFM_UNWRAP; 41512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 42512cbf1dSJens Wiklander return PKCS11_CKFM_ENCRYPT; 43512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 44512cbf1dSJens Wiklander return PKCS11_CKFM_DECRYPT; 45512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN: 46512cbf1dSJens Wiklander return PKCS11_CKFM_SIGN; 47512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY: 48512cbf1dSJens Wiklander return PKCS11_CKFM_VERIFY; 49512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN_RECOVER: 50512cbf1dSJens Wiklander return PKCS11_CKFM_SIGN_RECOVER; 51512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY_RECOVER: 52512cbf1dSJens Wiklander return PKCS11_CKFM_VERIFY_RECOVER; 53512cbf1dSJens Wiklander default: 54512cbf1dSJens Wiklander return 0; 55512cbf1dSJens Wiklander } 56512cbf1dSJens Wiklander } 57512cbf1dSJens Wiklander 58512cbf1dSJens Wiklander enum pkcs11_rc 59512cbf1dSJens Wiklander check_mechanism_against_processing(struct pkcs11_session *session, 60512cbf1dSJens Wiklander enum pkcs11_mechanism_id mechanism_type, 61512cbf1dSJens Wiklander enum processing_func function, 62512cbf1dSJens Wiklander enum processing_step step) 63512cbf1dSJens Wiklander { 64512cbf1dSJens Wiklander bool allowed = false; 65512cbf1dSJens Wiklander 66512cbf1dSJens Wiklander switch (step) { 67512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_INIT: 68512cbf1dSJens Wiklander switch (function) { 69512cbf1dSJens Wiklander case PKCS11_FUNCTION_IMPORT: 70512cbf1dSJens Wiklander case PKCS11_FUNCTION_COPY: 71512cbf1dSJens Wiklander case PKCS11_FUNCTION_MODIFY: 72512cbf1dSJens Wiklander case PKCS11_FUNCTION_DESTROY: 73512cbf1dSJens Wiklander return PKCS11_CKR_OK; 74512cbf1dSJens Wiklander default: 75512cbf1dSJens Wiklander break; 76512cbf1dSJens Wiklander } 77512cbf1dSJens Wiklander /* 78512cbf1dSJens Wiklander * Check that the returned PKCS11_CKFM_* flag from 79512cbf1dSJens Wiklander * pkcs11_func2ckfm() is among the ones from 80512cbf1dSJens Wiklander * mechanism_supported_flags(). 81512cbf1dSJens Wiklander */ 82512cbf1dSJens Wiklander allowed = mechanism_supported_flags(mechanism_type) & 83512cbf1dSJens Wiklander pkcs11_func2ckfm(function); 84512cbf1dSJens Wiklander break; 85512cbf1dSJens Wiklander 86512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_ONESHOT: 870460a039SRuchika Gupta if (session->processing->always_authen && 880460a039SRuchika Gupta !session->processing->relogged) 890460a039SRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 900460a039SRuchika Gupta 912364aa69SRuchika Gupta if (session->processing->step == PKCS11_FUNC_STEP_UPDATE || 922364aa69SRuchika Gupta session->processing->step == PKCS11_FUNC_STEP_FINAL) { 932364aa69SRuchika Gupta EMSG("Cannot perform one-shot on active processing"); 940460a039SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE; 950460a039SRuchika Gupta } 960460a039SRuchika Gupta 970460a039SRuchika Gupta allowed = true; 980460a039SRuchika Gupta break; 990460a039SRuchika Gupta 100512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_UPDATE: 101512cbf1dSJens Wiklander if (session->processing->always_authen && 102512cbf1dSJens Wiklander !session->processing->relogged) 103512cbf1dSJens Wiklander return PKCS11_CKR_USER_NOT_LOGGED_IN; 104512cbf1dSJens Wiklander 1052364aa69SRuchika Gupta if (session->processing->step == PKCS11_FUNC_STEP_ONESHOT || 1062364aa69SRuchika Gupta session->processing->step == PKCS11_FUNC_STEP_FINAL) { 1072364aa69SRuchika Gupta EMSG("Cannot perform update on finalized processing"); 1082364aa69SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE; 1092364aa69SRuchika Gupta } 1102364aa69SRuchika Gupta 111512cbf1dSJens Wiklander allowed = !mechanism_is_one_shot_only(mechanism_type); 112512cbf1dSJens Wiklander break; 113512cbf1dSJens Wiklander 1149e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE_KEY: 1159e91a619SVesa Jääskeläinen assert(function == PKCS11_FUNCTION_DIGEST); 1169e91a619SVesa Jääskeläinen 1179e91a619SVesa Jääskeläinen if (session->processing->always_authen && 1189e91a619SVesa Jääskeläinen !session->processing->relogged) 1199e91a619SVesa Jääskeläinen return PKCS11_CKR_USER_NOT_LOGGED_IN; 1209e91a619SVesa Jääskeläinen 1219e91a619SVesa Jääskeläinen allowed = true; 1229e91a619SVesa Jääskeläinen break; 1239e91a619SVesa Jääskeläinen 124512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_FINAL: 125512cbf1dSJens Wiklander if (session->processing->always_authen && 126512cbf1dSJens Wiklander !session->processing->relogged) 127512cbf1dSJens Wiklander return PKCS11_CKR_USER_NOT_LOGGED_IN; 128512cbf1dSJens Wiklander 1292364aa69SRuchika Gupta if (session->processing->step == PKCS11_FUNC_STEP_ONESHOT) { 1302364aa69SRuchika Gupta EMSG("Cannot perform final on oneshot processing"); 1312364aa69SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE; 1322364aa69SRuchika Gupta } 133512cbf1dSJens Wiklander return PKCS11_CKR_OK; 134512cbf1dSJens Wiklander 135512cbf1dSJens Wiklander default: 136512cbf1dSJens Wiklander TEE_Panic(step); 137512cbf1dSJens Wiklander break; 138512cbf1dSJens Wiklander } 139512cbf1dSJens Wiklander 140512cbf1dSJens Wiklander if (!allowed) { 141512cbf1dSJens Wiklander EMSG("Processing %#x/%s not permitted (%u/%u)", 142512cbf1dSJens Wiklander (unsigned int)mechanism_type, id2str_proc(mechanism_type), 143512cbf1dSJens Wiklander function, step); 144df705578SRuchika Gupta return PKCS11_CKR_MECHANISM_INVALID; 145512cbf1dSJens Wiklander } 146512cbf1dSJens Wiklander 147512cbf1dSJens Wiklander return PKCS11_CKR_OK; 148512cbf1dSJens Wiklander } 149512cbf1dSJens Wiklander 15063f89caaSJens Wiklander /* 15163f89caaSJens Wiklander * Object default boolean attributes as per PKCS#11 15263f89caaSJens Wiklander */ 15363f89caaSJens Wiklander static uint8_t *pkcs11_object_default_boolprop(uint32_t attribute) 15463f89caaSJens Wiklander { 15563f89caaSJens Wiklander static const uint8_t bool_true = 1; 15663f89caaSJens Wiklander static const uint8_t bool_false; 15763f89caaSJens Wiklander 15863f89caaSJens Wiklander switch (attribute) { 15963f89caaSJens Wiklander /* As per PKCS#11 default value */ 16063f89caaSJens Wiklander case PKCS11_CKA_MODIFIABLE: 16163f89caaSJens Wiklander case PKCS11_CKA_COPYABLE: 16263f89caaSJens Wiklander case PKCS11_CKA_DESTROYABLE: 16363f89caaSJens Wiklander return (uint8_t *)&bool_true; 16463f89caaSJens Wiklander case PKCS11_CKA_TOKEN: 16563f89caaSJens Wiklander case PKCS11_CKA_PRIVATE: 16639fc24faSEtienne Carriere case PKCS11_CKA_WRAP_WITH_TRUSTED: 16739fc24faSEtienne Carriere case PKCS11_CKA_ALWAYS_AUTHENTICATE: 16863f89caaSJens Wiklander case PKCS11_CKA_SENSITIVE: 16963f89caaSJens Wiklander return (uint8_t *)&bool_false; 17063f89caaSJens Wiklander /* Token specific default value */ 17163f89caaSJens Wiklander case PKCS11_CKA_SIGN: 17263f89caaSJens Wiklander case PKCS11_CKA_VERIFY: 17363f89caaSJens Wiklander case PKCS11_CKA_DERIVE: 17463f89caaSJens Wiklander case PKCS11_CKA_ENCRYPT: 17563f89caaSJens Wiklander case PKCS11_CKA_DECRYPT: 17663f89caaSJens Wiklander case PKCS11_CKA_SIGN_RECOVER: 17763f89caaSJens Wiklander case PKCS11_CKA_VERIFY_RECOVER: 17863f89caaSJens Wiklander case PKCS11_CKA_WRAP: 17963f89caaSJens Wiklander case PKCS11_CKA_UNWRAP: 18063f89caaSJens Wiklander case PKCS11_CKA_EXTRACTABLE: 18163f89caaSJens Wiklander case PKCS11_CKA_TRUSTED: 18263f89caaSJens Wiklander return (uint8_t *)&bool_false; 18363f89caaSJens Wiklander default: 18463f89caaSJens Wiklander DMSG("No default for boolprop attribute %#"PRIx32, attribute); 18563f89caaSJens Wiklander return NULL; 18663f89caaSJens Wiklander } 18763f89caaSJens Wiklander } 18863f89caaSJens Wiklander 18963f89caaSJens Wiklander /* 19063f89caaSJens Wiklander * Object expects several boolean attributes to be set to a default value 19163f89caaSJens Wiklander * or to a validate client configuration value. This function append the input 19263f89caaSJens Wiklander * attribute (id/size/value) in the serialized object. 19363f89caaSJens Wiklander */ 19463f89caaSJens Wiklander static enum pkcs11_rc pkcs11_import_object_boolprop(struct obj_attrs **out, 19563f89caaSJens Wiklander struct obj_attrs *templ, 19663f89caaSJens Wiklander uint32_t attribute) 19763f89caaSJens Wiklander { 19863f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 19963f89caaSJens Wiklander uint8_t bbool = 0; 20063f89caaSJens Wiklander uint32_t size = sizeof(uint8_t); 20163f89caaSJens Wiklander void *attr = NULL; 20263f89caaSJens Wiklander 20363f89caaSJens Wiklander rc = get_attribute(templ, attribute, &bbool, &size); 20463f89caaSJens Wiklander if (rc) { 20563f89caaSJens Wiklander if (rc != PKCS11_RV_NOT_FOUND) 20663f89caaSJens Wiklander return rc; 20763f89caaSJens Wiklander attr = pkcs11_object_default_boolprop(attribute); 20863f89caaSJens Wiklander if (!attr) 20963f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCOMPLETE; 21063f89caaSJens Wiklander } else { 21163f89caaSJens Wiklander attr = &bbool; 21263f89caaSJens Wiklander } 21363f89caaSJens Wiklander 21463f89caaSJens Wiklander /* Boolean attributes are 1byte in the ABI, no alignment issue */ 21563f89caaSJens Wiklander return add_attribute(out, attribute, attr, sizeof(uint8_t)); 21663f89caaSJens Wiklander } 21763f89caaSJens Wiklander 21863f89caaSJens Wiklander static enum pkcs11_rc set_mandatory_boolprops(struct obj_attrs **out, 21963f89caaSJens Wiklander struct obj_attrs *temp, 22063f89caaSJens Wiklander uint32_t const *bp, 22163f89caaSJens Wiklander size_t bp_count) 22263f89caaSJens Wiklander { 22363f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 22463f89caaSJens Wiklander size_t n = 0; 22563f89caaSJens Wiklander 22663f89caaSJens Wiklander for (n = 0; n < bp_count; n++) { 22763f89caaSJens Wiklander rc = pkcs11_import_object_boolprop(out, temp, bp[n]); 22863f89caaSJens Wiklander if (rc) 22963f89caaSJens Wiklander return rc; 23063f89caaSJens Wiklander } 23163f89caaSJens Wiklander 23263f89caaSJens Wiklander return rc; 23363f89caaSJens Wiklander } 23463f89caaSJens Wiklander 23563f89caaSJens Wiklander static enum pkcs11_rc set_mandatory_attributes(struct obj_attrs **out, 23663f89caaSJens Wiklander struct obj_attrs *temp, 23716df60c7SEtienne Carriere uint32_t const *attrs, 23816df60c7SEtienne Carriere size_t attrs_count) 23963f89caaSJens Wiklander { 24063f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 24163f89caaSJens Wiklander size_t n = 0; 24263f89caaSJens Wiklander 24316df60c7SEtienne Carriere for (n = 0; n < attrs_count; n++) { 24463f89caaSJens Wiklander uint32_t size = 0; 24563f89caaSJens Wiklander void *value = NULL; 24663f89caaSJens Wiklander 24716df60c7SEtienne Carriere if (get_attribute_ptr(temp, attrs[n], &value, &size)) 24863f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCOMPLETE; 24963f89caaSJens Wiklander 25016df60c7SEtienne Carriere rc = add_attribute(out, attrs[n], value, size); 25163f89caaSJens Wiklander if (rc) 25263f89caaSJens Wiklander return rc; 25363f89caaSJens Wiklander } 25463f89caaSJens Wiklander 25563f89caaSJens Wiklander return rc; 25663f89caaSJens Wiklander } 25763f89caaSJens Wiklander 25863f89caaSJens Wiklander static enum pkcs11_rc get_default_value(enum pkcs11_attr_id id, void **value, 25963f89caaSJens Wiklander uint32_t *size) 26063f89caaSJens Wiklander { 26163f89caaSJens Wiklander /* should have been taken care of already */ 26263f89caaSJens Wiklander assert(!pkcs11_attr_is_boolean(id)); 26363f89caaSJens Wiklander 26463f89caaSJens Wiklander /* All other attributes have an empty default value */ 26563f89caaSJens Wiklander *value = NULL; 26663f89caaSJens Wiklander *size = 0; 26763f89caaSJens Wiklander return PKCS11_CKR_OK; 26863f89caaSJens Wiklander } 26963f89caaSJens Wiklander 2704eb88651SRuchika Gupta static enum pkcs11_rc set_optional_attributes_with_def(struct obj_attrs **out, 27163f89caaSJens Wiklander struct obj_attrs *temp, 27216df60c7SEtienne Carriere uint32_t const *attrs, 27316df60c7SEtienne Carriere size_t attrs_count, 2744eb88651SRuchika Gupta bool default_to_null) 27563f89caaSJens Wiklander { 27663f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 27763f89caaSJens Wiklander size_t n = 0; 27863f89caaSJens Wiklander 27916df60c7SEtienne Carriere for (n = 0; n < attrs_count; n++) { 28063f89caaSJens Wiklander uint32_t size = 0; 28163f89caaSJens Wiklander void *value = NULL; 28263f89caaSJens Wiklander 28316df60c7SEtienne Carriere rc = get_attribute_ptr(temp, attrs[n], &value, &size); 2844eb88651SRuchika Gupta if (rc == PKCS11_RV_NOT_FOUND) { 2854eb88651SRuchika Gupta if (default_to_null) { 28616df60c7SEtienne Carriere rc = get_default_value(attrs[n], &value, &size); 2874eb88651SRuchika Gupta } else { 2884eb88651SRuchika Gupta rc = PKCS11_CKR_OK; 2894eb88651SRuchika Gupta continue; 2904eb88651SRuchika Gupta } 2914eb88651SRuchika Gupta } 29263f89caaSJens Wiklander if (rc) 29363f89caaSJens Wiklander return rc; 29463f89caaSJens Wiklander 29516df60c7SEtienne Carriere rc = add_attribute(out, attrs[n], value, size); 29663f89caaSJens Wiklander if (rc) 29763f89caaSJens Wiklander return rc; 29863f89caaSJens Wiklander } 29963f89caaSJens Wiklander 30063f89caaSJens Wiklander return rc; 30163f89caaSJens Wiklander } 30263f89caaSJens Wiklander 3034eb88651SRuchika Gupta static enum pkcs11_rc set_attributes_opt_or_null(struct obj_attrs **out, 3044eb88651SRuchika Gupta struct obj_attrs *temp, 30516df60c7SEtienne Carriere uint32_t const *attrs, 30616df60c7SEtienne Carriere size_t attrs_count) 3074eb88651SRuchika Gupta { 30816df60c7SEtienne Carriere return set_optional_attributes_with_def(out, temp, attrs, attrs_count, 30916df60c7SEtienne Carriere true /* defaults to empty */); 3104eb88651SRuchika Gupta } 3114eb88651SRuchika Gupta 3124eb88651SRuchika Gupta static enum pkcs11_rc set_optional_attributes(struct obj_attrs **out, 3134eb88651SRuchika Gupta struct obj_attrs *temp, 31416df60c7SEtienne Carriere uint32_t const *attrs, 31516df60c7SEtienne Carriere size_t attrs_count) 3164eb88651SRuchika Gupta { 31716df60c7SEtienne Carriere return set_optional_attributes_with_def(out, temp, attrs, attrs_count, 31816df60c7SEtienne Carriere false /* no default value */); 3194eb88651SRuchika Gupta } 3204eb88651SRuchika Gupta 32163f89caaSJens Wiklander /* 32263f89caaSJens Wiklander * Below are listed the mandated or optional expected attributes for 32363f89caaSJens Wiklander * PKCS#11 storage objects. 32463f89caaSJens Wiklander * 32563f89caaSJens Wiklander * Note: boolprops (mandated boolean attributes) PKCS11_CKA_ALWAYS_SENSITIVE, 32663f89caaSJens Wiklander * and PKCS11_CKA_NEVER_EXTRACTABLE are set by the token, not provided 32763f89caaSJens Wiklander * in the client template. 32863f89caaSJens Wiklander */ 32963f89caaSJens Wiklander 33063f89caaSJens Wiklander /* PKCS#11 specification for any object (session/token) of the storage */ 3314eb88651SRuchika Gupta static const uint32_t any_object_boolprops[] = { 33263f89caaSJens Wiklander PKCS11_CKA_TOKEN, PKCS11_CKA_PRIVATE, 33363f89caaSJens Wiklander PKCS11_CKA_MODIFIABLE, PKCS11_CKA_COPYABLE, PKCS11_CKA_DESTROYABLE, 33463f89caaSJens Wiklander }; 33563f89caaSJens Wiklander 3364eb88651SRuchika Gupta static const uint32_t any_object_opt_or_null[] = { 33763f89caaSJens Wiklander PKCS11_CKA_LABEL, 33863f89caaSJens Wiklander }; 33963f89caaSJens Wiklander 3404eb88651SRuchika Gupta /* PKCS#11 specification for raw data object (+any_object_xxx) */ 3414eb88651SRuchika Gupta const uint32_t raw_data_opt_or_null[] = { 34263f89caaSJens Wiklander PKCS11_CKA_OBJECT_ID, PKCS11_CKA_APPLICATION, PKCS11_CKA_VALUE, 34363f89caaSJens Wiklander }; 34463f89caaSJens Wiklander 3454137952dSVesa Jääskeläinen /* PKCS#11 specification for certificate object (+pkcs11_any_object_xxx) */ 3464137952dSVesa Jääskeläinen static const uint32_t pkcs11_certificate_mandated[] = { 3474137952dSVesa Jääskeläinen PKCS11_CKA_CERTIFICATE_TYPE, 3484137952dSVesa Jääskeläinen }; 3494137952dSVesa Jääskeläinen 3504137952dSVesa Jääskeläinen static const uint32_t pkcs11_certificate_boolprops[] = { 3514137952dSVesa Jääskeläinen PKCS11_CKA_TRUSTED, 3524137952dSVesa Jääskeläinen }; 3534137952dSVesa Jääskeläinen 3544137952dSVesa Jääskeläinen static const uint32_t pkcs11_certificate_optional[] = { 3554137952dSVesa Jääskeläinen PKCS11_CKA_CERTIFICATE_CATEGORY, PKCS11_CKA_CHECK_VALUE, 3564137952dSVesa Jääskeläinen PKCS11_CKA_START_DATE, PKCS11_CKA_END_DATE, PKCS11_CKA_PUBLIC_KEY_INFO, 3574137952dSVesa Jääskeläinen }; 3584137952dSVesa Jääskeläinen 3594137952dSVesa Jääskeläinen /* 3604137952dSVesa Jääskeläinen * PKCS#11 specification for X.509 certificate object (+pkcs11_certificate_xxx) 3614137952dSVesa Jääskeläinen */ 3624137952dSVesa Jääskeläinen static const uint32_t pkcs11_x509_certificate_mandated[] = { 3634137952dSVesa Jääskeläinen PKCS11_CKA_SUBJECT, 3644137952dSVesa Jääskeläinen }; 3654137952dSVesa Jääskeläinen 3664137952dSVesa Jääskeläinen static const uint32_t pkcs11_x509_certificate_optional[] = { 3674137952dSVesa Jääskeläinen PKCS11_CKA_ID, PKCS11_CKA_ISSUER, PKCS11_CKA_SERIAL_NUMBER, 3684137952dSVesa Jääskeläinen PKCS11_CKA_VALUE, PKCS11_CKA_URL, 3694137952dSVesa Jääskeläinen PKCS11_CKA_HASH_OF_SUBJECT_PUBLIC_KEY, 3704137952dSVesa Jääskeläinen PKCS11_CKA_HASH_OF_ISSUER_PUBLIC_KEY, 3714137952dSVesa Jääskeläinen PKCS11_CKA_JAVA_MIDP_SECURITY_DOMAIN, PKCS11_CKA_NAME_HASH_ALGORITHM, 3724137952dSVesa Jääskeläinen }; 3734137952dSVesa Jääskeläinen 3744eb88651SRuchika Gupta /* PKCS#11 specification for any key object (+any_object_xxx) */ 3754eb88651SRuchika Gupta static const uint32_t any_key_boolprops[] = { 37663f89caaSJens Wiklander PKCS11_CKA_DERIVE, 37763f89caaSJens Wiklander }; 37863f89caaSJens Wiklander 3794eb88651SRuchika Gupta static const uint32_t any_key_opt_or_null[] = { 38063f89caaSJens Wiklander PKCS11_CKA_ID, 38163f89caaSJens Wiklander PKCS11_CKA_START_DATE, PKCS11_CKA_END_DATE, 3824eb88651SRuchika Gupta }; 3834eb88651SRuchika Gupta 3844eb88651SRuchika Gupta static const uint32_t any_key_optional[] = { 38563f89caaSJens Wiklander PKCS11_CKA_ALLOWED_MECHANISMS, 38663f89caaSJens Wiklander }; 38763f89caaSJens Wiklander 3884eb88651SRuchika Gupta /* PKCS#11 specification for any symmetric key (+any_key_xxx) */ 3894eb88651SRuchika Gupta static const uint32_t symm_key_boolprops[] = { 39063f89caaSJens Wiklander PKCS11_CKA_ENCRYPT, PKCS11_CKA_DECRYPT, 39163f89caaSJens Wiklander PKCS11_CKA_SIGN, PKCS11_CKA_VERIFY, 39263f89caaSJens Wiklander PKCS11_CKA_WRAP, PKCS11_CKA_UNWRAP, 39363f89caaSJens Wiklander PKCS11_CKA_SENSITIVE, PKCS11_CKA_EXTRACTABLE, 39463f89caaSJens Wiklander PKCS11_CKA_WRAP_WITH_TRUSTED, PKCS11_CKA_TRUSTED, 39563f89caaSJens Wiklander }; 39663f89caaSJens Wiklander 3974eb88651SRuchika Gupta static const uint32_t symm_key_opt_or_null[] = { 39863f89caaSJens Wiklander PKCS11_CKA_WRAP_TEMPLATE, PKCS11_CKA_UNWRAP_TEMPLATE, 3990ac5c695SRuchika Gupta PKCS11_CKA_DERIVE_TEMPLATE, PKCS11_CKA_VALUE, 4000ac5c695SRuchika Gupta }; 4010ac5c695SRuchika Gupta 4020ac5c695SRuchika Gupta static const uint32_t symm_key_optional[] = { 4030ac5c695SRuchika Gupta PKCS11_CKA_VALUE_LEN, 40463f89caaSJens Wiklander }; 40563f89caaSJens Wiklander 4064eb88651SRuchika Gupta /* PKCS#11 specification for any asymmetric public key (+any_key_xxx) */ 4074eb88651SRuchika Gupta static const uint32_t public_key_boolprops[] = { 40863f89caaSJens Wiklander PKCS11_CKA_ENCRYPT, PKCS11_CKA_VERIFY, PKCS11_CKA_VERIFY_RECOVER, 40963f89caaSJens Wiklander PKCS11_CKA_WRAP, 41063f89caaSJens Wiklander PKCS11_CKA_TRUSTED, 41163f89caaSJens Wiklander }; 41263f89caaSJens Wiklander 4134eb88651SRuchika Gupta static const uint32_t public_key_mandated[] = { 41463f89caaSJens Wiklander }; 41563f89caaSJens Wiklander 4164eb88651SRuchika Gupta static const uint32_t public_key_opt_or_null[] = { 417edd95148SVesa Jääskeläinen PKCS11_CKA_SUBJECT, PKCS11_CKA_WRAP_TEMPLATE, 418edd95148SVesa Jääskeläinen PKCS11_CKA_PUBLIC_KEY_INFO, 41963f89caaSJens Wiklander }; 42063f89caaSJens Wiklander 4214eb88651SRuchika Gupta /* PKCS#11 specification for any asymmetric private key (+any_key_xxx) */ 4224eb88651SRuchika Gupta static const uint32_t private_key_boolprops[] = { 42363f89caaSJens Wiklander PKCS11_CKA_DECRYPT, PKCS11_CKA_SIGN, PKCS11_CKA_SIGN_RECOVER, 42463f89caaSJens Wiklander PKCS11_CKA_UNWRAP, 42563f89caaSJens Wiklander PKCS11_CKA_SENSITIVE, PKCS11_CKA_EXTRACTABLE, 42663f89caaSJens Wiklander PKCS11_CKA_WRAP_WITH_TRUSTED, PKCS11_CKA_ALWAYS_AUTHENTICATE, 42763f89caaSJens Wiklander }; 42863f89caaSJens Wiklander 4294eb88651SRuchika Gupta static const uint32_t private_key_mandated[] = { 43063f89caaSJens Wiklander }; 43163f89caaSJens Wiklander 4324eb88651SRuchika Gupta static const uint32_t private_key_opt_or_null[] = { 433edd95148SVesa Jääskeläinen PKCS11_CKA_SUBJECT, PKCS11_CKA_UNWRAP_TEMPLATE, 434edd95148SVesa Jääskeläinen PKCS11_CKA_PUBLIC_KEY_INFO, 43563f89caaSJens Wiklander }; 43663f89caaSJens Wiklander 4374eb88651SRuchika Gupta /* PKCS#11 specification for any RSA key (+public/private_key_xxx) */ 4389cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_gen_mand[] = { 43963f89caaSJens Wiklander PKCS11_CKA_MODULUS_BITS, 44063f89caaSJens Wiklander }; 44163f89caaSJens Wiklander 4429cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_create_mand[] = { 44363f89caaSJens Wiklander PKCS11_CKA_MODULUS, PKCS11_CKA_PUBLIC_EXPONENT, 44463f89caaSJens Wiklander }; 44563f89caaSJens Wiklander 4469cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_gen_opt_or_null[] = { 4479cf1afceSVesa Jääskeläinen PKCS11_CKA_PUBLIC_EXPONENT, 4489cf1afceSVesa Jääskeläinen }; 4499cf1afceSVesa Jääskeläinen 4509cf1afceSVesa Jääskeläinen static const uint32_t rsa_priv_key_opt_or_null[] = { 45163f89caaSJens Wiklander PKCS11_CKA_MODULUS, PKCS11_CKA_PUBLIC_EXPONENT, 45263f89caaSJens Wiklander PKCS11_CKA_PRIVATE_EXPONENT, 45363f89caaSJens Wiklander PKCS11_CKA_PRIME_1, PKCS11_CKA_PRIME_2, 45463f89caaSJens Wiklander PKCS11_CKA_EXPONENT_1, PKCS11_CKA_EXPONENT_2, PKCS11_CKA_COEFFICIENT, 45563f89caaSJens Wiklander }; 45663f89caaSJens Wiklander 4574eb88651SRuchika Gupta /* PKCS#11 specification for any EC key (+public/private_key_xxx) */ 4584eb88651SRuchika Gupta static const uint32_t ec_public_key_mandated[] = { 45963f89caaSJens Wiklander PKCS11_CKA_EC_PARAMS, 46063f89caaSJens Wiklander }; 46163f89caaSJens Wiklander 4624eb88651SRuchika Gupta static const uint32_t ec_public_key_opt_or_null[] = { 46363f89caaSJens Wiklander PKCS11_CKA_EC_POINT, 46463f89caaSJens Wiklander }; 46563f89caaSJens Wiklander 4664eb88651SRuchika Gupta static const uint32_t ec_private_key_mandated[] = { 46763f89caaSJens Wiklander }; 46863f89caaSJens Wiklander 4694eb88651SRuchika Gupta static const uint32_t ec_private_key_opt_or_null[] = { 47002b16804SVesa Jääskeläinen PKCS11_CKA_EC_PARAMS, 47163f89caaSJens Wiklander PKCS11_CKA_VALUE, 47263f89caaSJens Wiklander }; 47363f89caaSJens Wiklander 47403e07432SValerii Chubar static const uint32_t eddsa_private_key_opt_or_null[] = { 47503e07432SValerii Chubar PKCS11_CKA_EC_PARAMS, 47603e07432SValerii Chubar PKCS11_CKA_VALUE, 47703e07432SValerii Chubar PKCS11_CKA_EC_POINT, 47803e07432SValerii Chubar }; 47903e07432SValerii Chubar 48063f89caaSJens Wiklander static enum pkcs11_rc create_storage_attributes(struct obj_attrs **out, 48163f89caaSJens Wiklander struct obj_attrs *temp) 48263f89caaSJens Wiklander { 48363f89caaSJens Wiklander enum pkcs11_class_id class = PKCS11_CKO_UNDEFINED_ID; 48463f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 48563f89caaSJens Wiklander 48663f89caaSJens Wiklander rc = init_attributes_head(out); 48763f89caaSJens Wiklander if (rc) 48863f89caaSJens Wiklander return rc; 48963f89caaSJens Wiklander 49063f89caaSJens Wiklander /* Object class is mandatory */ 49163f89caaSJens Wiklander class = get_class(temp); 49263f89caaSJens Wiklander if (class == PKCS11_CKO_UNDEFINED_ID) { 49363f89caaSJens Wiklander EMSG("Class attribute not found"); 49463f89caaSJens Wiklander 49563f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 49663f89caaSJens Wiklander } 49763f89caaSJens Wiklander rc = add_attribute(out, PKCS11_CKA_CLASS, &class, sizeof(uint32_t)); 49863f89caaSJens Wiklander if (rc) 49963f89caaSJens Wiklander return rc; 50063f89caaSJens Wiklander 5014eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, any_object_boolprops, 5024eb88651SRuchika Gupta ARRAY_SIZE(any_object_boolprops)); 50363f89caaSJens Wiklander if (rc) 50463f89caaSJens Wiklander return rc; 50563f89caaSJens Wiklander 5064eb88651SRuchika Gupta return set_attributes_opt_or_null(out, temp, any_object_opt_or_null, 5074eb88651SRuchika Gupta ARRAY_SIZE(any_object_opt_or_null)); 50863f89caaSJens Wiklander } 50963f89caaSJens Wiklander 51063f89caaSJens Wiklander static enum pkcs11_rc create_genkey_attributes(struct obj_attrs **out, 51163f89caaSJens Wiklander struct obj_attrs *temp) 51263f89caaSJens Wiklander { 51363f89caaSJens Wiklander uint32_t type = PKCS11_CKO_UNDEFINED_ID; 51463f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 51563f89caaSJens Wiklander 51663f89caaSJens Wiklander rc = create_storage_attributes(out, temp); 51763f89caaSJens Wiklander if (rc) 51863f89caaSJens Wiklander return rc; 51963f89caaSJens Wiklander 52063f89caaSJens Wiklander type = get_key_type(temp); 52163f89caaSJens Wiklander if (type == PKCS11_CKK_UNDEFINED_ID) { 52263f89caaSJens Wiklander EMSG("Key type attribute not found"); 52363f89caaSJens Wiklander 52463f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 52563f89caaSJens Wiklander } 52663f89caaSJens Wiklander rc = add_attribute(out, PKCS11_CKA_KEY_TYPE, &type, sizeof(uint32_t)); 52763f89caaSJens Wiklander if (rc) 52863f89caaSJens Wiklander return rc; 52963f89caaSJens Wiklander 5304eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, any_key_boolprops, 5314eb88651SRuchika Gupta ARRAY_SIZE(any_key_boolprops)); 53263f89caaSJens Wiklander if (rc) 53363f89caaSJens Wiklander return rc; 53463f89caaSJens Wiklander 5354eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, any_key_opt_or_null, 5364eb88651SRuchika Gupta ARRAY_SIZE(any_key_opt_or_null)); 5374eb88651SRuchika Gupta if (rc) 5384eb88651SRuchika Gupta return rc; 5394eb88651SRuchika Gupta 5404eb88651SRuchika Gupta return set_optional_attributes(out, temp, any_key_optional, 5414eb88651SRuchika Gupta ARRAY_SIZE(any_key_optional)); 5424eb88651SRuchika Gupta 54363f89caaSJens Wiklander } 54463f89caaSJens Wiklander 54563f89caaSJens Wiklander static enum pkcs11_rc create_symm_key_attributes(struct obj_attrs **out, 54663f89caaSJens Wiklander struct obj_attrs *temp) 54763f89caaSJens Wiklander { 54863f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 54963f89caaSJens Wiklander 55063f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_SECRET_KEY); 55163f89caaSJens Wiklander 55263f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 55363f89caaSJens Wiklander if (rc) 55463f89caaSJens Wiklander return rc; 55563f89caaSJens Wiklander 55663f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_SECRET_KEY); 55763f89caaSJens Wiklander 55863f89caaSJens Wiklander switch (get_key_type(*out)) { 55963f89caaSJens Wiklander case PKCS11_CKK_GENERIC_SECRET: 56063f89caaSJens Wiklander case PKCS11_CKK_AES: 56163f89caaSJens Wiklander case PKCS11_CKK_MD5_HMAC: 56263f89caaSJens Wiklander case PKCS11_CKK_SHA_1_HMAC: 56363f89caaSJens Wiklander case PKCS11_CKK_SHA256_HMAC: 56463f89caaSJens Wiklander case PKCS11_CKK_SHA384_HMAC: 56563f89caaSJens Wiklander case PKCS11_CKK_SHA512_HMAC: 56663f89caaSJens Wiklander case PKCS11_CKK_SHA224_HMAC: 56763f89caaSJens Wiklander break; 56863f89caaSJens Wiklander default: 56963f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 57063f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 57163f89caaSJens Wiklander 57263f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 57363f89caaSJens Wiklander } 57463f89caaSJens Wiklander 5754eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, symm_key_boolprops, 5764eb88651SRuchika Gupta ARRAY_SIZE(symm_key_boolprops)); 57763f89caaSJens Wiklander if (rc) 57863f89caaSJens Wiklander return rc; 57963f89caaSJens Wiklander 5800ac5c695SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, symm_key_opt_or_null, 5814eb88651SRuchika Gupta ARRAY_SIZE(symm_key_opt_or_null)); 5820ac5c695SRuchika Gupta if (rc) 5830ac5c695SRuchika Gupta return rc; 5840ac5c695SRuchika Gupta 5850ac5c695SRuchika Gupta return set_optional_attributes(out, temp, symm_key_optional, 5860ac5c695SRuchika Gupta ARRAY_SIZE(symm_key_optional)); 58763f89caaSJens Wiklander } 58863f89caaSJens Wiklander 58963f89caaSJens Wiklander static enum pkcs11_rc create_data_attributes(struct obj_attrs **out, 59063f89caaSJens Wiklander struct obj_attrs *temp) 59163f89caaSJens Wiklander { 59263f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 59363f89caaSJens Wiklander 59463f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_DATA); 59563f89caaSJens Wiklander 59663f89caaSJens Wiklander rc = create_storage_attributes(out, temp); 59763f89caaSJens Wiklander if (rc) 59863f89caaSJens Wiklander return rc; 59963f89caaSJens Wiklander 60063f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_DATA); 60163f89caaSJens Wiklander 6024eb88651SRuchika Gupta return set_attributes_opt_or_null(out, temp, raw_data_opt_or_null, 6034eb88651SRuchika Gupta ARRAY_SIZE(raw_data_opt_or_null)); 60463f89caaSJens Wiklander } 60563f89caaSJens Wiklander 6064137952dSVesa Jääskeläinen static enum pkcs11_rc create_certificate_attributes(struct obj_attrs **out, 6074137952dSVesa Jääskeläinen struct obj_attrs *temp) 6084137952dSVesa Jääskeläinen { 6094137952dSVesa Jääskeläinen uint32_t const *mandated = NULL; 6104137952dSVesa Jääskeläinen uint32_t const *optional = NULL; 6114137952dSVesa Jääskeläinen size_t mandated_count = 0; 6124137952dSVesa Jääskeläinen size_t optional_count = 0; 6134137952dSVesa Jääskeläinen void *attr_value = NULL; 6144137952dSVesa Jääskeläinen uint32_t attr_size = 0; 6154137952dSVesa Jääskeläinen uint32_t default_cert_category = 6164137952dSVesa Jääskeläinen PKCS11_CK_CERTIFICATE_CATEGORY_UNSPECIFIED; 6174137952dSVesa Jääskeläinen uint32_t default_name_hash_alg = PKCS11_CKM_SHA_1; 6184137952dSVesa Jääskeläinen uint32_t cert_category = 0; 6194137952dSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_OK; 6204137952dSVesa Jääskeläinen 6214137952dSVesa Jääskeläinen assert(get_class(temp) == PKCS11_CKO_CERTIFICATE); 6224137952dSVesa Jääskeläinen 6234137952dSVesa Jääskeläinen rc = create_storage_attributes(out, temp); 6244137952dSVesa Jääskeläinen if (rc) 6254137952dSVesa Jääskeläinen return rc; 6264137952dSVesa Jääskeläinen 6274137952dSVesa Jääskeläinen assert(get_class(*out) == PKCS11_CKO_CERTIFICATE); 6284137952dSVesa Jääskeläinen 6294137952dSVesa Jääskeläinen rc = set_mandatory_boolprops(out, temp, pkcs11_certificate_boolprops, 6304137952dSVesa Jääskeläinen ARRAY_SIZE(pkcs11_certificate_boolprops)); 6314137952dSVesa Jääskeläinen if (rc) 6324137952dSVesa Jääskeläinen return rc; 6334137952dSVesa Jääskeläinen 6344137952dSVesa Jääskeläinen rc = set_mandatory_attributes(out, temp, pkcs11_certificate_mandated, 6354137952dSVesa Jääskeläinen ARRAY_SIZE(pkcs11_certificate_mandated)); 6364137952dSVesa Jääskeläinen if (rc) 6374137952dSVesa Jääskeläinen return rc; 6384137952dSVesa Jääskeläinen 6394137952dSVesa Jääskeläinen rc = set_optional_attributes(out, temp, pkcs11_certificate_optional, 6404137952dSVesa Jääskeläinen ARRAY_SIZE(pkcs11_certificate_optional)); 6414137952dSVesa Jääskeläinen if (rc) 6424137952dSVesa Jääskeläinen return rc; 6434137952dSVesa Jääskeläinen 6444137952dSVesa Jääskeläinen switch (get_certificate_type(*out)) { 6454137952dSVesa Jääskeläinen case PKCS11_CKC_X_509: 6464137952dSVesa Jääskeläinen mandated = pkcs11_x509_certificate_mandated; 6474137952dSVesa Jääskeläinen optional = pkcs11_x509_certificate_optional; 6484137952dSVesa Jääskeläinen mandated_count = ARRAY_SIZE(pkcs11_x509_certificate_mandated); 6494137952dSVesa Jääskeläinen optional_count = ARRAY_SIZE(pkcs11_x509_certificate_optional); 6504137952dSVesa Jääskeläinen break; 6514137952dSVesa Jääskeläinen default: 6524137952dSVesa Jääskeläinen EMSG("Invalid certificate type %#"PRIx32"/%s", 6534137952dSVesa Jääskeläinen get_certificate_type(*out), 6544137952dSVesa Jääskeläinen id2str_certificate_type(get_certificate_type(*out))); 6554137952dSVesa Jääskeläinen 6564137952dSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 6574137952dSVesa Jääskeläinen } 6584137952dSVesa Jääskeläinen 6594137952dSVesa Jääskeläinen rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 6604137952dSVesa Jääskeläinen if (rc) 6614137952dSVesa Jääskeläinen return rc; 6624137952dSVesa Jääskeläinen 6634137952dSVesa Jääskeläinen rc = set_optional_attributes(out, temp, optional, optional_count); 6644137952dSVesa Jääskeläinen if (rc) 6654137952dSVesa Jääskeläinen return rc; 6664137952dSVesa Jääskeläinen 6674137952dSVesa Jääskeläinen attr_size = 0; 6684137952dSVesa Jääskeläinen rc = get_attribute_ptr(*out, PKCS11_CKA_CERTIFICATE_CATEGORY, 6694137952dSVesa Jääskeläinen &attr_value, &attr_size); 6704137952dSVesa Jääskeläinen if (rc == PKCS11_CKR_OK && attr_size == sizeof(cert_category)) { 6714137952dSVesa Jääskeläinen /* Sanitize certificate category */ 6724137952dSVesa Jääskeläinen TEE_MemMove(&cert_category, attr_value, sizeof(cert_category)); 6734137952dSVesa Jääskeläinen 6744137952dSVesa Jääskeläinen switch (cert_category) { 6754137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_UNSPECIFIED: 6764137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_TOKEN_USER: 6774137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_AUTHORITY: 6784137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_OTHER_ENTITY: 6794137952dSVesa Jääskeläinen break; 6804137952dSVesa Jääskeläinen default: 6814137952dSVesa Jääskeläinen EMSG("Invalid certificate category %#"PRIx32, 6824137952dSVesa Jääskeläinen cert_category); 6834137952dSVesa Jääskeläinen 6844137952dSVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 6854137952dSVesa Jääskeläinen } 6864137952dSVesa Jääskeläinen } else if (rc == PKCS11_RV_NOT_FOUND) { 6874137952dSVesa Jääskeläinen /* Set default category when missing */ 6884137952dSVesa Jääskeläinen rc = set_attribute(out, PKCS11_CKA_CERTIFICATE_CATEGORY, 6894137952dSVesa Jääskeläinen &default_cert_category, 6904137952dSVesa Jääskeläinen sizeof(default_cert_category)); 6914137952dSVesa Jääskeläinen if (rc) 6924137952dSVesa Jääskeläinen return rc; 6934137952dSVesa Jääskeläinen } else { 6944137952dSVesa Jääskeläinen /* All other cases are errors */ 6954137952dSVesa Jääskeläinen EMSG("Invalid certificate category"); 6964137952dSVesa Jääskeläinen 6974137952dSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 6984137952dSVesa Jääskeläinen } 6994137952dSVesa Jääskeläinen 7004137952dSVesa Jääskeläinen attr_size = 0; 7014137952dSVesa Jääskeläinen rc = get_attribute_ptr(*out, PKCS11_CKA_NAME_HASH_ALGORITHM, NULL, 7024137952dSVesa Jääskeläinen &attr_size); 7034137952dSVesa Jääskeläinen if (rc == PKCS11_CKR_OK && attr_size == sizeof(uint32_t)) { 7044137952dSVesa Jääskeläinen /* We accept any algorithm what caller wanted to specify */ 7054137952dSVesa Jääskeläinen } else if (rc == PKCS11_RV_NOT_FOUND) { 7064137952dSVesa Jääskeläinen /* Set default hash algorithm when missing */ 7074137952dSVesa Jääskeläinen rc = set_attribute(out, PKCS11_CKA_NAME_HASH_ALGORITHM, 7084137952dSVesa Jääskeläinen &default_name_hash_alg, 7094137952dSVesa Jääskeläinen sizeof(default_name_hash_alg)); 7104137952dSVesa Jääskeläinen if (rc) 7114137952dSVesa Jääskeläinen return rc; 7124137952dSVesa Jääskeläinen } else { 7134137952dSVesa Jääskeläinen /* All other cases are errors */ 7144137952dSVesa Jääskeläinen EMSG("Invalid name hash algorithm"); 7154137952dSVesa Jääskeläinen 7164137952dSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 7174137952dSVesa Jääskeläinen } 7184137952dSVesa Jääskeläinen 7194137952dSVesa Jääskeläinen return rc; 7204137952dSVesa Jääskeläinen } 7214137952dSVesa Jääskeläinen 72263f89caaSJens Wiklander static enum pkcs11_rc create_pub_key_attributes(struct obj_attrs **out, 7239cf1afceSVesa Jääskeläinen struct obj_attrs *temp, 7249cf1afceSVesa Jääskeläinen enum processing_func function) 72563f89caaSJens Wiklander { 72663f89caaSJens Wiklander uint32_t const *mandated = NULL; 7279cf1afceSVesa Jääskeläinen uint32_t const *oon = NULL; 72863f89caaSJens Wiklander size_t mandated_count = 0; 7299cf1afceSVesa Jääskeläinen size_t oon_count = 0; 73063f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 73163f89caaSJens Wiklander 73263f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_PUBLIC_KEY); 73363f89caaSJens Wiklander 73463f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 73563f89caaSJens Wiklander if (rc) 73663f89caaSJens Wiklander return rc; 73763f89caaSJens Wiklander 73863f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_PUBLIC_KEY); 73963f89caaSJens Wiklander 7404eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, public_key_boolprops, 7414eb88651SRuchika Gupta ARRAY_SIZE(public_key_boolprops)); 74263f89caaSJens Wiklander if (rc) 74363f89caaSJens Wiklander return rc; 74463f89caaSJens Wiklander 7454eb88651SRuchika Gupta rc = set_mandatory_attributes(out, temp, public_key_mandated, 7464eb88651SRuchika Gupta ARRAY_SIZE(public_key_mandated)); 74763f89caaSJens Wiklander if (rc) 74863f89caaSJens Wiklander return rc; 74963f89caaSJens Wiklander 7504eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, 7514eb88651SRuchika Gupta public_key_opt_or_null, 7524eb88651SRuchika Gupta ARRAY_SIZE(public_key_opt_or_null)); 75363f89caaSJens Wiklander if (rc) 75463f89caaSJens Wiklander return rc; 75563f89caaSJens Wiklander 75663f89caaSJens Wiklander switch (get_key_type(*out)) { 75763f89caaSJens Wiklander case PKCS11_CKK_RSA: 7589cf1afceSVesa Jääskeläinen switch (function) { 7599cf1afceSVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 7609cf1afceSVesa Jääskeläinen mandated = rsa_pub_key_gen_mand; 7619cf1afceSVesa Jääskeläinen oon = rsa_pub_key_gen_opt_or_null; 7629cf1afceSVesa Jääskeläinen mandated_count = ARRAY_SIZE(rsa_pub_key_gen_mand); 7639cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(rsa_pub_key_gen_opt_or_null); 7649cf1afceSVesa Jääskeläinen break; 7659cf1afceSVesa Jääskeläinen case PKCS11_FUNCTION_IMPORT: 7669cf1afceSVesa Jääskeläinen mandated = rsa_pub_key_create_mand; 7679cf1afceSVesa Jääskeläinen mandated_count = ARRAY_SIZE(rsa_pub_key_create_mand); 7689cf1afceSVesa Jääskeläinen break; 7699cf1afceSVesa Jääskeläinen default: 7709cf1afceSVesa Jääskeläinen EMSG("Unsupported function %#"PRIx32"/%s", function, 7719cf1afceSVesa Jääskeläinen id2str_function(function)); 7729cf1afceSVesa Jääskeläinen 7739cf1afceSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 7749cf1afceSVesa Jääskeläinen } 77563f89caaSJens Wiklander break; 77663f89caaSJens Wiklander case PKCS11_CKK_EC: 77703e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 7784eb88651SRuchika Gupta mandated = ec_public_key_mandated; 7799cf1afceSVesa Jääskeläinen oon = ec_public_key_opt_or_null; 7804eb88651SRuchika Gupta mandated_count = ARRAY_SIZE(ec_public_key_mandated); 7819cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(ec_public_key_opt_or_null); 78263f89caaSJens Wiklander break; 78363f89caaSJens Wiklander default: 78463f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 78563f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 78663f89caaSJens Wiklander 78763f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 78863f89caaSJens Wiklander } 78963f89caaSJens Wiklander 79063f89caaSJens Wiklander rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 79163f89caaSJens Wiklander if (rc) 79263f89caaSJens Wiklander return rc; 79363f89caaSJens Wiklander 7949cf1afceSVesa Jääskeläinen return set_attributes_opt_or_null(out, temp, oon, oon_count); 79563f89caaSJens Wiklander } 79663f89caaSJens Wiklander 7975071d7d1SVesa Jääskeläinen static enum pkcs11_rc 7985071d7d1SVesa Jääskeläinen create_pub_key_rsa_generated_attributes(struct obj_attrs **out, 7995071d7d1SVesa Jääskeläinen struct obj_attrs *temp, 8005071d7d1SVesa Jääskeläinen enum processing_func function) 8015071d7d1SVesa Jääskeläinen { 8025071d7d1SVesa Jääskeläinen uint32_t key_bits = 0; 8035071d7d1SVesa Jääskeläinen void *a_ptr = NULL; 8045071d7d1SVesa Jääskeläinen uint32_t a_size = 0; 8055071d7d1SVesa Jääskeläinen 8065071d7d1SVesa Jääskeläinen if (function != PKCS11_FUNCTION_IMPORT) 8075071d7d1SVesa Jääskeläinen return PKCS11_CKR_OK; 8085071d7d1SVesa Jääskeläinen 8095071d7d1SVesa Jääskeläinen /* Calculate CKA_MODULUS_BITS */ 8105071d7d1SVesa Jääskeläinen 8115071d7d1SVesa Jääskeläinen if (get_attribute_ptr(temp, PKCS11_CKA_MODULUS, 8125071d7d1SVesa Jääskeläinen &a_ptr, &a_size) || !a_ptr) { 8135071d7d1SVesa Jääskeläinen EMSG("No CKA_MODULUS attribute found in public key"); 8145071d7d1SVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 8155071d7d1SVesa Jääskeläinen } 8165071d7d1SVesa Jääskeläinen 8175071d7d1SVesa Jääskeläinen key_bits = a_size * 8; 8185071d7d1SVesa Jääskeläinen 8195071d7d1SVesa Jääskeläinen return add_attribute(out, PKCS11_CKA_MODULUS_BITS, &key_bits, 8205071d7d1SVesa Jääskeläinen sizeof(key_bits)); 8215071d7d1SVesa Jääskeläinen } 8225071d7d1SVesa Jääskeläinen 8235071d7d1SVesa Jääskeläinen static enum pkcs11_rc 8245071d7d1SVesa Jääskeläinen create_pub_key_generated_attributes(struct obj_attrs **out, 8255071d7d1SVesa Jääskeläinen struct obj_attrs *temp, 8265071d7d1SVesa Jääskeläinen enum processing_func function) 8275071d7d1SVesa Jääskeläinen { 8285071d7d1SVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_OK; 8295071d7d1SVesa Jääskeläinen 8305071d7d1SVesa Jääskeläinen switch (get_key_type(*out)) { 8315071d7d1SVesa Jääskeläinen case PKCS11_CKK_RSA: 8325071d7d1SVesa Jääskeläinen rc = create_pub_key_rsa_generated_attributes(out, temp, 8335071d7d1SVesa Jääskeläinen function); 8345071d7d1SVesa Jääskeläinen break; 8355071d7d1SVesa Jääskeläinen default: 8365071d7d1SVesa Jääskeläinen /* no-op */ 8375071d7d1SVesa Jääskeläinen break; 8385071d7d1SVesa Jääskeläinen } 8395071d7d1SVesa Jääskeläinen 8405071d7d1SVesa Jääskeläinen return rc; 8415071d7d1SVesa Jääskeläinen } 8425071d7d1SVesa Jääskeläinen 84363f89caaSJens Wiklander static enum pkcs11_rc create_priv_key_attributes(struct obj_attrs **out, 84463f89caaSJens Wiklander struct obj_attrs *temp) 84563f89caaSJens Wiklander { 84663f89caaSJens Wiklander uint32_t const *mandated = NULL; 8479cf1afceSVesa Jääskeläinen uint32_t const *oon = NULL; 84863f89caaSJens Wiklander size_t mandated_count = 0; 8499cf1afceSVesa Jääskeläinen size_t oon_count = 0; 85063f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 85163f89caaSJens Wiklander 85263f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_PRIVATE_KEY); 85363f89caaSJens Wiklander 85463f89caaSJens Wiklander rc = create_genkey_attributes(out, temp); 85563f89caaSJens Wiklander if (rc) 85663f89caaSJens Wiklander return rc; 85763f89caaSJens Wiklander 85863f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_PRIVATE_KEY); 85963f89caaSJens Wiklander 8604eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, private_key_boolprops, 8614eb88651SRuchika Gupta ARRAY_SIZE(private_key_boolprops)); 86263f89caaSJens Wiklander if (rc) 86363f89caaSJens Wiklander return rc; 86463f89caaSJens Wiklander 8654eb88651SRuchika Gupta rc = set_mandatory_attributes(out, temp, private_key_mandated, 8664eb88651SRuchika Gupta ARRAY_SIZE(private_key_mandated)); 86763f89caaSJens Wiklander if (rc) 86863f89caaSJens Wiklander return rc; 86963f89caaSJens Wiklander 8704eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, private_key_opt_or_null, 8714eb88651SRuchika Gupta ARRAY_SIZE(private_key_opt_or_null)); 87263f89caaSJens Wiklander if (rc) 87363f89caaSJens Wiklander return rc; 87463f89caaSJens Wiklander 87563f89caaSJens Wiklander switch (get_key_type(*out)) { 87663f89caaSJens Wiklander case PKCS11_CKK_RSA: 8779cf1afceSVesa Jääskeläinen oon = rsa_priv_key_opt_or_null; 8789cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(rsa_priv_key_opt_or_null); 87963f89caaSJens Wiklander break; 88063f89caaSJens Wiklander case PKCS11_CKK_EC: 8814eb88651SRuchika Gupta mandated = ec_private_key_mandated; 8829cf1afceSVesa Jääskeläinen oon = ec_private_key_opt_or_null; 8834eb88651SRuchika Gupta mandated_count = ARRAY_SIZE(ec_private_key_mandated); 8849cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(ec_private_key_opt_or_null); 88563f89caaSJens Wiklander break; 88603e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 88703e07432SValerii Chubar mandated = ec_private_key_mandated; 88803e07432SValerii Chubar oon = eddsa_private_key_opt_or_null; 88903e07432SValerii Chubar mandated_count = ARRAY_SIZE(ec_private_key_mandated); 89003e07432SValerii Chubar oon_count = ARRAY_SIZE(eddsa_private_key_opt_or_null); 89103e07432SValerii Chubar break; 89263f89caaSJens Wiklander default: 89363f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s", 89463f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out))); 89563f89caaSJens Wiklander 89663f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 89763f89caaSJens Wiklander } 89863f89caaSJens Wiklander 89963f89caaSJens Wiklander rc = set_mandatory_attributes(out, temp, mandated, mandated_count); 90063f89caaSJens Wiklander if (rc) 90163f89caaSJens Wiklander return rc; 90263f89caaSJens Wiklander 9039cf1afceSVesa Jääskeläinen return set_attributes_opt_or_null(out, temp, oon, oon_count); 90463f89caaSJens Wiklander } 90563f89caaSJens Wiklander 906196bcd93SRuchika Gupta static enum pkcs11_rc 907196bcd93SRuchika Gupta sanitize_symm_key_attributes(struct obj_attrs **temp, 908196bcd93SRuchika Gupta enum processing_func function) 909196bcd93SRuchika Gupta { 910196bcd93SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK; 911196bcd93SRuchika Gupta uint32_t a_size = 0; 912196bcd93SRuchika Gupta 913196bcd93SRuchika Gupta assert(get_class(*temp) == PKCS11_CKO_SECRET_KEY); 914196bcd93SRuchika Gupta 915196bcd93SRuchika Gupta rc = get_attribute_ptr(*temp, PKCS11_CKA_VALUE, NULL, &a_size); 916196bcd93SRuchika Gupta 917196bcd93SRuchika Gupta switch (get_key_type(*temp)) { 918196bcd93SRuchika Gupta case PKCS11_CKK_GENERIC_SECRET: 919196bcd93SRuchika Gupta case PKCS11_CKK_AES: 920196bcd93SRuchika Gupta case PKCS11_CKK_MD5_HMAC: 921196bcd93SRuchika Gupta case PKCS11_CKK_SHA_1_HMAC: 922196bcd93SRuchika Gupta case PKCS11_CKK_SHA256_HMAC: 923196bcd93SRuchika Gupta case PKCS11_CKK_SHA384_HMAC: 924196bcd93SRuchika Gupta case PKCS11_CKK_SHA512_HMAC: 925196bcd93SRuchika Gupta case PKCS11_CKK_SHA224_HMAC: 926196bcd93SRuchika Gupta switch (function) { 927196bcd93SRuchika Gupta case PKCS11_FUNCTION_IMPORT: 928196bcd93SRuchika Gupta /* CKA_VALUE is a mandatory with C_CreateObject */ 929196bcd93SRuchika Gupta if (rc || a_size == 0) 930196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 931196bcd93SRuchika Gupta 932196bcd93SRuchika Gupta if (get_attribute_ptr(*temp, PKCS11_CKA_VALUE_LEN, NULL, 933196bcd93SRuchika Gupta NULL) != PKCS11_RV_NOT_FOUND) 934196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 935196bcd93SRuchika Gupta 936196bcd93SRuchika Gupta return add_attribute(temp, PKCS11_CKA_VALUE_LEN, 937196bcd93SRuchika Gupta &a_size, sizeof(uint32_t)); 938196bcd93SRuchika Gupta case PKCS11_FUNCTION_GENERATE: 939196bcd93SRuchika Gupta if (rc != PKCS11_RV_NOT_FOUND) 940196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 941196bcd93SRuchika Gupta break; 942196bcd93SRuchika Gupta default: 943196bcd93SRuchika Gupta break; 944196bcd93SRuchika Gupta } 945196bcd93SRuchika Gupta break; 946196bcd93SRuchika Gupta default: 947196bcd93SRuchika Gupta EMSG("Invalid key type %#"PRIx32"/%s", 948196bcd93SRuchika Gupta get_key_type(*temp), id2str_key_type(get_key_type(*temp))); 949196bcd93SRuchika Gupta 950196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 951196bcd93SRuchika Gupta } 952196bcd93SRuchika Gupta 953196bcd93SRuchika Gupta return PKCS11_CKR_OK; 954196bcd93SRuchika Gupta } 955196bcd93SRuchika Gupta 95663f89caaSJens Wiklander /* 95763f89caaSJens Wiklander * Create an attribute list for a new object from a template and a parent 95863f89caaSJens Wiklander * object (optional) for an object generation function (generate, copy, 95963f89caaSJens Wiklander * derive...). 96063f89caaSJens Wiklander * 96163f89caaSJens Wiklander * PKCS#11 directives on the supplied template and expected return value: 96263f89caaSJens Wiklander * - template has an invalid attribute ID: ATTRIBUTE_TYPE_INVALID 96363f89caaSJens Wiklander * - template has an invalid value for an attribute: ATTRIBUTE_VALID_INVALID 96463f89caaSJens Wiklander * - template has value for a read-only attribute: ATTRIBUTE_READ_ONLY 96563f89caaSJens Wiklander * - template+default+parent => still miss an attribute: TEMPLATE_INCONSISTENT 96663f89caaSJens Wiklander * 96763f89caaSJens Wiklander * INFO on PKCS11_CMD_COPY_OBJECT: 96863f89caaSJens Wiklander * - parent PKCS11_CKA_COPYIABLE=false => return ACTION_PROHIBITED. 96963f89caaSJens Wiklander * - template can specify PKCS11_CKA_TOKEN, PKCS11_CKA_PRIVATE, 97063f89caaSJens Wiklander * PKCS11_CKA_MODIFIABLE, PKCS11_CKA_DESTROYABLE. 97163f89caaSJens Wiklander * - SENSITIVE can change from false to true, not from true to false. 97263f89caaSJens Wiklander * - LOCAL is the parent LOCAL 97363f89caaSJens Wiklander */ 97463f89caaSJens Wiklander enum pkcs11_rc 97563f89caaSJens Wiklander create_attributes_from_template(struct obj_attrs **out, void *template, 97663f89caaSJens Wiklander size_t template_size, 97748799892SRuchika Gupta struct obj_attrs *parent, 97863f89caaSJens Wiklander enum processing_func function, 9794cfce748SRuchika Gupta enum pkcs11_mechanism_id mecha, 98002b16804SVesa Jääskeläinen enum pkcs11_class_id template_class) 98163f89caaSJens Wiklander { 98263f89caaSJens Wiklander struct obj_attrs *temp = NULL; 98363f89caaSJens Wiklander struct obj_attrs *attrs = NULL; 98463f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 98563f89caaSJens Wiklander uint8_t local = 0; 98663f89caaSJens Wiklander uint8_t always_sensitive = 0; 98763f89caaSJens Wiklander uint8_t never_extract = 0; 988e3f0cb56SRuchika Gupta uint8_t extractable = 0; 989fa247a2aSRuchika Gupta uint32_t class = PKCS11_UNDEFINED_ID; 990fa247a2aSRuchika Gupta uint32_t type = PKCS11_UNDEFINED_ID; 99163f89caaSJens Wiklander uint32_t mechanism_id = PKCS11_CKM_UNDEFINED_ID; 992e3f0cb56SRuchika Gupta struct obj_attrs *req_attrs = NULL; 993e3f0cb56SRuchika Gupta uint32_t size = 0; 994e3f0cb56SRuchika Gupta uint32_t indirect_template = PKCS11_CKA_UNDEFINED_ID; 99563f89caaSJens Wiklander 99663f89caaSJens Wiklander #ifdef DEBUG /* Sanity: check function argument */ 99763f89caaSJens Wiklander trace_attributes_from_api_head("template", template, template_size); 99863f89caaSJens Wiklander switch (function) { 999fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 1000013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 100163f89caaSJens Wiklander case PKCS11_FUNCTION_IMPORT: 10022d25a9bcSRuchika Gupta case PKCS11_FUNCTION_MODIFY: 100348799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 1004e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 10052d25a9bcSRuchika Gupta case PKCS11_FUNCTION_COPY: 100663f89caaSJens Wiklander break; 100763f89caaSJens Wiklander default: 100863f89caaSJens Wiklander TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 100963f89caaSJens Wiklander } 101063f89caaSJens Wiklander #endif 101163f89caaSJens Wiklander 1012dcad3409SRuchika Gupta /* 1013dcad3409SRuchika Gupta * For PKCS11_FUNCTION_GENERATE, find the class and type 1014dcad3409SRuchika Gupta * based on the mechanism. These will be passed as hint 1015dcad3409SRuchika Gupta * sanitize_client_object() and added in temp if not 1016dcad3409SRuchika Gupta * already present 1017dcad3409SRuchika Gupta */ 1018dcad3409SRuchika Gupta if (function == PKCS11_FUNCTION_GENERATE) { 1019fa247a2aSRuchika Gupta switch (mecha) { 1020fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1021fa247a2aSRuchika Gupta class = PKCS11_CKO_SECRET_KEY; 1022fa247a2aSRuchika Gupta type = PKCS11_CKK_GENERIC_SECRET; 1023fa247a2aSRuchika Gupta break; 1024fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 1025fa247a2aSRuchika Gupta class = PKCS11_CKO_SECRET_KEY; 1026fa247a2aSRuchika Gupta type = PKCS11_CKK_AES; 1027fa247a2aSRuchika Gupta break; 1028fa247a2aSRuchika Gupta default: 1029dcad3409SRuchika Gupta TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 1030fa247a2aSRuchika Gupta } 1031fa247a2aSRuchika Gupta } 1032fa247a2aSRuchika Gupta 10332d25a9bcSRuchika Gupta /* 1034013934d8SVesa Jääskeläinen * For PKCS11_FUNCTION_GENERATE_PAIR, find the class and type 1035013934d8SVesa Jääskeläinen * based on the mechanism. These will be passed as hint 1036013934d8SVesa Jääskeläinen * sanitize_client_object() and added in temp if not 1037013934d8SVesa Jääskeläinen * already present 1038013934d8SVesa Jääskeläinen */ 1039013934d8SVesa Jääskeläinen if (function == PKCS11_FUNCTION_GENERATE_PAIR) { 1040013934d8SVesa Jääskeläinen switch (mecha) { 104103e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: 104203e07432SValerii Chubar class = template_class; 104303e07432SValerii Chubar type = PKCS11_CKK_EDDSA; 104403e07432SValerii Chubar break; 104502b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 104602b16804SVesa Jääskeläinen class = template_class; 104702b16804SVesa Jääskeläinen type = PKCS11_CKK_EC; 104802b16804SVesa Jääskeläinen break; 104986922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 105086922832SVesa Jääskeläinen class = template_class; 105186922832SVesa Jääskeläinen type = PKCS11_CKK_RSA; 105286922832SVesa Jääskeläinen break; 1053013934d8SVesa Jääskeläinen default: 1054013934d8SVesa Jääskeläinen TEE_Panic(TEE_ERROR_NOT_SUPPORTED); 1055013934d8SVesa Jääskeläinen } 1056013934d8SVesa Jääskeläinen } 1057013934d8SVesa Jääskeläinen 1058013934d8SVesa Jääskeläinen /* 10592d25a9bcSRuchika Gupta * Check and remove duplicates if any and create a new temporary 10602d25a9bcSRuchika Gupta * template 10612d25a9bcSRuchika Gupta */ 1062dcad3409SRuchika Gupta rc = sanitize_client_object(&temp, template, template_size, class, 1063dcad3409SRuchika Gupta type); 1064dcad3409SRuchika Gupta if (rc) 1065dcad3409SRuchika Gupta goto out; 1066dcad3409SRuchika Gupta 1067dcad3409SRuchika Gupta /* 10682d25a9bcSRuchika Gupta * For function type modify and copy return the created template 10692d25a9bcSRuchika Gupta * from here. Rest of the code below is for creating objects 10702d25a9bcSRuchika Gupta * or generating keys. 10712d25a9bcSRuchika Gupta */ 10722d25a9bcSRuchika Gupta switch (function) { 10732d25a9bcSRuchika Gupta case PKCS11_FUNCTION_MODIFY: 10742d25a9bcSRuchika Gupta case PKCS11_FUNCTION_COPY: 10752d25a9bcSRuchika Gupta *out = temp; 10762d25a9bcSRuchika Gupta return rc; 1077e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 1078e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 1079e3f0cb56SRuchika Gupta if (function == PKCS11_FUNCTION_UNWRAP) 1080e3f0cb56SRuchika Gupta indirect_template = PKCS11_CKA_UNWRAP_TEMPLATE; 1081e3f0cb56SRuchika Gupta else 1082e3f0cb56SRuchika Gupta indirect_template = PKCS11_CKA_DERIVE_TEMPLATE; 1083e3f0cb56SRuchika Gupta 1084e3f0cb56SRuchika Gupta rc = get_attribute_ptr(parent, indirect_template, 1085e3f0cb56SRuchika Gupta (void *)&req_attrs, &size); 1086e3f0cb56SRuchika Gupta if (rc == PKCS11_CKR_OK && size != 0) { 1087e3f0cb56SRuchika Gupta rc = attributes_match_add_reference(&temp, req_attrs); 1088e3f0cb56SRuchika Gupta if (rc) 1089e3f0cb56SRuchika Gupta goto out; 1090e3f0cb56SRuchika Gupta } 1091e3f0cb56SRuchika Gupta break; 10922d25a9bcSRuchika Gupta default: 10932d25a9bcSRuchika Gupta break; 10942d25a9bcSRuchika Gupta } 10952d25a9bcSRuchika Gupta 10962d25a9bcSRuchika Gupta /* 1097dcad3409SRuchika Gupta * Check if class and type in temp are consistent with the mechanism 1098dcad3409SRuchika Gupta */ 1099fa247a2aSRuchika Gupta switch (mecha) { 1100fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1101fa247a2aSRuchika Gupta if (get_class(temp) != PKCS11_CKO_SECRET_KEY || 1102fa247a2aSRuchika Gupta get_key_type(temp) != PKCS11_CKK_GENERIC_SECRET) { 1103fa247a2aSRuchika Gupta rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 1104fa247a2aSRuchika Gupta goto out; 1105fa247a2aSRuchika Gupta } 1106fa247a2aSRuchika Gupta break; 1107fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 1108fa247a2aSRuchika Gupta if (get_class(temp) != PKCS11_CKO_SECRET_KEY || 1109fa247a2aSRuchika Gupta get_key_type(temp) != PKCS11_CKK_AES) { 1110fa247a2aSRuchika Gupta rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 1111fa247a2aSRuchika Gupta goto out; 1112fa247a2aSRuchika Gupta } 1113fa247a2aSRuchika Gupta break; 111402b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 111502b16804SVesa Jääskeläinen if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && 111602b16804SVesa Jääskeläinen get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || 111702b16804SVesa Jääskeläinen get_key_type(temp) != PKCS11_CKK_EC) { 111802b16804SVesa Jääskeläinen rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 111902b16804SVesa Jääskeläinen goto out; 112002b16804SVesa Jääskeläinen } 112102b16804SVesa Jääskeläinen break; 112203e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: 112303e07432SValerii Chubar if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && 112403e07432SValerii Chubar get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || 112503e07432SValerii Chubar get_key_type(temp) != PKCS11_CKK_EC_EDWARDS) { 112603e07432SValerii Chubar rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 112703e07432SValerii Chubar goto out; 112803e07432SValerii Chubar } 112903e07432SValerii Chubar break; 113086922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 113186922832SVesa Jääskeläinen if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && 113286922832SVesa Jääskeläinen get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || 113386922832SVesa Jääskeläinen get_key_type(temp) != PKCS11_CKK_RSA) { 113486922832SVesa Jääskeläinen rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 113586922832SVesa Jääskeläinen goto out; 113686922832SVesa Jääskeläinen } 113786922832SVesa Jääskeläinen break; 1138fa247a2aSRuchika Gupta default: 1139fa247a2aSRuchika Gupta break; 1140fa247a2aSRuchika Gupta } 114163f89caaSJens Wiklander 114263f89caaSJens Wiklander if (!sanitize_consistent_class_and_type(temp)) { 114363f89caaSJens Wiklander EMSG("Inconsistent class/type"); 114463f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 114563f89caaSJens Wiklander goto out; 114663f89caaSJens Wiklander } 114763f89caaSJens Wiklander 1148e3f0cb56SRuchika Gupta /* 1149e3f0cb56SRuchika Gupta * TBD - Add a check to see if temp contains any attribute which 1150e3f0cb56SRuchika Gupta * is not consistent with the object class or type and return error. 1151e3f0cb56SRuchika Gupta * In current implementation such attributes are ignored and not 1152e3f0cb56SRuchika Gupta * added to final object while PKCS#11 specification expects a 1153e3f0cb56SRuchika Gupta * failure and an error code be returned. 1154e3f0cb56SRuchika Gupta */ 1155e3f0cb56SRuchika Gupta 115663f89caaSJens Wiklander switch (get_class(temp)) { 115763f89caaSJens Wiklander case PKCS11_CKO_DATA: 115863f89caaSJens Wiklander rc = create_data_attributes(&attrs, temp); 115963f89caaSJens Wiklander break; 11604137952dSVesa Jääskeläinen case PKCS11_CKO_CERTIFICATE: 11614137952dSVesa Jääskeläinen rc = create_certificate_attributes(&attrs, temp); 11624137952dSVesa Jääskeläinen break; 116363f89caaSJens Wiklander case PKCS11_CKO_SECRET_KEY: 1164196bcd93SRuchika Gupta rc = sanitize_symm_key_attributes(&temp, function); 1165196bcd93SRuchika Gupta if (rc) 1166196bcd93SRuchika Gupta goto out; 116763f89caaSJens Wiklander rc = create_symm_key_attributes(&attrs, temp); 116863f89caaSJens Wiklander break; 116963f89caaSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 11709cf1afceSVesa Jääskeläinen rc = create_pub_key_attributes(&attrs, temp, function); 11715071d7d1SVesa Jääskeläinen if (rc) 11725071d7d1SVesa Jääskeläinen goto out; 11735071d7d1SVesa Jääskeläinen rc = create_pub_key_generated_attributes(&attrs, temp, 11745071d7d1SVesa Jääskeläinen function); 117563f89caaSJens Wiklander break; 117663f89caaSJens Wiklander case PKCS11_CKO_PRIVATE_KEY: 117763f89caaSJens Wiklander rc = create_priv_key_attributes(&attrs, temp); 117863f89caaSJens Wiklander break; 117963f89caaSJens Wiklander default: 118063f89caaSJens Wiklander DMSG("Invalid object class %#"PRIx32"/%s", 118163f89caaSJens Wiklander get_class(temp), id2str_class(get_class(temp))); 118263f89caaSJens Wiklander 118363f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 118463f89caaSJens Wiklander break; 118563f89caaSJens Wiklander } 118663f89caaSJens Wiklander if (rc) 118763f89caaSJens Wiklander goto out; 118863f89caaSJens Wiklander 118990c47fe2SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_LOCAL, NULL, NULL) != 1190002f6b93SEtienne Carriere PKCS11_RV_NOT_FOUND) { 1191002f6b93SEtienne Carriere rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 119263f89caaSJens Wiklander goto out; 1193002f6b93SEtienne Carriere } 119463f89caaSJens Wiklander 119590c47fe2SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_KEY_GEN_MECHANISM, NULL, NULL) != 1196002f6b93SEtienne Carriere PKCS11_RV_NOT_FOUND) { 1197002f6b93SEtienne Carriere rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 119863f89caaSJens Wiklander goto out; 1199002f6b93SEtienne Carriere } 120063f89caaSJens Wiklander 120163f89caaSJens Wiklander switch (function) { 1202fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 1203013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 1204fa247a2aSRuchika Gupta local = PKCS11_TRUE; 1205fa247a2aSRuchika Gupta break; 120663f89caaSJens Wiklander case PKCS11_FUNCTION_IMPORT: 120748799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 1208e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 120963f89caaSJens Wiklander default: 121063f89caaSJens Wiklander local = PKCS11_FALSE; 121163f89caaSJens Wiklander break; 121263f89caaSJens Wiklander } 121363f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_LOCAL, &local, sizeof(local)); 121463f89caaSJens Wiklander if (rc) 121563f89caaSJens Wiklander goto out; 121663f89caaSJens Wiklander 121763f89caaSJens Wiklander switch (get_class(attrs)) { 121863f89caaSJens Wiklander case PKCS11_CKO_SECRET_KEY: 121963f89caaSJens Wiklander case PKCS11_CKO_PRIVATE_KEY: 122063f89caaSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 122163f89caaSJens Wiklander always_sensitive = PKCS11_FALSE; 122263f89caaSJens Wiklander never_extract = PKCS11_FALSE; 122363f89caaSJens Wiklander 1224fa247a2aSRuchika Gupta switch (function) { 122548799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE: 122648799892SRuchika Gupta always_sensitive = 122748799892SRuchika Gupta get_bool(parent, PKCS11_CKA_ALWAYS_SENSITIVE) && 122848799892SRuchika Gupta get_bool(attrs, PKCS11_CKA_SENSITIVE); 122948799892SRuchika Gupta never_extract = 123048799892SRuchika Gupta get_bool(parent, PKCS11_CKA_NEVER_EXTRACTABLE) && 123148799892SRuchika Gupta !get_bool(attrs, PKCS11_CKA_EXTRACTABLE); 123248799892SRuchika Gupta break; 1233e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP: 1234e3f0cb56SRuchika Gupta always_sensitive = PKCS11_FALSE; 1235e3f0cb56SRuchika Gupta never_extract = PKCS11_FALSE; 1236e3f0cb56SRuchika Gupta extractable = PKCS11_TRUE; 1237e3f0cb56SRuchika Gupta 1238e3f0cb56SRuchika Gupta /* 1239e3f0cb56SRuchika Gupta * Check if template passed by user has CKA_EXTRACTABLE. 1240e3f0cb56SRuchika Gupta * If not, by default value of CKA_EXTRACTABLE is set as 1241e3f0cb56SRuchika Gupta * TRUE. 1242e3f0cb56SRuchika Gupta */ 1243e3f0cb56SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_EXTRACTABLE, 1244e3f0cb56SRuchika Gupta NULL, 1245e3f0cb56SRuchika Gupta NULL) == PKCS11_RV_NOT_FOUND) { 1246e3f0cb56SRuchika Gupta rc = set_attribute(&attrs, 1247e3f0cb56SRuchika Gupta PKCS11_CKA_EXTRACTABLE, 1248e3f0cb56SRuchika Gupta &extractable, 1249e3f0cb56SRuchika Gupta sizeof(extractable)); 1250e3f0cb56SRuchika Gupta if (rc) 1251e3f0cb56SRuchika Gupta goto out; 1252e3f0cb56SRuchika Gupta } 1253e3f0cb56SRuchika Gupta break; 1254fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE: 1255013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR: 1256fa247a2aSRuchika Gupta always_sensitive = get_bool(attrs, 1257fa247a2aSRuchika Gupta PKCS11_CKA_SENSITIVE); 1258fa247a2aSRuchika Gupta never_extract = !get_bool(attrs, 1259fa247a2aSRuchika Gupta PKCS11_CKA_EXTRACTABLE); 1260fa247a2aSRuchika Gupta break; 1261fa247a2aSRuchika Gupta default: 1262fa247a2aSRuchika Gupta break; 1263fa247a2aSRuchika Gupta } 1264fa247a2aSRuchika Gupta 126563f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_ALWAYS_SENSITIVE, 126663f89caaSJens Wiklander &always_sensitive, sizeof(always_sensitive)); 126763f89caaSJens Wiklander if (rc) 126863f89caaSJens Wiklander goto out; 126963f89caaSJens Wiklander 127063f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_NEVER_EXTRACTABLE, 127163f89caaSJens Wiklander &never_extract, sizeof(never_extract)); 127263f89caaSJens Wiklander if (rc) 127363f89caaSJens Wiklander goto out; 127463f89caaSJens Wiklander 127563f89caaSJens Wiklander /* Keys mandate attribute PKCS11_CKA_KEY_GEN_MECHANISM */ 1276fa247a2aSRuchika Gupta if (local) 1277fa247a2aSRuchika Gupta mechanism_id = mecha; 1278fa247a2aSRuchika Gupta else 127963f89caaSJens Wiklander mechanism_id = PKCS11_CK_UNAVAILABLE_INFORMATION; 1280fa247a2aSRuchika Gupta 128163f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_KEY_GEN_MECHANISM, 128263f89caaSJens Wiklander &mechanism_id, sizeof(mechanism_id)); 128363f89caaSJens Wiklander if (rc) 128463f89caaSJens Wiklander goto out; 128563f89caaSJens Wiklander break; 128663f89caaSJens Wiklander 128763f89caaSJens Wiklander default: 128863f89caaSJens Wiklander break; 128963f89caaSJens Wiklander } 129063f89caaSJens Wiklander 129163f89caaSJens Wiklander *out = attrs; 129263f89caaSJens Wiklander 129363f89caaSJens Wiklander #ifdef DEBUG 129463f89caaSJens Wiklander trace_attributes("object", attrs); 129563f89caaSJens Wiklander #endif 129663f89caaSJens Wiklander 129763f89caaSJens Wiklander out: 129863f89caaSJens Wiklander TEE_Free(temp); 129963f89caaSJens Wiklander if (rc) 130063f89caaSJens Wiklander TEE_Free(attrs); 130163f89caaSJens Wiklander 130263f89caaSJens Wiklander return rc; 130363f89caaSJens Wiklander } 130463f89caaSJens Wiklander 130563f89caaSJens Wiklander static enum pkcs11_rc check_attrs_misc_integrity(struct obj_attrs *head) 130663f89caaSJens Wiklander { 130763f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_NEVER_EXTRACTABLE) && 130863f89caaSJens Wiklander get_bool(head, PKCS11_CKA_EXTRACTABLE)) { 130963f89caaSJens Wiklander DMSG("Never/Extractable attributes mismatch %d/%d", 131063f89caaSJens Wiklander get_bool(head, PKCS11_CKA_NEVER_EXTRACTABLE), 131163f89caaSJens Wiklander get_bool(head, PKCS11_CKA_EXTRACTABLE)); 131263f89caaSJens Wiklander 131363f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 131463f89caaSJens Wiklander } 131563f89caaSJens Wiklander 131663f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_ALWAYS_SENSITIVE) && 131763f89caaSJens Wiklander !get_bool(head, PKCS11_CKA_SENSITIVE)) { 131863f89caaSJens Wiklander DMSG("Sensitive/always attributes mismatch %d/%d", 131963f89caaSJens Wiklander get_bool(head, PKCS11_CKA_SENSITIVE), 132063f89caaSJens Wiklander get_bool(head, PKCS11_CKA_ALWAYS_SENSITIVE)); 132163f89caaSJens Wiklander 132263f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 132363f89caaSJens Wiklander } 132463f89caaSJens Wiklander 132563f89caaSJens Wiklander return PKCS11_CKR_OK; 132663f89caaSJens Wiklander } 132763f89caaSJens Wiklander 132889735787SRuchika Gupta bool object_is_private(struct obj_attrs *head) 132989735787SRuchika Gupta { 133065fb9092SVesa Jääskeläinen return get_bool(head, PKCS11_CKA_PRIVATE); 133189735787SRuchika Gupta } 133289735787SRuchika Gupta 13332d25a9bcSRuchika Gupta bool object_is_token(struct obj_attrs *head) 13342d25a9bcSRuchika Gupta { 13352d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_TOKEN); 13362d25a9bcSRuchika Gupta } 13372d25a9bcSRuchika Gupta 13382d25a9bcSRuchika Gupta bool object_is_modifiable(struct obj_attrs *head) 13392d25a9bcSRuchika Gupta { 13402d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_MODIFIABLE); 13412d25a9bcSRuchika Gupta } 13422d25a9bcSRuchika Gupta 13432d25a9bcSRuchika Gupta bool object_is_copyable(struct obj_attrs *head) 13442d25a9bcSRuchika Gupta { 13452d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_COPYABLE); 13462d25a9bcSRuchika Gupta } 13472d25a9bcSRuchika Gupta 134863f89caaSJens Wiklander /* 1349512cbf1dSJens Wiklander * Check access to object against authentication to token 1350512cbf1dSJens Wiklander */ 1351512cbf1dSJens Wiklander enum pkcs11_rc check_access_attrs_against_token(struct pkcs11_session *session, 1352512cbf1dSJens Wiklander struct obj_attrs *head) 1353512cbf1dSJens Wiklander { 1354512cbf1dSJens Wiklander bool private = true; 1355512cbf1dSJens Wiklander 1356512cbf1dSJens Wiklander switch (get_class(head)) { 1357512cbf1dSJens Wiklander case PKCS11_CKO_SECRET_KEY: 135865fb9092SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1359512cbf1dSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 1360512cbf1dSJens Wiklander case PKCS11_CKO_DATA: 13614137952dSVesa Jääskeläinen case PKCS11_CKO_CERTIFICATE: 136265fb9092SVesa Jääskeläinen private = object_is_private(head); 1363512cbf1dSJens Wiklander break; 1364512cbf1dSJens Wiklander default: 1365512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1366512cbf1dSJens Wiklander } 1367512cbf1dSJens Wiklander 13685db0fef4SRuchika Gupta if (private && (pkcs11_session_is_public(session) || 13695db0fef4SRuchika Gupta pkcs11_session_is_so(session))) { 13705db0fef4SRuchika Gupta DMSG("Private object access from a public or SO session"); 1371512cbf1dSJens Wiklander 137212f1ba86SRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 1373512cbf1dSJens Wiklander } 1374512cbf1dSJens Wiklander 1375512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1376512cbf1dSJens Wiklander } 1377512cbf1dSJens Wiklander 1378512cbf1dSJens Wiklander /* 137963f89caaSJens Wiklander * Check the attributes of a to-be-created object matches the token state 138063f89caaSJens Wiklander */ 138163f89caaSJens Wiklander enum pkcs11_rc check_created_attrs_against_token(struct pkcs11_session *session, 138263f89caaSJens Wiklander struct obj_attrs *head) 138363f89caaSJens Wiklander { 138463f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 138563f89caaSJens Wiklander 138663f89caaSJens Wiklander rc = check_attrs_misc_integrity(head); 138763f89caaSJens Wiklander if (rc) 138863f89caaSJens Wiklander return rc; 138963f89caaSJens Wiklander 139063f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_TRUSTED) && 139163f89caaSJens Wiklander !pkcs11_session_is_so(session)) { 139263f89caaSJens Wiklander DMSG("Can't create trusted object"); 139363f89caaSJens Wiklander 139463f89caaSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 139563f89caaSJens Wiklander } 139663f89caaSJens Wiklander 139763f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_TOKEN) && 139863f89caaSJens Wiklander !pkcs11_session_is_read_write(session)) { 139963f89caaSJens Wiklander DMSG("Can't create persistent object"); 140063f89caaSJens Wiklander 140163f89caaSJens Wiklander return PKCS11_CKR_SESSION_READ_ONLY; 140263f89caaSJens Wiklander } 140363f89caaSJens Wiklander 140463f89caaSJens Wiklander return PKCS11_CKR_OK; 140563f89caaSJens Wiklander } 140663f89caaSJens Wiklander 140763f89caaSJens Wiklander #define DMSG_BAD_BBOOL(attr, proc, head) \ 140863f89caaSJens Wiklander do { \ 140963f89caaSJens Wiklander uint32_t __maybe_unused _attr = (attr); \ 141063f89caaSJens Wiklander uint8_t __maybe_unused _bvalue = 0; \ 141163f89caaSJens Wiklander enum pkcs11_rc __maybe_unused _rc = PKCS11_CKR_OK; \ 141263f89caaSJens Wiklander \ 141363f89caaSJens Wiklander _rc = get_attribute((head), _attr, &_bvalue, NULL); \ 141463f89caaSJens Wiklander DMSG("%s issue for %s: %sfound, value %"PRIu8, \ 141563f89caaSJens Wiklander id2str_attr(_attr), id2str_proc((proc)), \ 141663f89caaSJens Wiklander _rc ? "not " : "", _bvalue); \ 141763f89caaSJens Wiklander } while (0) 141863f89caaSJens Wiklander 141963f89caaSJens Wiklander static bool __maybe_unused check_attr_bval(uint32_t proc_id __maybe_unused, 142063f89caaSJens Wiklander struct obj_attrs *head, 142163f89caaSJens Wiklander uint32_t attribute, bool val) 142263f89caaSJens Wiklander { 142363f89caaSJens Wiklander uint8_t bbool = 0; 142463f89caaSJens Wiklander uint32_t sz = sizeof(bbool); 142563f89caaSJens Wiklander 142663f89caaSJens Wiklander if (!get_attribute(head, attribute, &bbool, &sz) && !!bbool == val) 142763f89caaSJens Wiklander return true; 142863f89caaSJens Wiklander 142963f89caaSJens Wiklander DMSG_BAD_BBOOL(attribute, proc_id, head); 143063f89caaSJens Wiklander return false; 143163f89caaSJens Wiklander } 143263f89caaSJens Wiklander 143363f89caaSJens Wiklander /* 143463f89caaSJens Wiklander * Check the attributes of a new secret match the processing/mechanism 143563f89caaSJens Wiklander * used to create it. 143663f89caaSJens Wiklander * 143763f89caaSJens Wiklander * @proc_id - PKCS11_CKM_xxx 143863f89caaSJens Wiklander * @head - head of the attributes of the to-be-created object. 143963f89caaSJens Wiklander */ 144063f89caaSJens Wiklander enum pkcs11_rc check_created_attrs_against_processing(uint32_t proc_id, 144163f89caaSJens Wiklander struct obj_attrs *head) 144263f89caaSJens Wiklander { 144363f89caaSJens Wiklander /* 144463f89caaSJens Wiklander * Processings that do not create secrets are not expected to call 144563f89caaSJens Wiklander * this function which would panic. 144663f89caaSJens Wiklander */ 144763f89caaSJens Wiklander switch (proc_id) { 144863f89caaSJens Wiklander case PKCS11_PROCESSING_IMPORT: 1449cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 1450e3f0cb56SRuchika Gupta case PKCS11_CKM_AES_ECB: 1451e3f0cb56SRuchika Gupta case PKCS11_CKM_AES_CBC: 145248799892SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 145348799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 145445d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP: 145563f89caaSJens Wiklander assert(check_attr_bval(proc_id, head, PKCS11_CKA_LOCAL, false)); 145663f89caaSJens Wiklander break; 1457fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1458fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 145903e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: 146002b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 146186922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 1462fa247a2aSRuchika Gupta assert(check_attr_bval(proc_id, head, PKCS11_CKA_LOCAL, true)); 1463fa247a2aSRuchika Gupta break; 146463f89caaSJens Wiklander default: 146563f89caaSJens Wiklander TEE_Panic(proc_id); 146663f89caaSJens Wiklander break; 146763f89caaSJens Wiklander } 146863f89caaSJens Wiklander 1469fa247a2aSRuchika Gupta switch (proc_id) { 1470fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 1471fa247a2aSRuchika Gupta assert(get_key_type(head) == PKCS11_CKK_GENERIC_SECRET); 1472fa247a2aSRuchika Gupta break; 1473fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN: 1474fa247a2aSRuchika Gupta assert(get_key_type(head) == PKCS11_CKK_AES); 1475fa247a2aSRuchika Gupta break; 147603e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: 147703e07432SValerii Chubar assert(get_key_type(head) == PKCS11_CKK_EC_EDWARDS); 147803e07432SValerii Chubar break; 147902b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN: 148002b16804SVesa Jääskeläinen assert(get_key_type(head) == PKCS11_CKK_EC); 148102b16804SVesa Jääskeläinen break; 148286922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: 148386922832SVesa Jääskeläinen assert(get_key_type(head) == PKCS11_CKK_RSA); 148486922832SVesa Jääskeläinen break; 1485fa247a2aSRuchika Gupta case PKCS11_PROCESSING_IMPORT: 1486cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 1487fa247a2aSRuchika Gupta default: 1488fa247a2aSRuchika Gupta break; 1489fa247a2aSRuchika Gupta } 1490fa247a2aSRuchika Gupta 149163f89caaSJens Wiklander return PKCS11_CKR_OK; 149263f89caaSJens Wiklander } 1493512cbf1dSJens Wiklander 14942d0cd829SRuchika Gupta /* Return min and max key size supported for a key_type in bytes */ 1495512cbf1dSJens Wiklander static void get_key_min_max_sizes(enum pkcs11_key_type key_type, 1496512cbf1dSJens Wiklander uint32_t *min_key_size, 1497512cbf1dSJens Wiklander uint32_t *max_key_size) 1498512cbf1dSJens Wiklander { 1499512cbf1dSJens Wiklander enum pkcs11_mechanism_id mechanism = PKCS11_CKM_UNDEFINED_ID; 1500512cbf1dSJens Wiklander 1501512cbf1dSJens Wiklander switch (key_type) { 1502fa247a2aSRuchika Gupta case PKCS11_CKK_GENERIC_SECRET: 1503fa247a2aSRuchika Gupta mechanism = PKCS11_CKM_GENERIC_SECRET_KEY_GEN; 1504fa247a2aSRuchika Gupta break; 1505512cbf1dSJens Wiklander case PKCS11_CKK_AES: 1506512cbf1dSJens Wiklander mechanism = PKCS11_CKM_AES_KEY_GEN; 1507512cbf1dSJens Wiklander break; 15081f45c9cfSRuchika Gupta case PKCS11_CKK_MD5_HMAC: 15091f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_MD5_HMAC; 15101f45c9cfSRuchika Gupta break; 15111f45c9cfSRuchika Gupta case PKCS11_CKK_SHA_1_HMAC: 15121f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA_1_HMAC; 15131f45c9cfSRuchika Gupta break; 15141f45c9cfSRuchika Gupta case PKCS11_CKK_SHA224_HMAC: 15151f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA224_HMAC; 15161f45c9cfSRuchika Gupta break; 1517a339a354SEtienne Carriere case PKCS11_CKK_SHA256_HMAC: 1518a339a354SEtienne Carriere mechanism = PKCS11_CKM_SHA256_HMAC; 1519a339a354SEtienne Carriere break; 15201f45c9cfSRuchika Gupta case PKCS11_CKK_SHA384_HMAC: 15211f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA384_HMAC; 15221f45c9cfSRuchika Gupta break; 15231f45c9cfSRuchika Gupta case PKCS11_CKK_SHA512_HMAC: 15241f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA512_HMAC; 15251f45c9cfSRuchika Gupta break; 1526db28c542SVesa Jääskeläinen case PKCS11_CKK_EC: 1527db28c542SVesa Jääskeläinen mechanism = PKCS11_CKM_EC_KEY_PAIR_GEN; 1528db28c542SVesa Jääskeläinen break; 152903e07432SValerii Chubar case PKCS11_CKK_EDDSA: 153003e07432SValerii Chubar mechanism = PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN; 153103e07432SValerii Chubar break; 153286922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 153386922832SVesa Jääskeläinen mechanism = PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN; 153486922832SVesa Jääskeläinen break; 1535512cbf1dSJens Wiklander default: 1536512cbf1dSJens Wiklander TEE_Panic(key_type); 1537512cbf1dSJens Wiklander break; 1538512cbf1dSJens Wiklander } 1539512cbf1dSJens Wiklander 15402d0cd829SRuchika Gupta mechanism_supported_key_sizes_bytes(mechanism, min_key_size, 1541512cbf1dSJens Wiklander max_key_size); 1542512cbf1dSJens Wiklander } 1543512cbf1dSJens Wiklander 1544512cbf1dSJens Wiklander enum pkcs11_rc check_created_attrs(struct obj_attrs *key1, 1545512cbf1dSJens Wiklander struct obj_attrs *key2) 1546512cbf1dSJens Wiklander { 1547512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 1548512cbf1dSJens Wiklander struct obj_attrs *secret = NULL; 1549013934d8SVesa Jääskeläinen struct obj_attrs *private = NULL; 1550013934d8SVesa Jääskeläinen struct obj_attrs *public = NULL; 1551512cbf1dSJens Wiklander uint32_t max_key_size = 0; 1552512cbf1dSJens Wiklander uint32_t min_key_size = 0; 1553512cbf1dSJens Wiklander uint32_t key_length = 0; 1554512cbf1dSJens Wiklander 1555512cbf1dSJens Wiklander switch (get_class(key1)) { 1556512cbf1dSJens Wiklander case PKCS11_CKO_SECRET_KEY: 1557512cbf1dSJens Wiklander secret = key1; 1558512cbf1dSJens Wiklander break; 1559013934d8SVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 1560013934d8SVesa Jääskeläinen public = key1; 1561013934d8SVesa Jääskeläinen break; 1562013934d8SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1563013934d8SVesa Jääskeläinen private = key1; 1564013934d8SVesa Jääskeläinen break; 1565512cbf1dSJens Wiklander default: 1566512cbf1dSJens Wiklander return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 1567512cbf1dSJens Wiklander } 1568512cbf1dSJens Wiklander 1569013934d8SVesa Jääskeläinen if (key2) { 1570013934d8SVesa Jääskeläinen switch (get_class(key2)) { 1571013934d8SVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 1572013934d8SVesa Jääskeläinen public = key2; 1573013934d8SVesa Jääskeläinen if (private == key1) 1574013934d8SVesa Jääskeläinen break; 1575013934d8SVesa Jääskeläinen 1576013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1577013934d8SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 1578013934d8SVesa Jääskeläinen private = key2; 1579013934d8SVesa Jääskeläinen if (public == key1) 1580013934d8SVesa Jääskeläinen break; 1581013934d8SVesa Jääskeläinen 1582013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1583013934d8SVesa Jääskeläinen default: 1584512cbf1dSJens Wiklander return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 1585013934d8SVesa Jääskeläinen } 1586013934d8SVesa Jääskeläinen 1587013934d8SVesa Jääskeläinen if (get_key_type(private) != get_key_type(public)) 1588013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1589013934d8SVesa Jääskeläinen } 1590512cbf1dSJens Wiklander 1591512cbf1dSJens Wiklander if (secret) { 1592512cbf1dSJens Wiklander switch (get_key_type(secret)) { 1593512cbf1dSJens Wiklander case PKCS11_CKK_AES: 1594512cbf1dSJens Wiklander case PKCS11_CKK_GENERIC_SECRET: 1595512cbf1dSJens Wiklander case PKCS11_CKK_MD5_HMAC: 1596512cbf1dSJens Wiklander case PKCS11_CKK_SHA_1_HMAC: 1597512cbf1dSJens Wiklander case PKCS11_CKK_SHA224_HMAC: 1598512cbf1dSJens Wiklander case PKCS11_CKK_SHA256_HMAC: 1599512cbf1dSJens Wiklander case PKCS11_CKK_SHA384_HMAC: 1600512cbf1dSJens Wiklander case PKCS11_CKK_SHA512_HMAC: 1601512cbf1dSJens Wiklander break; 1602512cbf1dSJens Wiklander default: 1603512cbf1dSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1604512cbf1dSJens Wiklander } 1605512cbf1dSJens Wiklander 1606512cbf1dSJens Wiklander /* Get key size */ 1607512cbf1dSJens Wiklander rc = get_u32_attribute(secret, PKCS11_CKA_VALUE_LEN, 1608512cbf1dSJens Wiklander &key_length); 1609512cbf1dSJens Wiklander if (rc) 1610d1d44372SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCOMPLETE; 1611512cbf1dSJens Wiklander } 1612013934d8SVesa Jääskeläinen if (public) { 1613013934d8SVesa Jääskeläinen switch (get_key_type(public)) { 161486922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 161586922832SVesa Jääskeläinen /* Get key size */ 161686922832SVesa Jääskeläinen rc = get_u32_attribute(public, PKCS11_CKA_MODULUS_BITS, 161786922832SVesa Jääskeläinen &key_length); 161886922832SVesa Jääskeläinen if (rc) 161986922832SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 162086922832SVesa Jääskeläinen key_length = ROUNDUP(key_length, 8) / 8; 162186922832SVesa Jääskeläinen break; 162202b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 162303e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 162402b16804SVesa Jääskeläinen break; 1625013934d8SVesa Jääskeläinen default: 1626013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1627013934d8SVesa Jääskeläinen } 1628013934d8SVesa Jääskeläinen } 1629013934d8SVesa Jääskeläinen if (private) { 1630013934d8SVesa Jääskeläinen switch (get_key_type(private)) { 163186922832SVesa Jääskeläinen case PKCS11_CKK_RSA: 163202b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 163303e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 163402b16804SVesa Jääskeläinen break; 1635013934d8SVesa Jääskeläinen default: 1636013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 1637013934d8SVesa Jääskeläinen } 1638013934d8SVesa Jääskeläinen } 1639512cbf1dSJens Wiklander 164002b16804SVesa Jääskeläinen /* 164102b16804SVesa Jääskeläinen * Check key size for symmetric keys and RSA keys 164202b16804SVesa Jääskeläinen * EC is bound to domains, no need to check here. 164302b16804SVesa Jääskeläinen */ 164402b16804SVesa Jääskeläinen switch (get_key_type(key1)) { 164502b16804SVesa Jääskeläinen case PKCS11_CKK_EC: 164603e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 164702b16804SVesa Jääskeläinen return PKCS11_CKR_OK; 164802b16804SVesa Jääskeläinen default: 164902b16804SVesa Jääskeläinen break; 165002b16804SVesa Jääskeläinen } 165102b16804SVesa Jääskeläinen 1652512cbf1dSJens Wiklander get_key_min_max_sizes(get_key_type(key1), &min_key_size, &max_key_size); 1653512cbf1dSJens Wiklander if (key_length < min_key_size || key_length > max_key_size) { 1654512cbf1dSJens Wiklander EMSG("Length %"PRIu32" vs range [%"PRIu32" %"PRIu32"]", 1655512cbf1dSJens Wiklander key_length, min_key_size, max_key_size); 1656512cbf1dSJens Wiklander 1657512cbf1dSJens Wiklander return PKCS11_CKR_KEY_SIZE_RANGE; 1658512cbf1dSJens Wiklander } 1659512cbf1dSJens Wiklander 166049ed60abSRuchika Gupta if (secret && get_key_type(secret) == PKCS11_CKK_AES) { 166149ed60abSRuchika Gupta if (key_length != 16 && key_length != 24 && key_length != 32) 166249ed60abSRuchika Gupta return PKCS11_CKR_KEY_SIZE_RANGE; 166349ed60abSRuchika Gupta } 166449ed60abSRuchika Gupta 1665512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1666512cbf1dSJens Wiklander } 1667512cbf1dSJens Wiklander 1668512cbf1dSJens Wiklander /* Check processing ID against attribute ALLOWED_MECHANISMS if any */ 1669512cbf1dSJens Wiklander static bool parent_key_complies_allowed_processings(uint32_t proc_id, 1670512cbf1dSJens Wiklander struct obj_attrs *head) 1671512cbf1dSJens Wiklander { 1672512cbf1dSJens Wiklander char *attr = NULL; 1673512cbf1dSJens Wiklander uint32_t size = 0; 1674512cbf1dSJens Wiklander uint32_t proc = 0; 1675512cbf1dSJens Wiklander size_t count = 0; 16766a760c9eSEtienne Carriere enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 1677512cbf1dSJens Wiklander 16786a760c9eSEtienne Carriere rc = get_attribute_ptr(head, PKCS11_CKA_ALLOWED_MECHANISMS, 16796a760c9eSEtienne Carriere (void *)&attr, &size); 16806a760c9eSEtienne Carriere if (rc == PKCS11_RV_NOT_FOUND) 1681512cbf1dSJens Wiklander return true; 16826a760c9eSEtienne Carriere if (rc) { 16836a760c9eSEtienne Carriere EMSG("unexpected attributes state"); 16846a760c9eSEtienne Carriere TEE_Panic(TEE_ERROR_BAD_STATE); 1685512cbf1dSJens Wiklander } 1686512cbf1dSJens Wiklander 1687512cbf1dSJens Wiklander for (count = size / sizeof(uint32_t); count; count--) { 1688512cbf1dSJens Wiklander TEE_MemMove(&proc, attr, sizeof(uint32_t)); 1689512cbf1dSJens Wiklander attr += sizeof(uint32_t); 1690512cbf1dSJens Wiklander 1691512cbf1dSJens Wiklander if (proc == proc_id) 1692512cbf1dSJens Wiklander return true; 1693512cbf1dSJens Wiklander } 1694512cbf1dSJens Wiklander 1695512cbf1dSJens Wiklander DMSG("can't find %s in allowed list", id2str_proc(proc_id)); 1696512cbf1dSJens Wiklander return false; 1697512cbf1dSJens Wiklander } 1698512cbf1dSJens Wiklander 1699512cbf1dSJens Wiklander static enum pkcs11_attr_id func_to_attr(enum processing_func func) 1700512cbf1dSJens Wiklander { 1701512cbf1dSJens Wiklander switch (func) { 1702512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT: 1703512cbf1dSJens Wiklander return PKCS11_CKA_ENCRYPT; 1704512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT: 1705512cbf1dSJens Wiklander return PKCS11_CKA_DECRYPT; 1706512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN: 1707512cbf1dSJens Wiklander return PKCS11_CKA_SIGN; 1708512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY: 1709512cbf1dSJens Wiklander return PKCS11_CKA_VERIFY; 1710512cbf1dSJens Wiklander case PKCS11_FUNCTION_WRAP: 1711512cbf1dSJens Wiklander return PKCS11_CKA_WRAP; 1712512cbf1dSJens Wiklander case PKCS11_FUNCTION_UNWRAP: 1713512cbf1dSJens Wiklander return PKCS11_CKA_UNWRAP; 1714512cbf1dSJens Wiklander case PKCS11_FUNCTION_DERIVE: 1715512cbf1dSJens Wiklander return PKCS11_CKA_DERIVE; 1716512cbf1dSJens Wiklander default: 1717512cbf1dSJens Wiklander return PKCS11_CKA_UNDEFINED_ID; 1718512cbf1dSJens Wiklander } 1719512cbf1dSJens Wiklander } 1720512cbf1dSJens Wiklander 1721512cbf1dSJens Wiklander enum pkcs11_rc 1722512cbf1dSJens Wiklander check_parent_attrs_against_processing(enum pkcs11_mechanism_id proc_id, 1723512cbf1dSJens Wiklander enum processing_func function, 1724512cbf1dSJens Wiklander struct obj_attrs *head) 1725512cbf1dSJens Wiklander { 1726512cbf1dSJens Wiklander enum pkcs11_class_id key_class = get_class(head); 1727512cbf1dSJens Wiklander enum pkcs11_key_type key_type = get_key_type(head); 1728512cbf1dSJens Wiklander enum pkcs11_attr_id attr = func_to_attr(function); 1729512cbf1dSJens Wiklander 1730512cbf1dSJens Wiklander if (!get_bool(head, attr)) { 1731512cbf1dSJens Wiklander DMSG("%s not permitted", id2str_attr(attr)); 1732512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1733512cbf1dSJens Wiklander } 1734512cbf1dSJens Wiklander 1735512cbf1dSJens Wiklander /* Check processing complies with parent key family */ 1736512cbf1dSJens Wiklander switch (proc_id) { 1737512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB: 1738512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC: 1739512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS: 1740512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR: 17410ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC: 17420ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC_GENERAL: 1743512cbf1dSJens Wiklander if (key_class == PKCS11_CKO_SECRET_KEY && 1744512cbf1dSJens Wiklander key_type == PKCS11_CKK_AES) 1745512cbf1dSJens Wiklander break; 1746512cbf1dSJens Wiklander 1747512cbf1dSJens Wiklander DMSG("%s invalid key %s/%s", id2str_proc(proc_id), 1748512cbf1dSJens Wiklander id2str_class(key_class), id2str_key_type(key_type)); 1749512cbf1dSJens Wiklander 17505f80f270SRuchika Gupta if (function == PKCS11_FUNCTION_WRAP) 17515f80f270SRuchika Gupta return PKCS11_CKR_WRAPPING_KEY_TYPE_INCONSISTENT; 1752e3f0cb56SRuchika Gupta else if (function == PKCS11_FUNCTION_UNWRAP) 1753e3f0cb56SRuchika Gupta return PKCS11_CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT; 17545f80f270SRuchika Gupta else 1755512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1756512cbf1dSJens Wiklander 1757c3033708SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA: 1758c3033708SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA: 1759c3033708SRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY && 1760c3033708SRuchika Gupta key_type != PKCS11_CKK_AES) 1761c3033708SRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1762c3033708SRuchika Gupta 1763c3033708SRuchika Gupta if (get_bool(head, PKCS11_CKA_ENCRYPT)) { 1764c3033708SRuchika Gupta /* 1765c3033708SRuchika Gupta * Intentionally refuse to proceed despite 1766c3033708SRuchika Gupta * PKCS#11 specifications v2.40 and v3.0 not expecting 1767c3033708SRuchika Gupta * this behavior to avoid potential security issue 1768c3033708SRuchika Gupta * where keys derived by these mechanisms can be 1769c3033708SRuchika Gupta * revealed by doing data encryption using parent key. 1770c3033708SRuchika Gupta */ 1771c3033708SRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED; 1772c3033708SRuchika Gupta } 1773c3033708SRuchika Gupta 1774c3033708SRuchika Gupta break; 1775689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 1776689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 1777689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 1778689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 1779689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 1780689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 178170b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 178270b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 178370b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 178470b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 178570b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 178670b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 1787689f4e5bSRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY) 1788689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1789689f4e5bSRuchika Gupta 1790689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_GENERIC_SECRET) 1791689f4e5bSRuchika Gupta break; 1792689f4e5bSRuchika Gupta 1793689f4e5bSRuchika Gupta switch (proc_id) { 1794689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC: 179570b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL: 1796689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_MD5_HMAC) 1797689f4e5bSRuchika Gupta break; 1798689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1799689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC: 180070b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL: 1801689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA_1_HMAC) 1802689f4e5bSRuchika Gupta break; 1803689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1804689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC: 180570b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL: 1806689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA224_HMAC) 1807689f4e5bSRuchika Gupta break; 1808689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1809689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC: 181070b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL: 1811689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA256_HMAC) 1812689f4e5bSRuchika Gupta break; 1813689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1814689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC: 181570b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL: 1816689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA384_HMAC) 1817689f4e5bSRuchika Gupta break; 1818689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1819689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC: 182070b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL: 1821689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA512_HMAC) 1822689f4e5bSRuchika Gupta break; 1823689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1824689f4e5bSRuchika Gupta default: 1825689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1826689f4e5bSRuchika Gupta } 1827689f4e5bSRuchika Gupta break; 1828689f4e5bSRuchika Gupta 182903e07432SValerii Chubar case PKCS11_CKM_EDDSA: 183003e07432SValerii Chubar if (key_type != PKCS11_CKK_EC_EDWARDS) { 183103e07432SValerii Chubar EMSG("Invalid key %s for mechanism %s", 183203e07432SValerii Chubar id2str_type(key_type, key_class), 183303e07432SValerii Chubar id2str_proc(proc_id)); 183403e07432SValerii Chubar return PKCS11_CKR_KEY_TYPE_INCONSISTENT; 183503e07432SValerii Chubar } 183603e07432SValerii Chubar if (key_class != PKCS11_CKO_PUBLIC_KEY && 183703e07432SValerii Chubar key_class != PKCS11_CKO_PRIVATE_KEY) { 183803e07432SValerii Chubar EMSG("Invalid key class for mechanism %s", 183903e07432SValerii Chubar id2str_proc(proc_id)); 184003e07432SValerii Chubar 184103e07432SValerii Chubar return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 184203e07432SValerii Chubar } 184303e07432SValerii Chubar break; 184403e07432SValerii Chubar 1845fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 1846fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 1847fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 1848fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 1849fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 1850fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 1851cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 1852fb279d8bSVesa Jääskeläinen if (key_type != PKCS11_CKK_EC) { 1853fb279d8bSVesa Jääskeläinen EMSG("Invalid key %s for mechanism %s", 1854fb279d8bSVesa Jääskeläinen id2str_type(key_type, key_class), 1855fb279d8bSVesa Jääskeläinen id2str_proc(proc_id)); 1856fb279d8bSVesa Jääskeläinen 1857fb279d8bSVesa Jääskeläinen return PKCS11_CKR_KEY_TYPE_INCONSISTENT; 1858fb279d8bSVesa Jääskeläinen } 1859fb279d8bSVesa Jääskeläinen if (key_class != PKCS11_CKO_PUBLIC_KEY && 1860fb279d8bSVesa Jääskeläinen key_class != PKCS11_CKO_PRIVATE_KEY) { 1861fb279d8bSVesa Jääskeläinen EMSG("Invalid key class for mechanism %s", 1862fb279d8bSVesa Jääskeläinen id2str_proc(proc_id)); 1863fb279d8bSVesa Jääskeläinen 1864fb279d8bSVesa Jääskeläinen return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1865fb279d8bSVesa Jääskeläinen } 1866fb279d8bSVesa Jääskeläinen break; 18670442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 18680442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 18690442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 18700442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 18710442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 18720442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 18730442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 187445d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP: 1875dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 1876d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 1877d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 1878d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 1879d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 1880d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 1881d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 18820442c956SVesa Jääskeläinen if (key_type != PKCS11_CKK_RSA) { 18830442c956SVesa Jääskeläinen EMSG("Invalid key %s for mechanism %s", 18840442c956SVesa Jääskeläinen id2str_type(key_type, key_class), 18850442c956SVesa Jääskeläinen id2str_proc(proc_id)); 18860442c956SVesa Jääskeläinen 18870442c956SVesa Jääskeläinen return PKCS11_CKR_KEY_TYPE_INCONSISTENT; 18880442c956SVesa Jääskeläinen } 18890442c956SVesa Jääskeläinen if (key_class != PKCS11_CKO_PUBLIC_KEY && 18900442c956SVesa Jääskeläinen key_class != PKCS11_CKO_PRIVATE_KEY) { 18910442c956SVesa Jääskeläinen EMSG("Invalid key class for mechanism %s", 18920442c956SVesa Jääskeläinen id2str_proc(proc_id)); 18930442c956SVesa Jääskeläinen 18940442c956SVesa Jääskeläinen return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 18950442c956SVesa Jääskeläinen } 18960442c956SVesa Jääskeläinen break; 1897512cbf1dSJens Wiklander default: 1898512cbf1dSJens Wiklander DMSG("Invalid processing %#"PRIx32"/%s", proc_id, 1899512cbf1dSJens Wiklander id2str_proc(proc_id)); 1900512cbf1dSJens Wiklander 1901512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_INVALID; 1902512cbf1dSJens Wiklander } 1903512cbf1dSJens Wiklander 1904512cbf1dSJens Wiklander if (!parent_key_complies_allowed_processings(proc_id, head)) { 1905512cbf1dSJens Wiklander DMSG("Allowed mechanism failed"); 1906512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; 1907512cbf1dSJens Wiklander } 1908512cbf1dSJens Wiklander 1909512cbf1dSJens Wiklander return PKCS11_CKR_OK; 1910512cbf1dSJens Wiklander } 1911783c1515SRuchika Gupta 1912783c1515SRuchika Gupta bool attribute_is_exportable(struct pkcs11_attribute_head *req_attr, 1913783c1515SRuchika Gupta struct pkcs11_object *obj) 1914783c1515SRuchika Gupta { 1915783c1515SRuchika Gupta uint8_t boolval = 0; 1916783c1515SRuchika Gupta uint32_t boolsize = 0; 1917783c1515SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 1918783c1515SRuchika Gupta enum pkcs11_class_id key_class = get_class(obj->attributes); 1919783c1515SRuchika Gupta 1920*981966bcSVesa Jääskeläinen if (attribute_is_hidden(req_attr)) 1921*981966bcSVesa Jääskeläinen return false; 1922*981966bcSVesa Jääskeläinen 1923783c1515SRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY && 1924783c1515SRuchika Gupta key_class != PKCS11_CKO_PRIVATE_KEY) 1925783c1515SRuchika Gupta return true; 1926783c1515SRuchika Gupta 1927783c1515SRuchika Gupta switch (req_attr->id) { 1928783c1515SRuchika Gupta case PKCS11_CKA_PRIVATE_EXPONENT: 1929783c1515SRuchika Gupta case PKCS11_CKA_PRIME_1: 1930783c1515SRuchika Gupta case PKCS11_CKA_PRIME_2: 1931783c1515SRuchika Gupta case PKCS11_CKA_EXPONENT_1: 1932783c1515SRuchika Gupta case PKCS11_CKA_EXPONENT_2: 1933783c1515SRuchika Gupta case PKCS11_CKA_COEFFICIENT: 1934783c1515SRuchika Gupta case PKCS11_CKA_VALUE: 1935783c1515SRuchika Gupta boolsize = sizeof(boolval); 1936783c1515SRuchika Gupta rc = get_attribute(obj->attributes, PKCS11_CKA_EXTRACTABLE, 1937783c1515SRuchika Gupta &boolval, &boolsize); 1938783c1515SRuchika Gupta if (rc || boolval == PKCS11_FALSE) 1939783c1515SRuchika Gupta return false; 1940783c1515SRuchika Gupta 1941783c1515SRuchika Gupta boolsize = sizeof(boolval); 1942783c1515SRuchika Gupta rc = get_attribute(obj->attributes, PKCS11_CKA_SENSITIVE, 1943783c1515SRuchika Gupta &boolval, &boolsize); 1944783c1515SRuchika Gupta if (rc || boolval == PKCS11_TRUE) 1945783c1515SRuchika Gupta return false; 1946783c1515SRuchika Gupta break; 1947783c1515SRuchika Gupta default: 1948783c1515SRuchika Gupta break; 1949783c1515SRuchika Gupta } 1950783c1515SRuchika Gupta 1951783c1515SRuchika Gupta return true; 1952783c1515SRuchika Gupta } 19532d25a9bcSRuchika Gupta 19542d25a9bcSRuchika Gupta static bool attr_is_modifiable_any_key(struct pkcs11_attribute_head *attr) 19552d25a9bcSRuchika Gupta { 19562d25a9bcSRuchika Gupta switch (attr->id) { 19572d25a9bcSRuchika Gupta case PKCS11_CKA_ID: 19582d25a9bcSRuchika Gupta case PKCS11_CKA_START_DATE: 19592d25a9bcSRuchika Gupta case PKCS11_CKA_END_DATE: 19602d25a9bcSRuchika Gupta case PKCS11_CKA_DERIVE: 19612d25a9bcSRuchika Gupta return true; 19622d25a9bcSRuchika Gupta default: 19632d25a9bcSRuchika Gupta return false; 19642d25a9bcSRuchika Gupta } 19652d25a9bcSRuchika Gupta } 19662d25a9bcSRuchika Gupta 19672d25a9bcSRuchika Gupta static bool attr_is_modifiable_secret_key(struct pkcs11_attribute_head *attr, 19682d25a9bcSRuchika Gupta struct pkcs11_session *session, 19692d25a9bcSRuchika Gupta struct pkcs11_object *obj) 19702d25a9bcSRuchika Gupta { 19712d25a9bcSRuchika Gupta switch (attr->id) { 19722d25a9bcSRuchika Gupta case PKCS11_CKA_ENCRYPT: 19732d25a9bcSRuchika Gupta case PKCS11_CKA_DECRYPT: 19742d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN: 19752d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY: 19762d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP: 19772d25a9bcSRuchika Gupta case PKCS11_CKA_UNWRAP: 19782d25a9bcSRuchika Gupta return true; 19792d25a9bcSRuchika Gupta /* Can't be modified once set to CK_FALSE - 12 in Table 10 */ 19802d25a9bcSRuchika Gupta case PKCS11_CKA_EXTRACTABLE: 19812d25a9bcSRuchika Gupta return get_bool(obj->attributes, attr->id); 19822d25a9bcSRuchika Gupta /* Can't be modified once set to CK_TRUE - 11 in Table 10 */ 19832d25a9bcSRuchika Gupta case PKCS11_CKA_SENSITIVE: 19842d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP_WITH_TRUSTED: 19852d25a9bcSRuchika Gupta return !get_bool(obj->attributes, attr->id); 19862d25a9bcSRuchika Gupta /* Change in CKA_TRUSTED can only be done by SO */ 19872d25a9bcSRuchika Gupta case PKCS11_CKA_TRUSTED: 19882d25a9bcSRuchika Gupta return pkcs11_session_is_so(session); 19892d25a9bcSRuchika Gupta case PKCS11_CKA_NEVER_EXTRACTABLE: 19902d25a9bcSRuchika Gupta case PKCS11_CKA_ALWAYS_SENSITIVE: 19912d25a9bcSRuchika Gupta return false; 19922d25a9bcSRuchika Gupta default: 19932d25a9bcSRuchika Gupta return false; 19942d25a9bcSRuchika Gupta } 19952d25a9bcSRuchika Gupta } 19962d25a9bcSRuchika Gupta 19972d25a9bcSRuchika Gupta static bool attr_is_modifiable_public_key(struct pkcs11_attribute_head *attr, 19982d25a9bcSRuchika Gupta struct pkcs11_session *session, 19992d25a9bcSRuchika Gupta struct pkcs11_object *obj __unused) 20002d25a9bcSRuchika Gupta { 20012d25a9bcSRuchika Gupta switch (attr->id) { 20022d25a9bcSRuchika Gupta case PKCS11_CKA_SUBJECT: 20032d25a9bcSRuchika Gupta case PKCS11_CKA_ENCRYPT: 20042d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY: 20052d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY_RECOVER: 20062d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP: 20072d25a9bcSRuchika Gupta return true; 20082d25a9bcSRuchika Gupta case PKCS11_CKA_TRUSTED: 20092d25a9bcSRuchika Gupta /* Change in CKA_TRUSTED can only be done by SO */ 20102d25a9bcSRuchika Gupta return pkcs11_session_is_so(session); 20112d25a9bcSRuchika Gupta default: 20122d25a9bcSRuchika Gupta return false; 20132d25a9bcSRuchika Gupta } 20142d25a9bcSRuchika Gupta } 20152d25a9bcSRuchika Gupta 20162d25a9bcSRuchika Gupta static bool attr_is_modifiable_private_key(struct pkcs11_attribute_head *attr, 20172d25a9bcSRuchika Gupta struct pkcs11_session *sess __unused, 20182d25a9bcSRuchika Gupta struct pkcs11_object *obj) 20192d25a9bcSRuchika Gupta { 20202d25a9bcSRuchika Gupta switch (attr->id) { 20212d25a9bcSRuchika Gupta case PKCS11_CKA_SUBJECT: 20222d25a9bcSRuchika Gupta case PKCS11_CKA_DECRYPT: 20232d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN: 20242d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN_RECOVER: 20252d25a9bcSRuchika Gupta case PKCS11_CKA_UNWRAP: 20262d25a9bcSRuchika Gupta /* 20272d25a9bcSRuchika Gupta * TBD: Revisit if we don't support PKCS11_CKA_PUBLIC_KEY_INFO 20282d25a9bcSRuchika Gupta * Specification mentions that if this attribute is 20292d25a9bcSRuchika Gupta * supplied as part of a template for C_CreateObject, C_CopyObject or 20302d25a9bcSRuchika Gupta * C_SetAttributeValue for a private key, the token MUST verify 20312d25a9bcSRuchika Gupta * correspondence between the private key data and the public key data 20322d25a9bcSRuchika Gupta * as supplied in CKA_PUBLIC_KEY_INFO. This needs to be 20332d25a9bcSRuchika Gupta * taken care of when this object type will be implemented 20342d25a9bcSRuchika Gupta */ 20352d25a9bcSRuchika Gupta case PKCS11_CKA_PUBLIC_KEY_INFO: 20362d25a9bcSRuchika Gupta return true; 20372d25a9bcSRuchika Gupta /* Can't be modified once set to CK_FALSE - 12 in Table 10 */ 20382d25a9bcSRuchika Gupta case PKCS11_CKA_EXTRACTABLE: 20392d25a9bcSRuchika Gupta return get_bool(obj->attributes, attr->id); 20402d25a9bcSRuchika Gupta /* Can't be modified once set to CK_TRUE - 11 in Table 10 */ 20412d25a9bcSRuchika Gupta case PKCS11_CKA_SENSITIVE: 20422d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP_WITH_TRUSTED: 20432d25a9bcSRuchika Gupta return !get_bool(obj->attributes, attr->id); 20442d25a9bcSRuchika Gupta case PKCS11_CKA_NEVER_EXTRACTABLE: 20452d25a9bcSRuchika Gupta case PKCS11_CKA_ALWAYS_SENSITIVE: 20462d25a9bcSRuchika Gupta return false; 20472d25a9bcSRuchika Gupta default: 20482d25a9bcSRuchika Gupta return false; 20492d25a9bcSRuchika Gupta } 20502d25a9bcSRuchika Gupta } 20512d25a9bcSRuchika Gupta 20524137952dSVesa Jääskeläinen static bool attr_is_modifiable_certificate(struct pkcs11_attribute_head *attr, 20534137952dSVesa Jääskeläinen struct pkcs11_session *session, 20544137952dSVesa Jääskeläinen struct pkcs11_object *obj) 20554137952dSVesa Jääskeläinen { 20564137952dSVesa Jääskeläinen uint8_t boolval = 0; 20574137952dSVesa Jääskeläinen uint32_t boolsize = 0; 20584137952dSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 20594137952dSVesa Jääskeläinen 20604137952dSVesa Jääskeläinen /* Trusted certificates cannot be modified. */ 20614137952dSVesa Jääskeläinen rc = get_attribute(obj->attributes, PKCS11_CKA_TRUSTED, 20624137952dSVesa Jääskeläinen &boolval, &boolsize); 20634137952dSVesa Jääskeläinen if (rc || boolval == PKCS11_TRUE) 20644137952dSVesa Jääskeläinen return false; 20654137952dSVesa Jääskeläinen 20664137952dSVesa Jääskeläinen /* Common certificate attributes */ 20674137952dSVesa Jääskeläinen switch (attr->id) { 20684137952dSVesa Jääskeläinen case PKCS11_CKA_TRUSTED: 20694137952dSVesa Jääskeläinen /* 20704137952dSVesa Jääskeläinen * The CKA_TRUSTED attribute cannot be set to CK_TRUE by an 20714137952dSVesa Jääskeläinen * application. It MUST be set by a token initialization 20724137952dSVesa Jääskeläinen * application or by the token’s SO. 20734137952dSVesa Jääskeläinen */ 20744137952dSVesa Jääskeläinen return pkcs11_session_is_so(session); 20754137952dSVesa Jääskeläinen case PKCS11_CKA_CERTIFICATE_TYPE: 20764137952dSVesa Jääskeläinen case PKCS11_CKA_CERTIFICATE_CATEGORY: 20774137952dSVesa Jääskeläinen return false; 20784137952dSVesa Jääskeläinen default: 20794137952dSVesa Jääskeläinen break; 20804137952dSVesa Jääskeläinen } 20814137952dSVesa Jääskeläinen 20824137952dSVesa Jääskeläinen /* Certificate type specific attributes */ 20834137952dSVesa Jääskeläinen switch (get_certificate_type(obj->attributes)) { 20844137952dSVesa Jääskeläinen case PKCS11_CKC_X_509: 20854137952dSVesa Jääskeläinen /* 20864137952dSVesa Jääskeläinen * Only the CKA_ID, CKA_ISSUER, and CKA_SERIAL_NUMBER 20874137952dSVesa Jääskeläinen * attributes may be modified after the object is created. 20884137952dSVesa Jääskeläinen */ 20894137952dSVesa Jääskeläinen switch (attr->id) { 20904137952dSVesa Jääskeläinen case PKCS11_CKA_ID: 20914137952dSVesa Jääskeläinen case PKCS11_CKA_ISSUER: 20924137952dSVesa Jääskeläinen case PKCS11_CKA_SERIAL_NUMBER: 20934137952dSVesa Jääskeläinen return true; 20944137952dSVesa Jääskeläinen default: 20954137952dSVesa Jääskeläinen break; 20964137952dSVesa Jääskeläinen } 20974137952dSVesa Jääskeläinen break; 20984137952dSVesa Jääskeläinen default: 20994137952dSVesa Jääskeläinen /* Unsupported certificate type */ 21004137952dSVesa Jääskeläinen break; 21014137952dSVesa Jääskeläinen } 21024137952dSVesa Jääskeläinen 21034137952dSVesa Jääskeläinen return false; 21044137952dSVesa Jääskeläinen } 21054137952dSVesa Jääskeläinen 21062d25a9bcSRuchika Gupta static bool attribute_is_modifiable(struct pkcs11_session *session, 21072d25a9bcSRuchika Gupta struct pkcs11_attribute_head *req_attr, 21082d25a9bcSRuchika Gupta struct pkcs11_object *obj, 21092d25a9bcSRuchika Gupta enum pkcs11_class_id class, 21102d25a9bcSRuchika Gupta enum processing_func function) 21112d25a9bcSRuchika Gupta { 21122d25a9bcSRuchika Gupta /* Check modifiable attributes common to any object */ 21132d25a9bcSRuchika Gupta switch (req_attr->id) { 21142d25a9bcSRuchika Gupta case PKCS11_CKA_LABEL: 21152d25a9bcSRuchika Gupta return true; 21162d25a9bcSRuchika Gupta case PKCS11_CKA_TOKEN: 21172d25a9bcSRuchika Gupta case PKCS11_CKA_MODIFIABLE: 21182d25a9bcSRuchika Gupta case PKCS11_CKA_DESTROYABLE: 21192d25a9bcSRuchika Gupta case PKCS11_CKA_PRIVATE: 21202d25a9bcSRuchika Gupta return function == PKCS11_FUNCTION_COPY; 21212d25a9bcSRuchika Gupta case PKCS11_CKA_COPYABLE: 21222d25a9bcSRuchika Gupta /* 21232d25a9bcSRuchika Gupta * Specification mentions that if the attribute value is false 21242d25a9bcSRuchika Gupta * it can't be set to true. Reading this we assume that it 21252d25a9bcSRuchika Gupta * should be possible to modify this attribute even though this 21262d25a9bcSRuchika Gupta * is not marked as modifiable in Table 10 if done in right 21272d25a9bcSRuchika Gupta * direction i.e from TRUE -> FALSE. 21282d25a9bcSRuchika Gupta */ 21292d25a9bcSRuchika Gupta return get_bool(obj->attributes, req_attr->id); 21302d25a9bcSRuchika Gupta default: 21312d25a9bcSRuchika Gupta break; 21322d25a9bcSRuchika Gupta } 21332d25a9bcSRuchika Gupta 21342d25a9bcSRuchika Gupta /* Attribute checking based on class type */ 21352d25a9bcSRuchika Gupta switch (class) { 21362d25a9bcSRuchika Gupta case PKCS11_CKO_SECRET_KEY: 21372d25a9bcSRuchika Gupta case PKCS11_CKO_PUBLIC_KEY: 21382d25a9bcSRuchika Gupta case PKCS11_CKO_PRIVATE_KEY: 21392d25a9bcSRuchika Gupta if (attr_is_modifiable_any_key(req_attr)) 21402d25a9bcSRuchika Gupta return true; 21412d25a9bcSRuchika Gupta if (class == PKCS11_CKO_SECRET_KEY && 21422d25a9bcSRuchika Gupta attr_is_modifiable_secret_key(req_attr, session, obj)) 21432d25a9bcSRuchika Gupta return true; 21442d25a9bcSRuchika Gupta if (class == PKCS11_CKO_PUBLIC_KEY && 21452d25a9bcSRuchika Gupta attr_is_modifiable_public_key(req_attr, session, obj)) 21462d25a9bcSRuchika Gupta return true; 21472d25a9bcSRuchika Gupta if (class == PKCS11_CKO_PRIVATE_KEY && 21482d25a9bcSRuchika Gupta attr_is_modifiable_private_key(req_attr, session, obj)) 21492d25a9bcSRuchika Gupta return true; 21502d25a9bcSRuchika Gupta break; 21512d25a9bcSRuchika Gupta case PKCS11_CKO_DATA: 21522d25a9bcSRuchika Gupta /* None of the data object attributes are modifiable */ 21532d25a9bcSRuchika Gupta return false; 21544137952dSVesa Jääskeläinen case PKCS11_CKO_CERTIFICATE: 21554137952dSVesa Jääskeläinen return attr_is_modifiable_certificate(req_attr, session, obj); 21562d25a9bcSRuchika Gupta default: 21572d25a9bcSRuchika Gupta break; 21582d25a9bcSRuchika Gupta } 21592d25a9bcSRuchika Gupta 21602d25a9bcSRuchika Gupta return false; 21612d25a9bcSRuchika Gupta } 21622d25a9bcSRuchika Gupta 21632d25a9bcSRuchika Gupta enum pkcs11_rc check_attrs_against_modification(struct pkcs11_session *session, 21642d25a9bcSRuchika Gupta struct obj_attrs *head, 21652d25a9bcSRuchika Gupta struct pkcs11_object *obj, 21662d25a9bcSRuchika Gupta enum processing_func function) 21672d25a9bcSRuchika Gupta { 21682d25a9bcSRuchika Gupta enum pkcs11_class_id class = PKCS11_CKO_UNDEFINED_ID; 21692d25a9bcSRuchika Gupta char *cur = NULL; 21702d25a9bcSRuchika Gupta char *end = NULL; 21712d25a9bcSRuchika Gupta size_t len = 0; 21722d25a9bcSRuchika Gupta 21732d25a9bcSRuchika Gupta class = get_class(obj->attributes); 21742d25a9bcSRuchika Gupta 21752d25a9bcSRuchika Gupta cur = (char *)head + sizeof(struct obj_attrs); 21762d25a9bcSRuchika Gupta end = cur + head->attrs_size; 21772d25a9bcSRuchika Gupta 21782d25a9bcSRuchika Gupta for (; cur < end; cur += len) { 21792d25a9bcSRuchika Gupta /* Structure aligned copy of the pkcs11_ref in the object */ 21802d25a9bcSRuchika Gupta struct pkcs11_attribute_head cli_ref = { }; 21812d25a9bcSRuchika Gupta 21822d25a9bcSRuchika Gupta TEE_MemMove(&cli_ref, cur, sizeof(cli_ref)); 21832d25a9bcSRuchika Gupta len = sizeof(cli_ref) + cli_ref.size; 21842d25a9bcSRuchika Gupta 2185*981966bcSVesa Jääskeläinen /* Protect hidden attributes */ 2186*981966bcSVesa Jääskeläinen if (attribute_is_hidden(&cli_ref)) 2187*981966bcSVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 2188*981966bcSVesa Jääskeläinen 21892d25a9bcSRuchika Gupta /* 21902d25a9bcSRuchika Gupta * Check 1 - Check if attribute belongs to the object 21912d25a9bcSRuchika Gupta * The obj->attributes has all the attributes in 21922d25a9bcSRuchika Gupta * it which are allowed for an object. 21932d25a9bcSRuchika Gupta */ 21942d25a9bcSRuchika Gupta if (get_attribute_ptr(obj->attributes, cli_ref.id, NULL, 21952d25a9bcSRuchika Gupta NULL) == PKCS11_RV_NOT_FOUND) 21962d25a9bcSRuchika Gupta return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 21972d25a9bcSRuchika Gupta 21982d25a9bcSRuchika Gupta /* Check 2 - Is attribute modifiable */ 21992d25a9bcSRuchika Gupta if (!attribute_is_modifiable(session, &cli_ref, obj, class, 22002d25a9bcSRuchika Gupta function)) 22012d25a9bcSRuchika Gupta return PKCS11_CKR_ATTRIBUTE_READ_ONLY; 22022d25a9bcSRuchika Gupta 22032d25a9bcSRuchika Gupta /* 22042d25a9bcSRuchika Gupta * Checks for modification in PKCS11_CKA_TOKEN and 22052d25a9bcSRuchika Gupta * PKCS11_CKA_PRIVATE are required for PKCS11_FUNCTION_COPY 22062d25a9bcSRuchika Gupta * only, so skip them for PKCS11_FUNCTION_MODIFY. 22072d25a9bcSRuchika Gupta */ 22082d25a9bcSRuchika Gupta if (function == PKCS11_FUNCTION_MODIFY) 22092d25a9bcSRuchika Gupta continue; 22102d25a9bcSRuchika Gupta 22112d25a9bcSRuchika Gupta /* 22122d25a9bcSRuchika Gupta * An attempt to copy an object to a token will fail for 22132d25a9bcSRuchika Gupta * RO session 22142d25a9bcSRuchika Gupta */ 22152d25a9bcSRuchika Gupta if (cli_ref.id == PKCS11_CKA_TOKEN && 22162d25a9bcSRuchika Gupta get_bool(head, PKCS11_CKA_TOKEN)) { 22172d25a9bcSRuchika Gupta if (!pkcs11_session_is_read_write(session)) { 22182d25a9bcSRuchika Gupta DMSG("Can't copy to token in a RO session"); 22192d25a9bcSRuchika Gupta return PKCS11_CKR_SESSION_READ_ONLY; 22202d25a9bcSRuchika Gupta } 22212d25a9bcSRuchika Gupta } 22222d25a9bcSRuchika Gupta 22232d25a9bcSRuchika Gupta if (cli_ref.id == PKCS11_CKA_PRIVATE) { 22242d25a9bcSRuchika Gupta bool parent_priv = 22252d25a9bcSRuchika Gupta get_bool(obj->attributes, cli_ref.id); 22262d25a9bcSRuchika Gupta bool obj_priv = get_bool(head, cli_ref.id); 22272d25a9bcSRuchika Gupta 22282d25a9bcSRuchika Gupta /* 22292d25a9bcSRuchika Gupta * If PKCS11_CKA_PRIVATE is being set to TRUE from 22302d25a9bcSRuchika Gupta * FALSE, user has to be logged in 22312d25a9bcSRuchika Gupta */ 22322d25a9bcSRuchika Gupta if (!parent_priv && obj_priv) { 22332d25a9bcSRuchika Gupta if ((pkcs11_session_is_public(session) || 22342d25a9bcSRuchika Gupta pkcs11_session_is_so(session))) 22352d25a9bcSRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN; 22362d25a9bcSRuchika Gupta } 2237df017b2bSRuchika Gupta 2238df017b2bSRuchika Gupta /* 2239df017b2bSRuchika Gupta * Restriction added - Even for Copy, do not allow 2240df017b2bSRuchika Gupta * modification of CKA_PRIVATE from TRUE to FALSE 2241df017b2bSRuchika Gupta */ 2242df017b2bSRuchika Gupta if (parent_priv && !obj_priv) 2243df017b2bSRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT; 22442d25a9bcSRuchika Gupta } 22452d25a9bcSRuchika Gupta } 22462d25a9bcSRuchika Gupta 22472d25a9bcSRuchika Gupta return PKCS11_CKR_OK; 22482d25a9bcSRuchika Gupta } 22498c499324SRuchika Gupta 22508c499324SRuchika Gupta static enum pkcs11_rc set_secret_key_data(struct obj_attrs **head, void *data, 22518c499324SRuchika Gupta size_t key_size) 22528c499324SRuchika Gupta { 22538c499324SRuchika Gupta uint32_t size = sizeof(uint32_t); 22548c499324SRuchika Gupta uint32_t key_length = 0; 22558c499324SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 22568c499324SRuchika Gupta 22578c499324SRuchika Gupta /* Get key size if present in template */ 22588c499324SRuchika Gupta rc = get_attribute(*head, PKCS11_CKA_VALUE_LEN, &key_length, &size); 22598c499324SRuchika Gupta if (rc && rc != PKCS11_RV_NOT_FOUND) 22608c499324SRuchika Gupta return rc; 22618c499324SRuchika Gupta 22628c499324SRuchika Gupta if (key_length) { 22638c499324SRuchika Gupta if (key_size < key_length) 22648c499324SRuchika Gupta return PKCS11_CKR_DATA_LEN_RANGE; 22658c499324SRuchika Gupta } else { 22668c499324SRuchika Gupta key_length = key_size; 22678c499324SRuchika Gupta rc = set_attribute(head, PKCS11_CKA_VALUE_LEN, &key_length, 22688c499324SRuchika Gupta sizeof(uint32_t)); 22698c499324SRuchika Gupta if (rc) 22708c499324SRuchika Gupta return rc; 22718c499324SRuchika Gupta } 22728c499324SRuchika Gupta 22738c499324SRuchika Gupta /* Now we can check the VALUE_LEN field */ 22748c499324SRuchika Gupta rc = check_created_attrs(*head, NULL); 22758c499324SRuchika Gupta if (rc) 22768c499324SRuchika Gupta return rc; 22778c499324SRuchika Gupta 22788c499324SRuchika Gupta /* Remove the default empty value attribute if found */ 22798c499324SRuchika Gupta rc = remove_empty_attribute(head, PKCS11_CKA_VALUE); 22808c499324SRuchika Gupta if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND) 22818c499324SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 22828c499324SRuchika Gupta 22838c499324SRuchika Gupta return add_attribute(head, PKCS11_CKA_VALUE, data, key_length); 22848c499324SRuchika Gupta } 22858c499324SRuchika Gupta 228645d40bdaSValerii Chubar static enum pkcs11_rc set_private_key_data_rsa(struct obj_attrs **head, 228745d40bdaSValerii Chubar void *data, 228845d40bdaSValerii Chubar size_t key_size) 228945d40bdaSValerii Chubar { 229045d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 229145d40bdaSValerii Chubar int mbedtls_rc = 0; 229245d40bdaSValerii Chubar uint32_t key_bits = 0; 229345d40bdaSValerii Chubar uint32_t size = 0; 229445d40bdaSValerii Chubar uint32_t buffer_size = 0; 229545d40bdaSValerii Chubar void *buffer = NULL; 229645d40bdaSValerii Chubar mbedtls_pk_context pk = { }; 229745d40bdaSValerii Chubar mbedtls_rsa_context *rsa = NULL; 229845d40bdaSValerii Chubar mbedtls_mpi n = { }; 229945d40bdaSValerii Chubar mbedtls_mpi e = { }; 230045d40bdaSValerii Chubar mbedtls_mpi d = { }; 230145d40bdaSValerii Chubar mbedtls_mpi p = { }; 230245d40bdaSValerii Chubar mbedtls_mpi q = { }; 230345d40bdaSValerii Chubar 230445d40bdaSValerii Chubar rc = get_u32_attribute(*head, PKCS11_CKA_MODULUS_BITS, &key_bits); 230545d40bdaSValerii Chubar if (rc && rc != PKCS11_RV_NOT_FOUND) 230645d40bdaSValerii Chubar return rc; 230745d40bdaSValerii Chubar 230845d40bdaSValerii Chubar if (remove_empty_attribute(head, PKCS11_CKA_MODULUS) || 230945d40bdaSValerii Chubar remove_empty_attribute(head, PKCS11_CKA_PUBLIC_EXPONENT) || 231045d40bdaSValerii Chubar remove_empty_attribute(head, PKCS11_CKA_PRIVATE_EXPONENT) || 231145d40bdaSValerii Chubar remove_empty_attribute(head, PKCS11_CKA_PRIME_1) || 231245d40bdaSValerii Chubar remove_empty_attribute(head, PKCS11_CKA_PRIME_2)) 231345d40bdaSValerii Chubar return PKCS11_CKR_GENERAL_ERROR; 231445d40bdaSValerii Chubar 231545d40bdaSValerii Chubar mbedtls_pk_init(&pk); 231645d40bdaSValerii Chubar mbedtls_mpi_init(&n); 231745d40bdaSValerii Chubar mbedtls_mpi_init(&e); 231845d40bdaSValerii Chubar mbedtls_mpi_init(&d); 231945d40bdaSValerii Chubar mbedtls_mpi_init(&p); 232045d40bdaSValerii Chubar mbedtls_mpi_init(&q); 232145d40bdaSValerii Chubar 232245d40bdaSValerii Chubar mbedtls_rc = mbedtls_pk_parse_key(&pk, data, key_size, NULL, 0); 232345d40bdaSValerii Chubar if (mbedtls_rc) { 232445d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 232545d40bdaSValerii Chubar goto out; 232645d40bdaSValerii Chubar } 232745d40bdaSValerii Chubar 232845d40bdaSValerii Chubar rsa = mbedtls_pk_rsa(pk); 232945d40bdaSValerii Chubar mbedtls_rc = mbedtls_rsa_export(rsa, &n, &p, &q, &d, &e); 233045d40bdaSValerii Chubar if (mbedtls_rc) { 233145d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 233245d40bdaSValerii Chubar goto out; 233345d40bdaSValerii Chubar } 233445d40bdaSValerii Chubar 233545d40bdaSValerii Chubar if (key_bits && mbedtls_mpi_bitlen(&n) != key_bits) { 233645d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE; 233745d40bdaSValerii Chubar goto out; 233845d40bdaSValerii Chubar } 233945d40bdaSValerii Chubar 234045d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&n), 8); 234145d40bdaSValerii Chubar buffer_size = size; 234245d40bdaSValerii Chubar buffer = TEE_Malloc(buffer_size, TEE_USER_MEM_HINT_NO_FILL_ZERO); 234345d40bdaSValerii Chubar if (!buffer) { 234445d40bdaSValerii Chubar rc = PKCS11_CKR_DEVICE_MEMORY; 234545d40bdaSValerii Chubar goto out; 234645d40bdaSValerii Chubar } 234745d40bdaSValerii Chubar 234845d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&n, buffer, size); 234945d40bdaSValerii Chubar if (mbedtls_rc) { 235045d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 235145d40bdaSValerii Chubar goto out; 235245d40bdaSValerii Chubar } 235345d40bdaSValerii Chubar 235445d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_MODULUS, buffer, size); 235545d40bdaSValerii Chubar if (rc) 235645d40bdaSValerii Chubar goto out; 235745d40bdaSValerii Chubar 235845d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&e), 8); 235945d40bdaSValerii Chubar if (buffer_size < size) { 236045d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE; 236145d40bdaSValerii Chubar goto out; 236245d40bdaSValerii Chubar } 236345d40bdaSValerii Chubar 236445d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&e, buffer, size); 236545d40bdaSValerii Chubar if (mbedtls_rc) { 236645d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 236745d40bdaSValerii Chubar goto out; 236845d40bdaSValerii Chubar } 236945d40bdaSValerii Chubar 237045d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_PUBLIC_EXPONENT, buffer, size); 237145d40bdaSValerii Chubar if (rc) 237245d40bdaSValerii Chubar goto out; 237345d40bdaSValerii Chubar 237445d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&d), 8); 237545d40bdaSValerii Chubar if (buffer_size < size) { 237645d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE; 237745d40bdaSValerii Chubar goto out; 237845d40bdaSValerii Chubar } 237945d40bdaSValerii Chubar 238045d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&d, buffer, size); 238145d40bdaSValerii Chubar if (mbedtls_rc) { 238245d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 238345d40bdaSValerii Chubar goto out; 238445d40bdaSValerii Chubar } 238545d40bdaSValerii Chubar 238645d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_PRIVATE_EXPONENT, buffer, size); 238745d40bdaSValerii Chubar if (rc) 238845d40bdaSValerii Chubar goto out; 238945d40bdaSValerii Chubar 239045d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&p), 8); 239145d40bdaSValerii Chubar if (buffer_size < size) { 239245d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE; 239345d40bdaSValerii Chubar goto out; 239445d40bdaSValerii Chubar } 239545d40bdaSValerii Chubar 239645d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&p, buffer, size); 239745d40bdaSValerii Chubar if (mbedtls_rc) { 239845d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 239945d40bdaSValerii Chubar goto out; 240045d40bdaSValerii Chubar } 240145d40bdaSValerii Chubar 240245d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_PRIME_1, buffer, size); 240345d40bdaSValerii Chubar if (rc) 240445d40bdaSValerii Chubar goto out; 240545d40bdaSValerii Chubar 240645d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&q), 8); 240745d40bdaSValerii Chubar if (buffer_size < size) { 240845d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE; 240945d40bdaSValerii Chubar goto out; 241045d40bdaSValerii Chubar } 241145d40bdaSValerii Chubar 241245d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&q, buffer, size); 241345d40bdaSValerii Chubar if (mbedtls_rc) { 241445d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 241545d40bdaSValerii Chubar goto out; 241645d40bdaSValerii Chubar } 241745d40bdaSValerii Chubar 241845d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_PRIME_2, buffer, size); 241945d40bdaSValerii Chubar 242045d40bdaSValerii Chubar out: 242145d40bdaSValerii Chubar mbedtls_pk_free(&pk); 242245d40bdaSValerii Chubar mbedtls_mpi_free(&n); 242345d40bdaSValerii Chubar mbedtls_mpi_free(&e); 242445d40bdaSValerii Chubar mbedtls_mpi_free(&d); 242545d40bdaSValerii Chubar mbedtls_mpi_free(&p); 242645d40bdaSValerii Chubar mbedtls_mpi_free(&q); 242745d40bdaSValerii Chubar TEE_Free(buffer); 242845d40bdaSValerii Chubar return rc; 242945d40bdaSValerii Chubar } 243045d40bdaSValerii Chubar 24318c499324SRuchika Gupta enum pkcs11_rc set_key_data(struct obj_attrs **head, void *data, 24328c499324SRuchika Gupta size_t key_size) 24338c499324SRuchika Gupta { 24348c499324SRuchika Gupta switch (get_class(*head)) { 24358c499324SRuchika Gupta case PKCS11_CKO_SECRET_KEY: 24368c499324SRuchika Gupta return set_secret_key_data(head, data, key_size); 243745d40bdaSValerii Chubar case PKCS11_CKO_PRIVATE_KEY: 243845d40bdaSValerii Chubar if (get_key_type(*head) == PKCS11_CKK_RSA) 243945d40bdaSValerii Chubar return set_private_key_data_rsa(head, data, key_size); 244045d40bdaSValerii Chubar break; 24418c499324SRuchika Gupta default: 24428c499324SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR; 24438c499324SRuchika Gupta } 244445d40bdaSValerii Chubar 244545d40bdaSValerii Chubar return PKCS11_CKR_GENERAL_ERROR; 24468c499324SRuchika Gupta } 24475e1d94ebSVesa Jääskeläinen 2448a9aa45d8SValerii Chubar static enum pkcs11_rc alloc_copy_attribute_value(struct obj_attrs *head, 2449a9aa45d8SValerii Chubar void **data, uint32_t *sz) 2450a9aa45d8SValerii Chubar { 2451a9aa45d8SValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 2452a9aa45d8SValerii Chubar void *buffer = NULL; 2453a9aa45d8SValerii Chubar void *value = NULL; 2454a9aa45d8SValerii Chubar 2455a9aa45d8SValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_VALUE, &value, sz); 2456a9aa45d8SValerii Chubar if (rc) 2457a9aa45d8SValerii Chubar return PKCS11_CKR_ARGUMENTS_BAD; 2458a9aa45d8SValerii Chubar 2459a9aa45d8SValerii Chubar buffer = TEE_Malloc(*sz, TEE_USER_MEM_HINT_NO_FILL_ZERO); 2460a9aa45d8SValerii Chubar if (!buffer) 2461a9aa45d8SValerii Chubar return PKCS11_CKR_DEVICE_MEMORY; 2462a9aa45d8SValerii Chubar 2463a9aa45d8SValerii Chubar TEE_MemMove(buffer, value, *sz); 2464a9aa45d8SValerii Chubar *data = buffer; 2465a9aa45d8SValerii Chubar 2466a9aa45d8SValerii Chubar return PKCS11_CKR_OK; 2467a9aa45d8SValerii Chubar } 2468a9aa45d8SValerii Chubar 246945d40bdaSValerii Chubar static enum pkcs11_rc 247045d40bdaSValerii Chubar encode_rsa_private_key_der(struct obj_attrs *head, void **data, uint32_t *sz) 247145d40bdaSValerii Chubar { 247245d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 247345d40bdaSValerii Chubar int i = 0; 247445d40bdaSValerii Chubar int mbedtls_rc = 0; 247545d40bdaSValerii Chubar int start = 0; 247645d40bdaSValerii Chubar int der_size = 0; 247745d40bdaSValerii Chubar void *n = NULL; 247845d40bdaSValerii Chubar void *p = NULL; 247945d40bdaSValerii Chubar void *q = NULL; 248045d40bdaSValerii Chubar void *d = NULL; 248145d40bdaSValerii Chubar void *e = NULL; 248245d40bdaSValerii Chubar uint32_t n_len = 0; 248345d40bdaSValerii Chubar uint32_t p_len = 0; 248445d40bdaSValerii Chubar uint32_t q_len = 0; 248545d40bdaSValerii Chubar uint32_t d_len = 0; 248645d40bdaSValerii Chubar uint32_t e_len = 0; 248745d40bdaSValerii Chubar uint8_t *buffer = NULL; 248845d40bdaSValerii Chubar mbedtls_pk_context pk = { }; 248945d40bdaSValerii Chubar mbedtls_rsa_context *rsa = NULL; 249045d40bdaSValerii Chubar const mbedtls_pk_info_t *pk_info = NULL; 249145d40bdaSValerii Chubar 249245d40bdaSValerii Chubar mbedtls_pk_init(&pk); 249345d40bdaSValerii Chubar pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA); 249445d40bdaSValerii Chubar if (mbedtls_pk_setup(&pk, pk_info)) { 249545d40bdaSValerii Chubar rc = PKCS11_CKR_GENERAL_ERROR; 249645d40bdaSValerii Chubar goto out; 249745d40bdaSValerii Chubar } 249845d40bdaSValerii Chubar 249945d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_MODULUS, &n, &n_len); 250045d40bdaSValerii Chubar if (rc) 250145d40bdaSValerii Chubar goto out; 250245d40bdaSValerii Chubar 250345d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_PRIME_1, &p, &p_len); 250445d40bdaSValerii Chubar if (rc) 250545d40bdaSValerii Chubar goto out; 250645d40bdaSValerii Chubar 250745d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_PRIME_2, &q, &q_len); 250845d40bdaSValerii Chubar if (rc) 250945d40bdaSValerii Chubar goto out; 251045d40bdaSValerii Chubar 251145d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_PRIVATE_EXPONENT, &d, &d_len); 251245d40bdaSValerii Chubar if (rc) 251345d40bdaSValerii Chubar goto out; 251445d40bdaSValerii Chubar 251545d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_PUBLIC_EXPONENT, &e, &e_len); 251645d40bdaSValerii Chubar if (rc) 251745d40bdaSValerii Chubar goto out; 251845d40bdaSValerii Chubar 251945d40bdaSValerii Chubar rsa = mbedtls_pk_rsa(pk); 252045d40bdaSValerii Chubar mbedtls_rc = mbedtls_rsa_import_raw(rsa, n, n_len, p, p_len, 252145d40bdaSValerii Chubar q, q_len, d, d_len, e, e_len); 252245d40bdaSValerii Chubar if (mbedtls_rc) { 252345d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 252445d40bdaSValerii Chubar goto out; 252545d40bdaSValerii Chubar } 252645d40bdaSValerii Chubar 252745d40bdaSValerii Chubar if (mbedtls_rsa_complete(rsa)) { 252845d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 252945d40bdaSValerii Chubar goto out; 253045d40bdaSValerii Chubar } 253145d40bdaSValerii Chubar 253245d40bdaSValerii Chubar if (mbedtls_rsa_check_privkey(rsa)) { 253345d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 253445d40bdaSValerii Chubar goto out; 253545d40bdaSValerii Chubar } 253645d40bdaSValerii Chubar 253745d40bdaSValerii Chubar der_size = n_len * 8; 253845d40bdaSValerii Chubar buffer = TEE_Malloc(der_size, TEE_USER_MEM_HINT_NO_FILL_ZERO); 253945d40bdaSValerii Chubar if (!buffer) { 254045d40bdaSValerii Chubar rc = PKCS11_CKR_DEVICE_MEMORY; 254145d40bdaSValerii Chubar goto out; 254245d40bdaSValerii Chubar } 254345d40bdaSValerii Chubar 254445d40bdaSValerii Chubar mbedtls_rc = mbedtls_pk_write_key_der(&pk, buffer, der_size); 254545d40bdaSValerii Chubar if (mbedtls_rc < 0) { 254645d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 254745d40bdaSValerii Chubar goto out; 254845d40bdaSValerii Chubar } 254945d40bdaSValerii Chubar 255045d40bdaSValerii Chubar start = der_size - mbedtls_rc; 255145d40bdaSValerii Chubar for (i = 0; i < mbedtls_rc; i++) { 255245d40bdaSValerii Chubar buffer[i] = buffer[i + start]; 255345d40bdaSValerii Chubar buffer[i + start] = 0; 255445d40bdaSValerii Chubar } 255545d40bdaSValerii Chubar 255645d40bdaSValerii Chubar *data = buffer; 255745d40bdaSValerii Chubar *sz = mbedtls_rc; 255845d40bdaSValerii Chubar out: 255945d40bdaSValerii Chubar mbedtls_pk_free(&pk); 256045d40bdaSValerii Chubar 256145d40bdaSValerii Chubar if (rc) 256245d40bdaSValerii Chubar TEE_Free(buffer); 256345d40bdaSValerii Chubar 256445d40bdaSValerii Chubar return rc; 256545d40bdaSValerii Chubar } 256645d40bdaSValerii Chubar 2567a9aa45d8SValerii Chubar enum pkcs11_rc alloc_key_data_to_wrap(struct obj_attrs *head, void **data, 25685f80f270SRuchika Gupta uint32_t *sz) 25695f80f270SRuchika Gupta { 257045d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 257145d40bdaSValerii Chubar 25725f80f270SRuchika Gupta switch (get_class(head)) { 25735f80f270SRuchika Gupta case PKCS11_CKO_SECRET_KEY: 257445d40bdaSValerii Chubar rc = alloc_copy_attribute_value(head, data, sz); 257545d40bdaSValerii Chubar break; 257645d40bdaSValerii Chubar case PKCS11_CKO_PRIVATE_KEY: 257745d40bdaSValerii Chubar if (get_key_type(head) == PKCS11_CKK_RSA) 257845d40bdaSValerii Chubar rc = encode_rsa_private_key_der(head, data, sz); 257945d40bdaSValerii Chubar break; 25805f80f270SRuchika Gupta default: 258145d40bdaSValerii Chubar break; 25825f80f270SRuchika Gupta } 25835f80f270SRuchika Gupta 258445d40bdaSValerii Chubar return rc; 25855f80f270SRuchika Gupta } 25865f80f270SRuchika Gupta 25875e1d94ebSVesa Jääskeläinen enum pkcs11_rc add_missing_attribute_id(struct obj_attrs **pub_head, 25885e1d94ebSVesa Jääskeläinen struct obj_attrs **priv_head) 25895e1d94ebSVesa Jääskeläinen { 25905e1d94ebSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 25915e1d94ebSVesa Jääskeläinen void *id1 = NULL; 25925e1d94ebSVesa Jääskeläinen uint32_t id1_size = 0; 25935e1d94ebSVesa Jääskeläinen void *id2 = NULL; 25945e1d94ebSVesa Jääskeläinen uint32_t id2_size = 0; 25955e1d94ebSVesa Jääskeläinen 25965e1d94ebSVesa Jääskeläinen assert(pub_head); 25975e1d94ebSVesa Jääskeläinen assert(priv_head); 25985e1d94ebSVesa Jääskeläinen 25995e1d94ebSVesa Jääskeläinen rc = get_attribute_ptr(*pub_head, PKCS11_CKA_ID, &id1, &id1_size); 26005e1d94ebSVesa Jääskeläinen if (rc) { 26015e1d94ebSVesa Jääskeläinen if (rc != PKCS11_RV_NOT_FOUND) 26025e1d94ebSVesa Jääskeläinen return rc; 26035e1d94ebSVesa Jääskeläinen id1 = NULL; 26045e1d94ebSVesa Jääskeläinen } else if (!id1_size) { 26055e1d94ebSVesa Jääskeläinen id1 = NULL; 26065e1d94ebSVesa Jääskeläinen } 26075e1d94ebSVesa Jääskeläinen 26085e1d94ebSVesa Jääskeläinen rc = get_attribute_ptr(*priv_head, PKCS11_CKA_ID, &id2, &id2_size); 26095e1d94ebSVesa Jääskeläinen if (rc) { 26105e1d94ebSVesa Jääskeläinen if (rc != PKCS11_RV_NOT_FOUND) 26115e1d94ebSVesa Jääskeläinen return rc; 26125e1d94ebSVesa Jääskeläinen id2 = NULL; 26135e1d94ebSVesa Jääskeläinen } else if (!id2_size) { 26145e1d94ebSVesa Jääskeläinen id2 = NULL; 26155e1d94ebSVesa Jääskeläinen } 26165e1d94ebSVesa Jääskeläinen 26175e1d94ebSVesa Jääskeläinen /* Both have value -- let them be what caller has specified them */ 26185e1d94ebSVesa Jääskeläinen if (id1 && id2) 26195e1d94ebSVesa Jääskeläinen return PKCS11_CKR_OK; 26205e1d94ebSVesa Jääskeläinen 26215e1d94ebSVesa Jääskeläinen /* Both are empty -- leave empty values */ 26225e1d94ebSVesa Jääskeläinen if (!id1 && !id2) 26235e1d94ebSVesa Jääskeläinen return PKCS11_CKR_OK; 26245e1d94ebSVesa Jääskeläinen 26255e1d94ebSVesa Jääskeläinen /* Cross copy CKA_ID value */ 26265e1d94ebSVesa Jääskeläinen if (id1) 26275e1d94ebSVesa Jääskeläinen return set_attribute(priv_head, PKCS11_CKA_ID, id1, id1_size); 26285e1d94ebSVesa Jääskeläinen else 26295e1d94ebSVesa Jääskeläinen return set_attribute(pub_head, PKCS11_CKA_ID, id2, id2_size); 26305e1d94ebSVesa Jääskeläinen } 2631