xref: /optee_os/ta/pkcs11/src/processing_digest.c (revision c7f1b4f7881fded88ca7b5bffc8cc47b94c07dd5)
19e91a619SVesa Jääskeläinen // SPDX-License-Identifier: BSD-2-Clause
29e91a619SVesa Jääskeläinen /*
39e91a619SVesa Jääskeläinen  * Copyright (c) 2021, Vaisala Oyj
49e91a619SVesa Jääskeläinen  */
59e91a619SVesa Jääskeläinen 
69e91a619SVesa Jääskeläinen #include <assert.h>
7eb88d2deSVesa Jääskeläinen #include <config.h>
89e91a619SVesa Jääskeläinen #include <pkcs11_ta.h>
99e91a619SVesa Jääskeläinen #include <string.h>
109e91a619SVesa Jääskeläinen #include <tee_api_defines.h>
119e91a619SVesa Jääskeläinen #include <tee_internal_api.h>
129e91a619SVesa Jääskeläinen #include <tee_internal_api_extensions.h>
139e91a619SVesa Jääskeläinen #include <utee_defines.h>
149e91a619SVesa Jääskeläinen #include <util.h>
159e91a619SVesa Jääskeläinen 
169e91a619SVesa Jääskeläinen #include "attributes.h"
179e91a619SVesa Jääskeläinen #include "object.h"
189e91a619SVesa Jääskeläinen #include "pkcs11_attributes.h"
199e91a619SVesa Jääskeläinen #include "pkcs11_helpers.h"
209e91a619SVesa Jääskeläinen #include "pkcs11_token.h"
219e91a619SVesa Jääskeläinen #include "processing.h"
229e91a619SVesa Jääskeläinen #include "serializer.h"
239e91a619SVesa Jääskeläinen 
processing_is_tee_digest(enum pkcs11_mechanism_id mecha_id)249e91a619SVesa Jääskeläinen bool processing_is_tee_digest(enum pkcs11_mechanism_id mecha_id)
259e91a619SVesa Jääskeläinen {
269e91a619SVesa Jääskeläinen 	switch (mecha_id) {
279e91a619SVesa Jääskeläinen 	case PKCS11_CKM_MD5:
289e91a619SVesa Jääskeläinen 	case PKCS11_CKM_SHA_1:
299e91a619SVesa Jääskeläinen 	case PKCS11_CKM_SHA224:
309e91a619SVesa Jääskeläinen 	case PKCS11_CKM_SHA256:
319e91a619SVesa Jääskeläinen 	case PKCS11_CKM_SHA384:
329e91a619SVesa Jääskeläinen 	case PKCS11_CKM_SHA512:
339e91a619SVesa Jääskeläinen 		return true;
349e91a619SVesa Jääskeläinen 	default:
359e91a619SVesa Jääskeläinen 		return false;
369e91a619SVesa Jääskeläinen 	}
379e91a619SVesa Jääskeläinen }
389e91a619SVesa Jääskeläinen 
399e91a619SVesa Jääskeläinen static enum pkcs11_rc
pkcs2tee_algorithm(uint32_t * tee_id,struct pkcs11_attribute_head * proc_params)409e91a619SVesa Jääskeläinen pkcs2tee_algorithm(uint32_t *tee_id, struct pkcs11_attribute_head *proc_params)
419e91a619SVesa Jääskeläinen {
429e91a619SVesa Jääskeläinen 	static const struct {
439e91a619SVesa Jääskeläinen 		enum pkcs11_mechanism_id mech_id;
449e91a619SVesa Jääskeläinen 		uint32_t tee_id;
459e91a619SVesa Jääskeläinen 	} pkcs2tee_algo[] = {
469e91a619SVesa Jääskeläinen 		{ PKCS11_CKM_MD5, TEE_ALG_MD5 },
479e91a619SVesa Jääskeläinen 		{ PKCS11_CKM_SHA_1, TEE_ALG_SHA1 },
489e91a619SVesa Jääskeläinen 		{ PKCS11_CKM_SHA224, TEE_ALG_SHA224 },
499e91a619SVesa Jääskeläinen 		{ PKCS11_CKM_SHA256, TEE_ALG_SHA256 },
509e91a619SVesa Jääskeläinen 		{ PKCS11_CKM_SHA384, TEE_ALG_SHA384 },
519e91a619SVesa Jääskeläinen 		{ PKCS11_CKM_SHA512, TEE_ALG_SHA512 },
529e91a619SVesa Jääskeläinen 	};
539e91a619SVesa Jääskeläinen 	size_t n = 0;
549e91a619SVesa Jääskeläinen 
559e91a619SVesa Jääskeläinen 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) {
569e91a619SVesa Jääskeläinen 		if (proc_params->id == pkcs2tee_algo[n].mech_id) {
579e91a619SVesa Jääskeläinen 			*tee_id = pkcs2tee_algo[n].tee_id;
589e91a619SVesa Jääskeläinen 			return PKCS11_CKR_OK;
599e91a619SVesa Jääskeläinen 		}
609e91a619SVesa Jääskeläinen 	}
619e91a619SVesa Jääskeläinen 
629e91a619SVesa Jääskeläinen 	return PKCS11_RV_NOT_IMPLEMENTED;
639e91a619SVesa Jääskeläinen }
649e91a619SVesa Jääskeläinen 
659e91a619SVesa Jääskeläinen static enum pkcs11_rc
allocate_tee_operation(struct pkcs11_session * session,struct pkcs11_attribute_head * params)669e91a619SVesa Jääskeläinen allocate_tee_operation(struct pkcs11_session *session,
679e91a619SVesa Jääskeläinen 		       struct pkcs11_attribute_head *params)
689e91a619SVesa Jääskeläinen {
699e91a619SVesa Jääskeläinen 	uint32_t algo = 0;
709e91a619SVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
719e91a619SVesa Jääskeläinen 
729e91a619SVesa Jääskeläinen 	assert(session->processing->tee_op_handle == TEE_HANDLE_NULL);
739e91a619SVesa Jääskeläinen 
749e91a619SVesa Jääskeläinen 	if (pkcs2tee_algorithm(&algo, params))
759e91a619SVesa Jääskeläinen 		return PKCS11_CKR_FUNCTION_FAILED;
769e91a619SVesa Jääskeläinen 
779e91a619SVesa Jääskeläinen 	res = TEE_AllocateOperation(&session->processing->tee_op_handle,
789e91a619SVesa Jääskeläinen 				    algo, TEE_MODE_DIGEST, 0);
799e91a619SVesa Jääskeläinen 	if (res)
809e91a619SVesa Jääskeläinen 		EMSG("TEE_AllocateOp. failed %#"PRIx32, algo);
819e91a619SVesa Jääskeläinen 
829e91a619SVesa Jääskeläinen 	if (res == TEE_ERROR_NOT_SUPPORTED)
839e91a619SVesa Jääskeläinen 		return PKCS11_CKR_MECHANISM_INVALID;
849e91a619SVesa Jääskeläinen 
859e91a619SVesa Jääskeläinen 	return tee2pkcs_error(res);
869e91a619SVesa Jääskeläinen }
879e91a619SVesa Jääskeläinen 
init_digest_operation(struct pkcs11_session * session,struct pkcs11_attribute_head * proc_params)889e91a619SVesa Jääskeläinen enum pkcs11_rc init_digest_operation(struct pkcs11_session *session,
899e91a619SVesa Jääskeläinen 				     struct pkcs11_attribute_head *proc_params)
909e91a619SVesa Jääskeläinen {
91909efccbSEtienne Carriere 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
92909efccbSEtienne Carriere 
939e91a619SVesa Jääskeläinen 	assert(processing_is_tee_digest(proc_params->id));
949e91a619SVesa Jääskeläinen 
95909efccbSEtienne Carriere 	rc = allocate_tee_operation(session, proc_params);
96909efccbSEtienne Carriere 	if (!rc)
97909efccbSEtienne Carriere 		session->processing->mecha_type = proc_params->id;
98909efccbSEtienne Carriere 
99909efccbSEtienne Carriere 	return rc;
1009e91a619SVesa Jääskeläinen }
1019e91a619SVesa Jääskeläinen 
1029e91a619SVesa Jääskeläinen /*
1039e91a619SVesa Jääskeläinen  * step_digest_operation - processing digest operation step
1049e91a619SVesa Jääskeläinen  *
1059e91a619SVesa Jääskeläinen  * @session - current session
1069e91a619SVesa Jääskeläinen  * @step - step ID in the processing (oneshot, update, final)
1079e91a619SVesa Jääskeläinen  * @obj - PKCS#11 object for key based operations
1089e91a619SVesa Jääskeläinen  * @ptype - invocation parameter types
1099e91a619SVesa Jääskeläinen  * @params - invocation parameter references
1109e91a619SVesa Jääskeläinen  */
step_digest_operation(struct pkcs11_session * session,enum processing_step step,struct pkcs11_object * obj,uint32_t ptypes,TEE_Param * params)1119e91a619SVesa Jääskeläinen enum pkcs11_rc step_digest_operation(struct pkcs11_session *session,
1129e91a619SVesa Jääskeläinen 				     enum processing_step step,
1139e91a619SVesa Jääskeläinen 				     struct pkcs11_object *obj,
1149e91a619SVesa Jääskeläinen 				     uint32_t ptypes, TEE_Param *params)
1159e91a619SVesa Jääskeläinen {
1169e91a619SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
1179e91a619SVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
1189e91a619SVesa Jääskeläinen 	void *in_buf = NULL;
1199e91a619SVesa Jääskeläinen 	size_t in_size = 0;
1209e91a619SVesa Jääskeläinen 	void *out_buf = NULL;
121*c7f1b4f7SJens Wiklander 	size_t out_size = 0;
1229e91a619SVesa Jääskeläinen 	void *secret_value = NULL;
1239e91a619SVesa Jääskeläinen 	uint32_t secret_value_size = 0;
1249e91a619SVesa Jääskeläinen 	enum pkcs11_key_type key_type = PKCS11_CKK_UNDEFINED_ID;
1259e91a619SVesa Jääskeläinen 	struct active_processing *proc = session->processing;
1269e91a619SVesa Jääskeläinen 
1279e91a619SVesa Jääskeläinen 	if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) {
1289e91a619SVesa Jääskeläinen 		in_buf = params[1].memref.buffer;
1299e91a619SVesa Jääskeläinen 		in_size = params[1].memref.size;
1309e91a619SVesa Jääskeläinen 		if (in_size && !in_buf)
1319e91a619SVesa Jääskeläinen 			return PKCS11_CKR_ARGUMENTS_BAD;
1329e91a619SVesa Jääskeläinen 	}
1339e91a619SVesa Jääskeläinen 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) {
1349e91a619SVesa Jääskeläinen 		out_buf = params[2].memref.buffer;
1359e91a619SVesa Jääskeläinen 		out_size = params[2].memref.size;
1369e91a619SVesa Jääskeläinen 		if (out_size && !out_buf)
1379e91a619SVesa Jääskeläinen 			return PKCS11_CKR_ARGUMENTS_BAD;
1389e91a619SVesa Jääskeläinen 	}
1399e91a619SVesa Jääskeläinen 	if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE)
1409e91a619SVesa Jääskeläinen 		return PKCS11_CKR_ARGUMENTS_BAD;
1419e91a619SVesa Jääskeläinen 
1429e91a619SVesa Jääskeläinen 	switch (step) {
1439e91a619SVesa Jääskeläinen 	case PKCS11_FUNC_STEP_ONESHOT:
1449e91a619SVesa Jääskeläinen 	case PKCS11_FUNC_STEP_UPDATE:
1459e91a619SVesa Jääskeläinen 	case PKCS11_FUNC_STEP_UPDATE_KEY:
1469e91a619SVesa Jääskeläinen 	case PKCS11_FUNC_STEP_FINAL:
1479e91a619SVesa Jääskeläinen 		break;
1489e91a619SVesa Jääskeläinen 	default:
1499e91a619SVesa Jääskeläinen 		TEE_Panic(step);
1509e91a619SVesa Jääskeläinen 		break;
1519e91a619SVesa Jääskeläinen 	}
1529e91a619SVesa Jääskeläinen 
1539e91a619SVesa Jääskeläinen 	assert(proc->tee_op_handle != TEE_HANDLE_NULL);
1549e91a619SVesa Jääskeläinen 
1559e91a619SVesa Jääskeläinen 	assert(processing_is_tee_digest(proc->mecha_type));
1569e91a619SVesa Jääskeläinen 
1579e91a619SVesa Jääskeläinen 	/*
1589e91a619SVesa Jääskeläinen 	 * Feed active operation with data
1599e91a619SVesa Jääskeläinen 	 */
1609e91a619SVesa Jääskeläinen 
1619e91a619SVesa Jääskeläinen 	switch (step) {
1629e91a619SVesa Jääskeläinen 	case PKCS11_FUNC_STEP_UPDATE_KEY:
1639e91a619SVesa Jääskeläinen 		assert(obj);
1649e91a619SVesa Jääskeläinen 
165eb88d2deSVesa Jääskeläinen 		if (!IS_ENABLED(CFG_PKCS11_TA_ALLOW_DIGEST_KEY))
166eb88d2deSVesa Jääskeläinen 			return PKCS11_CKR_KEY_INDIGESTIBLE;
167eb88d2deSVesa Jääskeläinen 
1689e91a619SVesa Jääskeläinen 		if (get_class(obj->attributes) != PKCS11_CKO_SECRET_KEY)
1699e91a619SVesa Jääskeläinen 			return PKCS11_CKR_KEY_INDIGESTIBLE;
1709e91a619SVesa Jääskeläinen 
1719e91a619SVesa Jääskeläinen 		key_type = get_key_type(obj->attributes);
1729e91a619SVesa Jääskeläinen 
1739e91a619SVesa Jääskeläinen 		if (key_type != PKCS11_CKK_GENERIC_SECRET &&
1749e91a619SVesa Jääskeläinen 		    key_type != PKCS11_CKK_AES)
1759e91a619SVesa Jääskeläinen 			return PKCS11_CKR_KEY_INDIGESTIBLE;
1769e91a619SVesa Jääskeläinen 
1779e91a619SVesa Jääskeläinen 		rc = get_attribute_ptr(obj->attributes, PKCS11_CKA_VALUE,
1789e91a619SVesa Jääskeläinen 				       &secret_value, &secret_value_size);
1799e91a619SVesa Jääskeläinen 		assert(!rc && secret_value && secret_value_size);
1809e91a619SVesa Jääskeläinen 
1819e91a619SVesa Jääskeläinen 		TEE_DigestUpdate(proc->tee_op_handle, secret_value,
1829e91a619SVesa Jääskeläinen 				 secret_value_size);
1839e91a619SVesa Jääskeläinen 		return PKCS11_CKR_OK;
1849e91a619SVesa Jääskeläinen 
1859e91a619SVesa Jääskeläinen 	case PKCS11_FUNC_STEP_UPDATE:
1869e91a619SVesa Jääskeläinen 		if (!in_buf || !in_size)
1879e91a619SVesa Jääskeläinen 			return PKCS11_CKR_OK;
1889e91a619SVesa Jääskeläinen 
1899e91a619SVesa Jääskeläinen 		TEE_DigestUpdate(proc->tee_op_handle, in_buf, in_size);
1909e91a619SVesa Jääskeläinen 		return PKCS11_CKR_OK;
1919e91a619SVesa Jääskeläinen 
1929e91a619SVesa Jääskeläinen 	case PKCS11_FUNC_STEP_ONESHOT:
1939e91a619SVesa Jääskeläinen 		if (!out_buf)
1949e91a619SVesa Jääskeläinen 			return PKCS11_CKR_ARGUMENTS_BAD;
1959e91a619SVesa Jääskeläinen 
1969e91a619SVesa Jääskeläinen 		goto do_final;
1979e91a619SVesa Jääskeläinen 
1989e91a619SVesa Jääskeläinen 	case PKCS11_FUNC_STEP_FINAL:
1999e91a619SVesa Jääskeläinen 		if (in_buf || !out_buf)
2009e91a619SVesa Jääskeläinen 			return PKCS11_CKR_ARGUMENTS_BAD;
2019e91a619SVesa Jääskeläinen 
2029e91a619SVesa Jääskeläinen 		goto do_final;
2039e91a619SVesa Jääskeläinen 
2049e91a619SVesa Jääskeläinen 	default:
2059e91a619SVesa Jääskeläinen 		TEE_Panic(step);
2069e91a619SVesa Jääskeläinen 		break;
2079e91a619SVesa Jääskeläinen 	}
2089e91a619SVesa Jääskeläinen 
2099e91a619SVesa Jääskeläinen do_final:
2109e91a619SVesa Jääskeläinen 	res = TEE_DigestDoFinal(proc->tee_op_handle,
2119e91a619SVesa Jääskeläinen 				in_buf, in_size, out_buf,
2129e91a619SVesa Jääskeläinen 				&out_size);
2139e91a619SVesa Jääskeläinen 	rc = tee2pkcs_error(res);
2149e91a619SVesa Jääskeläinen 
2159e91a619SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)
2169e91a619SVesa Jääskeläinen 		params[2].memref.size = out_size;
2179e91a619SVesa Jääskeläinen 
2189e91a619SVesa Jääskeläinen 	return rc;
2199e91a619SVesa Jääskeläinen }
220