xref: /optee_os/ta/pkcs11/src/processing_digest.c (revision 9e91a619a03fd01c1744986a56843f4da105a060)
1*9e91a619SVesa Jääskeläinen // SPDX-License-Identifier: BSD-2-Clause
2*9e91a619SVesa Jääskeläinen /*
3*9e91a619SVesa Jääskeläinen  * Copyright (c) 2021, Vaisala Oyj
4*9e91a619SVesa Jääskeläinen  */
5*9e91a619SVesa Jääskeläinen 
6*9e91a619SVesa Jääskeläinen #include <assert.h>
7*9e91a619SVesa Jääskeläinen #include <pkcs11_ta.h>
8*9e91a619SVesa Jääskeläinen #include <string.h>
9*9e91a619SVesa Jääskeläinen #include <tee_api_defines.h>
10*9e91a619SVesa Jääskeläinen #include <tee_internal_api.h>
11*9e91a619SVesa Jääskeläinen #include <tee_internal_api_extensions.h>
12*9e91a619SVesa Jääskeläinen #include <utee_defines.h>
13*9e91a619SVesa Jääskeläinen #include <util.h>
14*9e91a619SVesa Jääskeläinen 
15*9e91a619SVesa Jääskeläinen #include "attributes.h"
16*9e91a619SVesa Jääskeläinen #include "object.h"
17*9e91a619SVesa Jääskeläinen #include "pkcs11_attributes.h"
18*9e91a619SVesa Jääskeläinen #include "pkcs11_helpers.h"
19*9e91a619SVesa Jääskeläinen #include "pkcs11_token.h"
20*9e91a619SVesa Jääskeläinen #include "processing.h"
21*9e91a619SVesa Jääskeläinen #include "serializer.h"
22*9e91a619SVesa Jääskeläinen 
23*9e91a619SVesa Jääskeläinen bool processing_is_tee_digest(enum pkcs11_mechanism_id mecha_id)
24*9e91a619SVesa Jääskeläinen {
25*9e91a619SVesa Jääskeläinen 	switch (mecha_id) {
26*9e91a619SVesa Jääskeläinen 	case PKCS11_CKM_MD5:
27*9e91a619SVesa Jääskeläinen 	case PKCS11_CKM_SHA_1:
28*9e91a619SVesa Jääskeläinen 	case PKCS11_CKM_SHA224:
29*9e91a619SVesa Jääskeläinen 	case PKCS11_CKM_SHA256:
30*9e91a619SVesa Jääskeläinen 	case PKCS11_CKM_SHA384:
31*9e91a619SVesa Jääskeläinen 	case PKCS11_CKM_SHA512:
32*9e91a619SVesa Jääskeläinen 		return true;
33*9e91a619SVesa Jääskeläinen 	default:
34*9e91a619SVesa Jääskeläinen 		return false;
35*9e91a619SVesa Jääskeläinen 	}
36*9e91a619SVesa Jääskeläinen }
37*9e91a619SVesa Jääskeläinen 
38*9e91a619SVesa Jääskeläinen static enum pkcs11_rc
39*9e91a619SVesa Jääskeläinen pkcs2tee_algorithm(uint32_t *tee_id, struct pkcs11_attribute_head *proc_params)
40*9e91a619SVesa Jääskeläinen {
41*9e91a619SVesa Jääskeläinen 	static const struct {
42*9e91a619SVesa Jääskeläinen 		enum pkcs11_mechanism_id mech_id;
43*9e91a619SVesa Jääskeläinen 		uint32_t tee_id;
44*9e91a619SVesa Jääskeläinen 	} pkcs2tee_algo[] = {
45*9e91a619SVesa Jääskeläinen 		{ PKCS11_CKM_MD5, TEE_ALG_MD5 },
46*9e91a619SVesa Jääskeläinen 		{ PKCS11_CKM_SHA_1, TEE_ALG_SHA1 },
47*9e91a619SVesa Jääskeläinen 		{ PKCS11_CKM_SHA224, TEE_ALG_SHA224 },
48*9e91a619SVesa Jääskeläinen 		{ PKCS11_CKM_SHA256, TEE_ALG_SHA256 },
49*9e91a619SVesa Jääskeläinen 		{ PKCS11_CKM_SHA384, TEE_ALG_SHA384 },
50*9e91a619SVesa Jääskeläinen 		{ PKCS11_CKM_SHA512, TEE_ALG_SHA512 },
51*9e91a619SVesa Jääskeläinen 	};
52*9e91a619SVesa Jääskeläinen 	size_t n = 0;
53*9e91a619SVesa Jääskeläinen 
54*9e91a619SVesa Jääskeläinen 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) {
55*9e91a619SVesa Jääskeläinen 		if (proc_params->id == pkcs2tee_algo[n].mech_id) {
56*9e91a619SVesa Jääskeläinen 			*tee_id = pkcs2tee_algo[n].tee_id;
57*9e91a619SVesa Jääskeläinen 			return PKCS11_CKR_OK;
58*9e91a619SVesa Jääskeläinen 		}
59*9e91a619SVesa Jääskeläinen 	}
60*9e91a619SVesa Jääskeläinen 
61*9e91a619SVesa Jääskeläinen 	return PKCS11_RV_NOT_IMPLEMENTED;
62*9e91a619SVesa Jääskeläinen }
63*9e91a619SVesa Jääskeläinen 
64*9e91a619SVesa Jääskeläinen static enum pkcs11_rc
65*9e91a619SVesa Jääskeläinen allocate_tee_operation(struct pkcs11_session *session,
66*9e91a619SVesa Jääskeläinen 		       struct pkcs11_attribute_head *params)
67*9e91a619SVesa Jääskeläinen {
68*9e91a619SVesa Jääskeläinen 	uint32_t algo = 0;
69*9e91a619SVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
70*9e91a619SVesa Jääskeläinen 
71*9e91a619SVesa Jääskeläinen 	assert(session->processing->tee_op_handle == TEE_HANDLE_NULL);
72*9e91a619SVesa Jääskeläinen 
73*9e91a619SVesa Jääskeläinen 	if (pkcs2tee_algorithm(&algo, params))
74*9e91a619SVesa Jääskeläinen 		return PKCS11_CKR_FUNCTION_FAILED;
75*9e91a619SVesa Jääskeläinen 
76*9e91a619SVesa Jääskeläinen 	res = TEE_AllocateOperation(&session->processing->tee_op_handle,
77*9e91a619SVesa Jääskeläinen 				    algo, TEE_MODE_DIGEST, 0);
78*9e91a619SVesa Jääskeläinen 	if (res)
79*9e91a619SVesa Jääskeläinen 		EMSG("TEE_AllocateOp. failed %#"PRIx32, algo);
80*9e91a619SVesa Jääskeläinen 
81*9e91a619SVesa Jääskeläinen 	if (res == TEE_ERROR_NOT_SUPPORTED)
82*9e91a619SVesa Jääskeläinen 		return PKCS11_CKR_MECHANISM_INVALID;
83*9e91a619SVesa Jääskeläinen 
84*9e91a619SVesa Jääskeläinen 	return tee2pkcs_error(res);
85*9e91a619SVesa Jääskeläinen }
86*9e91a619SVesa Jääskeläinen 
87*9e91a619SVesa Jääskeläinen enum pkcs11_rc init_digest_operation(struct pkcs11_session *session,
88*9e91a619SVesa Jääskeläinen 				     struct pkcs11_attribute_head *proc_params)
89*9e91a619SVesa Jääskeläinen {
90*9e91a619SVesa Jääskeläinen 	assert(processing_is_tee_digest(proc_params->id));
91*9e91a619SVesa Jääskeläinen 
92*9e91a619SVesa Jääskeläinen 	return allocate_tee_operation(session, proc_params);
93*9e91a619SVesa Jääskeläinen }
94*9e91a619SVesa Jääskeläinen 
95*9e91a619SVesa Jääskeläinen /*
96*9e91a619SVesa Jääskeläinen  * step_digest_operation - processing digest operation step
97*9e91a619SVesa Jääskeläinen  *
98*9e91a619SVesa Jääskeläinen  * @session - current session
99*9e91a619SVesa Jääskeläinen  * @step - step ID in the processing (oneshot, update, final)
100*9e91a619SVesa Jääskeläinen  * @obj - PKCS#11 object for key based operations
101*9e91a619SVesa Jääskeläinen  * @ptype - invocation parameter types
102*9e91a619SVesa Jääskeläinen  * @params - invocation parameter references
103*9e91a619SVesa Jääskeläinen  */
104*9e91a619SVesa Jääskeläinen enum pkcs11_rc step_digest_operation(struct pkcs11_session *session,
105*9e91a619SVesa Jääskeläinen 				     enum processing_step step,
106*9e91a619SVesa Jääskeläinen 				     struct pkcs11_object *obj,
107*9e91a619SVesa Jääskeläinen 				     uint32_t ptypes, TEE_Param *params)
108*9e91a619SVesa Jääskeläinen {
109*9e91a619SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
110*9e91a619SVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
111*9e91a619SVesa Jääskeläinen 	void *in_buf = NULL;
112*9e91a619SVesa Jääskeläinen 	size_t in_size = 0;
113*9e91a619SVesa Jääskeläinen 	void *out_buf = NULL;
114*9e91a619SVesa Jääskeläinen 	uint32_t out_size = 0;
115*9e91a619SVesa Jääskeläinen 	void *secret_value = NULL;
116*9e91a619SVesa Jääskeläinen 	uint32_t secret_value_size = 0;
117*9e91a619SVesa Jääskeläinen 	enum pkcs11_key_type key_type = PKCS11_CKK_UNDEFINED_ID;
118*9e91a619SVesa Jääskeläinen 	struct active_processing *proc = session->processing;
119*9e91a619SVesa Jääskeläinen 
120*9e91a619SVesa Jääskeläinen 	if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) {
121*9e91a619SVesa Jääskeläinen 		in_buf = params[1].memref.buffer;
122*9e91a619SVesa Jääskeläinen 		in_size = params[1].memref.size;
123*9e91a619SVesa Jääskeläinen 		if (in_size && !in_buf)
124*9e91a619SVesa Jääskeläinen 			return PKCS11_CKR_ARGUMENTS_BAD;
125*9e91a619SVesa Jääskeläinen 	}
126*9e91a619SVesa Jääskeläinen 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) {
127*9e91a619SVesa Jääskeläinen 		out_buf = params[2].memref.buffer;
128*9e91a619SVesa Jääskeläinen 		out_size = params[2].memref.size;
129*9e91a619SVesa Jääskeläinen 		if (out_size && !out_buf)
130*9e91a619SVesa Jääskeläinen 			return PKCS11_CKR_ARGUMENTS_BAD;
131*9e91a619SVesa Jääskeläinen 	}
132*9e91a619SVesa Jääskeläinen 	if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE)
133*9e91a619SVesa Jääskeläinen 		return PKCS11_CKR_ARGUMENTS_BAD;
134*9e91a619SVesa Jääskeläinen 
135*9e91a619SVesa Jääskeläinen 	switch (step) {
136*9e91a619SVesa Jääskeläinen 	case PKCS11_FUNC_STEP_ONESHOT:
137*9e91a619SVesa Jääskeläinen 	case PKCS11_FUNC_STEP_UPDATE:
138*9e91a619SVesa Jääskeläinen 	case PKCS11_FUNC_STEP_UPDATE_KEY:
139*9e91a619SVesa Jääskeläinen 	case PKCS11_FUNC_STEP_FINAL:
140*9e91a619SVesa Jääskeläinen 		break;
141*9e91a619SVesa Jääskeläinen 	default:
142*9e91a619SVesa Jääskeläinen 		TEE_Panic(step);
143*9e91a619SVesa Jääskeläinen 		break;
144*9e91a619SVesa Jääskeläinen 	}
145*9e91a619SVesa Jääskeläinen 
146*9e91a619SVesa Jääskeläinen 	assert(proc->tee_op_handle != TEE_HANDLE_NULL);
147*9e91a619SVesa Jääskeläinen 
148*9e91a619SVesa Jääskeläinen 	assert(processing_is_tee_digest(proc->mecha_type));
149*9e91a619SVesa Jääskeläinen 
150*9e91a619SVesa Jääskeläinen 	/*
151*9e91a619SVesa Jääskeläinen 	 * Feed active operation with data
152*9e91a619SVesa Jääskeläinen 	 */
153*9e91a619SVesa Jääskeläinen 
154*9e91a619SVesa Jääskeläinen 	switch (step) {
155*9e91a619SVesa Jääskeläinen 	case PKCS11_FUNC_STEP_UPDATE_KEY:
156*9e91a619SVesa Jääskeläinen 		assert(obj);
157*9e91a619SVesa Jääskeläinen 
158*9e91a619SVesa Jääskeläinen 		if (get_class(obj->attributes) != PKCS11_CKO_SECRET_KEY)
159*9e91a619SVesa Jääskeläinen 			return PKCS11_CKR_KEY_INDIGESTIBLE;
160*9e91a619SVesa Jääskeläinen 
161*9e91a619SVesa Jääskeläinen 		key_type = get_key_type(obj->attributes);
162*9e91a619SVesa Jääskeläinen 
163*9e91a619SVesa Jääskeläinen 		if (key_type != PKCS11_CKK_GENERIC_SECRET &&
164*9e91a619SVesa Jääskeläinen 		    key_type != PKCS11_CKK_AES)
165*9e91a619SVesa Jääskeläinen 			return PKCS11_CKR_KEY_INDIGESTIBLE;
166*9e91a619SVesa Jääskeläinen 
167*9e91a619SVesa Jääskeläinen 		rc = get_attribute_ptr(obj->attributes, PKCS11_CKA_VALUE,
168*9e91a619SVesa Jääskeläinen 				       &secret_value, &secret_value_size);
169*9e91a619SVesa Jääskeläinen 		assert(!rc && secret_value && secret_value_size);
170*9e91a619SVesa Jääskeläinen 
171*9e91a619SVesa Jääskeläinen 		TEE_DigestUpdate(proc->tee_op_handle, secret_value,
172*9e91a619SVesa Jääskeläinen 				 secret_value_size);
173*9e91a619SVesa Jääskeläinen 		return PKCS11_CKR_OK;
174*9e91a619SVesa Jääskeläinen 
175*9e91a619SVesa Jääskeläinen 	case PKCS11_FUNC_STEP_UPDATE:
176*9e91a619SVesa Jääskeläinen 		if (!in_buf || !in_size)
177*9e91a619SVesa Jääskeläinen 			return PKCS11_CKR_OK;
178*9e91a619SVesa Jääskeläinen 
179*9e91a619SVesa Jääskeläinen 		TEE_DigestUpdate(proc->tee_op_handle, in_buf, in_size);
180*9e91a619SVesa Jääskeläinen 		return PKCS11_CKR_OK;
181*9e91a619SVesa Jääskeläinen 
182*9e91a619SVesa Jääskeläinen 	case PKCS11_FUNC_STEP_ONESHOT:
183*9e91a619SVesa Jääskeläinen 		if (!out_buf)
184*9e91a619SVesa Jääskeläinen 			return PKCS11_CKR_ARGUMENTS_BAD;
185*9e91a619SVesa Jääskeläinen 
186*9e91a619SVesa Jääskeläinen 		goto do_final;
187*9e91a619SVesa Jääskeläinen 
188*9e91a619SVesa Jääskeläinen 	case PKCS11_FUNC_STEP_FINAL:
189*9e91a619SVesa Jääskeläinen 		if (in_buf || !out_buf)
190*9e91a619SVesa Jääskeläinen 			return PKCS11_CKR_ARGUMENTS_BAD;
191*9e91a619SVesa Jääskeläinen 
192*9e91a619SVesa Jääskeläinen 		goto do_final;
193*9e91a619SVesa Jääskeläinen 
194*9e91a619SVesa Jääskeläinen 	default:
195*9e91a619SVesa Jääskeläinen 		TEE_Panic(step);
196*9e91a619SVesa Jääskeläinen 		break;
197*9e91a619SVesa Jääskeläinen 	}
198*9e91a619SVesa Jääskeläinen 
199*9e91a619SVesa Jääskeläinen do_final:
200*9e91a619SVesa Jääskeläinen 	res = TEE_DigestDoFinal(proc->tee_op_handle,
201*9e91a619SVesa Jääskeläinen 				in_buf, in_size, out_buf,
202*9e91a619SVesa Jääskeläinen 				&out_size);
203*9e91a619SVesa Jääskeläinen 	rc = tee2pkcs_error(res);
204*9e91a619SVesa Jääskeläinen 
205*9e91a619SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)
206*9e91a619SVesa Jääskeläinen 		params[2].memref.size = out_size;
207*9e91a619SVesa Jääskeläinen 
208*9e91a619SVesa Jääskeläinen 	return rc;
209*9e91a619SVesa Jääskeläinen }
210