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>
7bcac2127SMarouene Boubakri #include <config.h>
863f89caaSJens Wiklander #include <inttypes.h>
97c243321SVesa Jääskeläinen #include <mbedtls/asn1write.h>
107c243321SVesa Jääskeläinen #include <mbedtls/ecp.h>
1145d40bdaSValerii Chubar #include <mbedtls/pk.h>
1263f89caaSJens Wiklander #include <pkcs11_ta.h>
1363f89caaSJens Wiklander #include <stdlib.h>
1463f89caaSJens Wiklander #include <tee_internal_api_extensions.h>
1563f89caaSJens Wiklander #include <tee_internal_api.h>
166a760c9eSEtienne Carriere #include <trace.h>
1763f89caaSJens Wiklander #include <util.h>
1863f89caaSJens Wiklander
1963f89caaSJens Wiklander #include "attributes.h"
2063f89caaSJens Wiklander #include "handle.h"
2163f89caaSJens Wiklander #include "pkcs11_attributes.h"
2263f89caaSJens Wiklander #include "pkcs11_helpers.h"
2363f89caaSJens Wiklander #include "pkcs11_token.h"
247c243321SVesa Jääskeläinen #include "processing.h"
2563f89caaSJens Wiklander #include "sanitize_object.h"
2663f89caaSJens Wiklander #include "serializer.h"
2763f89caaSJens Wiklander #include "token_capabilities.h"
2863f89caaSJens Wiklander
pkcs11_func2ckfm(enum processing_func function)29512cbf1dSJens Wiklander static uint32_t pkcs11_func2ckfm(enum processing_func function)
30512cbf1dSJens Wiklander {
31512cbf1dSJens Wiklander switch (function) {
32512cbf1dSJens Wiklander case PKCS11_FUNCTION_DIGEST:
33512cbf1dSJens Wiklander return PKCS11_CKFM_DIGEST;
34512cbf1dSJens Wiklander case PKCS11_FUNCTION_GENERATE:
35512cbf1dSJens Wiklander return PKCS11_CKFM_GENERATE;
36512cbf1dSJens Wiklander case PKCS11_FUNCTION_GENERATE_PAIR:
37512cbf1dSJens Wiklander return PKCS11_CKFM_GENERATE_KEY_PAIR;
38512cbf1dSJens Wiklander case PKCS11_FUNCTION_DERIVE:
39512cbf1dSJens Wiklander return PKCS11_CKFM_DERIVE;
40512cbf1dSJens Wiklander case PKCS11_FUNCTION_WRAP:
41512cbf1dSJens Wiklander return PKCS11_CKFM_WRAP;
42512cbf1dSJens Wiklander case PKCS11_FUNCTION_UNWRAP:
43512cbf1dSJens Wiklander return PKCS11_CKFM_UNWRAP;
44512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT:
45512cbf1dSJens Wiklander return PKCS11_CKFM_ENCRYPT;
46512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT:
47512cbf1dSJens Wiklander return PKCS11_CKFM_DECRYPT;
48512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN:
49512cbf1dSJens Wiklander return PKCS11_CKFM_SIGN;
50512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY:
51512cbf1dSJens Wiklander return PKCS11_CKFM_VERIFY;
52512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN_RECOVER:
53512cbf1dSJens Wiklander return PKCS11_CKFM_SIGN_RECOVER;
54512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY_RECOVER:
55512cbf1dSJens Wiklander return PKCS11_CKFM_VERIFY_RECOVER;
56512cbf1dSJens Wiklander default:
57512cbf1dSJens Wiklander return 0;
58512cbf1dSJens Wiklander }
59512cbf1dSJens Wiklander }
60512cbf1dSJens Wiklander
61512cbf1dSJens Wiklander enum pkcs11_rc
check_mechanism_against_processing(struct pkcs11_session * session,enum pkcs11_mechanism_id mechanism_type,enum processing_func function,enum processing_step step)62512cbf1dSJens Wiklander check_mechanism_against_processing(struct pkcs11_session *session,
63512cbf1dSJens Wiklander enum pkcs11_mechanism_id mechanism_type,
64512cbf1dSJens Wiklander enum processing_func function,
65512cbf1dSJens Wiklander enum processing_step step)
66512cbf1dSJens Wiklander {
67512cbf1dSJens Wiklander bool allowed = false;
68512cbf1dSJens Wiklander
69512cbf1dSJens Wiklander switch (step) {
70512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_INIT:
71512cbf1dSJens Wiklander switch (function) {
72512cbf1dSJens Wiklander case PKCS11_FUNCTION_IMPORT:
73512cbf1dSJens Wiklander case PKCS11_FUNCTION_COPY:
74512cbf1dSJens Wiklander case PKCS11_FUNCTION_MODIFY:
75512cbf1dSJens Wiklander case PKCS11_FUNCTION_DESTROY:
76512cbf1dSJens Wiklander return PKCS11_CKR_OK;
77512cbf1dSJens Wiklander default:
78512cbf1dSJens Wiklander break;
79512cbf1dSJens Wiklander }
80512cbf1dSJens Wiklander /*
81512cbf1dSJens Wiklander * Check that the returned PKCS11_CKFM_* flag from
82512cbf1dSJens Wiklander * pkcs11_func2ckfm() is among the ones from
83512cbf1dSJens Wiklander * mechanism_supported_flags().
84512cbf1dSJens Wiklander */
85512cbf1dSJens Wiklander allowed = mechanism_supported_flags(mechanism_type) &
86512cbf1dSJens Wiklander pkcs11_func2ckfm(function);
87512cbf1dSJens Wiklander break;
88512cbf1dSJens Wiklander
89512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_ONESHOT:
900460a039SRuchika Gupta if (session->processing->always_authen &&
910460a039SRuchika Gupta !session->processing->relogged)
920460a039SRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN;
930460a039SRuchika Gupta
942364aa69SRuchika Gupta if (session->processing->step == PKCS11_FUNC_STEP_UPDATE ||
952364aa69SRuchika Gupta session->processing->step == PKCS11_FUNC_STEP_FINAL) {
962364aa69SRuchika Gupta EMSG("Cannot perform one-shot on active processing");
970460a039SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE;
980460a039SRuchika Gupta }
990460a039SRuchika Gupta
1000460a039SRuchika Gupta allowed = true;
1010460a039SRuchika Gupta break;
1020460a039SRuchika Gupta
103512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_UPDATE:
104512cbf1dSJens Wiklander if (session->processing->always_authen &&
105512cbf1dSJens Wiklander !session->processing->relogged)
106512cbf1dSJens Wiklander return PKCS11_CKR_USER_NOT_LOGGED_IN;
107512cbf1dSJens Wiklander
1082364aa69SRuchika Gupta if (session->processing->step == PKCS11_FUNC_STEP_ONESHOT ||
1092364aa69SRuchika Gupta session->processing->step == PKCS11_FUNC_STEP_FINAL) {
1102364aa69SRuchika Gupta EMSG("Cannot perform update on finalized processing");
1112364aa69SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE;
1122364aa69SRuchika Gupta }
1132364aa69SRuchika Gupta
114512cbf1dSJens Wiklander allowed = !mechanism_is_one_shot_only(mechanism_type);
115512cbf1dSJens Wiklander break;
116512cbf1dSJens Wiklander
1179e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE_KEY:
1189e91a619SVesa Jääskeläinen assert(function == PKCS11_FUNCTION_DIGEST);
1199e91a619SVesa Jääskeläinen
1209e91a619SVesa Jääskeläinen if (session->processing->always_authen &&
1219e91a619SVesa Jääskeläinen !session->processing->relogged)
1229e91a619SVesa Jääskeläinen return PKCS11_CKR_USER_NOT_LOGGED_IN;
1239e91a619SVesa Jääskeläinen
1249e91a619SVesa Jääskeläinen allowed = true;
1259e91a619SVesa Jääskeläinen break;
1269e91a619SVesa Jääskeläinen
127512cbf1dSJens Wiklander case PKCS11_FUNC_STEP_FINAL:
128512cbf1dSJens Wiklander if (session->processing->always_authen &&
129512cbf1dSJens Wiklander !session->processing->relogged)
130512cbf1dSJens Wiklander return PKCS11_CKR_USER_NOT_LOGGED_IN;
131512cbf1dSJens Wiklander
1322364aa69SRuchika Gupta if (session->processing->step == PKCS11_FUNC_STEP_ONESHOT) {
1332364aa69SRuchika Gupta EMSG("Cannot perform final on oneshot processing");
1342364aa69SRuchika Gupta return PKCS11_CKR_OPERATION_ACTIVE;
1352364aa69SRuchika Gupta }
136512cbf1dSJens Wiklander return PKCS11_CKR_OK;
137512cbf1dSJens Wiklander
138512cbf1dSJens Wiklander default:
139512cbf1dSJens Wiklander TEE_Panic(step);
140512cbf1dSJens Wiklander break;
141512cbf1dSJens Wiklander }
142512cbf1dSJens Wiklander
143512cbf1dSJens Wiklander if (!allowed) {
144512cbf1dSJens Wiklander EMSG("Processing %#x/%s not permitted (%u/%u)",
145512cbf1dSJens Wiklander (unsigned int)mechanism_type, id2str_proc(mechanism_type),
146512cbf1dSJens Wiklander function, step);
147df705578SRuchika Gupta return PKCS11_CKR_MECHANISM_INVALID;
148512cbf1dSJens Wiklander }
149512cbf1dSJens Wiklander
150512cbf1dSJens Wiklander return PKCS11_CKR_OK;
151512cbf1dSJens Wiklander }
152512cbf1dSJens Wiklander
15363f89caaSJens Wiklander /*
15463f89caaSJens Wiklander * Object default boolean attributes as per PKCS#11
15563f89caaSJens Wiklander */
pkcs11_object_default_boolprop(uint32_t attribute)15663f89caaSJens Wiklander static uint8_t *pkcs11_object_default_boolprop(uint32_t attribute)
15763f89caaSJens Wiklander {
15863f89caaSJens Wiklander static const uint8_t bool_true = 1;
15963f89caaSJens Wiklander static const uint8_t bool_false;
16063f89caaSJens Wiklander
16163f89caaSJens Wiklander switch (attribute) {
16263f89caaSJens Wiklander /* As per PKCS#11 default value */
16363f89caaSJens Wiklander case PKCS11_CKA_MODIFIABLE:
16463f89caaSJens Wiklander case PKCS11_CKA_COPYABLE:
16563f89caaSJens Wiklander case PKCS11_CKA_DESTROYABLE:
16663f89caaSJens Wiklander return (uint8_t *)&bool_true;
16763f89caaSJens Wiklander case PKCS11_CKA_TOKEN:
16863f89caaSJens Wiklander case PKCS11_CKA_PRIVATE:
16939fc24faSEtienne Carriere case PKCS11_CKA_WRAP_WITH_TRUSTED:
17039fc24faSEtienne Carriere case PKCS11_CKA_ALWAYS_AUTHENTICATE:
17163f89caaSJens Wiklander case PKCS11_CKA_SENSITIVE:
17263f89caaSJens Wiklander return (uint8_t *)&bool_false;
17363f89caaSJens Wiklander /* Token specific default value */
17463f89caaSJens Wiklander case PKCS11_CKA_SIGN:
17563f89caaSJens Wiklander case PKCS11_CKA_VERIFY:
17663f89caaSJens Wiklander case PKCS11_CKA_DERIVE:
17763f89caaSJens Wiklander case PKCS11_CKA_ENCRYPT:
17863f89caaSJens Wiklander case PKCS11_CKA_DECRYPT:
17963f89caaSJens Wiklander case PKCS11_CKA_SIGN_RECOVER:
18063f89caaSJens Wiklander case PKCS11_CKA_VERIFY_RECOVER:
18163f89caaSJens Wiklander case PKCS11_CKA_WRAP:
18263f89caaSJens Wiklander case PKCS11_CKA_UNWRAP:
18363f89caaSJens Wiklander case PKCS11_CKA_EXTRACTABLE:
18463f89caaSJens Wiklander case PKCS11_CKA_TRUSTED:
18563f89caaSJens Wiklander return (uint8_t *)&bool_false;
18663f89caaSJens Wiklander default:
18763f89caaSJens Wiklander DMSG("No default for boolprop attribute %#"PRIx32, attribute);
18863f89caaSJens Wiklander return NULL;
18963f89caaSJens Wiklander }
19063f89caaSJens Wiklander }
19163f89caaSJens Wiklander
19263f89caaSJens Wiklander /*
19363f89caaSJens Wiklander * Object expects several boolean attributes to be set to a default value
19463f89caaSJens Wiklander * or to a validate client configuration value. This function append the input
19563f89caaSJens Wiklander * attribute (id/size/value) in the serialized object.
19663f89caaSJens Wiklander */
pkcs11_import_object_boolprop(struct obj_attrs ** out,struct obj_attrs * templ,uint32_t attribute)19763f89caaSJens Wiklander static enum pkcs11_rc pkcs11_import_object_boolprop(struct obj_attrs **out,
19863f89caaSJens Wiklander struct obj_attrs *templ,
19963f89caaSJens Wiklander uint32_t attribute)
20063f89caaSJens Wiklander {
20163f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK;
20263f89caaSJens Wiklander uint8_t bbool = 0;
20363f89caaSJens Wiklander uint32_t size = sizeof(uint8_t);
20463f89caaSJens Wiklander void *attr = NULL;
20563f89caaSJens Wiklander
20663f89caaSJens Wiklander rc = get_attribute(templ, attribute, &bbool, &size);
20763f89caaSJens Wiklander if (rc) {
20863f89caaSJens Wiklander if (rc != PKCS11_RV_NOT_FOUND)
20963f89caaSJens Wiklander return rc;
21063f89caaSJens Wiklander attr = pkcs11_object_default_boolprop(attribute);
21163f89caaSJens Wiklander if (!attr)
21263f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCOMPLETE;
21363f89caaSJens Wiklander } else {
21463f89caaSJens Wiklander attr = &bbool;
21563f89caaSJens Wiklander }
21663f89caaSJens Wiklander
21763f89caaSJens Wiklander /* Boolean attributes are 1byte in the ABI, no alignment issue */
21863f89caaSJens Wiklander return add_attribute(out, attribute, attr, sizeof(uint8_t));
21963f89caaSJens Wiklander }
22063f89caaSJens Wiklander
set_mandatory_boolprops(struct obj_attrs ** out,struct obj_attrs * temp,uint32_t const * bp,size_t bp_count)22163f89caaSJens Wiklander static enum pkcs11_rc set_mandatory_boolprops(struct obj_attrs **out,
22263f89caaSJens Wiklander struct obj_attrs *temp,
22363f89caaSJens Wiklander uint32_t const *bp,
22463f89caaSJens Wiklander size_t bp_count)
22563f89caaSJens Wiklander {
22663f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK;
22763f89caaSJens Wiklander size_t n = 0;
22863f89caaSJens Wiklander
22963f89caaSJens Wiklander for (n = 0; n < bp_count; n++) {
23063f89caaSJens Wiklander rc = pkcs11_import_object_boolprop(out, temp, bp[n]);
23163f89caaSJens Wiklander if (rc)
23263f89caaSJens Wiklander return rc;
23363f89caaSJens Wiklander }
23463f89caaSJens Wiklander
23563f89caaSJens Wiklander return rc;
23663f89caaSJens Wiklander }
23763f89caaSJens Wiklander
set_mandatory_attributes(struct obj_attrs ** out,struct obj_attrs * temp,uint32_t const * attrs,size_t attrs_count)23863f89caaSJens Wiklander static enum pkcs11_rc set_mandatory_attributes(struct obj_attrs **out,
23963f89caaSJens Wiklander struct obj_attrs *temp,
24016df60c7SEtienne Carriere uint32_t const *attrs,
24116df60c7SEtienne Carriere size_t attrs_count)
24263f89caaSJens Wiklander {
24363f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK;
24463f89caaSJens Wiklander size_t n = 0;
24563f89caaSJens Wiklander
24616df60c7SEtienne Carriere for (n = 0; n < attrs_count; n++) {
24763f89caaSJens Wiklander uint32_t size = 0;
24863f89caaSJens Wiklander void *value = NULL;
24963f89caaSJens Wiklander
25016df60c7SEtienne Carriere if (get_attribute_ptr(temp, attrs[n], &value, &size))
25163f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCOMPLETE;
25263f89caaSJens Wiklander
25316df60c7SEtienne Carriere rc = add_attribute(out, attrs[n], value, size);
25463f89caaSJens Wiklander if (rc)
25563f89caaSJens Wiklander return rc;
25663f89caaSJens Wiklander }
25763f89caaSJens Wiklander
25863f89caaSJens Wiklander return rc;
25963f89caaSJens Wiklander }
26063f89caaSJens Wiklander
get_default_value(enum pkcs11_attr_id id __maybe_unused,void ** value,uint32_t * size)261897aaf11SEtienne Carriere static enum pkcs11_rc get_default_value(enum pkcs11_attr_id id __maybe_unused,
262897aaf11SEtienne Carriere void **value, uint32_t *size)
26363f89caaSJens Wiklander {
26463f89caaSJens Wiklander /* should have been taken care of already */
26563f89caaSJens Wiklander assert(!pkcs11_attr_is_boolean(id));
26663f89caaSJens Wiklander
26763f89caaSJens Wiklander /* All other attributes have an empty default value */
26863f89caaSJens Wiklander *value = NULL;
26963f89caaSJens Wiklander *size = 0;
27063f89caaSJens Wiklander return PKCS11_CKR_OK;
27163f89caaSJens Wiklander }
27263f89caaSJens Wiklander
set_optional_attributes_with_def(struct obj_attrs ** out,struct obj_attrs * temp,uint32_t const * attrs,size_t attrs_count,bool default_to_null)2734eb88651SRuchika Gupta static enum pkcs11_rc set_optional_attributes_with_def(struct obj_attrs **out,
27463f89caaSJens Wiklander struct obj_attrs *temp,
27516df60c7SEtienne Carriere uint32_t const *attrs,
27616df60c7SEtienne Carriere size_t attrs_count,
2774eb88651SRuchika Gupta bool default_to_null)
27863f89caaSJens Wiklander {
27963f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK;
28063f89caaSJens Wiklander size_t n = 0;
28163f89caaSJens Wiklander
28216df60c7SEtienne Carriere for (n = 0; n < attrs_count; n++) {
28363f89caaSJens Wiklander uint32_t size = 0;
28463f89caaSJens Wiklander void *value = NULL;
28563f89caaSJens Wiklander
28616df60c7SEtienne Carriere rc = get_attribute_ptr(temp, attrs[n], &value, &size);
2874eb88651SRuchika Gupta if (rc == PKCS11_RV_NOT_FOUND) {
2884eb88651SRuchika Gupta if (default_to_null) {
28916df60c7SEtienne Carriere rc = get_default_value(attrs[n], &value, &size);
2904eb88651SRuchika Gupta } else {
2914eb88651SRuchika Gupta rc = PKCS11_CKR_OK;
2924eb88651SRuchika Gupta continue;
2934eb88651SRuchika Gupta }
2944eb88651SRuchika Gupta }
29563f89caaSJens Wiklander if (rc)
29663f89caaSJens Wiklander return rc;
29763f89caaSJens Wiklander
29816df60c7SEtienne Carriere rc = add_attribute(out, attrs[n], value, size);
29963f89caaSJens Wiklander if (rc)
30063f89caaSJens Wiklander return rc;
30163f89caaSJens Wiklander }
30263f89caaSJens Wiklander
30363f89caaSJens Wiklander return rc;
30463f89caaSJens Wiklander }
30563f89caaSJens Wiklander
set_attributes_opt_or_null(struct obj_attrs ** out,struct obj_attrs * temp,uint32_t const * attrs,size_t attrs_count)3064eb88651SRuchika Gupta static enum pkcs11_rc set_attributes_opt_or_null(struct obj_attrs **out,
3074eb88651SRuchika Gupta struct obj_attrs *temp,
30816df60c7SEtienne Carriere uint32_t const *attrs,
30916df60c7SEtienne Carriere size_t attrs_count)
3104eb88651SRuchika Gupta {
31116df60c7SEtienne Carriere return set_optional_attributes_with_def(out, temp, attrs, attrs_count,
31216df60c7SEtienne Carriere true /* defaults to empty */);
3134eb88651SRuchika Gupta }
3144eb88651SRuchika Gupta
set_optional_attributes(struct obj_attrs ** out,struct obj_attrs * temp,uint32_t const * attrs,size_t attrs_count)3154eb88651SRuchika Gupta static enum pkcs11_rc set_optional_attributes(struct obj_attrs **out,
3164eb88651SRuchika Gupta struct obj_attrs *temp,
31716df60c7SEtienne Carriere uint32_t const *attrs,
31816df60c7SEtienne Carriere size_t attrs_count)
3194eb88651SRuchika Gupta {
32016df60c7SEtienne Carriere return set_optional_attributes_with_def(out, temp, attrs, attrs_count,
32116df60c7SEtienne Carriere false /* no default value */);
3224eb88651SRuchika Gupta }
3234eb88651SRuchika Gupta
32463f89caaSJens Wiklander /*
32563f89caaSJens Wiklander * Below are listed the mandated or optional expected attributes for
32663f89caaSJens Wiklander * PKCS#11 storage objects.
32763f89caaSJens Wiklander *
32863f89caaSJens Wiklander * Note: boolprops (mandated boolean attributes) PKCS11_CKA_ALWAYS_SENSITIVE,
32963f89caaSJens Wiklander * and PKCS11_CKA_NEVER_EXTRACTABLE are set by the token, not provided
33063f89caaSJens Wiklander * in the client template.
33163f89caaSJens Wiklander */
33263f89caaSJens Wiklander
33363f89caaSJens Wiklander /* PKCS#11 specification for any object (session/token) of the storage */
3344eb88651SRuchika Gupta static const uint32_t any_object_boolprops[] = {
33563f89caaSJens Wiklander PKCS11_CKA_TOKEN, PKCS11_CKA_PRIVATE,
33663f89caaSJens Wiklander PKCS11_CKA_MODIFIABLE, PKCS11_CKA_COPYABLE, PKCS11_CKA_DESTROYABLE,
33763f89caaSJens Wiklander };
33863f89caaSJens Wiklander
3394eb88651SRuchika Gupta static const uint32_t any_object_opt_or_null[] = {
34063f89caaSJens Wiklander PKCS11_CKA_LABEL,
34163f89caaSJens Wiklander };
34263f89caaSJens Wiklander
3434eb88651SRuchika Gupta /* PKCS#11 specification for raw data object (+any_object_xxx) */
3444eb88651SRuchika Gupta const uint32_t raw_data_opt_or_null[] = {
34563f89caaSJens Wiklander PKCS11_CKA_OBJECT_ID, PKCS11_CKA_APPLICATION, PKCS11_CKA_VALUE,
34663f89caaSJens Wiklander };
34763f89caaSJens Wiklander
3484137952dSVesa Jääskeläinen /* PKCS#11 specification for certificate object (+pkcs11_any_object_xxx) */
3494137952dSVesa Jääskeläinen static const uint32_t pkcs11_certificate_mandated[] = {
3504137952dSVesa Jääskeläinen PKCS11_CKA_CERTIFICATE_TYPE,
3514137952dSVesa Jääskeläinen };
3524137952dSVesa Jääskeläinen
3534137952dSVesa Jääskeläinen static const uint32_t pkcs11_certificate_boolprops[] = {
3544137952dSVesa Jääskeläinen PKCS11_CKA_TRUSTED,
3554137952dSVesa Jääskeläinen };
3564137952dSVesa Jääskeläinen
3574137952dSVesa Jääskeläinen static const uint32_t pkcs11_certificate_optional[] = {
358bcac2127SMarouene Boubakri PKCS11_CKA_CERTIFICATE_CATEGORY, PKCS11_CKA_START_DATE,
359bcac2127SMarouene Boubakri PKCS11_CKA_END_DATE, PKCS11_CKA_PUBLIC_KEY_INFO,
360bcac2127SMarouene Boubakri #ifdef CFG_PKCS11_TA_CHECK_VALUE_ATTRIBUTE
361bcac2127SMarouene Boubakri /* Consider KCV attribute only when supported */
362bcac2127SMarouene Boubakri PKCS11_CKA_CHECK_VALUE,
363bcac2127SMarouene Boubakri #endif
3644137952dSVesa Jääskeläinen };
3654137952dSVesa Jääskeläinen
3664137952dSVesa Jääskeläinen /*
3674137952dSVesa Jääskeläinen * PKCS#11 specification for X.509 certificate object (+pkcs11_certificate_xxx)
3684137952dSVesa Jääskeläinen */
3694137952dSVesa Jääskeläinen static const uint32_t pkcs11_x509_certificate_mandated[] = {
3704137952dSVesa Jääskeläinen PKCS11_CKA_SUBJECT,
3714137952dSVesa Jääskeläinen };
3724137952dSVesa Jääskeläinen
3734137952dSVesa Jääskeläinen static const uint32_t pkcs11_x509_certificate_optional[] = {
3744137952dSVesa Jääskeläinen PKCS11_CKA_ID, PKCS11_CKA_ISSUER, PKCS11_CKA_SERIAL_NUMBER,
3754137952dSVesa Jääskeläinen PKCS11_CKA_VALUE, PKCS11_CKA_URL,
3764137952dSVesa Jääskeläinen PKCS11_CKA_HASH_OF_SUBJECT_PUBLIC_KEY,
3774137952dSVesa Jääskeläinen PKCS11_CKA_HASH_OF_ISSUER_PUBLIC_KEY,
3784137952dSVesa Jääskeläinen PKCS11_CKA_JAVA_MIDP_SECURITY_DOMAIN, PKCS11_CKA_NAME_HASH_ALGORITHM,
3794137952dSVesa Jääskeläinen };
3804137952dSVesa Jääskeläinen
3814eb88651SRuchika Gupta /* PKCS#11 specification for any key object (+any_object_xxx) */
3824eb88651SRuchika Gupta static const uint32_t any_key_boolprops[] = {
38363f89caaSJens Wiklander PKCS11_CKA_DERIVE,
38463f89caaSJens Wiklander };
38563f89caaSJens Wiklander
3864eb88651SRuchika Gupta static const uint32_t any_key_opt_or_null[] = {
38763f89caaSJens Wiklander PKCS11_CKA_ID,
38863f89caaSJens Wiklander PKCS11_CKA_START_DATE, PKCS11_CKA_END_DATE,
3894eb88651SRuchika Gupta };
3904eb88651SRuchika Gupta
3914eb88651SRuchika Gupta static const uint32_t any_key_optional[] = {
39263f89caaSJens Wiklander PKCS11_CKA_ALLOWED_MECHANISMS,
39363f89caaSJens Wiklander };
39463f89caaSJens Wiklander
3954eb88651SRuchika Gupta /* PKCS#11 specification for any symmetric key (+any_key_xxx) */
3964eb88651SRuchika Gupta static const uint32_t symm_key_boolprops[] = {
39763f89caaSJens Wiklander PKCS11_CKA_ENCRYPT, PKCS11_CKA_DECRYPT,
39863f89caaSJens Wiklander PKCS11_CKA_SIGN, PKCS11_CKA_VERIFY,
39963f89caaSJens Wiklander PKCS11_CKA_WRAP, PKCS11_CKA_UNWRAP,
40063f89caaSJens Wiklander PKCS11_CKA_SENSITIVE, PKCS11_CKA_EXTRACTABLE,
40163f89caaSJens Wiklander PKCS11_CKA_WRAP_WITH_TRUSTED, PKCS11_CKA_TRUSTED,
40263f89caaSJens Wiklander };
40363f89caaSJens Wiklander
4044eb88651SRuchika Gupta static const uint32_t symm_key_opt_or_null[] = {
40563f89caaSJens Wiklander PKCS11_CKA_WRAP_TEMPLATE, PKCS11_CKA_UNWRAP_TEMPLATE,
4060ac5c695SRuchika Gupta PKCS11_CKA_DERIVE_TEMPLATE, PKCS11_CKA_VALUE,
4070ac5c695SRuchika Gupta };
4080ac5c695SRuchika Gupta
4090ac5c695SRuchika Gupta static const uint32_t symm_key_optional[] = {
4100ac5c695SRuchika Gupta PKCS11_CKA_VALUE_LEN,
411bcac2127SMarouene Boubakri #ifdef CFG_PKCS11_TA_CHECK_VALUE_ATTRIBUTE
412bcac2127SMarouene Boubakri /* Consider KCV attribute only when supported */
413bcac2127SMarouene Boubakri PKCS11_CKA_CHECK_VALUE,
414bcac2127SMarouene Boubakri #endif
41563f89caaSJens Wiklander };
41663f89caaSJens Wiklander
4174eb88651SRuchika Gupta /* PKCS#11 specification for any asymmetric public key (+any_key_xxx) */
4184eb88651SRuchika Gupta static const uint32_t public_key_boolprops[] = {
41963f89caaSJens Wiklander PKCS11_CKA_ENCRYPT, PKCS11_CKA_VERIFY, PKCS11_CKA_VERIFY_RECOVER,
42063f89caaSJens Wiklander PKCS11_CKA_WRAP,
42163f89caaSJens Wiklander PKCS11_CKA_TRUSTED,
42263f89caaSJens Wiklander };
42363f89caaSJens Wiklander
4244eb88651SRuchika Gupta static const uint32_t public_key_mandated[] = {
42563f89caaSJens Wiklander };
42663f89caaSJens Wiklander
4274eb88651SRuchika Gupta static const uint32_t public_key_opt_or_null[] = {
428edd95148SVesa Jääskeläinen PKCS11_CKA_SUBJECT, PKCS11_CKA_WRAP_TEMPLATE,
429edd95148SVesa Jääskeläinen PKCS11_CKA_PUBLIC_KEY_INFO,
43063f89caaSJens Wiklander };
43163f89caaSJens Wiklander
4324eb88651SRuchika Gupta /* PKCS#11 specification for any asymmetric private key (+any_key_xxx) */
4334eb88651SRuchika Gupta static const uint32_t private_key_boolprops[] = {
43463f89caaSJens Wiklander PKCS11_CKA_DECRYPT, PKCS11_CKA_SIGN, PKCS11_CKA_SIGN_RECOVER,
43563f89caaSJens Wiklander PKCS11_CKA_UNWRAP,
43663f89caaSJens Wiklander PKCS11_CKA_SENSITIVE, PKCS11_CKA_EXTRACTABLE,
43763f89caaSJens Wiklander PKCS11_CKA_WRAP_WITH_TRUSTED, PKCS11_CKA_ALWAYS_AUTHENTICATE,
43863f89caaSJens Wiklander };
43963f89caaSJens Wiklander
4404eb88651SRuchika Gupta static const uint32_t private_key_mandated[] = {
44163f89caaSJens Wiklander };
44263f89caaSJens Wiklander
4434eb88651SRuchika Gupta static const uint32_t private_key_opt_or_null[] = {
444edd95148SVesa Jääskeläinen PKCS11_CKA_SUBJECT, PKCS11_CKA_UNWRAP_TEMPLATE,
445edd95148SVesa Jääskeläinen PKCS11_CKA_PUBLIC_KEY_INFO,
44663f89caaSJens Wiklander };
44763f89caaSJens Wiklander
4484eb88651SRuchika Gupta /* PKCS#11 specification for any RSA key (+public/private_key_xxx) */
4499cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_gen_mand[] = {
45063f89caaSJens Wiklander PKCS11_CKA_MODULUS_BITS,
45163f89caaSJens Wiklander };
45263f89caaSJens Wiklander
4539cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_create_mand[] = {
45463f89caaSJens Wiklander PKCS11_CKA_MODULUS, PKCS11_CKA_PUBLIC_EXPONENT,
45563f89caaSJens Wiklander };
45663f89caaSJens Wiklander
4579cf1afceSVesa Jääskeläinen static const uint32_t rsa_pub_key_gen_opt_or_null[] = {
4589cf1afceSVesa Jääskeläinen PKCS11_CKA_PUBLIC_EXPONENT,
4599cf1afceSVesa Jääskeläinen };
4609cf1afceSVesa Jääskeläinen
4619cf1afceSVesa Jääskeläinen static const uint32_t rsa_priv_key_opt_or_null[] = {
46263f89caaSJens Wiklander PKCS11_CKA_MODULUS, PKCS11_CKA_PUBLIC_EXPONENT,
46363f89caaSJens Wiklander PKCS11_CKA_PRIVATE_EXPONENT,
46463f89caaSJens Wiklander PKCS11_CKA_PRIME_1, PKCS11_CKA_PRIME_2,
46563f89caaSJens Wiklander PKCS11_CKA_EXPONENT_1, PKCS11_CKA_EXPONENT_2, PKCS11_CKA_COEFFICIENT,
46663f89caaSJens Wiklander };
46763f89caaSJens Wiklander
4684eb88651SRuchika Gupta /* PKCS#11 specification for any EC key (+public/private_key_xxx) */
4694eb88651SRuchika Gupta static const uint32_t ec_public_key_mandated[] = {
47063f89caaSJens Wiklander PKCS11_CKA_EC_PARAMS,
47163f89caaSJens Wiklander };
47263f89caaSJens Wiklander
4734eb88651SRuchika Gupta static const uint32_t ec_public_key_opt_or_null[] = {
47463f89caaSJens Wiklander PKCS11_CKA_EC_POINT,
47563f89caaSJens Wiklander };
47663f89caaSJens Wiklander
4774eb88651SRuchika Gupta static const uint32_t ec_private_key_mandated[] = {
47863f89caaSJens Wiklander };
47963f89caaSJens Wiklander
4804eb88651SRuchika Gupta static const uint32_t ec_private_key_opt_or_null[] = {
48102b16804SVesa Jääskeläinen PKCS11_CKA_EC_PARAMS,
48263f89caaSJens Wiklander PKCS11_CKA_VALUE,
48363f89caaSJens Wiklander };
48463f89caaSJens Wiklander
48503e07432SValerii Chubar static const uint32_t eddsa_private_key_opt_or_null[] = {
48603e07432SValerii Chubar PKCS11_CKA_EC_PARAMS,
48703e07432SValerii Chubar PKCS11_CKA_VALUE,
48803e07432SValerii Chubar PKCS11_CKA_EC_POINT,
48903e07432SValerii Chubar };
49003e07432SValerii Chubar
create_storage_attributes(struct obj_attrs ** out,struct obj_attrs * temp)49163f89caaSJens Wiklander static enum pkcs11_rc create_storage_attributes(struct obj_attrs **out,
49263f89caaSJens Wiklander struct obj_attrs *temp)
49363f89caaSJens Wiklander {
49463f89caaSJens Wiklander enum pkcs11_class_id class = PKCS11_CKO_UNDEFINED_ID;
49563f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK;
49663f89caaSJens Wiklander
49763f89caaSJens Wiklander rc = init_attributes_head(out);
49863f89caaSJens Wiklander if (rc)
49963f89caaSJens Wiklander return rc;
50063f89caaSJens Wiklander
50163f89caaSJens Wiklander /* Object class is mandatory */
50263f89caaSJens Wiklander class = get_class(temp);
50363f89caaSJens Wiklander if (class == PKCS11_CKO_UNDEFINED_ID) {
50463f89caaSJens Wiklander EMSG("Class attribute not found");
50563f89caaSJens Wiklander
50663f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT;
50763f89caaSJens Wiklander }
50863f89caaSJens Wiklander rc = add_attribute(out, PKCS11_CKA_CLASS, &class, sizeof(uint32_t));
50963f89caaSJens Wiklander if (rc)
51063f89caaSJens Wiklander return rc;
51163f89caaSJens Wiklander
5124eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, any_object_boolprops,
5134eb88651SRuchika Gupta ARRAY_SIZE(any_object_boolprops));
51463f89caaSJens Wiklander if (rc)
51563f89caaSJens Wiklander return rc;
51663f89caaSJens Wiklander
5174eb88651SRuchika Gupta return set_attributes_opt_or_null(out, temp, any_object_opt_or_null,
5184eb88651SRuchika Gupta ARRAY_SIZE(any_object_opt_or_null));
51963f89caaSJens Wiklander }
52063f89caaSJens Wiklander
create_genkey_attributes(struct obj_attrs ** out,struct obj_attrs * temp)52163f89caaSJens Wiklander static enum pkcs11_rc create_genkey_attributes(struct obj_attrs **out,
52263f89caaSJens Wiklander struct obj_attrs *temp)
52363f89caaSJens Wiklander {
52463f89caaSJens Wiklander uint32_t type = PKCS11_CKO_UNDEFINED_ID;
52563f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK;
52663f89caaSJens Wiklander
52763f89caaSJens Wiklander rc = create_storage_attributes(out, temp);
52863f89caaSJens Wiklander if (rc)
52963f89caaSJens Wiklander return rc;
53063f89caaSJens Wiklander
53163f89caaSJens Wiklander type = get_key_type(temp);
53263f89caaSJens Wiklander if (type == PKCS11_CKK_UNDEFINED_ID) {
53363f89caaSJens Wiklander EMSG("Key type attribute not found");
53463f89caaSJens Wiklander
53563f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT;
53663f89caaSJens Wiklander }
53763f89caaSJens Wiklander rc = add_attribute(out, PKCS11_CKA_KEY_TYPE, &type, sizeof(uint32_t));
53863f89caaSJens Wiklander if (rc)
53963f89caaSJens Wiklander return rc;
54063f89caaSJens Wiklander
5414eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, any_key_boolprops,
5424eb88651SRuchika Gupta ARRAY_SIZE(any_key_boolprops));
54363f89caaSJens Wiklander if (rc)
54463f89caaSJens Wiklander return rc;
54563f89caaSJens Wiklander
5464eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, any_key_opt_or_null,
5474eb88651SRuchika Gupta ARRAY_SIZE(any_key_opt_or_null));
5484eb88651SRuchika Gupta if (rc)
5494eb88651SRuchika Gupta return rc;
5504eb88651SRuchika Gupta
5514eb88651SRuchika Gupta return set_optional_attributes(out, temp, any_key_optional,
5524eb88651SRuchika Gupta ARRAY_SIZE(any_key_optional));
5534eb88651SRuchika Gupta
55463f89caaSJens Wiklander }
55563f89caaSJens Wiklander
create_symm_key_attributes(struct obj_attrs ** out,struct obj_attrs * temp)55663f89caaSJens Wiklander static enum pkcs11_rc create_symm_key_attributes(struct obj_attrs **out,
55763f89caaSJens Wiklander struct obj_attrs *temp)
55863f89caaSJens Wiklander {
55963f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK;
56063f89caaSJens Wiklander
56163f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_SECRET_KEY);
56263f89caaSJens Wiklander
56363f89caaSJens Wiklander rc = create_genkey_attributes(out, temp);
56463f89caaSJens Wiklander if (rc)
56563f89caaSJens Wiklander return rc;
56663f89caaSJens Wiklander
56763f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_SECRET_KEY);
56863f89caaSJens Wiklander
56963f89caaSJens Wiklander switch (get_key_type(*out)) {
57063f89caaSJens Wiklander case PKCS11_CKK_GENERIC_SECRET:
57163f89caaSJens Wiklander case PKCS11_CKK_AES:
57263f89caaSJens Wiklander case PKCS11_CKK_MD5_HMAC:
57363f89caaSJens Wiklander case PKCS11_CKK_SHA_1_HMAC:
57463f89caaSJens Wiklander case PKCS11_CKK_SHA256_HMAC:
57563f89caaSJens Wiklander case PKCS11_CKK_SHA384_HMAC:
57663f89caaSJens Wiklander case PKCS11_CKK_SHA512_HMAC:
57763f89caaSJens Wiklander case PKCS11_CKK_SHA224_HMAC:
57863f89caaSJens Wiklander break;
57963f89caaSJens Wiklander default:
58063f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s",
58163f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out)));
58263f89caaSJens Wiklander
58363f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT;
58463f89caaSJens Wiklander }
58563f89caaSJens Wiklander
5864eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, symm_key_boolprops,
5874eb88651SRuchika Gupta ARRAY_SIZE(symm_key_boolprops));
58863f89caaSJens Wiklander if (rc)
58963f89caaSJens Wiklander return rc;
59063f89caaSJens Wiklander
5910ac5c695SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, symm_key_opt_or_null,
5924eb88651SRuchika Gupta ARRAY_SIZE(symm_key_opt_or_null));
5930ac5c695SRuchika Gupta if (rc)
5940ac5c695SRuchika Gupta return rc;
5950ac5c695SRuchika Gupta
5960ac5c695SRuchika Gupta return set_optional_attributes(out, temp, symm_key_optional,
5970ac5c695SRuchika Gupta ARRAY_SIZE(symm_key_optional));
59863f89caaSJens Wiklander }
59963f89caaSJens Wiklander
create_data_attributes(struct obj_attrs ** out,struct obj_attrs * temp)60063f89caaSJens Wiklander static enum pkcs11_rc create_data_attributes(struct obj_attrs **out,
60163f89caaSJens Wiklander struct obj_attrs *temp)
60263f89caaSJens Wiklander {
60363f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK;
60463f89caaSJens Wiklander
60563f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_DATA);
60663f89caaSJens Wiklander
60763f89caaSJens Wiklander rc = create_storage_attributes(out, temp);
60863f89caaSJens Wiklander if (rc)
60963f89caaSJens Wiklander return rc;
61063f89caaSJens Wiklander
61163f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_DATA);
61263f89caaSJens Wiklander
6134eb88651SRuchika Gupta return set_attributes_opt_or_null(out, temp, raw_data_opt_or_null,
6144eb88651SRuchika Gupta ARRAY_SIZE(raw_data_opt_or_null));
61563f89caaSJens Wiklander }
61663f89caaSJens Wiklander
create_certificate_attributes(struct obj_attrs ** out,struct obj_attrs * temp)6174137952dSVesa Jääskeläinen static enum pkcs11_rc create_certificate_attributes(struct obj_attrs **out,
6184137952dSVesa Jääskeläinen struct obj_attrs *temp)
6194137952dSVesa Jääskeläinen {
6204137952dSVesa Jääskeläinen uint32_t const *mandated = NULL;
6214137952dSVesa Jääskeläinen uint32_t const *optional = NULL;
6224137952dSVesa Jääskeläinen size_t mandated_count = 0;
6234137952dSVesa Jääskeläinen size_t optional_count = 0;
6244137952dSVesa Jääskeläinen void *attr_value = NULL;
6254137952dSVesa Jääskeläinen uint32_t attr_size = 0;
6264137952dSVesa Jääskeläinen uint32_t default_cert_category =
6274137952dSVesa Jääskeläinen PKCS11_CK_CERTIFICATE_CATEGORY_UNSPECIFIED;
6284137952dSVesa Jääskeläinen uint32_t default_name_hash_alg = PKCS11_CKM_SHA_1;
6294137952dSVesa Jääskeläinen uint32_t cert_category = 0;
6304137952dSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_OK;
6314137952dSVesa Jääskeläinen
6324137952dSVesa Jääskeläinen assert(get_class(temp) == PKCS11_CKO_CERTIFICATE);
6334137952dSVesa Jääskeläinen
6344137952dSVesa Jääskeläinen rc = create_storage_attributes(out, temp);
6354137952dSVesa Jääskeläinen if (rc)
6364137952dSVesa Jääskeläinen return rc;
6374137952dSVesa Jääskeläinen
6384137952dSVesa Jääskeläinen assert(get_class(*out) == PKCS11_CKO_CERTIFICATE);
6394137952dSVesa Jääskeläinen
6404137952dSVesa Jääskeläinen rc = set_mandatory_boolprops(out, temp, pkcs11_certificate_boolprops,
6414137952dSVesa Jääskeläinen ARRAY_SIZE(pkcs11_certificate_boolprops));
6424137952dSVesa Jääskeläinen if (rc)
6434137952dSVesa Jääskeläinen return rc;
6444137952dSVesa Jääskeläinen
6454137952dSVesa Jääskeläinen rc = set_mandatory_attributes(out, temp, pkcs11_certificate_mandated,
6464137952dSVesa Jääskeläinen ARRAY_SIZE(pkcs11_certificate_mandated));
6474137952dSVesa Jääskeläinen if (rc)
6484137952dSVesa Jääskeläinen return rc;
6494137952dSVesa Jääskeläinen
6504137952dSVesa Jääskeläinen rc = set_optional_attributes(out, temp, pkcs11_certificate_optional,
6514137952dSVesa Jääskeläinen ARRAY_SIZE(pkcs11_certificate_optional));
6524137952dSVesa Jääskeläinen if (rc)
6534137952dSVesa Jääskeläinen return rc;
6544137952dSVesa Jääskeläinen
6554137952dSVesa Jääskeläinen switch (get_certificate_type(*out)) {
6564137952dSVesa Jääskeläinen case PKCS11_CKC_X_509:
6574137952dSVesa Jääskeläinen mandated = pkcs11_x509_certificate_mandated;
6584137952dSVesa Jääskeläinen optional = pkcs11_x509_certificate_optional;
6594137952dSVesa Jääskeläinen mandated_count = ARRAY_SIZE(pkcs11_x509_certificate_mandated);
6604137952dSVesa Jääskeläinen optional_count = ARRAY_SIZE(pkcs11_x509_certificate_optional);
6614137952dSVesa Jääskeläinen break;
6624137952dSVesa Jääskeläinen default:
6634137952dSVesa Jääskeläinen EMSG("Invalid certificate type %#"PRIx32"/%s",
6644137952dSVesa Jääskeläinen get_certificate_type(*out),
6654137952dSVesa Jääskeläinen id2str_certificate_type(get_certificate_type(*out)));
6664137952dSVesa Jääskeläinen
6674137952dSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT;
6684137952dSVesa Jääskeläinen }
6694137952dSVesa Jääskeläinen
6704137952dSVesa Jääskeläinen rc = set_mandatory_attributes(out, temp, mandated, mandated_count);
6714137952dSVesa Jääskeläinen if (rc)
6724137952dSVesa Jääskeläinen return rc;
6734137952dSVesa Jääskeläinen
6744137952dSVesa Jääskeläinen rc = set_optional_attributes(out, temp, optional, optional_count);
6754137952dSVesa Jääskeläinen if (rc)
6764137952dSVesa Jääskeläinen return rc;
6774137952dSVesa Jääskeläinen
6784137952dSVesa Jääskeläinen attr_size = 0;
6794137952dSVesa Jääskeläinen rc = get_attribute_ptr(*out, PKCS11_CKA_CERTIFICATE_CATEGORY,
6804137952dSVesa Jääskeläinen &attr_value, &attr_size);
6814137952dSVesa Jääskeläinen if (rc == PKCS11_CKR_OK && attr_size == sizeof(cert_category)) {
6824137952dSVesa Jääskeläinen /* Sanitize certificate category */
6834137952dSVesa Jääskeläinen TEE_MemMove(&cert_category, attr_value, sizeof(cert_category));
6844137952dSVesa Jääskeläinen
6854137952dSVesa Jääskeläinen switch (cert_category) {
6864137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_UNSPECIFIED:
6874137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_TOKEN_USER:
6884137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_AUTHORITY:
6894137952dSVesa Jääskeläinen case PKCS11_CK_CERTIFICATE_CATEGORY_OTHER_ENTITY:
6904137952dSVesa Jääskeläinen break;
6914137952dSVesa Jääskeläinen default:
6924137952dSVesa Jääskeläinen EMSG("Invalid certificate category %#"PRIx32,
6934137952dSVesa Jääskeläinen cert_category);
6944137952dSVesa Jääskeläinen
6954137952dSVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID;
6964137952dSVesa Jääskeläinen }
6974137952dSVesa Jääskeläinen } else if (rc == PKCS11_RV_NOT_FOUND) {
6984137952dSVesa Jääskeläinen /* Set default category when missing */
6994137952dSVesa Jääskeläinen rc = set_attribute(out, PKCS11_CKA_CERTIFICATE_CATEGORY,
7004137952dSVesa Jääskeläinen &default_cert_category,
7014137952dSVesa Jääskeläinen sizeof(default_cert_category));
7024137952dSVesa Jääskeläinen if (rc)
7034137952dSVesa Jääskeläinen return rc;
7044137952dSVesa Jääskeläinen } else {
7054137952dSVesa Jääskeläinen /* All other cases are errors */
7064137952dSVesa Jääskeläinen EMSG("Invalid certificate category");
7074137952dSVesa Jääskeläinen
7084137952dSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT;
7094137952dSVesa Jääskeläinen }
7104137952dSVesa Jääskeläinen
7114137952dSVesa Jääskeläinen attr_size = 0;
7124137952dSVesa Jääskeläinen rc = get_attribute_ptr(*out, PKCS11_CKA_NAME_HASH_ALGORITHM, NULL,
7134137952dSVesa Jääskeläinen &attr_size);
7144137952dSVesa Jääskeläinen if (rc == PKCS11_CKR_OK && attr_size == sizeof(uint32_t)) {
7154137952dSVesa Jääskeläinen /* We accept any algorithm what caller wanted to specify */
7164137952dSVesa Jääskeläinen } else if (rc == PKCS11_RV_NOT_FOUND) {
7174137952dSVesa Jääskeläinen /* Set default hash algorithm when missing */
7184137952dSVesa Jääskeläinen rc = set_attribute(out, PKCS11_CKA_NAME_HASH_ALGORITHM,
7194137952dSVesa Jääskeläinen &default_name_hash_alg,
7204137952dSVesa Jääskeläinen sizeof(default_name_hash_alg));
7214137952dSVesa Jääskeläinen if (rc)
7224137952dSVesa Jääskeläinen return rc;
7234137952dSVesa Jääskeläinen } else {
7244137952dSVesa Jääskeläinen /* All other cases are errors */
7254137952dSVesa Jääskeläinen EMSG("Invalid name hash algorithm");
7264137952dSVesa Jääskeläinen
7274137952dSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT;
7284137952dSVesa Jääskeläinen }
7294137952dSVesa Jääskeläinen
7304137952dSVesa Jääskeläinen return rc;
7314137952dSVesa Jääskeläinen }
7324137952dSVesa Jääskeläinen
create_pub_key_attributes(struct obj_attrs ** out,struct obj_attrs * temp,enum processing_func function)73363f89caaSJens Wiklander static enum pkcs11_rc create_pub_key_attributes(struct obj_attrs **out,
7349cf1afceSVesa Jääskeläinen struct obj_attrs *temp,
7359cf1afceSVesa Jääskeläinen enum processing_func function)
73663f89caaSJens Wiklander {
73763f89caaSJens Wiklander uint32_t const *mandated = NULL;
7389cf1afceSVesa Jääskeläinen uint32_t const *oon = NULL;
73963f89caaSJens Wiklander size_t mandated_count = 0;
7409cf1afceSVesa Jääskeläinen size_t oon_count = 0;
74163f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK;
74263f89caaSJens Wiklander
74363f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_PUBLIC_KEY);
74463f89caaSJens Wiklander
74563f89caaSJens Wiklander rc = create_genkey_attributes(out, temp);
74663f89caaSJens Wiklander if (rc)
74763f89caaSJens Wiklander return rc;
74863f89caaSJens Wiklander
74963f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_PUBLIC_KEY);
75063f89caaSJens Wiklander
7514eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, public_key_boolprops,
7524eb88651SRuchika Gupta ARRAY_SIZE(public_key_boolprops));
75363f89caaSJens Wiklander if (rc)
75463f89caaSJens Wiklander return rc;
75563f89caaSJens Wiklander
7564eb88651SRuchika Gupta rc = set_mandatory_attributes(out, temp, public_key_mandated,
7574eb88651SRuchika Gupta ARRAY_SIZE(public_key_mandated));
75863f89caaSJens Wiklander if (rc)
75963f89caaSJens Wiklander return rc;
76063f89caaSJens Wiklander
7614eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp,
7624eb88651SRuchika Gupta public_key_opt_or_null,
7634eb88651SRuchika Gupta ARRAY_SIZE(public_key_opt_or_null));
76463f89caaSJens Wiklander if (rc)
76563f89caaSJens Wiklander return rc;
76663f89caaSJens Wiklander
76763f89caaSJens Wiklander switch (get_key_type(*out)) {
76863f89caaSJens Wiklander case PKCS11_CKK_RSA:
7699cf1afceSVesa Jääskeläinen switch (function) {
7709cf1afceSVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR:
7719cf1afceSVesa Jääskeläinen mandated = rsa_pub_key_gen_mand;
7729cf1afceSVesa Jääskeläinen oon = rsa_pub_key_gen_opt_or_null;
7739cf1afceSVesa Jääskeläinen mandated_count = ARRAY_SIZE(rsa_pub_key_gen_mand);
7749cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(rsa_pub_key_gen_opt_or_null);
7759cf1afceSVesa Jääskeläinen break;
7769cf1afceSVesa Jääskeläinen case PKCS11_FUNCTION_IMPORT:
7779cf1afceSVesa Jääskeläinen mandated = rsa_pub_key_create_mand;
7789cf1afceSVesa Jääskeläinen mandated_count = ARRAY_SIZE(rsa_pub_key_create_mand);
7799cf1afceSVesa Jääskeläinen break;
7809cf1afceSVesa Jääskeläinen default:
7819cf1afceSVesa Jääskeläinen EMSG("Unsupported function %#"PRIx32"/%s", function,
7829cf1afceSVesa Jääskeläinen id2str_function(function));
7839cf1afceSVesa Jääskeläinen
7849cf1afceSVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT;
7859cf1afceSVesa Jääskeläinen }
78663f89caaSJens Wiklander break;
78763f89caaSJens Wiklander case PKCS11_CKK_EC:
78803e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS:
7894eb88651SRuchika Gupta mandated = ec_public_key_mandated;
7909cf1afceSVesa Jääskeläinen oon = ec_public_key_opt_or_null;
7914eb88651SRuchika Gupta mandated_count = ARRAY_SIZE(ec_public_key_mandated);
7929cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(ec_public_key_opt_or_null);
79363f89caaSJens Wiklander break;
79463f89caaSJens Wiklander default:
79563f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s",
79663f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out)));
79763f89caaSJens Wiklander
79863f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT;
79963f89caaSJens Wiklander }
80063f89caaSJens Wiklander
80163f89caaSJens Wiklander rc = set_mandatory_attributes(out, temp, mandated, mandated_count);
80263f89caaSJens Wiklander if (rc)
80363f89caaSJens Wiklander return rc;
80463f89caaSJens Wiklander
8059cf1afceSVesa Jääskeläinen return set_attributes_opt_or_null(out, temp, oon, oon_count);
80663f89caaSJens Wiklander }
80763f89caaSJens Wiklander
8085071d7d1SVesa Jääskeläinen static enum pkcs11_rc
create_pub_key_rsa_generated_attributes(struct obj_attrs ** out,struct obj_attrs * temp,enum processing_func function)8095071d7d1SVesa Jääskeläinen create_pub_key_rsa_generated_attributes(struct obj_attrs **out,
8105071d7d1SVesa Jääskeläinen struct obj_attrs *temp,
8115071d7d1SVesa Jääskeläinen enum processing_func function)
8125071d7d1SVesa Jääskeläinen {
8135071d7d1SVesa Jääskeläinen uint32_t key_bits = 0;
8145071d7d1SVesa Jääskeläinen void *a_ptr = NULL;
8155071d7d1SVesa Jääskeläinen uint32_t a_size = 0;
8165071d7d1SVesa Jääskeläinen
8175071d7d1SVesa Jääskeläinen if (function != PKCS11_FUNCTION_IMPORT)
8185071d7d1SVesa Jääskeläinen return PKCS11_CKR_OK;
8195071d7d1SVesa Jääskeläinen
8205071d7d1SVesa Jääskeläinen /* Calculate CKA_MODULUS_BITS */
8215071d7d1SVesa Jääskeläinen
8225071d7d1SVesa Jääskeläinen if (get_attribute_ptr(temp, PKCS11_CKA_MODULUS,
8235071d7d1SVesa Jääskeläinen &a_ptr, &a_size) || !a_ptr) {
8245071d7d1SVesa Jääskeläinen EMSG("No CKA_MODULUS attribute found in public key");
8255071d7d1SVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
8265071d7d1SVesa Jääskeläinen }
8275071d7d1SVesa Jääskeläinen
8285071d7d1SVesa Jääskeläinen key_bits = a_size * 8;
8295071d7d1SVesa Jääskeläinen
8305071d7d1SVesa Jääskeläinen return add_attribute(out, PKCS11_CKA_MODULUS_BITS, &key_bits,
8315071d7d1SVesa Jääskeläinen sizeof(key_bits));
8325071d7d1SVesa Jääskeläinen }
8335071d7d1SVesa Jääskeläinen
8345071d7d1SVesa Jääskeläinen static enum pkcs11_rc
create_pub_key_generated_attributes(struct obj_attrs ** out,struct obj_attrs * temp,enum processing_func function)8355071d7d1SVesa Jääskeläinen create_pub_key_generated_attributes(struct obj_attrs **out,
8365071d7d1SVesa Jääskeläinen struct obj_attrs *temp,
8375071d7d1SVesa Jääskeläinen enum processing_func function)
8385071d7d1SVesa Jääskeläinen {
8395071d7d1SVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_OK;
8405071d7d1SVesa Jääskeläinen
8415071d7d1SVesa Jääskeläinen switch (get_key_type(*out)) {
8425071d7d1SVesa Jääskeläinen case PKCS11_CKK_RSA:
8435071d7d1SVesa Jääskeläinen rc = create_pub_key_rsa_generated_attributes(out, temp,
8445071d7d1SVesa Jääskeläinen function);
8455071d7d1SVesa Jääskeläinen break;
8465071d7d1SVesa Jääskeläinen default:
8475071d7d1SVesa Jääskeläinen /* no-op */
8485071d7d1SVesa Jääskeläinen break;
8495071d7d1SVesa Jääskeläinen }
8505071d7d1SVesa Jääskeläinen
8515071d7d1SVesa Jääskeläinen return rc;
8525071d7d1SVesa Jääskeläinen }
8535071d7d1SVesa Jääskeläinen
create_priv_key_attributes(struct obj_attrs ** out,struct obj_attrs * temp)85463f89caaSJens Wiklander static enum pkcs11_rc create_priv_key_attributes(struct obj_attrs **out,
85563f89caaSJens Wiklander struct obj_attrs *temp)
85663f89caaSJens Wiklander {
85763f89caaSJens Wiklander uint32_t const *mandated = NULL;
8589cf1afceSVesa Jääskeläinen uint32_t const *oon = NULL;
85963f89caaSJens Wiklander size_t mandated_count = 0;
8609cf1afceSVesa Jääskeläinen size_t oon_count = 0;
86163f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK;
86263f89caaSJens Wiklander
86363f89caaSJens Wiklander assert(get_class(temp) == PKCS11_CKO_PRIVATE_KEY);
86463f89caaSJens Wiklander
86563f89caaSJens Wiklander rc = create_genkey_attributes(out, temp);
86663f89caaSJens Wiklander if (rc)
86763f89caaSJens Wiklander return rc;
86863f89caaSJens Wiklander
86963f89caaSJens Wiklander assert(get_class(*out) == PKCS11_CKO_PRIVATE_KEY);
87063f89caaSJens Wiklander
8714eb88651SRuchika Gupta rc = set_mandatory_boolprops(out, temp, private_key_boolprops,
8724eb88651SRuchika Gupta ARRAY_SIZE(private_key_boolprops));
87363f89caaSJens Wiklander if (rc)
87463f89caaSJens Wiklander return rc;
87563f89caaSJens Wiklander
8764eb88651SRuchika Gupta rc = set_mandatory_attributes(out, temp, private_key_mandated,
8774eb88651SRuchika Gupta ARRAY_SIZE(private_key_mandated));
87863f89caaSJens Wiklander if (rc)
87963f89caaSJens Wiklander return rc;
88063f89caaSJens Wiklander
8814eb88651SRuchika Gupta rc = set_attributes_opt_or_null(out, temp, private_key_opt_or_null,
8824eb88651SRuchika Gupta ARRAY_SIZE(private_key_opt_or_null));
88363f89caaSJens Wiklander if (rc)
88463f89caaSJens Wiklander return rc;
88563f89caaSJens Wiklander
88663f89caaSJens Wiklander switch (get_key_type(*out)) {
88763f89caaSJens Wiklander case PKCS11_CKK_RSA:
8889cf1afceSVesa Jääskeläinen oon = rsa_priv_key_opt_or_null;
8899cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(rsa_priv_key_opt_or_null);
89063f89caaSJens Wiklander break;
89163f89caaSJens Wiklander case PKCS11_CKK_EC:
8924eb88651SRuchika Gupta mandated = ec_private_key_mandated;
8939cf1afceSVesa Jääskeläinen oon = ec_private_key_opt_or_null;
8944eb88651SRuchika Gupta mandated_count = ARRAY_SIZE(ec_private_key_mandated);
8959cf1afceSVesa Jääskeläinen oon_count = ARRAY_SIZE(ec_private_key_opt_or_null);
89663f89caaSJens Wiklander break;
89703e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS:
89803e07432SValerii Chubar mandated = ec_private_key_mandated;
89903e07432SValerii Chubar oon = eddsa_private_key_opt_or_null;
90003e07432SValerii Chubar mandated_count = ARRAY_SIZE(ec_private_key_mandated);
90103e07432SValerii Chubar oon_count = ARRAY_SIZE(eddsa_private_key_opt_or_null);
90203e07432SValerii Chubar break;
90363f89caaSJens Wiklander default:
90463f89caaSJens Wiklander EMSG("Invalid key type %#"PRIx32"/%s",
90563f89caaSJens Wiklander get_key_type(*out), id2str_key_type(get_key_type(*out)));
90663f89caaSJens Wiklander
90763f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT;
90863f89caaSJens Wiklander }
90963f89caaSJens Wiklander
91063f89caaSJens Wiklander rc = set_mandatory_attributes(out, temp, mandated, mandated_count);
91163f89caaSJens Wiklander if (rc)
91263f89caaSJens Wiklander return rc;
91363f89caaSJens Wiklander
9149cf1afceSVesa Jääskeläinen return set_attributes_opt_or_null(out, temp, oon, oon_count);
91563f89caaSJens Wiklander }
91663f89caaSJens Wiklander
mbd_rand(void * rng_state __unused,unsigned char * output,size_t len)91732b31808SJens Wiklander static int mbd_rand(void *rng_state __unused, unsigned char *output, size_t len)
91832b31808SJens Wiklander {
91932b31808SJens Wiklander TEE_GenerateRandom(output, len);
92032b31808SJens Wiklander return 0;
92132b31808SJens Wiklander }
92232b31808SJens Wiklander
923196bcd93SRuchika Gupta static enum pkcs11_rc
create_ec_priv_key_hidden_attributes(struct obj_attrs ** out,struct obj_attrs * temp,enum processing_func function)9247c243321SVesa Jääskeläinen create_ec_priv_key_hidden_attributes(struct obj_attrs **out,
9257c243321SVesa Jääskeläinen struct obj_attrs *temp,
9267c243321SVesa Jääskeläinen enum processing_func function)
9277c243321SVesa Jääskeläinen {
9287c243321SVesa Jääskeläinen struct mbedtls_ecp_keypair key_pair = { };
9297c243321SVesa Jääskeläinen mbedtls_ecp_group_id ec_curve = MBEDTLS_ECP_DP_NONE;
93032b31808SJens Wiklander mbedtls_ecp_group key_pair_grp = { };
93132b31808SJens Wiklander mbedtls_ecp_point key_pair_Q = { };
93232b31808SJens Wiklander mbedtls_mpi key_pair_d = { };
9337c243321SVesa Jääskeläinen size_t buflen = 0;
9347c243321SVesa Jääskeläinen uint8_t *buf = NULL;
9357c243321SVesa Jääskeläinen size_t asnbuflen = 0;
9367c243321SVesa Jääskeläinen uint8_t *asnbuf = NULL;
9377c243321SVesa Jääskeläinen uint8_t *ptr = NULL;
9387c243321SVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
9397c243321SVesa Jääskeläinen int tee_size = 0;
9407c243321SVesa Jääskeläinen int tee_curve = 0;
9417c243321SVesa Jääskeläinen void *a_ptr = NULL;
9427c243321SVesa Jääskeläinen uint32_t a_size = 0;
9437c243321SVesa Jääskeläinen int ret = 0;
9447c243321SVesa Jääskeläinen
9457c243321SVesa Jääskeläinen if (function != PKCS11_FUNCTION_IMPORT)
9467c243321SVesa Jääskeläinen return PKCS11_CKR_OK;
9477c243321SVesa Jääskeläinen
9487c243321SVesa Jääskeläinen /*
9497c243321SVesa Jääskeläinen * TEE internal API requires that for private key operations there
9507c243321SVesa Jääskeläinen * needs to be also public key available.
9517c243321SVesa Jääskeläinen *
9527c243321SVesa Jääskeläinen * Generate hidden EC point from private key.
9537c243321SVesa Jääskeläinen */
9547c243321SVesa Jääskeläinen
9557c243321SVesa Jääskeläinen if (get_attribute_ptr(temp, PKCS11_CKA_EC_PARAMS,
9567c243321SVesa Jääskeläinen &a_ptr, &a_size) || !a_ptr) {
9577c243321SVesa Jääskeläinen EMSG("No EC_PARAMS attribute found in private key");
9587c243321SVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
9597c243321SVesa Jääskeläinen }
9607c243321SVesa Jääskeläinen
9617c243321SVesa Jääskeläinen /* Just valdiate that curve is found */
9627c243321SVesa Jääskeläinen tee_size = ec_params2tee_keysize(a_ptr, a_size);
9637c243321SVesa Jääskeläinen if (!tee_size) {
9647c243321SVesa Jääskeläinen EMSG("Unsupported EC_PARAMS curve");
9657c243321SVesa Jääskeläinen return PKCS11_CKR_CURVE_NOT_SUPPORTED;
9667c243321SVesa Jääskeläinen }
9677c243321SVesa Jääskeläinen
9687c243321SVesa Jääskeläinen tee_curve = ec_params2tee_curve(a_ptr, a_size);
9697c243321SVesa Jääskeläinen
9707c243321SVesa Jääskeläinen switch (tee_curve) {
9717c243321SVesa Jääskeläinen case TEE_ECC_CURVE_NIST_P192:
9727c243321SVesa Jääskeläinen ec_curve = MBEDTLS_ECP_DP_SECP192R1;
9737c243321SVesa Jääskeläinen break;
9747c243321SVesa Jääskeläinen case TEE_ECC_CURVE_NIST_P224:
9757c243321SVesa Jääskeläinen ec_curve = MBEDTLS_ECP_DP_SECP224R1;
9767c243321SVesa Jääskeläinen break;
9777c243321SVesa Jääskeläinen case TEE_ECC_CURVE_NIST_P256:
9787c243321SVesa Jääskeläinen ec_curve = MBEDTLS_ECP_DP_SECP256R1;
9797c243321SVesa Jääskeläinen break;
9807c243321SVesa Jääskeläinen case TEE_ECC_CURVE_NIST_P384:
9817c243321SVesa Jääskeläinen ec_curve = MBEDTLS_ECP_DP_SECP384R1;
9827c243321SVesa Jääskeläinen break;
9837c243321SVesa Jääskeläinen case TEE_ECC_CURVE_NIST_P521:
9847c243321SVesa Jääskeläinen ec_curve = MBEDTLS_ECP_DP_SECP521R1;
9857c243321SVesa Jääskeläinen break;
9867c243321SVesa Jääskeläinen default:
9877c243321SVesa Jääskeläinen EMSG("Failed to map EC_PARAMS to supported curve");
9887c243321SVesa Jääskeläinen return PKCS11_CKR_CURVE_NOT_SUPPORTED;
9897c243321SVesa Jääskeläinen }
9907c243321SVesa Jääskeläinen
9917c243321SVesa Jääskeläinen if (get_attribute_ptr(temp, PKCS11_CKA_VALUE,
9927c243321SVesa Jääskeläinen &a_ptr, &a_size) || !a_ptr) {
9937c243321SVesa Jääskeläinen EMSG("No VALUE attribute found in private key");
9947c243321SVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
9957c243321SVesa Jääskeläinen }
9967c243321SVesa Jääskeläinen
9977c243321SVesa Jääskeläinen mbedtls_ecp_keypair_init(&key_pair);
99832b31808SJens Wiklander mbedtls_ecp_group_init(&key_pair_grp);
99932b31808SJens Wiklander mbedtls_mpi_init(&key_pair_d);
100032b31808SJens Wiklander mbedtls_ecp_point_init(&key_pair_Q);
10017c243321SVesa Jääskeläinen
10027c243321SVesa Jääskeläinen ret = mbedtls_ecp_read_key(ec_curve, &key_pair, a_ptr, a_size);
10037c243321SVesa Jääskeläinen if (ret) {
10047c243321SVesa Jääskeläinen EMSG("Failed to parse CKA_VALUE");
10057c243321SVesa Jääskeläinen rc = PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
10067c243321SVesa Jääskeläinen goto out;
10077c243321SVesa Jääskeläinen }
10087c243321SVesa Jääskeläinen
100932b31808SJens Wiklander ret = mbedtls_ecp_export(&key_pair, &key_pair_grp, &key_pair_d,
101032b31808SJens Wiklander &key_pair_Q);
101132b31808SJens Wiklander if (ret) {
101232b31808SJens Wiklander EMSG("Failed to export key");
101332b31808SJens Wiklander goto out;
101432b31808SJens Wiklander }
101532b31808SJens Wiklander
101632b31808SJens Wiklander ret = mbedtls_ecp_mul(&key_pair_grp, &key_pair_Q, &key_pair_d,
101732b31808SJens Wiklander &key_pair_grp.G, mbd_rand, NULL);
10187c243321SVesa Jääskeläinen if (ret) {
10197c243321SVesa Jääskeläinen EMSG("Failed to create public key");
10207c243321SVesa Jääskeläinen goto out;
10217c243321SVesa Jääskeläinen }
10227c243321SVesa Jääskeläinen
102332b31808SJens Wiklander ret = mbedtls_ecp_check_privkey(&key_pair_grp, &key_pair_d);
10247c243321SVesa Jääskeläinen if (ret) {
10257c243321SVesa Jääskeläinen EMSG("Failed to verify private key");
10267c243321SVesa Jääskeläinen goto out;
10277c243321SVesa Jääskeläinen }
10287c243321SVesa Jääskeläinen
102932b31808SJens Wiklander ret = mbedtls_ecp_check_pubkey(&key_pair_grp, &key_pair_Q);
10307c243321SVesa Jääskeläinen if (ret) {
10317c243321SVesa Jääskeläinen EMSG("Failed to verify public key");
10327c243321SVesa Jääskeläinen goto out;
10337c243321SVesa Jääskeläinen }
10347c243321SVesa Jääskeläinen
103532b31808SJens Wiklander ret = mbedtls_ecp_point_write_binary(&key_pair_grp, &key_pair_Q,
10367c243321SVesa Jääskeläinen MBEDTLS_ECP_PF_UNCOMPRESSED,
10377c243321SVesa Jääskeläinen &buflen, NULL, 0);
10387c243321SVesa Jääskeläinen if (ret != MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL) {
10397c243321SVesa Jääskeläinen EMSG("Failed to determine size of binary public key");
10407c243321SVesa Jääskeläinen goto out;
10417c243321SVesa Jääskeläinen }
10427c243321SVesa Jääskeläinen
10437c243321SVesa Jääskeläinen buf = TEE_Malloc(buflen, TEE_MALLOC_FILL_ZERO);
10447c243321SVesa Jääskeläinen if (!buf) {
10457c243321SVesa Jääskeläinen EMSG("Failed to allocate memory for public key");
10467c243321SVesa Jääskeläinen rc = PKCS11_CKR_DEVICE_MEMORY;
10477c243321SVesa Jääskeläinen goto out;
10487c243321SVesa Jääskeläinen }
10497c243321SVesa Jääskeläinen
10507c243321SVesa Jääskeläinen asnbuflen = 1 /* octet string */ + 5 /* length */ + buflen;
10517c243321SVesa Jääskeläinen
10527c243321SVesa Jääskeläinen asnbuf = TEE_Malloc(asnbuflen, TEE_MALLOC_FILL_ZERO);
10537c243321SVesa Jääskeläinen if (!asnbuf) {
10547c243321SVesa Jääskeläinen EMSG("Failed to allocate memory for public key");
10557c243321SVesa Jääskeläinen rc = PKCS11_CKR_DEVICE_MEMORY;
10567c243321SVesa Jääskeläinen goto out;
10577c243321SVesa Jääskeläinen }
10587c243321SVesa Jääskeläinen
105932b31808SJens Wiklander ret = mbedtls_ecp_point_write_binary(&key_pair_grp, &key_pair_Q,
10607c243321SVesa Jääskeläinen MBEDTLS_ECP_PF_UNCOMPRESSED,
10617c243321SVesa Jääskeläinen &buflen, buf, buflen);
10627c243321SVesa Jääskeläinen if (ret) {
10637c243321SVesa Jääskeläinen EMSG("Failed to write binary public key");
10647c243321SVesa Jääskeläinen goto out;
10657c243321SVesa Jääskeläinen }
10667c243321SVesa Jääskeläinen
10677c243321SVesa Jääskeläinen /* Note: ASN.1 writing works backwards */
10687c243321SVesa Jääskeläinen ptr = asnbuf + asnbuflen;
10697c243321SVesa Jääskeläinen
10707c243321SVesa Jääskeläinen ret = mbedtls_asn1_write_octet_string(&ptr, asnbuf, buf, buflen);
10717c243321SVesa Jääskeläinen if (ret < 0) {
10727c243321SVesa Jääskeläinen EMSG("Failed to write asn1 public key");
10737c243321SVesa Jääskeläinen goto out;
10747c243321SVesa Jääskeläinen }
10757c243321SVesa Jääskeläinen
10767c243321SVesa Jääskeläinen rc = add_attribute(out, PKCS11_CKA_OPTEE_HIDDEN_EC_POINT, ptr,
10777c243321SVesa Jääskeläinen (size_t)ret);
10787c243321SVesa Jääskeläinen
10797c243321SVesa Jääskeläinen out:
10807c243321SVesa Jääskeläinen TEE_Free(asnbuf);
10817c243321SVesa Jääskeläinen TEE_Free(buf);
10827c243321SVesa Jääskeläinen mbedtls_ecp_keypair_free(&key_pair);
108332b31808SJens Wiklander mbedtls_ecp_group_free(&key_pair_grp);
108432b31808SJens Wiklander mbedtls_mpi_free(&key_pair_d);
108532b31808SJens Wiklander mbedtls_ecp_point_free(&key_pair_Q);
10867c243321SVesa Jääskeläinen
10877c243321SVesa Jääskeläinen return rc;
10887c243321SVesa Jääskeläinen }
10897c243321SVesa Jääskeläinen
10907c243321SVesa Jääskeläinen static enum pkcs11_rc
create_priv_key_hidden_attributes(struct obj_attrs ** out,struct obj_attrs * temp,enum processing_func function)10917c243321SVesa Jääskeläinen create_priv_key_hidden_attributes(struct obj_attrs **out,
10927c243321SVesa Jääskeläinen struct obj_attrs *temp,
10937c243321SVesa Jääskeläinen enum processing_func function)
10947c243321SVesa Jääskeläinen {
10957c243321SVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_OK;
10967c243321SVesa Jääskeläinen
10977c243321SVesa Jääskeläinen switch (get_key_type(*out)) {
10987c243321SVesa Jääskeläinen case PKCS11_CKK_EC:
10997c243321SVesa Jääskeläinen rc = create_ec_priv_key_hidden_attributes(out, temp, function);
11007c243321SVesa Jääskeläinen break;
11017c243321SVesa Jääskeläinen default:
11027c243321SVesa Jääskeläinen /* no-op */
11037c243321SVesa Jääskeläinen break;
11047c243321SVesa Jääskeläinen }
11057c243321SVesa Jääskeläinen
11067c243321SVesa Jääskeläinen return rc;
11077c243321SVesa Jääskeläinen }
11087c243321SVesa Jääskeläinen
11097c243321SVesa Jääskeläinen static enum pkcs11_rc
sanitize_symm_key_attributes(struct obj_attrs ** temp,enum processing_func function)1110196bcd93SRuchika Gupta sanitize_symm_key_attributes(struct obj_attrs **temp,
1111196bcd93SRuchika Gupta enum processing_func function)
1112196bcd93SRuchika Gupta {
1113196bcd93SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK;
1114196bcd93SRuchika Gupta uint32_t a_size = 0;
1115196bcd93SRuchika Gupta
1116196bcd93SRuchika Gupta assert(get_class(*temp) == PKCS11_CKO_SECRET_KEY);
1117196bcd93SRuchika Gupta
1118196bcd93SRuchika Gupta rc = get_attribute_ptr(*temp, PKCS11_CKA_VALUE, NULL, &a_size);
1119196bcd93SRuchika Gupta
1120196bcd93SRuchika Gupta switch (get_key_type(*temp)) {
1121196bcd93SRuchika Gupta case PKCS11_CKK_GENERIC_SECRET:
1122196bcd93SRuchika Gupta case PKCS11_CKK_AES:
1123196bcd93SRuchika Gupta case PKCS11_CKK_MD5_HMAC:
1124196bcd93SRuchika Gupta case PKCS11_CKK_SHA_1_HMAC:
1125196bcd93SRuchika Gupta case PKCS11_CKK_SHA256_HMAC:
1126196bcd93SRuchika Gupta case PKCS11_CKK_SHA384_HMAC:
1127196bcd93SRuchika Gupta case PKCS11_CKK_SHA512_HMAC:
1128196bcd93SRuchika Gupta case PKCS11_CKK_SHA224_HMAC:
1129196bcd93SRuchika Gupta switch (function) {
1130196bcd93SRuchika Gupta case PKCS11_FUNCTION_IMPORT:
1131196bcd93SRuchika Gupta /* CKA_VALUE is a mandatory with C_CreateObject */
1132196bcd93SRuchika Gupta if (rc || a_size == 0)
1133196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT;
1134196bcd93SRuchika Gupta
1135196bcd93SRuchika Gupta if (get_attribute_ptr(*temp, PKCS11_CKA_VALUE_LEN, NULL,
1136196bcd93SRuchika Gupta NULL) != PKCS11_RV_NOT_FOUND)
1137196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT;
1138196bcd93SRuchika Gupta
1139196bcd93SRuchika Gupta return add_attribute(temp, PKCS11_CKA_VALUE_LEN,
1140196bcd93SRuchika Gupta &a_size, sizeof(uint32_t));
1141196bcd93SRuchika Gupta case PKCS11_FUNCTION_GENERATE:
1142196bcd93SRuchika Gupta if (rc != PKCS11_RV_NOT_FOUND)
1143196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT;
1144196bcd93SRuchika Gupta break;
1145196bcd93SRuchika Gupta default:
1146196bcd93SRuchika Gupta break;
1147196bcd93SRuchika Gupta }
1148196bcd93SRuchika Gupta break;
1149196bcd93SRuchika Gupta default:
1150196bcd93SRuchika Gupta EMSG("Invalid key type %#"PRIx32"/%s",
1151196bcd93SRuchika Gupta get_key_type(*temp), id2str_key_type(get_key_type(*temp)));
1152196bcd93SRuchika Gupta
1153196bcd93SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT;
1154196bcd93SRuchika Gupta }
1155196bcd93SRuchika Gupta
1156196bcd93SRuchika Gupta return PKCS11_CKR_OK;
1157196bcd93SRuchika Gupta }
1158196bcd93SRuchika Gupta
115963f89caaSJens Wiklander /*
116063f89caaSJens Wiklander * Create an attribute list for a new object from a template and a parent
116163f89caaSJens Wiklander * object (optional) for an object generation function (generate, copy,
116263f89caaSJens Wiklander * derive...).
116363f89caaSJens Wiklander *
116463f89caaSJens Wiklander * PKCS#11 directives on the supplied template and expected return value:
116563f89caaSJens Wiklander * - template has an invalid attribute ID: ATTRIBUTE_TYPE_INVALID
116663f89caaSJens Wiklander * - template has an invalid value for an attribute: ATTRIBUTE_VALID_INVALID
116763f89caaSJens Wiklander * - template has value for a read-only attribute: ATTRIBUTE_READ_ONLY
116863f89caaSJens Wiklander * - template+default+parent => still miss an attribute: TEMPLATE_INCONSISTENT
116963f89caaSJens Wiklander *
117063f89caaSJens Wiklander * INFO on PKCS11_CMD_COPY_OBJECT:
117163f89caaSJens Wiklander * - parent PKCS11_CKA_COPYIABLE=false => return ACTION_PROHIBITED.
117263f89caaSJens Wiklander * - template can specify PKCS11_CKA_TOKEN, PKCS11_CKA_PRIVATE,
117363f89caaSJens Wiklander * PKCS11_CKA_MODIFIABLE, PKCS11_CKA_DESTROYABLE.
117463f89caaSJens Wiklander * - SENSITIVE can change from false to true, not from true to false.
117563f89caaSJens Wiklander * - LOCAL is the parent LOCAL
117663f89caaSJens Wiklander */
117763f89caaSJens Wiklander enum pkcs11_rc
create_attributes_from_template(struct obj_attrs ** out,void * template,size_t template_size,struct obj_attrs * parent,enum processing_func function,enum pkcs11_mechanism_id mecha,enum pkcs11_class_id template_class)117863f89caaSJens Wiklander create_attributes_from_template(struct obj_attrs **out, void *template,
117963f89caaSJens Wiklander size_t template_size,
118048799892SRuchika Gupta struct obj_attrs *parent,
118163f89caaSJens Wiklander enum processing_func function,
11824cfce748SRuchika Gupta enum pkcs11_mechanism_id mecha,
118302b16804SVesa Jääskeläinen enum pkcs11_class_id template_class)
118463f89caaSJens Wiklander {
118563f89caaSJens Wiklander struct obj_attrs *temp = NULL;
118663f89caaSJens Wiklander struct obj_attrs *attrs = NULL;
118763f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK;
118863f89caaSJens Wiklander uint8_t local = 0;
118963f89caaSJens Wiklander uint8_t always_sensitive = 0;
119063f89caaSJens Wiklander uint8_t never_extract = 0;
1191e3f0cb56SRuchika Gupta uint8_t extractable = 0;
1192fa247a2aSRuchika Gupta uint32_t class = PKCS11_UNDEFINED_ID;
1193fa247a2aSRuchika Gupta uint32_t type = PKCS11_UNDEFINED_ID;
119463f89caaSJens Wiklander uint32_t mechanism_id = PKCS11_CKM_UNDEFINED_ID;
1195e3f0cb56SRuchika Gupta struct obj_attrs *req_attrs = NULL;
1196e3f0cb56SRuchika Gupta uint32_t size = 0;
1197e3f0cb56SRuchika Gupta uint32_t indirect_template = PKCS11_CKA_UNDEFINED_ID;
119863f89caaSJens Wiklander
119963f89caaSJens Wiklander #ifdef DEBUG /* Sanity: check function argument */
120063f89caaSJens Wiklander trace_attributes_from_api_head("template", template, template_size);
120163f89caaSJens Wiklander switch (function) {
1202fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE:
1203013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR:
120463f89caaSJens Wiklander case PKCS11_FUNCTION_IMPORT:
12052d25a9bcSRuchika Gupta case PKCS11_FUNCTION_MODIFY:
120648799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE:
1207e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP:
12082d25a9bcSRuchika Gupta case PKCS11_FUNCTION_COPY:
120963f89caaSJens Wiklander break;
121063f89caaSJens Wiklander default:
121163f89caaSJens Wiklander TEE_Panic(TEE_ERROR_NOT_SUPPORTED);
121263f89caaSJens Wiklander }
121363f89caaSJens Wiklander #endif
121463f89caaSJens Wiklander
1215dcad3409SRuchika Gupta /*
1216dcad3409SRuchika Gupta * For PKCS11_FUNCTION_GENERATE, find the class and type
1217dcad3409SRuchika Gupta * based on the mechanism. These will be passed as hint
1218dcad3409SRuchika Gupta * sanitize_client_object() and added in temp if not
1219dcad3409SRuchika Gupta * already present
1220dcad3409SRuchika Gupta */
1221dcad3409SRuchika Gupta if (function == PKCS11_FUNCTION_GENERATE) {
1222fa247a2aSRuchika Gupta switch (mecha) {
1223fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN:
1224fa247a2aSRuchika Gupta class = PKCS11_CKO_SECRET_KEY;
1225fa247a2aSRuchika Gupta type = PKCS11_CKK_GENERIC_SECRET;
1226fa247a2aSRuchika Gupta break;
1227fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN:
1228fa247a2aSRuchika Gupta class = PKCS11_CKO_SECRET_KEY;
1229fa247a2aSRuchika Gupta type = PKCS11_CKK_AES;
1230fa247a2aSRuchika Gupta break;
1231fa247a2aSRuchika Gupta default:
1232dcad3409SRuchika Gupta TEE_Panic(TEE_ERROR_NOT_SUPPORTED);
1233fa247a2aSRuchika Gupta }
1234fa247a2aSRuchika Gupta }
1235fa247a2aSRuchika Gupta
12362d25a9bcSRuchika Gupta /*
1237013934d8SVesa Jääskeläinen * For PKCS11_FUNCTION_GENERATE_PAIR, find the class and type
1238013934d8SVesa Jääskeläinen * based on the mechanism. These will be passed as hint
1239013934d8SVesa Jääskeläinen * sanitize_client_object() and added in temp if not
1240013934d8SVesa Jääskeläinen * already present
1241013934d8SVesa Jääskeläinen */
1242013934d8SVesa Jääskeläinen if (function == PKCS11_FUNCTION_GENERATE_PAIR) {
1243013934d8SVesa Jääskeläinen switch (mecha) {
124403e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN:
124503e07432SValerii Chubar class = template_class;
124603e07432SValerii Chubar type = PKCS11_CKK_EDDSA;
124703e07432SValerii Chubar break;
124802b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN:
124902b16804SVesa Jääskeläinen class = template_class;
125002b16804SVesa Jääskeläinen type = PKCS11_CKK_EC;
125102b16804SVesa Jääskeläinen break;
125286922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN:
125386922832SVesa Jääskeläinen class = template_class;
125486922832SVesa Jääskeläinen type = PKCS11_CKK_RSA;
125586922832SVesa Jääskeläinen break;
1256013934d8SVesa Jääskeläinen default:
1257013934d8SVesa Jääskeläinen TEE_Panic(TEE_ERROR_NOT_SUPPORTED);
1258013934d8SVesa Jääskeläinen }
1259013934d8SVesa Jääskeläinen }
1260013934d8SVesa Jääskeläinen
1261013934d8SVesa Jääskeläinen /*
12622d25a9bcSRuchika Gupta * Check and remove duplicates if any and create a new temporary
12632d25a9bcSRuchika Gupta * template
12642d25a9bcSRuchika Gupta */
1265dcad3409SRuchika Gupta rc = sanitize_client_object(&temp, template, template_size, class,
1266dcad3409SRuchika Gupta type);
1267dcad3409SRuchika Gupta if (rc)
1268dcad3409SRuchika Gupta goto out;
1269dcad3409SRuchika Gupta
1270dcad3409SRuchika Gupta /*
12712d25a9bcSRuchika Gupta * For function type modify and copy return the created template
12722d25a9bcSRuchika Gupta * from here. Rest of the code below is for creating objects
12732d25a9bcSRuchika Gupta * or generating keys.
12742d25a9bcSRuchika Gupta */
12752d25a9bcSRuchika Gupta switch (function) {
12762d25a9bcSRuchika Gupta case PKCS11_FUNCTION_MODIFY:
12772d25a9bcSRuchika Gupta case PKCS11_FUNCTION_COPY:
12782d25a9bcSRuchika Gupta *out = temp;
12792d25a9bcSRuchika Gupta return rc;
1280e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_DERIVE:
1281e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP:
1282e3f0cb56SRuchika Gupta if (function == PKCS11_FUNCTION_UNWRAP)
1283e3f0cb56SRuchika Gupta indirect_template = PKCS11_CKA_UNWRAP_TEMPLATE;
1284e3f0cb56SRuchika Gupta else
1285e3f0cb56SRuchika Gupta indirect_template = PKCS11_CKA_DERIVE_TEMPLATE;
1286e3f0cb56SRuchika Gupta
1287e3f0cb56SRuchika Gupta rc = get_attribute_ptr(parent, indirect_template,
1288e3f0cb56SRuchika Gupta (void *)&req_attrs, &size);
1289e3f0cb56SRuchika Gupta if (rc == PKCS11_CKR_OK && size != 0) {
1290e3f0cb56SRuchika Gupta rc = attributes_match_add_reference(&temp, req_attrs);
1291e3f0cb56SRuchika Gupta if (rc)
1292e3f0cb56SRuchika Gupta goto out;
1293e3f0cb56SRuchika Gupta }
1294e3f0cb56SRuchika Gupta break;
12952d25a9bcSRuchika Gupta default:
12962d25a9bcSRuchika Gupta break;
12972d25a9bcSRuchika Gupta }
12982d25a9bcSRuchika Gupta
12992d25a9bcSRuchika Gupta /*
1300dcad3409SRuchika Gupta * Check if class and type in temp are consistent with the mechanism
1301dcad3409SRuchika Gupta */
1302fa247a2aSRuchika Gupta switch (mecha) {
1303fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN:
1304fa247a2aSRuchika Gupta if (get_class(temp) != PKCS11_CKO_SECRET_KEY ||
1305fa247a2aSRuchika Gupta get_key_type(temp) != PKCS11_CKK_GENERIC_SECRET) {
1306fa247a2aSRuchika Gupta rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
1307fa247a2aSRuchika Gupta goto out;
1308fa247a2aSRuchika Gupta }
1309fa247a2aSRuchika Gupta break;
1310fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN:
1311fa247a2aSRuchika Gupta if (get_class(temp) != PKCS11_CKO_SECRET_KEY ||
1312fa247a2aSRuchika Gupta get_key_type(temp) != PKCS11_CKK_AES) {
1313fa247a2aSRuchika Gupta rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
1314fa247a2aSRuchika Gupta goto out;
1315fa247a2aSRuchika Gupta }
1316fa247a2aSRuchika Gupta break;
131702b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN:
131802b16804SVesa Jääskeläinen if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY &&
131902b16804SVesa Jääskeläinen get_class(temp) != PKCS11_CKO_PRIVATE_KEY) ||
132002b16804SVesa Jääskeläinen get_key_type(temp) != PKCS11_CKK_EC) {
132102b16804SVesa Jääskeläinen rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
132202b16804SVesa Jääskeläinen goto out;
132302b16804SVesa Jääskeläinen }
132402b16804SVesa Jääskeläinen break;
132503e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN:
132603e07432SValerii Chubar if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY &&
132703e07432SValerii Chubar get_class(temp) != PKCS11_CKO_PRIVATE_KEY) ||
132803e07432SValerii Chubar get_key_type(temp) != PKCS11_CKK_EC_EDWARDS) {
132903e07432SValerii Chubar rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
133003e07432SValerii Chubar goto out;
133103e07432SValerii Chubar }
133203e07432SValerii Chubar break;
133386922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN:
133486922832SVesa Jääskeläinen if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY &&
133586922832SVesa Jääskeläinen get_class(temp) != PKCS11_CKO_PRIVATE_KEY) ||
133686922832SVesa Jääskeläinen get_key_type(temp) != PKCS11_CKK_RSA) {
133786922832SVesa Jääskeläinen rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
133886922832SVesa Jääskeläinen goto out;
133986922832SVesa Jääskeläinen }
134086922832SVesa Jääskeläinen break;
1341fa247a2aSRuchika Gupta default:
1342fa247a2aSRuchika Gupta break;
1343fa247a2aSRuchika Gupta }
134463f89caaSJens Wiklander
134563f89caaSJens Wiklander if (!sanitize_consistent_class_and_type(temp)) {
134663f89caaSJens Wiklander EMSG("Inconsistent class/type");
134763f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
134863f89caaSJens Wiklander goto out;
134963f89caaSJens Wiklander }
135063f89caaSJens Wiklander
1351e3f0cb56SRuchika Gupta /*
1352e3f0cb56SRuchika Gupta * TBD - Add a check to see if temp contains any attribute which
1353e3f0cb56SRuchika Gupta * is not consistent with the object class or type and return error.
1354e3f0cb56SRuchika Gupta * In current implementation such attributes are ignored and not
1355e3f0cb56SRuchika Gupta * added to final object while PKCS#11 specification expects a
1356e3f0cb56SRuchika Gupta * failure and an error code be returned.
1357e3f0cb56SRuchika Gupta */
1358e3f0cb56SRuchika Gupta
135963f89caaSJens Wiklander switch (get_class(temp)) {
136063f89caaSJens Wiklander case PKCS11_CKO_DATA:
136163f89caaSJens Wiklander rc = create_data_attributes(&attrs, temp);
136263f89caaSJens Wiklander break;
13634137952dSVesa Jääskeläinen case PKCS11_CKO_CERTIFICATE:
13644137952dSVesa Jääskeläinen rc = create_certificate_attributes(&attrs, temp);
13654137952dSVesa Jääskeläinen break;
136663f89caaSJens Wiklander case PKCS11_CKO_SECRET_KEY:
1367196bcd93SRuchika Gupta rc = sanitize_symm_key_attributes(&temp, function);
1368196bcd93SRuchika Gupta if (rc)
1369196bcd93SRuchika Gupta goto out;
137063f89caaSJens Wiklander rc = create_symm_key_attributes(&attrs, temp);
137163f89caaSJens Wiklander break;
137263f89caaSJens Wiklander case PKCS11_CKO_PUBLIC_KEY:
13739cf1afceSVesa Jääskeläinen rc = create_pub_key_attributes(&attrs, temp, function);
13745071d7d1SVesa Jääskeläinen if (rc)
13755071d7d1SVesa Jääskeläinen goto out;
13765071d7d1SVesa Jääskeläinen rc = create_pub_key_generated_attributes(&attrs, temp,
13775071d7d1SVesa Jääskeläinen function);
137863f89caaSJens Wiklander break;
137963f89caaSJens Wiklander case PKCS11_CKO_PRIVATE_KEY:
138063f89caaSJens Wiklander rc = create_priv_key_attributes(&attrs, temp);
13817c243321SVesa Jääskeläinen if (rc)
13827c243321SVesa Jääskeläinen goto out;
13837c243321SVesa Jääskeläinen rc = create_priv_key_hidden_attributes(&attrs, temp, function);
138463f89caaSJens Wiklander break;
138563f89caaSJens Wiklander default:
138663f89caaSJens Wiklander DMSG("Invalid object class %#"PRIx32"/%s",
138763f89caaSJens Wiklander get_class(temp), id2str_class(get_class(temp)));
138863f89caaSJens Wiklander
138963f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
139063f89caaSJens Wiklander break;
139163f89caaSJens Wiklander }
139263f89caaSJens Wiklander if (rc)
139363f89caaSJens Wiklander goto out;
139463f89caaSJens Wiklander
139590c47fe2SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_LOCAL, NULL, NULL) !=
1396002f6b93SEtienne Carriere PKCS11_RV_NOT_FOUND) {
1397002f6b93SEtienne Carriere rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
139863f89caaSJens Wiklander goto out;
1399002f6b93SEtienne Carriere }
140063f89caaSJens Wiklander
140190c47fe2SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_KEY_GEN_MECHANISM, NULL, NULL) !=
1402002f6b93SEtienne Carriere PKCS11_RV_NOT_FOUND) {
1403002f6b93SEtienne Carriere rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
140463f89caaSJens Wiklander goto out;
1405002f6b93SEtienne Carriere }
140663f89caaSJens Wiklander
140763f89caaSJens Wiklander switch (function) {
1408fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE:
1409013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR:
1410fa247a2aSRuchika Gupta local = PKCS11_TRUE;
1411fa247a2aSRuchika Gupta break;
141263f89caaSJens Wiklander case PKCS11_FUNCTION_IMPORT:
141348799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE:
1414e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP:
141563f89caaSJens Wiklander default:
141663f89caaSJens Wiklander local = PKCS11_FALSE;
141763f89caaSJens Wiklander break;
141863f89caaSJens Wiklander }
141963f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_LOCAL, &local, sizeof(local));
142063f89caaSJens Wiklander if (rc)
142163f89caaSJens Wiklander goto out;
142263f89caaSJens Wiklander
142363f89caaSJens Wiklander switch (get_class(attrs)) {
142463f89caaSJens Wiklander case PKCS11_CKO_SECRET_KEY:
142563f89caaSJens Wiklander case PKCS11_CKO_PRIVATE_KEY:
142663f89caaSJens Wiklander case PKCS11_CKO_PUBLIC_KEY:
142763f89caaSJens Wiklander always_sensitive = PKCS11_FALSE;
142863f89caaSJens Wiklander never_extract = PKCS11_FALSE;
142963f89caaSJens Wiklander
1430fa247a2aSRuchika Gupta switch (function) {
143148799892SRuchika Gupta case PKCS11_FUNCTION_DERIVE:
143248799892SRuchika Gupta always_sensitive =
143348799892SRuchika Gupta get_bool(parent, PKCS11_CKA_ALWAYS_SENSITIVE) &&
143448799892SRuchika Gupta get_bool(attrs, PKCS11_CKA_SENSITIVE);
143548799892SRuchika Gupta never_extract =
143648799892SRuchika Gupta get_bool(parent, PKCS11_CKA_NEVER_EXTRACTABLE) &&
143748799892SRuchika Gupta !get_bool(attrs, PKCS11_CKA_EXTRACTABLE);
143848799892SRuchika Gupta break;
1439e3f0cb56SRuchika Gupta case PKCS11_FUNCTION_UNWRAP:
1440e3f0cb56SRuchika Gupta always_sensitive = PKCS11_FALSE;
1441e3f0cb56SRuchika Gupta never_extract = PKCS11_FALSE;
1442e3f0cb56SRuchika Gupta extractable = PKCS11_TRUE;
1443e3f0cb56SRuchika Gupta
1444e3f0cb56SRuchika Gupta /*
1445e3f0cb56SRuchika Gupta * Check if template passed by user has CKA_EXTRACTABLE.
1446e3f0cb56SRuchika Gupta * If not, by default value of CKA_EXTRACTABLE is set as
1447e3f0cb56SRuchika Gupta * TRUE.
1448e3f0cb56SRuchika Gupta */
1449e3f0cb56SRuchika Gupta if (get_attribute_ptr(temp, PKCS11_CKA_EXTRACTABLE,
1450e3f0cb56SRuchika Gupta NULL,
1451e3f0cb56SRuchika Gupta NULL) == PKCS11_RV_NOT_FOUND) {
1452e3f0cb56SRuchika Gupta rc = set_attribute(&attrs,
1453e3f0cb56SRuchika Gupta PKCS11_CKA_EXTRACTABLE,
1454e3f0cb56SRuchika Gupta &extractable,
1455e3f0cb56SRuchika Gupta sizeof(extractable));
1456e3f0cb56SRuchika Gupta if (rc)
1457e3f0cb56SRuchika Gupta goto out;
1458e3f0cb56SRuchika Gupta }
1459e3f0cb56SRuchika Gupta break;
1460fa247a2aSRuchika Gupta case PKCS11_FUNCTION_GENERATE:
1461013934d8SVesa Jääskeläinen case PKCS11_FUNCTION_GENERATE_PAIR:
1462fa247a2aSRuchika Gupta always_sensitive = get_bool(attrs,
1463fa247a2aSRuchika Gupta PKCS11_CKA_SENSITIVE);
1464fa247a2aSRuchika Gupta never_extract = !get_bool(attrs,
1465fa247a2aSRuchika Gupta PKCS11_CKA_EXTRACTABLE);
1466fa247a2aSRuchika Gupta break;
1467fa247a2aSRuchika Gupta default:
1468fa247a2aSRuchika Gupta break;
1469fa247a2aSRuchika Gupta }
1470fa247a2aSRuchika Gupta
147163f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_ALWAYS_SENSITIVE,
147263f89caaSJens Wiklander &always_sensitive, sizeof(always_sensitive));
147363f89caaSJens Wiklander if (rc)
147463f89caaSJens Wiklander goto out;
147563f89caaSJens Wiklander
147663f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_NEVER_EXTRACTABLE,
147763f89caaSJens Wiklander &never_extract, sizeof(never_extract));
147863f89caaSJens Wiklander if (rc)
147963f89caaSJens Wiklander goto out;
148063f89caaSJens Wiklander
148163f89caaSJens Wiklander /* Keys mandate attribute PKCS11_CKA_KEY_GEN_MECHANISM */
1482fa247a2aSRuchika Gupta if (local)
1483fa247a2aSRuchika Gupta mechanism_id = mecha;
1484fa247a2aSRuchika Gupta else
148563f89caaSJens Wiklander mechanism_id = PKCS11_CK_UNAVAILABLE_INFORMATION;
1486fa247a2aSRuchika Gupta
148763f89caaSJens Wiklander rc = add_attribute(&attrs, PKCS11_CKA_KEY_GEN_MECHANISM,
148863f89caaSJens Wiklander &mechanism_id, sizeof(mechanism_id));
148963f89caaSJens Wiklander if (rc)
149063f89caaSJens Wiklander goto out;
149163f89caaSJens Wiklander break;
149263f89caaSJens Wiklander
149363f89caaSJens Wiklander default:
149463f89caaSJens Wiklander break;
149563f89caaSJens Wiklander }
149663f89caaSJens Wiklander
149763f89caaSJens Wiklander *out = attrs;
149863f89caaSJens Wiklander
149963f89caaSJens Wiklander #ifdef DEBUG
150063f89caaSJens Wiklander trace_attributes("object", attrs);
150163f89caaSJens Wiklander #endif
150263f89caaSJens Wiklander
150363f89caaSJens Wiklander out:
150463f89caaSJens Wiklander TEE_Free(temp);
150563f89caaSJens Wiklander if (rc)
150663f89caaSJens Wiklander TEE_Free(attrs);
150763f89caaSJens Wiklander
150863f89caaSJens Wiklander return rc;
150963f89caaSJens Wiklander }
151063f89caaSJens Wiklander
check_attrs_misc_integrity(struct obj_attrs * head)151163f89caaSJens Wiklander static enum pkcs11_rc check_attrs_misc_integrity(struct obj_attrs *head)
151263f89caaSJens Wiklander {
151363f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_NEVER_EXTRACTABLE) &&
151463f89caaSJens Wiklander get_bool(head, PKCS11_CKA_EXTRACTABLE)) {
151563f89caaSJens Wiklander DMSG("Never/Extractable attributes mismatch %d/%d",
151663f89caaSJens Wiklander get_bool(head, PKCS11_CKA_NEVER_EXTRACTABLE),
151763f89caaSJens Wiklander get_bool(head, PKCS11_CKA_EXTRACTABLE));
151863f89caaSJens Wiklander
151963f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT;
152063f89caaSJens Wiklander }
152163f89caaSJens Wiklander
152263f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_ALWAYS_SENSITIVE) &&
152363f89caaSJens Wiklander !get_bool(head, PKCS11_CKA_SENSITIVE)) {
152463f89caaSJens Wiklander DMSG("Sensitive/always attributes mismatch %d/%d",
152563f89caaSJens Wiklander get_bool(head, PKCS11_CKA_SENSITIVE),
152663f89caaSJens Wiklander get_bool(head, PKCS11_CKA_ALWAYS_SENSITIVE));
152763f89caaSJens Wiklander
152863f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT;
152963f89caaSJens Wiklander }
153063f89caaSJens Wiklander
153163f89caaSJens Wiklander return PKCS11_CKR_OK;
153263f89caaSJens Wiklander }
153363f89caaSJens Wiklander
object_is_private(struct obj_attrs * head)153489735787SRuchika Gupta bool object_is_private(struct obj_attrs *head)
153589735787SRuchika Gupta {
153665fb9092SVesa Jääskeläinen return get_bool(head, PKCS11_CKA_PRIVATE);
153789735787SRuchika Gupta }
153889735787SRuchika Gupta
object_is_token(struct obj_attrs * head)15392d25a9bcSRuchika Gupta bool object_is_token(struct obj_attrs *head)
15402d25a9bcSRuchika Gupta {
15412d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_TOKEN);
15422d25a9bcSRuchika Gupta }
15432d25a9bcSRuchika Gupta
object_is_modifiable(struct obj_attrs * head)15442d25a9bcSRuchika Gupta bool object_is_modifiable(struct obj_attrs *head)
15452d25a9bcSRuchika Gupta {
15462d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_MODIFIABLE);
15472d25a9bcSRuchika Gupta }
15482d25a9bcSRuchika Gupta
object_is_copyable(struct obj_attrs * head)15492d25a9bcSRuchika Gupta bool object_is_copyable(struct obj_attrs *head)
15502d25a9bcSRuchika Gupta {
15512d25a9bcSRuchika Gupta return get_bool(head, PKCS11_CKA_COPYABLE);
15522d25a9bcSRuchika Gupta }
15532d25a9bcSRuchika Gupta
155463f89caaSJens Wiklander /*
1555512cbf1dSJens Wiklander * Check access to object against authentication to token
1556512cbf1dSJens Wiklander */
check_access_attrs_against_token(struct pkcs11_session * session,struct obj_attrs * head)1557512cbf1dSJens Wiklander enum pkcs11_rc check_access_attrs_against_token(struct pkcs11_session *session,
1558512cbf1dSJens Wiklander struct obj_attrs *head)
1559512cbf1dSJens Wiklander {
1560512cbf1dSJens Wiklander bool private = true;
1561512cbf1dSJens Wiklander
1562512cbf1dSJens Wiklander switch (get_class(head)) {
1563512cbf1dSJens Wiklander case PKCS11_CKO_SECRET_KEY:
156465fb9092SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY:
1565512cbf1dSJens Wiklander case PKCS11_CKO_PUBLIC_KEY:
1566512cbf1dSJens Wiklander case PKCS11_CKO_DATA:
15674137952dSVesa Jääskeläinen case PKCS11_CKO_CERTIFICATE:
156865fb9092SVesa Jääskeläinen private = object_is_private(head);
1569512cbf1dSJens Wiklander break;
1570512cbf1dSJens Wiklander default:
1571512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED;
1572512cbf1dSJens Wiklander }
1573512cbf1dSJens Wiklander
15745db0fef4SRuchika Gupta if (private && (pkcs11_session_is_public(session) ||
15755db0fef4SRuchika Gupta pkcs11_session_is_so(session))) {
15765db0fef4SRuchika Gupta DMSG("Private object access from a public or SO session");
1577512cbf1dSJens Wiklander
157812f1ba86SRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN;
1579512cbf1dSJens Wiklander }
1580512cbf1dSJens Wiklander
1581512cbf1dSJens Wiklander return PKCS11_CKR_OK;
1582512cbf1dSJens Wiklander }
1583512cbf1dSJens Wiklander
1584512cbf1dSJens Wiklander /*
158563f89caaSJens Wiklander * Check the attributes of a to-be-created object matches the token state
158663f89caaSJens Wiklander */
check_created_attrs_against_token(struct pkcs11_session * session,struct obj_attrs * head)158763f89caaSJens Wiklander enum pkcs11_rc check_created_attrs_against_token(struct pkcs11_session *session,
158863f89caaSJens Wiklander struct obj_attrs *head)
158963f89caaSJens Wiklander {
159063f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK;
159163f89caaSJens Wiklander
159263f89caaSJens Wiklander rc = check_attrs_misc_integrity(head);
159363f89caaSJens Wiklander if (rc)
159463f89caaSJens Wiklander return rc;
159563f89caaSJens Wiklander
159663f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_TRUSTED) &&
159763f89caaSJens Wiklander !pkcs11_session_is_so(session)) {
159863f89caaSJens Wiklander DMSG("Can't create trusted object");
159963f89caaSJens Wiklander
160063f89caaSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED;
160163f89caaSJens Wiklander }
160263f89caaSJens Wiklander
160363f89caaSJens Wiklander if (get_bool(head, PKCS11_CKA_TOKEN) &&
160463f89caaSJens Wiklander !pkcs11_session_is_read_write(session)) {
160563f89caaSJens Wiklander DMSG("Can't create persistent object");
160663f89caaSJens Wiklander
160763f89caaSJens Wiklander return PKCS11_CKR_SESSION_READ_ONLY;
160863f89caaSJens Wiklander }
160963f89caaSJens Wiklander
161063f89caaSJens Wiklander return PKCS11_CKR_OK;
161163f89caaSJens Wiklander }
161263f89caaSJens Wiklander
161363f89caaSJens Wiklander #define DMSG_BAD_BBOOL(attr, proc, head) \
161463f89caaSJens Wiklander do { \
161563f89caaSJens Wiklander uint32_t __maybe_unused _attr = (attr); \
161663f89caaSJens Wiklander uint8_t __maybe_unused _bvalue = 0; \
161763f89caaSJens Wiklander enum pkcs11_rc __maybe_unused _rc = PKCS11_CKR_OK; \
161863f89caaSJens Wiklander \
161963f89caaSJens Wiklander _rc = get_attribute((head), _attr, &_bvalue, NULL); \
162063f89caaSJens Wiklander DMSG("%s issue for %s: %sfound, value %"PRIu8, \
162163f89caaSJens Wiklander id2str_attr(_attr), id2str_proc((proc)), \
162263f89caaSJens Wiklander _rc ? "not " : "", _bvalue); \
162363f89caaSJens Wiklander } while (0)
162463f89caaSJens Wiklander
check_attr_bval(uint32_t proc_id __maybe_unused,struct obj_attrs * head,uint32_t attribute,bool val)162563f89caaSJens Wiklander static bool __maybe_unused check_attr_bval(uint32_t proc_id __maybe_unused,
162663f89caaSJens Wiklander struct obj_attrs *head,
162763f89caaSJens Wiklander uint32_t attribute, bool val)
162863f89caaSJens Wiklander {
162963f89caaSJens Wiklander uint8_t bbool = 0;
163063f89caaSJens Wiklander uint32_t sz = sizeof(bbool);
163163f89caaSJens Wiklander
163263f89caaSJens Wiklander if (!get_attribute(head, attribute, &bbool, &sz) && !!bbool == val)
163363f89caaSJens Wiklander return true;
163463f89caaSJens Wiklander
163563f89caaSJens Wiklander DMSG_BAD_BBOOL(attribute, proc_id, head);
163663f89caaSJens Wiklander return false;
163763f89caaSJens Wiklander }
163863f89caaSJens Wiklander
163963f89caaSJens Wiklander /*
164063f89caaSJens Wiklander * Check the attributes of a new secret match the processing/mechanism
164163f89caaSJens Wiklander * used to create it.
164263f89caaSJens Wiklander *
164363f89caaSJens Wiklander * @proc_id - PKCS11_CKM_xxx
164463f89caaSJens Wiklander * @head - head of the attributes of the to-be-created object.
164563f89caaSJens Wiklander */
1646897aaf11SEtienne Carriere enum pkcs11_rc
check_created_attrs_against_processing(uint32_t proc_id,struct obj_attrs * head __maybe_unused)1647897aaf11SEtienne Carriere check_created_attrs_against_processing(uint32_t proc_id,
1648897aaf11SEtienne Carriere struct obj_attrs *head __maybe_unused)
164963f89caaSJens Wiklander {
165063f89caaSJens Wiklander /*
165163f89caaSJens Wiklander * Processings that do not create secrets are not expected to call
165263f89caaSJens Wiklander * this function which would panic.
165363f89caaSJens Wiklander */
165463f89caaSJens Wiklander switch (proc_id) {
165563f89caaSJens Wiklander case PKCS11_PROCESSING_IMPORT:
1656cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE:
1657e3f0cb56SRuchika Gupta case PKCS11_CKM_AES_ECB:
1658e3f0cb56SRuchika Gupta case PKCS11_CKM_AES_CBC:
165948799892SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
166048799892SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
166145d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP:
166263f89caaSJens Wiklander assert(check_attr_bval(proc_id, head, PKCS11_CKA_LOCAL, false));
166363f89caaSJens Wiklander break;
1664fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN:
1665fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN:
166603e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN:
166702b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN:
166886922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN:
1669fa247a2aSRuchika Gupta assert(check_attr_bval(proc_id, head, PKCS11_CKA_LOCAL, true));
1670fa247a2aSRuchika Gupta break;
167163f89caaSJens Wiklander default:
167263f89caaSJens Wiklander TEE_Panic(proc_id);
167363f89caaSJens Wiklander break;
167463f89caaSJens Wiklander }
167563f89caaSJens Wiklander
1676fa247a2aSRuchika Gupta switch (proc_id) {
1677fa247a2aSRuchika Gupta case PKCS11_CKM_GENERIC_SECRET_KEY_GEN:
1678fa247a2aSRuchika Gupta assert(get_key_type(head) == PKCS11_CKK_GENERIC_SECRET);
1679fa247a2aSRuchika Gupta break;
1680fa247a2aSRuchika Gupta case PKCS11_CKM_AES_KEY_GEN:
1681fa247a2aSRuchika Gupta assert(get_key_type(head) == PKCS11_CKK_AES);
1682fa247a2aSRuchika Gupta break;
168303e07432SValerii Chubar case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN:
168403e07432SValerii Chubar assert(get_key_type(head) == PKCS11_CKK_EC_EDWARDS);
168503e07432SValerii Chubar break;
168602b16804SVesa Jääskeläinen case PKCS11_CKM_EC_KEY_PAIR_GEN:
168702b16804SVesa Jääskeläinen assert(get_key_type(head) == PKCS11_CKK_EC);
168802b16804SVesa Jääskeläinen break;
168986922832SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN:
169086922832SVesa Jääskeläinen assert(get_key_type(head) == PKCS11_CKK_RSA);
169186922832SVesa Jääskeläinen break;
1692fa247a2aSRuchika Gupta case PKCS11_PROCESSING_IMPORT:
1693cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE:
1694fa247a2aSRuchika Gupta default:
1695fa247a2aSRuchika Gupta break;
1696fa247a2aSRuchika Gupta }
1697fa247a2aSRuchika Gupta
169863f89caaSJens Wiklander return PKCS11_CKR_OK;
169963f89caaSJens Wiklander }
1700512cbf1dSJens Wiklander
17012d0cd829SRuchika Gupta /* Return min and max key size supported for a key_type in bytes */
get_key_min_max_sizes(enum pkcs11_key_type key_type,uint32_t * min_key_size,uint32_t * max_key_size)1702512cbf1dSJens Wiklander static void get_key_min_max_sizes(enum pkcs11_key_type key_type,
1703512cbf1dSJens Wiklander uint32_t *min_key_size,
1704512cbf1dSJens Wiklander uint32_t *max_key_size)
1705512cbf1dSJens Wiklander {
1706512cbf1dSJens Wiklander enum pkcs11_mechanism_id mechanism = PKCS11_CKM_UNDEFINED_ID;
1707512cbf1dSJens Wiklander
1708512cbf1dSJens Wiklander switch (key_type) {
1709fa247a2aSRuchika Gupta case PKCS11_CKK_GENERIC_SECRET:
1710fa247a2aSRuchika Gupta mechanism = PKCS11_CKM_GENERIC_SECRET_KEY_GEN;
1711fa247a2aSRuchika Gupta break;
1712512cbf1dSJens Wiklander case PKCS11_CKK_AES:
1713512cbf1dSJens Wiklander mechanism = PKCS11_CKM_AES_KEY_GEN;
1714512cbf1dSJens Wiklander break;
17151f45c9cfSRuchika Gupta case PKCS11_CKK_MD5_HMAC:
17161f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_MD5_HMAC;
17171f45c9cfSRuchika Gupta break;
17181f45c9cfSRuchika Gupta case PKCS11_CKK_SHA_1_HMAC:
17191f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA_1_HMAC;
17201f45c9cfSRuchika Gupta break;
17211f45c9cfSRuchika Gupta case PKCS11_CKK_SHA224_HMAC:
17221f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA224_HMAC;
17231f45c9cfSRuchika Gupta break;
1724a339a354SEtienne Carriere case PKCS11_CKK_SHA256_HMAC:
1725a339a354SEtienne Carriere mechanism = PKCS11_CKM_SHA256_HMAC;
1726a339a354SEtienne Carriere break;
17271f45c9cfSRuchika Gupta case PKCS11_CKK_SHA384_HMAC:
17281f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA384_HMAC;
17291f45c9cfSRuchika Gupta break;
17301f45c9cfSRuchika Gupta case PKCS11_CKK_SHA512_HMAC:
17311f45c9cfSRuchika Gupta mechanism = PKCS11_CKM_SHA512_HMAC;
17321f45c9cfSRuchika Gupta break;
1733db28c542SVesa Jääskeläinen case PKCS11_CKK_EC:
1734db28c542SVesa Jääskeläinen mechanism = PKCS11_CKM_EC_KEY_PAIR_GEN;
1735db28c542SVesa Jääskeläinen break;
173603e07432SValerii Chubar case PKCS11_CKK_EDDSA:
173703e07432SValerii Chubar mechanism = PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN;
173803e07432SValerii Chubar break;
173986922832SVesa Jääskeläinen case PKCS11_CKK_RSA:
174086922832SVesa Jääskeläinen mechanism = PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN;
174186922832SVesa Jääskeläinen break;
1742512cbf1dSJens Wiklander default:
1743512cbf1dSJens Wiklander TEE_Panic(key_type);
1744512cbf1dSJens Wiklander break;
1745512cbf1dSJens Wiklander }
1746512cbf1dSJens Wiklander
17472d0cd829SRuchika Gupta mechanism_supported_key_sizes_bytes(mechanism, min_key_size,
1748512cbf1dSJens Wiklander max_key_size);
1749512cbf1dSJens Wiklander }
1750512cbf1dSJens Wiklander
check_created_attrs(struct obj_attrs * key1,struct obj_attrs * key2)1751512cbf1dSJens Wiklander enum pkcs11_rc check_created_attrs(struct obj_attrs *key1,
1752512cbf1dSJens Wiklander struct obj_attrs *key2)
1753512cbf1dSJens Wiklander {
1754512cbf1dSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK;
1755512cbf1dSJens Wiklander struct obj_attrs *secret = NULL;
1756013934d8SVesa Jääskeläinen struct obj_attrs *private = NULL;
1757013934d8SVesa Jääskeläinen struct obj_attrs *public = NULL;
1758512cbf1dSJens Wiklander uint32_t max_key_size = 0;
1759512cbf1dSJens Wiklander uint32_t min_key_size = 0;
1760512cbf1dSJens Wiklander uint32_t key_length = 0;
1761512cbf1dSJens Wiklander
1762512cbf1dSJens Wiklander switch (get_class(key1)) {
1763512cbf1dSJens Wiklander case PKCS11_CKO_SECRET_KEY:
1764512cbf1dSJens Wiklander secret = key1;
1765512cbf1dSJens Wiklander break;
1766013934d8SVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY:
1767013934d8SVesa Jääskeläinen public = key1;
1768013934d8SVesa Jääskeläinen break;
1769013934d8SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY:
1770013934d8SVesa Jääskeläinen private = key1;
1771013934d8SVesa Jääskeläinen break;
1772512cbf1dSJens Wiklander default:
1773512cbf1dSJens Wiklander return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID;
1774512cbf1dSJens Wiklander }
1775512cbf1dSJens Wiklander
1776013934d8SVesa Jääskeläinen if (key2) {
1777013934d8SVesa Jääskeläinen switch (get_class(key2)) {
1778013934d8SVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY:
1779013934d8SVesa Jääskeläinen public = key2;
1780013934d8SVesa Jääskeläinen if (private == key1)
1781013934d8SVesa Jääskeläinen break;
1782013934d8SVesa Jääskeläinen
1783013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT;
1784013934d8SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY:
1785013934d8SVesa Jääskeläinen private = key2;
1786013934d8SVesa Jääskeläinen if (public == key1)
1787013934d8SVesa Jääskeläinen break;
1788013934d8SVesa Jääskeläinen
1789013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT;
1790013934d8SVesa Jääskeläinen default:
1791512cbf1dSJens Wiklander return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID;
1792013934d8SVesa Jääskeläinen }
1793013934d8SVesa Jääskeläinen
1794013934d8SVesa Jääskeläinen if (get_key_type(private) != get_key_type(public))
1795013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT;
1796013934d8SVesa Jääskeläinen }
1797512cbf1dSJens Wiklander
1798512cbf1dSJens Wiklander if (secret) {
1799512cbf1dSJens Wiklander switch (get_key_type(secret)) {
1800512cbf1dSJens Wiklander case PKCS11_CKK_AES:
1801512cbf1dSJens Wiklander case PKCS11_CKK_GENERIC_SECRET:
1802512cbf1dSJens Wiklander case PKCS11_CKK_MD5_HMAC:
1803512cbf1dSJens Wiklander case PKCS11_CKK_SHA_1_HMAC:
1804512cbf1dSJens Wiklander case PKCS11_CKK_SHA224_HMAC:
1805512cbf1dSJens Wiklander case PKCS11_CKK_SHA256_HMAC:
1806512cbf1dSJens Wiklander case PKCS11_CKK_SHA384_HMAC:
1807512cbf1dSJens Wiklander case PKCS11_CKK_SHA512_HMAC:
1808512cbf1dSJens Wiklander break;
1809512cbf1dSJens Wiklander default:
1810512cbf1dSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT;
1811512cbf1dSJens Wiklander }
1812512cbf1dSJens Wiklander
1813512cbf1dSJens Wiklander /* Get key size */
1814512cbf1dSJens Wiklander rc = get_u32_attribute(secret, PKCS11_CKA_VALUE_LEN,
1815512cbf1dSJens Wiklander &key_length);
1816512cbf1dSJens Wiklander if (rc)
1817d1d44372SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCOMPLETE;
1818512cbf1dSJens Wiklander }
1819013934d8SVesa Jääskeläinen if (public) {
1820013934d8SVesa Jääskeläinen switch (get_key_type(public)) {
182186922832SVesa Jääskeläinen case PKCS11_CKK_RSA:
182286922832SVesa Jääskeläinen /* Get key size */
182386922832SVesa Jääskeläinen rc = get_u32_attribute(public, PKCS11_CKA_MODULUS_BITS,
182486922832SVesa Jääskeläinen &key_length);
182586922832SVesa Jääskeläinen if (rc)
182686922832SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT;
1827*04e46975SEtienne Carriere key_length = ROUNDUP_DIV(key_length, 8);
182886922832SVesa Jääskeläinen break;
182902b16804SVesa Jääskeläinen case PKCS11_CKK_EC:
183003e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS:
183102b16804SVesa Jääskeläinen break;
1832013934d8SVesa Jääskeläinen default:
1833013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT;
1834013934d8SVesa Jääskeläinen }
1835013934d8SVesa Jääskeläinen }
1836013934d8SVesa Jääskeläinen if (private) {
1837013934d8SVesa Jääskeläinen switch (get_key_type(private)) {
183886922832SVesa Jääskeläinen case PKCS11_CKK_RSA:
183902b16804SVesa Jääskeläinen case PKCS11_CKK_EC:
184003e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS:
184102b16804SVesa Jääskeläinen break;
1842013934d8SVesa Jääskeläinen default:
1843013934d8SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT;
1844013934d8SVesa Jääskeläinen }
1845013934d8SVesa Jääskeläinen }
1846512cbf1dSJens Wiklander
184702b16804SVesa Jääskeläinen /*
184802b16804SVesa Jääskeläinen * Check key size for symmetric keys and RSA keys
184902b16804SVesa Jääskeläinen * EC is bound to domains, no need to check here.
185002b16804SVesa Jääskeläinen */
185102b16804SVesa Jääskeläinen switch (get_key_type(key1)) {
185202b16804SVesa Jääskeläinen case PKCS11_CKK_EC:
185303e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS:
185402b16804SVesa Jääskeläinen return PKCS11_CKR_OK;
185502b16804SVesa Jääskeläinen default:
185602b16804SVesa Jääskeläinen break;
185702b16804SVesa Jääskeläinen }
185802b16804SVesa Jääskeläinen
1859512cbf1dSJens Wiklander get_key_min_max_sizes(get_key_type(key1), &min_key_size, &max_key_size);
1860512cbf1dSJens Wiklander if (key_length < min_key_size || key_length > max_key_size) {
1861512cbf1dSJens Wiklander EMSG("Length %"PRIu32" vs range [%"PRIu32" %"PRIu32"]",
1862512cbf1dSJens Wiklander key_length, min_key_size, max_key_size);
1863512cbf1dSJens Wiklander
1864512cbf1dSJens Wiklander return PKCS11_CKR_KEY_SIZE_RANGE;
1865512cbf1dSJens Wiklander }
1866512cbf1dSJens Wiklander
186749ed60abSRuchika Gupta if (secret && get_key_type(secret) == PKCS11_CKK_AES) {
186849ed60abSRuchika Gupta if (key_length != 16 && key_length != 24 && key_length != 32)
186949ed60abSRuchika Gupta return PKCS11_CKR_KEY_SIZE_RANGE;
187049ed60abSRuchika Gupta }
187149ed60abSRuchika Gupta
1872512cbf1dSJens Wiklander return PKCS11_CKR_OK;
1873512cbf1dSJens Wiklander }
1874512cbf1dSJens Wiklander
1875512cbf1dSJens Wiklander /* Check processing ID against attribute ALLOWED_MECHANISMS if any */
parent_key_complies_allowed_processings(uint32_t proc_id,struct obj_attrs * head)1876512cbf1dSJens Wiklander static bool parent_key_complies_allowed_processings(uint32_t proc_id,
1877512cbf1dSJens Wiklander struct obj_attrs *head)
1878512cbf1dSJens Wiklander {
1879512cbf1dSJens Wiklander char *attr = NULL;
1880512cbf1dSJens Wiklander uint32_t size = 0;
1881512cbf1dSJens Wiklander uint32_t proc = 0;
1882512cbf1dSJens Wiklander size_t count = 0;
18836a760c9eSEtienne Carriere enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
1884512cbf1dSJens Wiklander
18856a760c9eSEtienne Carriere rc = get_attribute_ptr(head, PKCS11_CKA_ALLOWED_MECHANISMS,
18866a760c9eSEtienne Carriere (void *)&attr, &size);
18876a760c9eSEtienne Carriere if (rc == PKCS11_RV_NOT_FOUND)
1888512cbf1dSJens Wiklander return true;
18896a760c9eSEtienne Carriere if (rc) {
18906a760c9eSEtienne Carriere EMSG("unexpected attributes state");
18916a760c9eSEtienne Carriere TEE_Panic(TEE_ERROR_BAD_STATE);
1892512cbf1dSJens Wiklander }
1893512cbf1dSJens Wiklander
1894512cbf1dSJens Wiklander for (count = size / sizeof(uint32_t); count; count--) {
1895512cbf1dSJens Wiklander TEE_MemMove(&proc, attr, sizeof(uint32_t));
1896512cbf1dSJens Wiklander attr += sizeof(uint32_t);
1897512cbf1dSJens Wiklander
1898512cbf1dSJens Wiklander if (proc == proc_id)
1899512cbf1dSJens Wiklander return true;
1900512cbf1dSJens Wiklander }
1901512cbf1dSJens Wiklander
1902512cbf1dSJens Wiklander DMSG("can't find %s in allowed list", id2str_proc(proc_id));
1903512cbf1dSJens Wiklander return false;
1904512cbf1dSJens Wiklander }
1905512cbf1dSJens Wiklander
func_to_attr(enum processing_func func)1906512cbf1dSJens Wiklander static enum pkcs11_attr_id func_to_attr(enum processing_func func)
1907512cbf1dSJens Wiklander {
1908512cbf1dSJens Wiklander switch (func) {
1909512cbf1dSJens Wiklander case PKCS11_FUNCTION_ENCRYPT:
1910512cbf1dSJens Wiklander return PKCS11_CKA_ENCRYPT;
1911512cbf1dSJens Wiklander case PKCS11_FUNCTION_DECRYPT:
1912512cbf1dSJens Wiklander return PKCS11_CKA_DECRYPT;
1913512cbf1dSJens Wiklander case PKCS11_FUNCTION_SIGN:
1914512cbf1dSJens Wiklander return PKCS11_CKA_SIGN;
1915512cbf1dSJens Wiklander case PKCS11_FUNCTION_VERIFY:
1916512cbf1dSJens Wiklander return PKCS11_CKA_VERIFY;
1917512cbf1dSJens Wiklander case PKCS11_FUNCTION_WRAP:
1918512cbf1dSJens Wiklander return PKCS11_CKA_WRAP;
1919512cbf1dSJens Wiklander case PKCS11_FUNCTION_UNWRAP:
1920512cbf1dSJens Wiklander return PKCS11_CKA_UNWRAP;
1921512cbf1dSJens Wiklander case PKCS11_FUNCTION_DERIVE:
1922512cbf1dSJens Wiklander return PKCS11_CKA_DERIVE;
1923512cbf1dSJens Wiklander default:
1924512cbf1dSJens Wiklander return PKCS11_CKA_UNDEFINED_ID;
1925512cbf1dSJens Wiklander }
1926512cbf1dSJens Wiklander }
1927512cbf1dSJens Wiklander
1928512cbf1dSJens Wiklander enum pkcs11_rc
check_parent_attrs_against_processing(enum pkcs11_mechanism_id proc_id,enum processing_func function,struct obj_attrs * head)1929512cbf1dSJens Wiklander check_parent_attrs_against_processing(enum pkcs11_mechanism_id proc_id,
1930512cbf1dSJens Wiklander enum processing_func function,
1931512cbf1dSJens Wiklander struct obj_attrs *head)
1932512cbf1dSJens Wiklander {
1933512cbf1dSJens Wiklander enum pkcs11_class_id key_class = get_class(head);
1934512cbf1dSJens Wiklander enum pkcs11_key_type key_type = get_key_type(head);
1935512cbf1dSJens Wiklander enum pkcs11_attr_id attr = func_to_attr(function);
1936512cbf1dSJens Wiklander
1937512cbf1dSJens Wiklander if (!get_bool(head, attr)) {
1938512cbf1dSJens Wiklander DMSG("%s not permitted", id2str_attr(attr));
1939512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED;
1940512cbf1dSJens Wiklander }
1941512cbf1dSJens Wiklander
1942512cbf1dSJens Wiklander /* Check processing complies with parent key family */
1943512cbf1dSJens Wiklander switch (proc_id) {
1944512cbf1dSJens Wiklander case PKCS11_CKM_AES_ECB:
1945512cbf1dSJens Wiklander case PKCS11_CKM_AES_CBC:
1946512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTS:
1947512cbf1dSJens Wiklander case PKCS11_CKM_AES_CTR:
194863778faaSEtienne Carriere case PKCS11_CKM_AES_GCM:
19490ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC:
19500ef6b144SVictor Chong case PKCS11_CKM_AES_CMAC_GENERAL:
1951512cbf1dSJens Wiklander if (key_class == PKCS11_CKO_SECRET_KEY &&
1952512cbf1dSJens Wiklander key_type == PKCS11_CKK_AES)
1953512cbf1dSJens Wiklander break;
1954512cbf1dSJens Wiklander
1955512cbf1dSJens Wiklander DMSG("%s invalid key %s/%s", id2str_proc(proc_id),
1956512cbf1dSJens Wiklander id2str_class(key_class), id2str_key_type(key_type));
1957512cbf1dSJens Wiklander
19585f80f270SRuchika Gupta if (function == PKCS11_FUNCTION_WRAP)
19595f80f270SRuchika Gupta return PKCS11_CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
1960e3f0cb56SRuchika Gupta else if (function == PKCS11_FUNCTION_UNWRAP)
1961e3f0cb56SRuchika Gupta return PKCS11_CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
19625f80f270SRuchika Gupta else
1963512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED;
1964512cbf1dSJens Wiklander
1965c3033708SRuchika Gupta case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
1966c3033708SRuchika Gupta case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
1967c3033708SRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY &&
1968c3033708SRuchika Gupta key_type != PKCS11_CKK_AES)
1969c3033708SRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED;
1970c3033708SRuchika Gupta
1971c3033708SRuchika Gupta if (get_bool(head, PKCS11_CKA_ENCRYPT)) {
1972c3033708SRuchika Gupta /*
1973c3033708SRuchika Gupta * Intentionally refuse to proceed despite
1974c3033708SRuchika Gupta * PKCS#11 specifications v2.40 and v3.0 not expecting
1975c3033708SRuchika Gupta * this behavior to avoid potential security issue
1976c3033708SRuchika Gupta * where keys derived by these mechanisms can be
1977c3033708SRuchika Gupta * revealed by doing data encryption using parent key.
1978c3033708SRuchika Gupta */
1979c3033708SRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED;
1980c3033708SRuchika Gupta }
1981c3033708SRuchika Gupta
1982c3033708SRuchika Gupta break;
1983689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC:
1984689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC:
1985689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC:
1986689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC:
1987689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC:
1988689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC:
198970b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL:
199070b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL:
199170b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL:
199270b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL:
199370b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL:
199470b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL:
1995689f4e5bSRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY)
1996689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED;
1997689f4e5bSRuchika Gupta
1998689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_GENERIC_SECRET)
1999689f4e5bSRuchika Gupta break;
2000689f4e5bSRuchika Gupta
2001689f4e5bSRuchika Gupta switch (proc_id) {
2002689f4e5bSRuchika Gupta case PKCS11_CKM_MD5_HMAC:
200370b6683bSVictor Chong case PKCS11_CKM_MD5_HMAC_GENERAL:
2004689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_MD5_HMAC)
2005689f4e5bSRuchika Gupta break;
2006689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED;
2007689f4e5bSRuchika Gupta case PKCS11_CKM_SHA_1_HMAC:
200870b6683bSVictor Chong case PKCS11_CKM_SHA_1_HMAC_GENERAL:
2009689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA_1_HMAC)
2010689f4e5bSRuchika Gupta break;
2011689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED;
2012689f4e5bSRuchika Gupta case PKCS11_CKM_SHA224_HMAC:
201370b6683bSVictor Chong case PKCS11_CKM_SHA224_HMAC_GENERAL:
2014689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA224_HMAC)
2015689f4e5bSRuchika Gupta break;
2016689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED;
2017689f4e5bSRuchika Gupta case PKCS11_CKM_SHA256_HMAC:
201870b6683bSVictor Chong case PKCS11_CKM_SHA256_HMAC_GENERAL:
2019689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA256_HMAC)
2020689f4e5bSRuchika Gupta break;
2021689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED;
2022689f4e5bSRuchika Gupta case PKCS11_CKM_SHA384_HMAC:
202370b6683bSVictor Chong case PKCS11_CKM_SHA384_HMAC_GENERAL:
2024689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA384_HMAC)
2025689f4e5bSRuchika Gupta break;
2026689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED;
2027689f4e5bSRuchika Gupta case PKCS11_CKM_SHA512_HMAC:
202870b6683bSVictor Chong case PKCS11_CKM_SHA512_HMAC_GENERAL:
2029689f4e5bSRuchika Gupta if (key_type == PKCS11_CKK_SHA512_HMAC)
2030689f4e5bSRuchika Gupta break;
2031689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED;
2032689f4e5bSRuchika Gupta default:
2033689f4e5bSRuchika Gupta return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED;
2034689f4e5bSRuchika Gupta }
2035689f4e5bSRuchika Gupta break;
2036689f4e5bSRuchika Gupta
203703e07432SValerii Chubar case PKCS11_CKM_EDDSA:
203803e07432SValerii Chubar if (key_type != PKCS11_CKK_EC_EDWARDS) {
203903e07432SValerii Chubar EMSG("Invalid key %s for mechanism %s",
204003e07432SValerii Chubar id2str_type(key_type, key_class),
204103e07432SValerii Chubar id2str_proc(proc_id));
204203e07432SValerii Chubar return PKCS11_CKR_KEY_TYPE_INCONSISTENT;
204303e07432SValerii Chubar }
204403e07432SValerii Chubar if (key_class != PKCS11_CKO_PUBLIC_KEY &&
204503e07432SValerii Chubar key_class != PKCS11_CKO_PRIVATE_KEY) {
204603e07432SValerii Chubar EMSG("Invalid key class for mechanism %s",
204703e07432SValerii Chubar id2str_proc(proc_id));
204803e07432SValerii Chubar
204903e07432SValerii Chubar return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED;
205003e07432SValerii Chubar }
205103e07432SValerii Chubar break;
205203e07432SValerii Chubar
2053fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA:
2054fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1:
2055fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224:
2056fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256:
2057fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384:
2058fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512:
2059cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE:
2060fb279d8bSVesa Jääskeläinen if (key_type != PKCS11_CKK_EC) {
2061fb279d8bSVesa Jääskeläinen EMSG("Invalid key %s for mechanism %s",
2062fb279d8bSVesa Jääskeläinen id2str_type(key_type, key_class),
2063fb279d8bSVesa Jääskeläinen id2str_proc(proc_id));
2064fb279d8bSVesa Jääskeläinen
2065fb279d8bSVesa Jääskeläinen return PKCS11_CKR_KEY_TYPE_INCONSISTENT;
2066fb279d8bSVesa Jääskeläinen }
2067fb279d8bSVesa Jääskeläinen if (key_class != PKCS11_CKO_PUBLIC_KEY &&
2068fb279d8bSVesa Jääskeläinen key_class != PKCS11_CKO_PRIVATE_KEY) {
2069fb279d8bSVesa Jääskeläinen EMSG("Invalid key class for mechanism %s",
2070fb279d8bSVesa Jääskeläinen id2str_proc(proc_id));
2071fb279d8bSVesa Jääskeläinen
2072fb279d8bSVesa Jääskeläinen return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED;
2073fb279d8bSVesa Jääskeläinen }
2074fb279d8bSVesa Jääskeläinen break;
20750442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS:
20760442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS:
20770442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS:
20780442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS:
20790442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS:
20800442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS:
20810442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS:
208245d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP:
2083dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP:
2084d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS:
2085e02f17f3SAlexandre Marechal case PKCS11_CKM_RSA_X_509:
2086d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
2087d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
2088d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
2089d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
2090d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
20910442c956SVesa Jääskeläinen if (key_type != PKCS11_CKK_RSA) {
20920442c956SVesa Jääskeläinen EMSG("Invalid key %s for mechanism %s",
20930442c956SVesa Jääskeläinen id2str_type(key_type, key_class),
20940442c956SVesa Jääskeläinen id2str_proc(proc_id));
20950442c956SVesa Jääskeläinen
20960442c956SVesa Jääskeläinen return PKCS11_CKR_KEY_TYPE_INCONSISTENT;
20970442c956SVesa Jääskeläinen }
20980442c956SVesa Jääskeläinen if (key_class != PKCS11_CKO_PUBLIC_KEY &&
20990442c956SVesa Jääskeläinen key_class != PKCS11_CKO_PRIVATE_KEY) {
21000442c956SVesa Jääskeläinen EMSG("Invalid key class for mechanism %s",
21010442c956SVesa Jääskeläinen id2str_proc(proc_id));
21020442c956SVesa Jääskeläinen
21030442c956SVesa Jääskeläinen return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED;
21040442c956SVesa Jääskeläinen }
21050442c956SVesa Jääskeläinen break;
2106512cbf1dSJens Wiklander default:
2107512cbf1dSJens Wiklander DMSG("Invalid processing %#"PRIx32"/%s", proc_id,
2108512cbf1dSJens Wiklander id2str_proc(proc_id));
2109512cbf1dSJens Wiklander
2110512cbf1dSJens Wiklander return PKCS11_CKR_MECHANISM_INVALID;
2111512cbf1dSJens Wiklander }
2112512cbf1dSJens Wiklander
2113512cbf1dSJens Wiklander if (!parent_key_complies_allowed_processings(proc_id, head)) {
2114512cbf1dSJens Wiklander DMSG("Allowed mechanism failed");
2115512cbf1dSJens Wiklander return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED;
2116512cbf1dSJens Wiklander }
2117512cbf1dSJens Wiklander
2118512cbf1dSJens Wiklander return PKCS11_CKR_OK;
2119512cbf1dSJens Wiklander }
2120783c1515SRuchika Gupta
attribute_is_exportable(struct pkcs11_attribute_head * req_attr,struct pkcs11_object * obj)2121783c1515SRuchika Gupta bool attribute_is_exportable(struct pkcs11_attribute_head *req_attr,
2122783c1515SRuchika Gupta struct pkcs11_object *obj)
2123783c1515SRuchika Gupta {
2124783c1515SRuchika Gupta uint8_t boolval = 0;
2125783c1515SRuchika Gupta uint32_t boolsize = 0;
2126783c1515SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
2127783c1515SRuchika Gupta enum pkcs11_class_id key_class = get_class(obj->attributes);
2128783c1515SRuchika Gupta
2129981966bcSVesa Jääskeläinen if (attribute_is_hidden(req_attr))
2130981966bcSVesa Jääskeläinen return false;
2131981966bcSVesa Jääskeläinen
2132783c1515SRuchika Gupta if (key_class != PKCS11_CKO_SECRET_KEY &&
2133783c1515SRuchika Gupta key_class != PKCS11_CKO_PRIVATE_KEY)
2134783c1515SRuchika Gupta return true;
2135783c1515SRuchika Gupta
2136783c1515SRuchika Gupta switch (req_attr->id) {
2137783c1515SRuchika Gupta case PKCS11_CKA_PRIVATE_EXPONENT:
2138783c1515SRuchika Gupta case PKCS11_CKA_PRIME_1:
2139783c1515SRuchika Gupta case PKCS11_CKA_PRIME_2:
2140783c1515SRuchika Gupta case PKCS11_CKA_EXPONENT_1:
2141783c1515SRuchika Gupta case PKCS11_CKA_EXPONENT_2:
2142783c1515SRuchika Gupta case PKCS11_CKA_COEFFICIENT:
2143783c1515SRuchika Gupta case PKCS11_CKA_VALUE:
2144783c1515SRuchika Gupta boolsize = sizeof(boolval);
2145783c1515SRuchika Gupta rc = get_attribute(obj->attributes, PKCS11_CKA_EXTRACTABLE,
2146783c1515SRuchika Gupta &boolval, &boolsize);
2147783c1515SRuchika Gupta if (rc || boolval == PKCS11_FALSE)
2148783c1515SRuchika Gupta return false;
2149783c1515SRuchika Gupta
2150783c1515SRuchika Gupta boolsize = sizeof(boolval);
2151783c1515SRuchika Gupta rc = get_attribute(obj->attributes, PKCS11_CKA_SENSITIVE,
2152783c1515SRuchika Gupta &boolval, &boolsize);
2153783c1515SRuchika Gupta if (rc || boolval == PKCS11_TRUE)
2154783c1515SRuchika Gupta return false;
2155783c1515SRuchika Gupta break;
2156783c1515SRuchika Gupta default:
2157783c1515SRuchika Gupta break;
2158783c1515SRuchika Gupta }
2159783c1515SRuchika Gupta
2160783c1515SRuchika Gupta return true;
2161783c1515SRuchika Gupta }
21622d25a9bcSRuchika Gupta
attr_is_modifiable_any_key(struct pkcs11_attribute_head * attr)21632d25a9bcSRuchika Gupta static bool attr_is_modifiable_any_key(struct pkcs11_attribute_head *attr)
21642d25a9bcSRuchika Gupta {
21652d25a9bcSRuchika Gupta switch (attr->id) {
21662d25a9bcSRuchika Gupta case PKCS11_CKA_ID:
21672d25a9bcSRuchika Gupta case PKCS11_CKA_START_DATE:
21682d25a9bcSRuchika Gupta case PKCS11_CKA_END_DATE:
21692d25a9bcSRuchika Gupta case PKCS11_CKA_DERIVE:
21702d25a9bcSRuchika Gupta return true;
21712d25a9bcSRuchika Gupta default:
21722d25a9bcSRuchika Gupta return false;
21732d25a9bcSRuchika Gupta }
21742d25a9bcSRuchika Gupta }
21752d25a9bcSRuchika Gupta
attr_is_modifiable_secret_key(struct pkcs11_attribute_head * attr,struct pkcs11_session * session,struct pkcs11_object * obj)21762d25a9bcSRuchika Gupta static bool attr_is_modifiable_secret_key(struct pkcs11_attribute_head *attr,
21772d25a9bcSRuchika Gupta struct pkcs11_session *session,
21782d25a9bcSRuchika Gupta struct pkcs11_object *obj)
21792d25a9bcSRuchika Gupta {
21802d25a9bcSRuchika Gupta switch (attr->id) {
21812d25a9bcSRuchika Gupta case PKCS11_CKA_ENCRYPT:
21822d25a9bcSRuchika Gupta case PKCS11_CKA_DECRYPT:
21832d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN:
21842d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY:
21852d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP:
21862d25a9bcSRuchika Gupta case PKCS11_CKA_UNWRAP:
2187bcac2127SMarouene Boubakri case PKCS11_CKA_CHECK_VALUE:
21882d25a9bcSRuchika Gupta return true;
21892d25a9bcSRuchika Gupta /* Can't be modified once set to CK_FALSE - 12 in Table 10 */
21902d25a9bcSRuchika Gupta case PKCS11_CKA_EXTRACTABLE:
21912d25a9bcSRuchika Gupta return get_bool(obj->attributes, attr->id);
21922d25a9bcSRuchika Gupta /* Can't be modified once set to CK_TRUE - 11 in Table 10 */
21932d25a9bcSRuchika Gupta case PKCS11_CKA_SENSITIVE:
21942d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP_WITH_TRUSTED:
21952d25a9bcSRuchika Gupta return !get_bool(obj->attributes, attr->id);
21962d25a9bcSRuchika Gupta /* Change in CKA_TRUSTED can only be done by SO */
21972d25a9bcSRuchika Gupta case PKCS11_CKA_TRUSTED:
21982d25a9bcSRuchika Gupta return pkcs11_session_is_so(session);
21992d25a9bcSRuchika Gupta case PKCS11_CKA_NEVER_EXTRACTABLE:
22002d25a9bcSRuchika Gupta case PKCS11_CKA_ALWAYS_SENSITIVE:
22012d25a9bcSRuchika Gupta return false;
22022d25a9bcSRuchika Gupta default:
22032d25a9bcSRuchika Gupta return false;
22042d25a9bcSRuchika Gupta }
22052d25a9bcSRuchika Gupta }
22062d25a9bcSRuchika Gupta
attr_is_modifiable_public_key(struct pkcs11_attribute_head * attr,struct pkcs11_session * session,struct pkcs11_object * obj __unused)22072d25a9bcSRuchika Gupta static bool attr_is_modifiable_public_key(struct pkcs11_attribute_head *attr,
22082d25a9bcSRuchika Gupta struct pkcs11_session *session,
22092d25a9bcSRuchika Gupta struct pkcs11_object *obj __unused)
22102d25a9bcSRuchika Gupta {
22112d25a9bcSRuchika Gupta switch (attr->id) {
22122d25a9bcSRuchika Gupta case PKCS11_CKA_SUBJECT:
22132d25a9bcSRuchika Gupta case PKCS11_CKA_ENCRYPT:
22142d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY:
22152d25a9bcSRuchika Gupta case PKCS11_CKA_VERIFY_RECOVER:
22162d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP:
22172d25a9bcSRuchika Gupta return true;
22182d25a9bcSRuchika Gupta case PKCS11_CKA_TRUSTED:
22192d25a9bcSRuchika Gupta /* Change in CKA_TRUSTED can only be done by SO */
22202d25a9bcSRuchika Gupta return pkcs11_session_is_so(session);
22212d25a9bcSRuchika Gupta default:
22222d25a9bcSRuchika Gupta return false;
22232d25a9bcSRuchika Gupta }
22242d25a9bcSRuchika Gupta }
22252d25a9bcSRuchika Gupta
attr_is_modifiable_private_key(struct pkcs11_attribute_head * attr,struct pkcs11_session * sess __unused,struct pkcs11_object * obj)22262d25a9bcSRuchika Gupta static bool attr_is_modifiable_private_key(struct pkcs11_attribute_head *attr,
22272d25a9bcSRuchika Gupta struct pkcs11_session *sess __unused,
22282d25a9bcSRuchika Gupta struct pkcs11_object *obj)
22292d25a9bcSRuchika Gupta {
22302d25a9bcSRuchika Gupta switch (attr->id) {
22312d25a9bcSRuchika Gupta case PKCS11_CKA_SUBJECT:
22322d25a9bcSRuchika Gupta case PKCS11_CKA_DECRYPT:
22332d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN:
22342d25a9bcSRuchika Gupta case PKCS11_CKA_SIGN_RECOVER:
22352d25a9bcSRuchika Gupta case PKCS11_CKA_UNWRAP:
22362d25a9bcSRuchika Gupta /*
22372d25a9bcSRuchika Gupta * TBD: Revisit if we don't support PKCS11_CKA_PUBLIC_KEY_INFO
22382d25a9bcSRuchika Gupta * Specification mentions that if this attribute is
22392d25a9bcSRuchika Gupta * supplied as part of a template for C_CreateObject, C_CopyObject or
22402d25a9bcSRuchika Gupta * C_SetAttributeValue for a private key, the token MUST verify
22412d25a9bcSRuchika Gupta * correspondence between the private key data and the public key data
22422d25a9bcSRuchika Gupta * as supplied in CKA_PUBLIC_KEY_INFO. This needs to be
22432d25a9bcSRuchika Gupta * taken care of when this object type will be implemented
22442d25a9bcSRuchika Gupta */
22452d25a9bcSRuchika Gupta case PKCS11_CKA_PUBLIC_KEY_INFO:
22462d25a9bcSRuchika Gupta return true;
22472d25a9bcSRuchika Gupta /* Can't be modified once set to CK_FALSE - 12 in Table 10 */
22482d25a9bcSRuchika Gupta case PKCS11_CKA_EXTRACTABLE:
22492d25a9bcSRuchika Gupta return get_bool(obj->attributes, attr->id);
22502d25a9bcSRuchika Gupta /* Can't be modified once set to CK_TRUE - 11 in Table 10 */
22512d25a9bcSRuchika Gupta case PKCS11_CKA_SENSITIVE:
22522d25a9bcSRuchika Gupta case PKCS11_CKA_WRAP_WITH_TRUSTED:
22532d25a9bcSRuchika Gupta return !get_bool(obj->attributes, attr->id);
22542d25a9bcSRuchika Gupta case PKCS11_CKA_NEVER_EXTRACTABLE:
22552d25a9bcSRuchika Gupta case PKCS11_CKA_ALWAYS_SENSITIVE:
22562d25a9bcSRuchika Gupta return false;
22572d25a9bcSRuchika Gupta default:
22582d25a9bcSRuchika Gupta return false;
22592d25a9bcSRuchika Gupta }
22602d25a9bcSRuchika Gupta }
22612d25a9bcSRuchika Gupta
attr_is_modifiable_certificate(struct pkcs11_attribute_head * attr,struct pkcs11_session * session,struct pkcs11_object * obj)22624137952dSVesa Jääskeläinen static bool attr_is_modifiable_certificate(struct pkcs11_attribute_head *attr,
22634137952dSVesa Jääskeläinen struct pkcs11_session *session,
22644137952dSVesa Jääskeläinen struct pkcs11_object *obj)
22654137952dSVesa Jääskeläinen {
22664137952dSVesa Jääskeläinen uint8_t boolval = 0;
22674137952dSVesa Jääskeläinen uint32_t boolsize = 0;
22684137952dSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
22694137952dSVesa Jääskeläinen
22704137952dSVesa Jääskeläinen /* Trusted certificates cannot be modified. */
22714137952dSVesa Jääskeläinen rc = get_attribute(obj->attributes, PKCS11_CKA_TRUSTED,
22724137952dSVesa Jääskeläinen &boolval, &boolsize);
22734137952dSVesa Jääskeläinen if (rc || boolval == PKCS11_TRUE)
22744137952dSVesa Jääskeläinen return false;
22754137952dSVesa Jääskeläinen
22764137952dSVesa Jääskeläinen /* Common certificate attributes */
22774137952dSVesa Jääskeläinen switch (attr->id) {
22784137952dSVesa Jääskeläinen case PKCS11_CKA_TRUSTED:
22794137952dSVesa Jääskeläinen /*
22804137952dSVesa Jääskeläinen * The CKA_TRUSTED attribute cannot be set to CK_TRUE by an
22814137952dSVesa Jääskeläinen * application. It MUST be set by a token initialization
22824137952dSVesa Jääskeläinen * application or by the token’s SO.
22834137952dSVesa Jääskeläinen */
22844137952dSVesa Jääskeläinen return pkcs11_session_is_so(session);
22854137952dSVesa Jääskeläinen case PKCS11_CKA_CERTIFICATE_TYPE:
22864137952dSVesa Jääskeläinen case PKCS11_CKA_CERTIFICATE_CATEGORY:
22874137952dSVesa Jääskeläinen return false;
22884137952dSVesa Jääskeläinen default:
22894137952dSVesa Jääskeläinen break;
22904137952dSVesa Jääskeläinen }
22914137952dSVesa Jääskeläinen
22924137952dSVesa Jääskeläinen /* Certificate type specific attributes */
22934137952dSVesa Jääskeläinen switch (get_certificate_type(obj->attributes)) {
22944137952dSVesa Jääskeläinen case PKCS11_CKC_X_509:
22954137952dSVesa Jääskeläinen /*
22964137952dSVesa Jääskeläinen * Only the CKA_ID, CKA_ISSUER, and CKA_SERIAL_NUMBER
22974137952dSVesa Jääskeläinen * attributes may be modified after the object is created.
22984137952dSVesa Jääskeläinen */
22994137952dSVesa Jääskeläinen switch (attr->id) {
23004137952dSVesa Jääskeläinen case PKCS11_CKA_ID:
23014137952dSVesa Jääskeläinen case PKCS11_CKA_ISSUER:
23024137952dSVesa Jääskeläinen case PKCS11_CKA_SERIAL_NUMBER:
23034137952dSVesa Jääskeläinen return true;
23044137952dSVesa Jääskeläinen default:
23054137952dSVesa Jääskeläinen break;
23064137952dSVesa Jääskeläinen }
23074137952dSVesa Jääskeläinen break;
23084137952dSVesa Jääskeläinen default:
23094137952dSVesa Jääskeläinen /* Unsupported certificate type */
23104137952dSVesa Jääskeläinen break;
23114137952dSVesa Jääskeläinen }
23124137952dSVesa Jääskeläinen
23134137952dSVesa Jääskeläinen return false;
23144137952dSVesa Jääskeläinen }
23154137952dSVesa Jääskeläinen
attribute_is_modifiable(struct pkcs11_session * session,struct pkcs11_attribute_head * req_attr,struct pkcs11_object * obj,enum pkcs11_class_id class,enum processing_func function)23162d25a9bcSRuchika Gupta static bool attribute_is_modifiable(struct pkcs11_session *session,
23172d25a9bcSRuchika Gupta struct pkcs11_attribute_head *req_attr,
23182d25a9bcSRuchika Gupta struct pkcs11_object *obj,
23192d25a9bcSRuchika Gupta enum pkcs11_class_id class,
23202d25a9bcSRuchika Gupta enum processing_func function)
23212d25a9bcSRuchika Gupta {
23222d25a9bcSRuchika Gupta /* Check modifiable attributes common to any object */
23232d25a9bcSRuchika Gupta switch (req_attr->id) {
23242d25a9bcSRuchika Gupta case PKCS11_CKA_LABEL:
23252d25a9bcSRuchika Gupta return true;
23262d25a9bcSRuchika Gupta case PKCS11_CKA_TOKEN:
23272d25a9bcSRuchika Gupta case PKCS11_CKA_MODIFIABLE:
23282d25a9bcSRuchika Gupta case PKCS11_CKA_DESTROYABLE:
23292d25a9bcSRuchika Gupta case PKCS11_CKA_PRIVATE:
23302d25a9bcSRuchika Gupta return function == PKCS11_FUNCTION_COPY;
23312d25a9bcSRuchika Gupta case PKCS11_CKA_COPYABLE:
23322d25a9bcSRuchika Gupta /*
23332d25a9bcSRuchika Gupta * Specification mentions that if the attribute value is false
23342d25a9bcSRuchika Gupta * it can't be set to true. Reading this we assume that it
23352d25a9bcSRuchika Gupta * should be possible to modify this attribute even though this
23362d25a9bcSRuchika Gupta * is not marked as modifiable in Table 10 if done in right
23372d25a9bcSRuchika Gupta * direction i.e from TRUE -> FALSE.
23382d25a9bcSRuchika Gupta */
23392d25a9bcSRuchika Gupta return get_bool(obj->attributes, req_attr->id);
23402d25a9bcSRuchika Gupta default:
23412d25a9bcSRuchika Gupta break;
23422d25a9bcSRuchika Gupta }
23432d25a9bcSRuchika Gupta
23442d25a9bcSRuchika Gupta /* Attribute checking based on class type */
23452d25a9bcSRuchika Gupta switch (class) {
23462d25a9bcSRuchika Gupta case PKCS11_CKO_SECRET_KEY:
23472d25a9bcSRuchika Gupta case PKCS11_CKO_PUBLIC_KEY:
23482d25a9bcSRuchika Gupta case PKCS11_CKO_PRIVATE_KEY:
23492d25a9bcSRuchika Gupta if (attr_is_modifiable_any_key(req_attr))
23502d25a9bcSRuchika Gupta return true;
23512d25a9bcSRuchika Gupta if (class == PKCS11_CKO_SECRET_KEY &&
23522d25a9bcSRuchika Gupta attr_is_modifiable_secret_key(req_attr, session, obj))
23532d25a9bcSRuchika Gupta return true;
23542d25a9bcSRuchika Gupta if (class == PKCS11_CKO_PUBLIC_KEY &&
23552d25a9bcSRuchika Gupta attr_is_modifiable_public_key(req_attr, session, obj))
23562d25a9bcSRuchika Gupta return true;
23572d25a9bcSRuchika Gupta if (class == PKCS11_CKO_PRIVATE_KEY &&
23582d25a9bcSRuchika Gupta attr_is_modifiable_private_key(req_attr, session, obj))
23592d25a9bcSRuchika Gupta return true;
23602d25a9bcSRuchika Gupta break;
23612d25a9bcSRuchika Gupta case PKCS11_CKO_DATA:
23622d25a9bcSRuchika Gupta /* None of the data object attributes are modifiable */
23632d25a9bcSRuchika Gupta return false;
23644137952dSVesa Jääskeläinen case PKCS11_CKO_CERTIFICATE:
23654137952dSVesa Jääskeläinen return attr_is_modifiable_certificate(req_attr, session, obj);
23662d25a9bcSRuchika Gupta default:
23672d25a9bcSRuchika Gupta break;
23682d25a9bcSRuchika Gupta }
23692d25a9bcSRuchika Gupta
23702d25a9bcSRuchika Gupta return false;
23712d25a9bcSRuchika Gupta }
23722d25a9bcSRuchika Gupta
check_attrs_against_modification(struct pkcs11_session * session,struct obj_attrs * head,struct pkcs11_object * obj,enum processing_func function)23732d25a9bcSRuchika Gupta enum pkcs11_rc check_attrs_against_modification(struct pkcs11_session *session,
23742d25a9bcSRuchika Gupta struct obj_attrs *head,
23752d25a9bcSRuchika Gupta struct pkcs11_object *obj,
23762d25a9bcSRuchika Gupta enum processing_func function)
23772d25a9bcSRuchika Gupta {
23782d25a9bcSRuchika Gupta enum pkcs11_class_id class = PKCS11_CKO_UNDEFINED_ID;
23792d25a9bcSRuchika Gupta char *cur = NULL;
23802d25a9bcSRuchika Gupta char *end = NULL;
23812d25a9bcSRuchika Gupta size_t len = 0;
23822d25a9bcSRuchika Gupta
23832d25a9bcSRuchika Gupta class = get_class(obj->attributes);
23842d25a9bcSRuchika Gupta
23852d25a9bcSRuchika Gupta cur = (char *)head + sizeof(struct obj_attrs);
23862d25a9bcSRuchika Gupta end = cur + head->attrs_size;
23872d25a9bcSRuchika Gupta
23882d25a9bcSRuchika Gupta for (; cur < end; cur += len) {
23892d25a9bcSRuchika Gupta /* Structure aligned copy of the pkcs11_ref in the object */
23902d25a9bcSRuchika Gupta struct pkcs11_attribute_head cli_ref = { };
23912d25a9bcSRuchika Gupta
23922d25a9bcSRuchika Gupta TEE_MemMove(&cli_ref, cur, sizeof(cli_ref));
23932d25a9bcSRuchika Gupta len = sizeof(cli_ref) + cli_ref.size;
23942d25a9bcSRuchika Gupta
2395981966bcSVesa Jääskeläinen /* Protect hidden attributes */
2396981966bcSVesa Jääskeläinen if (attribute_is_hidden(&cli_ref))
2397981966bcSVesa Jääskeläinen return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
2398981966bcSVesa Jääskeläinen
23992d25a9bcSRuchika Gupta /*
24002d25a9bcSRuchika Gupta * Check 1 - Check if attribute belongs to the object
24012d25a9bcSRuchika Gupta * The obj->attributes has all the attributes in
24022d25a9bcSRuchika Gupta * it which are allowed for an object.
24032d25a9bcSRuchika Gupta */
24042d25a9bcSRuchika Gupta if (get_attribute_ptr(obj->attributes, cli_ref.id, NULL,
24052d25a9bcSRuchika Gupta NULL) == PKCS11_RV_NOT_FOUND)
24062d25a9bcSRuchika Gupta return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
24072d25a9bcSRuchika Gupta
24082d25a9bcSRuchika Gupta /* Check 2 - Is attribute modifiable */
24092d25a9bcSRuchika Gupta if (!attribute_is_modifiable(session, &cli_ref, obj, class,
24102d25a9bcSRuchika Gupta function))
24112d25a9bcSRuchika Gupta return PKCS11_CKR_ATTRIBUTE_READ_ONLY;
24122d25a9bcSRuchika Gupta
24132d25a9bcSRuchika Gupta /*
24142d25a9bcSRuchika Gupta * Checks for modification in PKCS11_CKA_TOKEN and
24152d25a9bcSRuchika Gupta * PKCS11_CKA_PRIVATE are required for PKCS11_FUNCTION_COPY
24162d25a9bcSRuchika Gupta * only, so skip them for PKCS11_FUNCTION_MODIFY.
24172d25a9bcSRuchika Gupta */
24182d25a9bcSRuchika Gupta if (function == PKCS11_FUNCTION_MODIFY)
24192d25a9bcSRuchika Gupta continue;
24202d25a9bcSRuchika Gupta
24212d25a9bcSRuchika Gupta /*
24222d25a9bcSRuchika Gupta * An attempt to copy an object to a token will fail for
24232d25a9bcSRuchika Gupta * RO session
24242d25a9bcSRuchika Gupta */
24252d25a9bcSRuchika Gupta if (cli_ref.id == PKCS11_CKA_TOKEN &&
24262d25a9bcSRuchika Gupta get_bool(head, PKCS11_CKA_TOKEN)) {
24272d25a9bcSRuchika Gupta if (!pkcs11_session_is_read_write(session)) {
24282d25a9bcSRuchika Gupta DMSG("Can't copy to token in a RO session");
24292d25a9bcSRuchika Gupta return PKCS11_CKR_SESSION_READ_ONLY;
24302d25a9bcSRuchika Gupta }
24312d25a9bcSRuchika Gupta }
24322d25a9bcSRuchika Gupta
24332d25a9bcSRuchika Gupta if (cli_ref.id == PKCS11_CKA_PRIVATE) {
24342d25a9bcSRuchika Gupta bool parent_priv =
24352d25a9bcSRuchika Gupta get_bool(obj->attributes, cli_ref.id);
24362d25a9bcSRuchika Gupta bool obj_priv = get_bool(head, cli_ref.id);
24372d25a9bcSRuchika Gupta
24382d25a9bcSRuchika Gupta /*
24392d25a9bcSRuchika Gupta * If PKCS11_CKA_PRIVATE is being set to TRUE from
24402d25a9bcSRuchika Gupta * FALSE, user has to be logged in
24412d25a9bcSRuchika Gupta */
24422d25a9bcSRuchika Gupta if (!parent_priv && obj_priv) {
24432d25a9bcSRuchika Gupta if ((pkcs11_session_is_public(session) ||
24442d25a9bcSRuchika Gupta pkcs11_session_is_so(session)))
24452d25a9bcSRuchika Gupta return PKCS11_CKR_USER_NOT_LOGGED_IN;
24462d25a9bcSRuchika Gupta }
2447df017b2bSRuchika Gupta
2448df017b2bSRuchika Gupta /*
2449df017b2bSRuchika Gupta * Restriction added - Even for Copy, do not allow
2450df017b2bSRuchika Gupta * modification of CKA_PRIVATE from TRUE to FALSE
2451df017b2bSRuchika Gupta */
2452df017b2bSRuchika Gupta if (parent_priv && !obj_priv)
2453df017b2bSRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT;
24542d25a9bcSRuchika Gupta }
24552d25a9bcSRuchika Gupta }
24562d25a9bcSRuchika Gupta
24572d25a9bcSRuchika Gupta return PKCS11_CKR_OK;
24582d25a9bcSRuchika Gupta }
24598c499324SRuchika Gupta
set_secret_key_data(struct obj_attrs ** head,void * data,size_t key_size)24608c499324SRuchika Gupta static enum pkcs11_rc set_secret_key_data(struct obj_attrs **head, void *data,
24618c499324SRuchika Gupta size_t key_size)
24628c499324SRuchika Gupta {
24638c499324SRuchika Gupta uint32_t size = sizeof(uint32_t);
24648c499324SRuchika Gupta uint32_t key_length = 0;
24658c499324SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
24668c499324SRuchika Gupta
24678c499324SRuchika Gupta /* Get key size if present in template */
24688c499324SRuchika Gupta rc = get_attribute(*head, PKCS11_CKA_VALUE_LEN, &key_length, &size);
24698c499324SRuchika Gupta if (rc && rc != PKCS11_RV_NOT_FOUND)
24708c499324SRuchika Gupta return rc;
24718c499324SRuchika Gupta
24728c499324SRuchika Gupta if (key_length) {
24738c499324SRuchika Gupta if (key_size < key_length)
24748c499324SRuchika Gupta return PKCS11_CKR_DATA_LEN_RANGE;
24758c499324SRuchika Gupta } else {
24768c499324SRuchika Gupta key_length = key_size;
24778c499324SRuchika Gupta rc = set_attribute(head, PKCS11_CKA_VALUE_LEN, &key_length,
24788c499324SRuchika Gupta sizeof(uint32_t));
24798c499324SRuchika Gupta if (rc)
24808c499324SRuchika Gupta return rc;
24818c499324SRuchika Gupta }
24828c499324SRuchika Gupta
24838c499324SRuchika Gupta /* Now we can check the VALUE_LEN field */
24848c499324SRuchika Gupta rc = check_created_attrs(*head, NULL);
24858c499324SRuchika Gupta if (rc)
24868c499324SRuchika Gupta return rc;
24878c499324SRuchika Gupta
24888c499324SRuchika Gupta /* Remove the default empty value attribute if found */
24898c499324SRuchika Gupta rc = remove_empty_attribute(head, PKCS11_CKA_VALUE);
24908c499324SRuchika Gupta if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
24918c499324SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR;
24928c499324SRuchika Gupta
2493bcac2127SMarouene Boubakri rc = add_attribute(head, PKCS11_CKA_VALUE, data, key_length);
2494bcac2127SMarouene Boubakri if (rc)
2495bcac2127SMarouene Boubakri return rc;
2496bcac2127SMarouene Boubakri
2497bcac2127SMarouene Boubakri return set_check_value_attr(head);
24988c499324SRuchika Gupta }
24998c499324SRuchika Gupta
set_private_key_data_rsa(struct obj_attrs ** head,void * data,size_t key_size)250045d40bdaSValerii Chubar static enum pkcs11_rc set_private_key_data_rsa(struct obj_attrs **head,
250145d40bdaSValerii Chubar void *data,
250245d40bdaSValerii Chubar size_t key_size)
250345d40bdaSValerii Chubar {
250445d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
250545d40bdaSValerii Chubar int mbedtls_rc = 0;
250645d40bdaSValerii Chubar uint32_t key_bits = 0;
250745d40bdaSValerii Chubar uint32_t size = 0;
250845d40bdaSValerii Chubar uint32_t buffer_size = 0;
250945d40bdaSValerii Chubar void *buffer = NULL;
251045d40bdaSValerii Chubar mbedtls_pk_context pk = { };
251145d40bdaSValerii Chubar mbedtls_rsa_context *rsa = NULL;
251245d40bdaSValerii Chubar mbedtls_mpi n = { };
251345d40bdaSValerii Chubar mbedtls_mpi e = { };
251445d40bdaSValerii Chubar mbedtls_mpi d = { };
251545d40bdaSValerii Chubar mbedtls_mpi p = { };
251645d40bdaSValerii Chubar mbedtls_mpi q = { };
251745d40bdaSValerii Chubar
251845d40bdaSValerii Chubar rc = get_u32_attribute(*head, PKCS11_CKA_MODULUS_BITS, &key_bits);
251945d40bdaSValerii Chubar if (rc && rc != PKCS11_RV_NOT_FOUND)
252045d40bdaSValerii Chubar return rc;
252145d40bdaSValerii Chubar
252245d40bdaSValerii Chubar if (remove_empty_attribute(head, PKCS11_CKA_MODULUS) ||
252345d40bdaSValerii Chubar remove_empty_attribute(head, PKCS11_CKA_PUBLIC_EXPONENT) ||
252445d40bdaSValerii Chubar remove_empty_attribute(head, PKCS11_CKA_PRIVATE_EXPONENT) ||
252545d40bdaSValerii Chubar remove_empty_attribute(head, PKCS11_CKA_PRIME_1) ||
252645d40bdaSValerii Chubar remove_empty_attribute(head, PKCS11_CKA_PRIME_2))
252745d40bdaSValerii Chubar return PKCS11_CKR_GENERAL_ERROR;
252845d40bdaSValerii Chubar
252945d40bdaSValerii Chubar mbedtls_pk_init(&pk);
253045d40bdaSValerii Chubar mbedtls_mpi_init(&n);
253145d40bdaSValerii Chubar mbedtls_mpi_init(&e);
253245d40bdaSValerii Chubar mbedtls_mpi_init(&d);
253345d40bdaSValerii Chubar mbedtls_mpi_init(&p);
253445d40bdaSValerii Chubar mbedtls_mpi_init(&q);
253545d40bdaSValerii Chubar
253632b31808SJens Wiklander mbedtls_rc = mbedtls_pk_parse_key(&pk, data, key_size,
253732b31808SJens Wiklander NULL, 0, mbd_rand, NULL);
253845d40bdaSValerii Chubar if (mbedtls_rc) {
253945d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD;
254045d40bdaSValerii Chubar goto out;
254145d40bdaSValerii Chubar }
254245d40bdaSValerii Chubar
254345d40bdaSValerii Chubar rsa = mbedtls_pk_rsa(pk);
2544a2431e9fSClement Faure if (!rsa) {
2545a2431e9fSClement Faure rc = PKCS11_CKR_GENERAL_ERROR;
2546a2431e9fSClement Faure goto out;
2547a2431e9fSClement Faure }
2548a2431e9fSClement Faure
254945d40bdaSValerii Chubar mbedtls_rc = mbedtls_rsa_export(rsa, &n, &p, &q, &d, &e);
255045d40bdaSValerii Chubar if (mbedtls_rc) {
255145d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD;
255245d40bdaSValerii Chubar goto out;
255345d40bdaSValerii Chubar }
255445d40bdaSValerii Chubar
255545d40bdaSValerii Chubar if (key_bits && mbedtls_mpi_bitlen(&n) != key_bits) {
255645d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE;
255745d40bdaSValerii Chubar goto out;
255845d40bdaSValerii Chubar }
255945d40bdaSValerii Chubar
256045d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&n), 8);
256145d40bdaSValerii Chubar buffer_size = size;
256245d40bdaSValerii Chubar buffer = TEE_Malloc(buffer_size, TEE_USER_MEM_HINT_NO_FILL_ZERO);
256345d40bdaSValerii Chubar if (!buffer) {
256445d40bdaSValerii Chubar rc = PKCS11_CKR_DEVICE_MEMORY;
256545d40bdaSValerii Chubar goto out;
256645d40bdaSValerii Chubar }
256745d40bdaSValerii Chubar
256845d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&n, buffer, size);
256945d40bdaSValerii Chubar if (mbedtls_rc) {
257045d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID;
257145d40bdaSValerii Chubar goto out;
257245d40bdaSValerii Chubar }
257345d40bdaSValerii Chubar
257445d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_MODULUS, buffer, size);
257545d40bdaSValerii Chubar if (rc)
257645d40bdaSValerii Chubar goto out;
257745d40bdaSValerii Chubar
257845d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&e), 8);
257945d40bdaSValerii Chubar if (buffer_size < size) {
258045d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE;
258145d40bdaSValerii Chubar goto out;
258245d40bdaSValerii Chubar }
258345d40bdaSValerii Chubar
258445d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&e, buffer, size);
258545d40bdaSValerii Chubar if (mbedtls_rc) {
258645d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID;
258745d40bdaSValerii Chubar goto out;
258845d40bdaSValerii Chubar }
258945d40bdaSValerii Chubar
259045d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_PUBLIC_EXPONENT, buffer, size);
259145d40bdaSValerii Chubar if (rc)
259245d40bdaSValerii Chubar goto out;
259345d40bdaSValerii Chubar
259445d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&d), 8);
259545d40bdaSValerii Chubar if (buffer_size < size) {
259645d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE;
259745d40bdaSValerii Chubar goto out;
259845d40bdaSValerii Chubar }
259945d40bdaSValerii Chubar
260045d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&d, buffer, size);
260145d40bdaSValerii Chubar if (mbedtls_rc) {
260245d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID;
260345d40bdaSValerii Chubar goto out;
260445d40bdaSValerii Chubar }
260545d40bdaSValerii Chubar
260645d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_PRIVATE_EXPONENT, buffer, size);
260745d40bdaSValerii Chubar if (rc)
260845d40bdaSValerii Chubar goto out;
260945d40bdaSValerii Chubar
261045d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&p), 8);
261145d40bdaSValerii Chubar if (buffer_size < size) {
261245d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE;
261345d40bdaSValerii Chubar goto out;
261445d40bdaSValerii Chubar }
261545d40bdaSValerii Chubar
261645d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&p, buffer, size);
261745d40bdaSValerii Chubar if (mbedtls_rc) {
261845d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID;
261945d40bdaSValerii Chubar goto out;
262045d40bdaSValerii Chubar }
262145d40bdaSValerii Chubar
262245d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_PRIME_1, buffer, size);
262345d40bdaSValerii Chubar if (rc)
262445d40bdaSValerii Chubar goto out;
262545d40bdaSValerii Chubar
262645d40bdaSValerii Chubar size = ROUNDUP_DIV(mbedtls_mpi_bitlen(&q), 8);
262745d40bdaSValerii Chubar if (buffer_size < size) {
262845d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_LEN_RANGE;
262945d40bdaSValerii Chubar goto out;
263045d40bdaSValerii Chubar }
263145d40bdaSValerii Chubar
263245d40bdaSValerii Chubar mbedtls_rc = mbedtls_mpi_write_binary(&q, buffer, size);
263345d40bdaSValerii Chubar if (mbedtls_rc) {
263445d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID;
263545d40bdaSValerii Chubar goto out;
263645d40bdaSValerii Chubar }
263745d40bdaSValerii Chubar
263845d40bdaSValerii Chubar rc = add_attribute(head, PKCS11_CKA_PRIME_2, buffer, size);
263945d40bdaSValerii Chubar
264045d40bdaSValerii Chubar out:
264145d40bdaSValerii Chubar mbedtls_pk_free(&pk);
264245d40bdaSValerii Chubar mbedtls_mpi_free(&n);
264345d40bdaSValerii Chubar mbedtls_mpi_free(&e);
264445d40bdaSValerii Chubar mbedtls_mpi_free(&d);
264545d40bdaSValerii Chubar mbedtls_mpi_free(&p);
264645d40bdaSValerii Chubar mbedtls_mpi_free(&q);
264745d40bdaSValerii Chubar TEE_Free(buffer);
264845d40bdaSValerii Chubar return rc;
264945d40bdaSValerii Chubar }
265045d40bdaSValerii Chubar
set_key_data(struct obj_attrs ** head,void * data,size_t key_size)26518c499324SRuchika Gupta enum pkcs11_rc set_key_data(struct obj_attrs **head, void *data,
26528c499324SRuchika Gupta size_t key_size)
26538c499324SRuchika Gupta {
26548c499324SRuchika Gupta switch (get_class(*head)) {
26558c499324SRuchika Gupta case PKCS11_CKO_SECRET_KEY:
26568c499324SRuchika Gupta return set_secret_key_data(head, data, key_size);
265745d40bdaSValerii Chubar case PKCS11_CKO_PRIVATE_KEY:
265845d40bdaSValerii Chubar if (get_key_type(*head) == PKCS11_CKK_RSA)
265945d40bdaSValerii Chubar return set_private_key_data_rsa(head, data, key_size);
266045d40bdaSValerii Chubar break;
26618c499324SRuchika Gupta default:
26628c499324SRuchika Gupta return PKCS11_CKR_GENERAL_ERROR;
26638c499324SRuchika Gupta }
266445d40bdaSValerii Chubar
266545d40bdaSValerii Chubar return PKCS11_CKR_GENERAL_ERROR;
26668c499324SRuchika Gupta }
26675e1d94ebSVesa Jääskeläinen
alloc_copy_attribute_value(struct obj_attrs * head,void ** data,uint32_t * sz)2668a9aa45d8SValerii Chubar static enum pkcs11_rc alloc_copy_attribute_value(struct obj_attrs *head,
2669a9aa45d8SValerii Chubar void **data, uint32_t *sz)
2670a9aa45d8SValerii Chubar {
2671a9aa45d8SValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
2672a9aa45d8SValerii Chubar void *buffer = NULL;
2673a9aa45d8SValerii Chubar void *value = NULL;
2674a9aa45d8SValerii Chubar
2675a9aa45d8SValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_VALUE, &value, sz);
2676a9aa45d8SValerii Chubar if (rc)
2677a9aa45d8SValerii Chubar return PKCS11_CKR_ARGUMENTS_BAD;
2678a9aa45d8SValerii Chubar
2679a9aa45d8SValerii Chubar buffer = TEE_Malloc(*sz, TEE_USER_MEM_HINT_NO_FILL_ZERO);
2680a9aa45d8SValerii Chubar if (!buffer)
2681a9aa45d8SValerii Chubar return PKCS11_CKR_DEVICE_MEMORY;
2682a9aa45d8SValerii Chubar
2683a9aa45d8SValerii Chubar TEE_MemMove(buffer, value, *sz);
2684a9aa45d8SValerii Chubar *data = buffer;
2685a9aa45d8SValerii Chubar
2686a9aa45d8SValerii Chubar return PKCS11_CKR_OK;
2687a9aa45d8SValerii Chubar }
2688a9aa45d8SValerii Chubar
268945d40bdaSValerii Chubar static enum pkcs11_rc
encode_rsa_private_key_der(struct obj_attrs * head,void ** data,uint32_t * sz)269045d40bdaSValerii Chubar encode_rsa_private_key_der(struct obj_attrs *head, void **data, uint32_t *sz)
269145d40bdaSValerii Chubar {
269245d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
269345d40bdaSValerii Chubar int i = 0;
269445d40bdaSValerii Chubar int mbedtls_rc = 0;
269545d40bdaSValerii Chubar int start = 0;
269645d40bdaSValerii Chubar int der_size = 0;
269745d40bdaSValerii Chubar void *n = NULL;
269845d40bdaSValerii Chubar void *p = NULL;
269945d40bdaSValerii Chubar void *q = NULL;
270045d40bdaSValerii Chubar void *d = NULL;
270145d40bdaSValerii Chubar void *e = NULL;
270245d40bdaSValerii Chubar uint32_t n_len = 0;
270345d40bdaSValerii Chubar uint32_t p_len = 0;
270445d40bdaSValerii Chubar uint32_t q_len = 0;
270545d40bdaSValerii Chubar uint32_t d_len = 0;
270645d40bdaSValerii Chubar uint32_t e_len = 0;
270745d40bdaSValerii Chubar uint8_t *buffer = NULL;
270845d40bdaSValerii Chubar mbedtls_pk_context pk = { };
270945d40bdaSValerii Chubar mbedtls_rsa_context *rsa = NULL;
271045d40bdaSValerii Chubar const mbedtls_pk_info_t *pk_info = NULL;
271145d40bdaSValerii Chubar
271245d40bdaSValerii Chubar mbedtls_pk_init(&pk);
271345d40bdaSValerii Chubar pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
271445d40bdaSValerii Chubar if (mbedtls_pk_setup(&pk, pk_info)) {
271545d40bdaSValerii Chubar rc = PKCS11_CKR_GENERAL_ERROR;
271645d40bdaSValerii Chubar goto out;
271745d40bdaSValerii Chubar }
271845d40bdaSValerii Chubar
271945d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_MODULUS, &n, &n_len);
272045d40bdaSValerii Chubar if (rc)
272145d40bdaSValerii Chubar goto out;
272245d40bdaSValerii Chubar
272345d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_PRIME_1, &p, &p_len);
272445d40bdaSValerii Chubar if (rc)
272545d40bdaSValerii Chubar goto out;
272645d40bdaSValerii Chubar
272745d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_PRIME_2, &q, &q_len);
272845d40bdaSValerii Chubar if (rc)
272945d40bdaSValerii Chubar goto out;
273045d40bdaSValerii Chubar
273145d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_PRIVATE_EXPONENT, &d, &d_len);
273245d40bdaSValerii Chubar if (rc)
273345d40bdaSValerii Chubar goto out;
273445d40bdaSValerii Chubar
273545d40bdaSValerii Chubar rc = get_attribute_ptr(head, PKCS11_CKA_PUBLIC_EXPONENT, &e, &e_len);
273645d40bdaSValerii Chubar if (rc)
273745d40bdaSValerii Chubar goto out;
273845d40bdaSValerii Chubar
273945d40bdaSValerii Chubar rsa = mbedtls_pk_rsa(pk);
2740a2431e9fSClement Faure if (!rsa) {
2741a2431e9fSClement Faure rc = PKCS11_CKR_GENERAL_ERROR;
2742a2431e9fSClement Faure goto out;
2743a2431e9fSClement Faure }
2744a2431e9fSClement Faure
274545d40bdaSValerii Chubar mbedtls_rc = mbedtls_rsa_import_raw(rsa, n, n_len, p, p_len,
274645d40bdaSValerii Chubar q, q_len, d, d_len, e, e_len);
274745d40bdaSValerii Chubar if (mbedtls_rc) {
274845d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD;
274945d40bdaSValerii Chubar goto out;
275045d40bdaSValerii Chubar }
275145d40bdaSValerii Chubar
275245d40bdaSValerii Chubar if (mbedtls_rsa_complete(rsa)) {
275345d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD;
275445d40bdaSValerii Chubar goto out;
275545d40bdaSValerii Chubar }
275645d40bdaSValerii Chubar
275745d40bdaSValerii Chubar if (mbedtls_rsa_check_privkey(rsa)) {
275845d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD;
275945d40bdaSValerii Chubar goto out;
276045d40bdaSValerii Chubar }
276145d40bdaSValerii Chubar
276245d40bdaSValerii Chubar der_size = n_len * 8;
276345d40bdaSValerii Chubar buffer = TEE_Malloc(der_size, TEE_USER_MEM_HINT_NO_FILL_ZERO);
276445d40bdaSValerii Chubar if (!buffer) {
276545d40bdaSValerii Chubar rc = PKCS11_CKR_DEVICE_MEMORY;
276645d40bdaSValerii Chubar goto out;
276745d40bdaSValerii Chubar }
276845d40bdaSValerii Chubar
276945d40bdaSValerii Chubar mbedtls_rc = mbedtls_pk_write_key_der(&pk, buffer, der_size);
277045d40bdaSValerii Chubar if (mbedtls_rc < 0) {
277145d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD;
277245d40bdaSValerii Chubar goto out;
277345d40bdaSValerii Chubar }
277445d40bdaSValerii Chubar
277545d40bdaSValerii Chubar start = der_size - mbedtls_rc;
277645d40bdaSValerii Chubar for (i = 0; i < mbedtls_rc; i++) {
277745d40bdaSValerii Chubar buffer[i] = buffer[i + start];
277845d40bdaSValerii Chubar buffer[i + start] = 0;
277945d40bdaSValerii Chubar }
278045d40bdaSValerii Chubar
278145d40bdaSValerii Chubar *data = buffer;
278245d40bdaSValerii Chubar *sz = mbedtls_rc;
278345d40bdaSValerii Chubar out:
278445d40bdaSValerii Chubar mbedtls_pk_free(&pk);
278545d40bdaSValerii Chubar
278645d40bdaSValerii Chubar if (rc)
278745d40bdaSValerii Chubar TEE_Free(buffer);
278845d40bdaSValerii Chubar
278945d40bdaSValerii Chubar return rc;
279045d40bdaSValerii Chubar }
279145d40bdaSValerii Chubar
alloc_key_data_to_wrap(struct obj_attrs * head,void ** data,uint32_t * sz)2792a9aa45d8SValerii Chubar enum pkcs11_rc alloc_key_data_to_wrap(struct obj_attrs *head, void **data,
27935f80f270SRuchika Gupta uint32_t *sz)
27945f80f270SRuchika Gupta {
279545d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
279645d40bdaSValerii Chubar
27975f80f270SRuchika Gupta switch (get_class(head)) {
27985f80f270SRuchika Gupta case PKCS11_CKO_SECRET_KEY:
279945d40bdaSValerii Chubar rc = alloc_copy_attribute_value(head, data, sz);
280045d40bdaSValerii Chubar break;
280145d40bdaSValerii Chubar case PKCS11_CKO_PRIVATE_KEY:
280245d40bdaSValerii Chubar if (get_key_type(head) == PKCS11_CKK_RSA)
280345d40bdaSValerii Chubar rc = encode_rsa_private_key_der(head, data, sz);
280445d40bdaSValerii Chubar break;
28055f80f270SRuchika Gupta default:
280645d40bdaSValerii Chubar break;
28075f80f270SRuchika Gupta }
28085f80f270SRuchika Gupta
280945d40bdaSValerii Chubar return rc;
28105f80f270SRuchika Gupta }
28115f80f270SRuchika Gupta
add_missing_attribute_id(struct obj_attrs ** pub_head,struct obj_attrs ** priv_head)28125e1d94ebSVesa Jääskeläinen enum pkcs11_rc add_missing_attribute_id(struct obj_attrs **pub_head,
28135e1d94ebSVesa Jääskeläinen struct obj_attrs **priv_head)
28145e1d94ebSVesa Jääskeläinen {
28155e1d94ebSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
28165e1d94ebSVesa Jääskeläinen void *id1 = NULL;
28175e1d94ebSVesa Jääskeläinen uint32_t id1_size = 0;
28185e1d94ebSVesa Jääskeläinen void *id2 = NULL;
28195e1d94ebSVesa Jääskeläinen uint32_t id2_size = 0;
28205e1d94ebSVesa Jääskeläinen
28215e1d94ebSVesa Jääskeläinen assert(pub_head);
28225e1d94ebSVesa Jääskeläinen assert(priv_head);
28235e1d94ebSVesa Jääskeläinen
28245e1d94ebSVesa Jääskeläinen rc = get_attribute_ptr(*pub_head, PKCS11_CKA_ID, &id1, &id1_size);
28255e1d94ebSVesa Jääskeläinen if (rc) {
28265e1d94ebSVesa Jääskeläinen if (rc != PKCS11_RV_NOT_FOUND)
28275e1d94ebSVesa Jääskeläinen return rc;
28285e1d94ebSVesa Jääskeläinen id1 = NULL;
28295e1d94ebSVesa Jääskeläinen } else if (!id1_size) {
28305e1d94ebSVesa Jääskeläinen id1 = NULL;
28315e1d94ebSVesa Jääskeläinen }
28325e1d94ebSVesa Jääskeläinen
28335e1d94ebSVesa Jääskeläinen rc = get_attribute_ptr(*priv_head, PKCS11_CKA_ID, &id2, &id2_size);
28345e1d94ebSVesa Jääskeläinen if (rc) {
28355e1d94ebSVesa Jääskeläinen if (rc != PKCS11_RV_NOT_FOUND)
28365e1d94ebSVesa Jääskeläinen return rc;
28375e1d94ebSVesa Jääskeläinen id2 = NULL;
28385e1d94ebSVesa Jääskeläinen } else if (!id2_size) {
28395e1d94ebSVesa Jääskeläinen id2 = NULL;
28405e1d94ebSVesa Jääskeläinen }
28415e1d94ebSVesa Jääskeläinen
28425e1d94ebSVesa Jääskeläinen /* Both have value -- let them be what caller has specified them */
28435e1d94ebSVesa Jääskeläinen if (id1 && id2)
28445e1d94ebSVesa Jääskeläinen return PKCS11_CKR_OK;
28455e1d94ebSVesa Jääskeläinen
28465e1d94ebSVesa Jääskeläinen /* Both are empty -- leave empty values */
28475e1d94ebSVesa Jääskeläinen if (!id1 && !id2)
28485e1d94ebSVesa Jääskeläinen return PKCS11_CKR_OK;
28495e1d94ebSVesa Jääskeläinen
28505e1d94ebSVesa Jääskeläinen /* Cross copy CKA_ID value */
28515e1d94ebSVesa Jääskeläinen if (id1)
28525e1d94ebSVesa Jääskeläinen return set_attribute(priv_head, PKCS11_CKA_ID, id1, id1_size);
28535e1d94ebSVesa Jääskeläinen else
28545e1d94ebSVesa Jääskeläinen return set_attribute(pub_head, PKCS11_CKA_ID, id2, id2_size);
28555e1d94ebSVesa Jääskeläinen }
2856bcac2127SMarouene Boubakri
2857bcac2127SMarouene Boubakri /*
2858bcac2127SMarouene Boubakri * The key check value is derived from the object by taking the first
2859bcac2127SMarouene Boubakri * three bytes of the SHA-1 hash of the object's CKA_VALUE attribute.
2860bcac2127SMarouene Boubakri */
compute_check_value_with_sha1(void * key,uint32_t key_size,void * kcv)2861bcac2127SMarouene Boubakri static enum pkcs11_rc compute_check_value_with_sha1(void *key,
2862bcac2127SMarouene Boubakri uint32_t key_size,
2863bcac2127SMarouene Boubakri void *kcv)
2864bcac2127SMarouene Boubakri {
2865bcac2127SMarouene Boubakri enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
2866bcac2127SMarouene Boubakri TEE_Result res = TEE_ERROR_GENERIC;
2867bcac2127SMarouene Boubakri TEE_OperationHandle op = TEE_HANDLE_NULL;
2868bcac2127SMarouene Boubakri size_t buf_size = TEE_MAX_HASH_SIZE;
2869bcac2127SMarouene Boubakri uint8_t *buf = NULL;
2870bcac2127SMarouene Boubakri
2871bcac2127SMarouene Boubakri assert(key && kcv);
2872bcac2127SMarouene Boubakri
2873bcac2127SMarouene Boubakri res = TEE_AllocateOperation(&op, TEE_ALG_SHA1, TEE_MODE_DIGEST, 0);
2874bcac2127SMarouene Boubakri rc = tee2pkcs_error(res);
2875bcac2127SMarouene Boubakri if (rc != PKCS11_CKR_OK)
2876bcac2127SMarouene Boubakri goto out;
2877bcac2127SMarouene Boubakri
2878bcac2127SMarouene Boubakri buf = TEE_Malloc(buf_size, TEE_MALLOC_FILL_ZERO);
2879bcac2127SMarouene Boubakri if (!buf) {
2880bcac2127SMarouene Boubakri rc = PKCS11_CKR_DEVICE_MEMORY;
2881bcac2127SMarouene Boubakri goto out;
2882bcac2127SMarouene Boubakri }
2883bcac2127SMarouene Boubakri
2884bcac2127SMarouene Boubakri res = TEE_DigestDoFinal(op, key, key_size, buf, &buf_size);
2885bcac2127SMarouene Boubakri rc = tee2pkcs_error(res);
2886bcac2127SMarouene Boubakri if (rc != PKCS11_CKR_OK)
2887bcac2127SMarouene Boubakri goto out;
2888bcac2127SMarouene Boubakri
2889bcac2127SMarouene Boubakri TEE_MemMove(kcv, buf, PKCS11_CKA_CHECK_VALUE_SIZE);
2890bcac2127SMarouene Boubakri
2891bcac2127SMarouene Boubakri out:
2892bcac2127SMarouene Boubakri TEE_Free(buf);
2893bcac2127SMarouene Boubakri TEE_FreeOperation(op);
2894bcac2127SMarouene Boubakri
2895bcac2127SMarouene Boubakri return rc;
2896bcac2127SMarouene Boubakri }
2897bcac2127SMarouene Boubakri
2898bcac2127SMarouene Boubakri /*
2899bcac2127SMarouene Boubakri * The key check value that is calculated as follows:
2900bcac2127SMarouene Boubakri * 1) Take a buffer of the cipher block size of binary zeros (0x00).
2901bcac2127SMarouene Boubakri * 2) Encrypt this block in ECB mode.
2902bcac2127SMarouene Boubakri * 3) Take the first three bytes of cipher text as the check value.
2903bcac2127SMarouene Boubakri */
compute_check_value_with_ecb(void * key,uint32_t key_size,void * kcv)2904bcac2127SMarouene Boubakri static enum pkcs11_rc compute_check_value_with_ecb(void *key, uint32_t key_size,
2905bcac2127SMarouene Boubakri void *kcv)
2906bcac2127SMarouene Boubakri {
2907bcac2127SMarouene Boubakri enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
2908bcac2127SMarouene Boubakri TEE_Result res = TEE_ERROR_GENERIC;
2909bcac2127SMarouene Boubakri TEE_OperationHandle op = TEE_HANDLE_NULL;
2910bcac2127SMarouene Boubakri TEE_ObjectHandle hkey = TEE_HANDLE_NULL;
2911bcac2127SMarouene Boubakri TEE_Attribute attr = { };
2912adfad2cdSEtienne Carriere uint8_t buf[TEE_AES_BLOCK_SIZE] = { };
2913adfad2cdSEtienne Carriere size_t buf_size = sizeof(buf);
2914bcac2127SMarouene Boubakri
2915bcac2127SMarouene Boubakri assert(key && kcv);
2916bcac2127SMarouene Boubakri
2917bcac2127SMarouene Boubakri res = TEE_AllocateOperation(&op, TEE_ALG_AES_ECB_NOPAD,
2918bcac2127SMarouene Boubakri TEE_MODE_ENCRYPT, key_size * 8);
2919bcac2127SMarouene Boubakri rc = tee2pkcs_error(res);
2920bcac2127SMarouene Boubakri if (rc != PKCS11_CKR_OK)
2921bcac2127SMarouene Boubakri goto out;
2922bcac2127SMarouene Boubakri
2923bcac2127SMarouene Boubakri res = TEE_AllocateTransientObject(TEE_TYPE_AES, key_size * 8, &hkey);
2924bcac2127SMarouene Boubakri rc = tee2pkcs_error(res);
2925bcac2127SMarouene Boubakri if (rc != PKCS11_CKR_OK)
2926bcac2127SMarouene Boubakri goto out;
2927bcac2127SMarouene Boubakri
29283bc92b91SEtienne Carriere TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, key, key_size);
2929bcac2127SMarouene Boubakri
2930bcac2127SMarouene Boubakri res = TEE_PopulateTransientObject(hkey, &attr, 1);
2931bcac2127SMarouene Boubakri rc = tee2pkcs_error(res);
2932bcac2127SMarouene Boubakri if (rc != PKCS11_CKR_OK)
2933bcac2127SMarouene Boubakri goto out;
2934bcac2127SMarouene Boubakri
2935bcac2127SMarouene Boubakri res = TEE_SetOperationKey(op, hkey);
2936bcac2127SMarouene Boubakri rc = tee2pkcs_error(res);
2937bcac2127SMarouene Boubakri if (rc != PKCS11_CKR_OK)
2938bcac2127SMarouene Boubakri goto out;
2939bcac2127SMarouene Boubakri
2940bcac2127SMarouene Boubakri TEE_CipherInit(op, NULL, 0);
2941bcac2127SMarouene Boubakri
2942bcac2127SMarouene Boubakri res = TEE_CipherDoFinal(op, buf, buf_size, buf, &buf_size);
2943bcac2127SMarouene Boubakri rc = tee2pkcs_error(res);
2944bcac2127SMarouene Boubakri if (rc != PKCS11_CKR_OK)
2945bcac2127SMarouene Boubakri goto out;
2946bcac2127SMarouene Boubakri
2947bcac2127SMarouene Boubakri TEE_MemMove(kcv, buf, PKCS11_CKA_CHECK_VALUE_SIZE);
2948bcac2127SMarouene Boubakri
2949bcac2127SMarouene Boubakri out:
2950bcac2127SMarouene Boubakri TEE_FreeTransientObject(hkey);
2951bcac2127SMarouene Boubakri TEE_FreeOperation(op);
2952bcac2127SMarouene Boubakri
2953bcac2127SMarouene Boubakri return rc;
2954bcac2127SMarouene Boubakri }
2955bcac2127SMarouene Boubakri
set_check_value_attr(struct obj_attrs ** head)2956bcac2127SMarouene Boubakri enum pkcs11_rc set_check_value_attr(struct obj_attrs **head)
2957bcac2127SMarouene Boubakri {
2958bcac2127SMarouene Boubakri enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
2959bcac2127SMarouene Boubakri uint32_t val_len = 0;
2960bcac2127SMarouene Boubakri uint32_t kcv2_len = 0;
2961bcac2127SMarouene Boubakri void *val = NULL;
2962bcac2127SMarouene Boubakri uint8_t kcv[PKCS11_CKA_CHECK_VALUE_SIZE] = { };
2963bcac2127SMarouene Boubakri void *kcv2 = NULL;
2964bcac2127SMarouene Boubakri
2965bcac2127SMarouene Boubakri assert(head && *head);
2966bcac2127SMarouene Boubakri
2967bcac2127SMarouene Boubakri if (!IS_ENABLED(CFG_PKCS11_TA_CHECK_VALUE_ATTRIBUTE))
2968bcac2127SMarouene Boubakri return PKCS11_CKR_OK;
2969bcac2127SMarouene Boubakri
2970bcac2127SMarouene Boubakri switch (get_class(*head)) {
2971bcac2127SMarouene Boubakri case PKCS11_CKO_SECRET_KEY:
2972bcac2127SMarouene Boubakri case PKCS11_CKO_CERTIFICATE:
2973bcac2127SMarouene Boubakri break;
2974bcac2127SMarouene Boubakri default:
2975cfbe7874SEtienne Carriere /* Nothing to do */
2976cfbe7874SEtienne Carriere return PKCS11_CKR_OK;
2977bcac2127SMarouene Boubakri }
2978bcac2127SMarouene Boubakri
2979bcac2127SMarouene Boubakri /* Check whether CKA_CHECK_VALUE has been provided in the template */
2980bcac2127SMarouene Boubakri rc = get_attribute_ptr(*head, PKCS11_CKA_CHECK_VALUE, &kcv2, &kcv2_len);
2981bcac2127SMarouene Boubakri
2982bcac2127SMarouene Boubakri if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
2983bcac2127SMarouene Boubakri return PKCS11_CKR_GENERAL_ERROR;
2984bcac2127SMarouene Boubakri
2985bcac2127SMarouene Boubakri /*
2986bcac2127SMarouene Boubakri * The generation of the KCV may be prevented by the application
2987bcac2127SMarouene Boubakri * supplying the attribute in the template as a no-value (0 length)
2988bcac2127SMarouene Boubakri * entry.
2989bcac2127SMarouene Boubakri */
2990bcac2127SMarouene Boubakri if (rc == PKCS11_CKR_OK && !kcv2_len)
2991bcac2127SMarouene Boubakri return PKCS11_CKR_OK;
2992bcac2127SMarouene Boubakri
2993bcac2127SMarouene Boubakri if (rc == PKCS11_CKR_OK && kcv2_len != PKCS11_CKA_CHECK_VALUE_SIZE)
29942ea9746dSEtienne Carriere return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID;
2995bcac2127SMarouene Boubakri
2996bcac2127SMarouene Boubakri /* Get key CKA_VALUE */
2997bcac2127SMarouene Boubakri rc = get_attribute_ptr(*head, PKCS11_CKA_VALUE, &val, &val_len);
2998bcac2127SMarouene Boubakri if (rc)
2999bcac2127SMarouene Boubakri return rc;
3000bcac2127SMarouene Boubakri
3001bcac2127SMarouene Boubakri if (get_class(*head) == PKCS11_CKO_SECRET_KEY) {
3002bcac2127SMarouene Boubakri switch (get_key_type(*head)) {
3003bcac2127SMarouene Boubakri case PKCS11_CKK_AES:
3004bcac2127SMarouene Boubakri rc = compute_check_value_with_ecb(val, val_len, kcv);
3005bcac2127SMarouene Boubakri break;
3006bcac2127SMarouene Boubakri case PKCS11_CKK_GENERIC_SECRET:
3007bcac2127SMarouene Boubakri case PKCS11_CKK_MD5_HMAC:
3008bcac2127SMarouene Boubakri case PKCS11_CKK_SHA_1_HMAC:
3009bcac2127SMarouene Boubakri case PKCS11_CKK_SHA256_HMAC:
3010bcac2127SMarouene Boubakri case PKCS11_CKK_SHA384_HMAC:
3011bcac2127SMarouene Boubakri case PKCS11_CKK_SHA512_HMAC:
3012bcac2127SMarouene Boubakri case PKCS11_CKK_SHA224_HMAC:
3013bcac2127SMarouene Boubakri rc = compute_check_value_with_sha1(val, val_len, kcv);
3014bcac2127SMarouene Boubakri break;
3015bcac2127SMarouene Boubakri default:
3016bcac2127SMarouene Boubakri rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
3017bcac2127SMarouene Boubakri break;
3018bcac2127SMarouene Boubakri }
3019bcac2127SMarouene Boubakri } else {
3020bcac2127SMarouene Boubakri rc = compute_check_value_with_sha1(val, val_len, kcv);
3021bcac2127SMarouene Boubakri }
3022bcac2127SMarouene Boubakri
3023bcac2127SMarouene Boubakri if (rc)
3024bcac2127SMarouene Boubakri return rc;
3025bcac2127SMarouene Boubakri
3026bcac2127SMarouene Boubakri /*
3027bcac2127SMarouene Boubakri * If the computed KCV does not match the provided one
3028bcac2127SMarouene Boubakri * then return CKR_ATTRIBUTE_VALUE_INVALID
3029bcac2127SMarouene Boubakri */
3030bcac2127SMarouene Boubakri if (kcv2_len) {
3031bcac2127SMarouene Boubakri /* Provided KCV value shall match the computed one */
3032bcac2127SMarouene Boubakri if (TEE_MemCompare(kcv2, kcv, PKCS11_CKA_CHECK_VALUE_SIZE))
3033bcac2127SMarouene Boubakri rc = PKCS11_CKR_ATTRIBUTE_VALUE_INVALID;
3034bcac2127SMarouene Boubakri } else {
3035bcac2127SMarouene Boubakri rc = add_attribute(head, PKCS11_CKA_CHECK_VALUE, kcv,
3036bcac2127SMarouene Boubakri PKCS11_CKA_CHECK_VALUE_SIZE);
3037bcac2127SMarouene Boubakri }
3038bcac2127SMarouene Boubakri
3039bcac2127SMarouene Boubakri return rc;
3040bcac2127SMarouene Boubakri }
3041