xref: /optee_os/ta/pkcs11/src/processing_rsa.c (revision 0442c956edfb70be378634fd51dbec6e21550a5a)
186922832SVesa Jääskeläinen // SPDX-License-Identifier: BSD-2-Clause
286922832SVesa Jääskeläinen /*
386922832SVesa Jääskeläinen  * Copyright (c) 2018-2021, Linaro Limited
486922832SVesa Jääskeläinen  */
586922832SVesa Jääskeläinen 
686922832SVesa Jääskeläinen #include <assert.h>
786922832SVesa Jääskeläinen #include <pkcs11_ta.h>
886922832SVesa Jääskeläinen #include <tee_api_defines.h>
986922832SVesa Jääskeläinen #include <tee_internal_api.h>
1086922832SVesa Jääskeläinen #include <tee_internal_api_extensions.h>
1186922832SVesa Jääskeläinen 
1286922832SVesa Jääskeläinen #include "attributes.h"
13*0442c956SVesa Jääskeläinen #include "object.h"
1486922832SVesa Jääskeläinen #include "processing.h"
1586922832SVesa Jääskeläinen 
16*0442c956SVesa Jääskeläinen enum pkcs11_rc load_tee_rsa_key_attrs(TEE_Attribute **tee_attrs,
17*0442c956SVesa Jääskeläinen 				      size_t *tee_count,
18*0442c956SVesa Jääskeläinen 				      struct pkcs11_object *obj)
19*0442c956SVesa Jääskeläinen {
20*0442c956SVesa Jääskeläinen 	TEE_Attribute *attrs = NULL;
21*0442c956SVesa Jääskeläinen 	size_t count = 0;
22*0442c956SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
23*0442c956SVesa Jääskeläinen 	void *a_ptr = NULL;
24*0442c956SVesa Jääskeläinen 
25*0442c956SVesa Jääskeläinen 	assert(get_key_type(obj->attributes) == PKCS11_CKK_RSA);
26*0442c956SVesa Jääskeläinen 
27*0442c956SVesa Jääskeläinen 	switch (get_class(obj->attributes)) {
28*0442c956SVesa Jääskeläinen 	case PKCS11_CKO_PUBLIC_KEY:
29*0442c956SVesa Jääskeläinen 		attrs = TEE_Malloc(2 * sizeof(TEE_Attribute),
30*0442c956SVesa Jääskeläinen 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
31*0442c956SVesa Jääskeläinen 		if (!attrs)
32*0442c956SVesa Jääskeläinen 			return PKCS11_CKR_DEVICE_MEMORY;
33*0442c956SVesa Jääskeläinen 
34*0442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_MODULUS,
35*0442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_MODULUS))
36*0442c956SVesa Jääskeläinen 			count++;
37*0442c956SVesa Jääskeläinen 
38*0442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
39*0442c956SVesa Jääskeläinen 				       TEE_ATTR_RSA_PUBLIC_EXPONENT, obj,
40*0442c956SVesa Jääskeläinen 				       PKCS11_CKA_PUBLIC_EXPONENT))
41*0442c956SVesa Jääskeläinen 			count++;
42*0442c956SVesa Jääskeläinen 
43*0442c956SVesa Jääskeläinen 		if (count == 2)
44*0442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
45*0442c956SVesa Jääskeläinen 
46*0442c956SVesa Jääskeläinen 		break;
47*0442c956SVesa Jääskeläinen 
48*0442c956SVesa Jääskeläinen 	case PKCS11_CKO_PRIVATE_KEY:
49*0442c956SVesa Jääskeläinen 		attrs = TEE_Malloc(8 * sizeof(TEE_Attribute),
50*0442c956SVesa Jääskeläinen 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
51*0442c956SVesa Jääskeläinen 		if (!attrs)
52*0442c956SVesa Jääskeläinen 			return PKCS11_CKR_DEVICE_MEMORY;
53*0442c956SVesa Jääskeläinen 
54*0442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_MODULUS,
55*0442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_MODULUS))
56*0442c956SVesa Jääskeläinen 			count++;
57*0442c956SVesa Jääskeläinen 
58*0442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
59*0442c956SVesa Jääskeläinen 				       TEE_ATTR_RSA_PUBLIC_EXPONENT, obj,
60*0442c956SVesa Jääskeläinen 				       PKCS11_CKA_PUBLIC_EXPONENT))
61*0442c956SVesa Jääskeläinen 			count++;
62*0442c956SVesa Jääskeläinen 
63*0442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
64*0442c956SVesa Jääskeläinen 				       TEE_ATTR_RSA_PRIVATE_EXPONENT, obj,
65*0442c956SVesa Jääskeläinen 				       PKCS11_CKA_PRIVATE_EXPONENT))
66*0442c956SVesa Jääskeläinen 			count++;
67*0442c956SVesa Jääskeläinen 
68*0442c956SVesa Jääskeläinen 		if (count != 3)
69*0442c956SVesa Jääskeläinen 			break;
70*0442c956SVesa Jääskeläinen 
71*0442c956SVesa Jääskeläinen 		/* If pre-computed values are present load those */
72*0442c956SVesa Jääskeläinen 		rc = get_attribute_ptr(obj->attributes, PKCS11_CKA_PRIME_1,
73*0442c956SVesa Jääskeläinen 				       &a_ptr, NULL);
74*0442c956SVesa Jääskeläinen 		if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
75*0442c956SVesa Jääskeläinen 			break;
76*0442c956SVesa Jääskeläinen 		if (rc == PKCS11_RV_NOT_FOUND || !a_ptr) {
77*0442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
78*0442c956SVesa Jääskeläinen 			break;
79*0442c956SVesa Jääskeläinen 		}
80*0442c956SVesa Jääskeläinen 
81*0442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME1, obj,
82*0442c956SVesa Jääskeläinen 				       PKCS11_CKA_PRIME_1))
83*0442c956SVesa Jääskeläinen 			count++;
84*0442c956SVesa Jääskeläinen 
85*0442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME2, obj,
86*0442c956SVesa Jääskeläinen 				       PKCS11_CKA_PRIME_2))
87*0442c956SVesa Jääskeläinen 			count++;
88*0442c956SVesa Jääskeläinen 
89*0442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT1,
90*0442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_EXPONENT_1))
91*0442c956SVesa Jääskeläinen 			count++;
92*0442c956SVesa Jääskeläinen 
93*0442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT2,
94*0442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_EXPONENT_2))
95*0442c956SVesa Jääskeläinen 			count++;
96*0442c956SVesa Jääskeläinen 
97*0442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_COEFFICIENT,
98*0442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_COEFFICIENT))
99*0442c956SVesa Jääskeläinen 			count++;
100*0442c956SVesa Jääskeläinen 
101*0442c956SVesa Jääskeläinen 		if (count == 8)
102*0442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
103*0442c956SVesa Jääskeläinen 
104*0442c956SVesa Jääskeläinen 		break;
105*0442c956SVesa Jääskeläinen 
106*0442c956SVesa Jääskeläinen 	default:
107*0442c956SVesa Jääskeläinen 		assert(0);
108*0442c956SVesa Jääskeläinen 		break;
109*0442c956SVesa Jääskeläinen 	}
110*0442c956SVesa Jääskeläinen 
111*0442c956SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK) {
112*0442c956SVesa Jääskeläinen 		*tee_attrs = attrs;
113*0442c956SVesa Jääskeläinen 		*tee_count = count;
114*0442c956SVesa Jääskeläinen 	} else {
115*0442c956SVesa Jääskeläinen 		TEE_Free(attrs);
116*0442c956SVesa Jääskeläinen 	}
117*0442c956SVesa Jääskeläinen 
118*0442c956SVesa Jääskeläinen 	return rc;
119*0442c956SVesa Jääskeläinen }
120*0442c956SVesa Jääskeläinen 
12186922832SVesa Jääskeläinen static enum pkcs11_rc tee2pkcs_rsa_attributes(struct obj_attrs **pub_head,
12286922832SVesa Jääskeläinen 					      struct obj_attrs **priv_head,
12386922832SVesa Jääskeläinen 					      TEE_ObjectHandle tee_obj)
12486922832SVesa Jääskeläinen {
12586922832SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
12686922832SVesa Jääskeläinen 	void *a_ptr = NULL;
12786922832SVesa Jääskeläinen 
12886922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_MODULUS, tee_obj,
12986922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_MODULUS);
13086922832SVesa Jääskeläinen 	if (rc)
13186922832SVesa Jääskeläinen 		goto out;
13286922832SVesa Jääskeläinen 
13386922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr,
13486922832SVesa Jääskeläinen 			       NULL);
13586922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
13686922832SVesa Jääskeläinen 		goto out;
13786922832SVesa Jääskeläinen 
13886922832SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK && !a_ptr) {
13986922832SVesa Jääskeläinen 		rc = remove_empty_attribute(pub_head,
14086922832SVesa Jääskeläinen 					    PKCS11_CKA_PUBLIC_EXPONENT);
14186922832SVesa Jääskeläinen 		if (rc)
14286922832SVesa Jääskeläinen 			goto out;
14386922832SVesa Jääskeläinen 		rc = PKCS11_RV_NOT_FOUND;
14486922832SVesa Jääskeläinen 	}
14586922832SVesa Jääskeläinen 
14686922832SVesa Jääskeläinen 	if (rc == PKCS11_RV_NOT_FOUND) {
14786922832SVesa Jääskeläinen 		rc = tee2pkcs_add_attribute(pub_head,
14886922832SVesa Jääskeläinen 					    PKCS11_CKA_PUBLIC_EXPONENT,
14986922832SVesa Jääskeläinen 					    tee_obj,
15086922832SVesa Jääskeläinen 					    TEE_ATTR_RSA_PUBLIC_EXPONENT);
15186922832SVesa Jääskeläinen 		if (rc)
15286922832SVesa Jääskeläinen 			goto out;
15386922832SVesa Jääskeläinen 	}
15486922832SVesa Jääskeläinen 
15586922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_MODULUS, tee_obj,
15686922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_MODULUS);
15786922832SVesa Jääskeläinen 	if (rc)
15886922832SVesa Jääskeläinen 		goto out;
15986922832SVesa Jääskeläinen 
16086922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT,
16186922832SVesa Jääskeläinen 				    tee_obj, TEE_ATTR_RSA_PUBLIC_EXPONENT);
16286922832SVesa Jääskeläinen 	if (rc)
16386922832SVesa Jääskeläinen 		goto out;
16486922832SVesa Jääskeläinen 
16586922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT,
16686922832SVesa Jääskeläinen 				    tee_obj, TEE_ATTR_RSA_PRIVATE_EXPONENT);
16786922832SVesa Jääskeläinen 	if (rc)
16886922832SVesa Jääskeläinen 		goto out;
16986922832SVesa Jääskeläinen 
17086922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_1, tee_obj,
17186922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_PRIME1);
17286922832SVesa Jääskeläinen 	if (rc)
17386922832SVesa Jääskeläinen 		goto out;
17486922832SVesa Jääskeläinen 
17586922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_2, tee_obj,
17686922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_PRIME2);
17786922832SVesa Jääskeläinen 	if (rc)
17886922832SVesa Jääskeläinen 		goto out;
17986922832SVesa Jääskeläinen 
18086922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_1, tee_obj,
18186922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_EXPONENT1);
18286922832SVesa Jääskeläinen 	if (rc)
18386922832SVesa Jääskeläinen 		goto out;
18486922832SVesa Jääskeläinen 
18586922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_2, tee_obj,
18686922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_EXPONENT2);
18786922832SVesa Jääskeläinen 	if (rc)
18886922832SVesa Jääskeläinen 		goto out;
18986922832SVesa Jääskeläinen 
19086922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_COEFFICIENT, tee_obj,
19186922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_COEFFICIENT);
19286922832SVesa Jääskeläinen out:
19386922832SVesa Jääskeläinen 	return rc;
19486922832SVesa Jääskeläinen }
19586922832SVesa Jääskeläinen 
19686922832SVesa Jääskeläinen enum pkcs11_rc generate_rsa_keys(struct pkcs11_attribute_head *proc_params,
19786922832SVesa Jääskeläinen 				 struct obj_attrs **pub_head,
19886922832SVesa Jääskeläinen 				 struct obj_attrs **priv_head)
19986922832SVesa Jääskeläinen {
20086922832SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
20186922832SVesa Jääskeläinen 	void *a_ptr = NULL;
20286922832SVesa Jääskeläinen 	uint32_t a_size = 0;
20386922832SVesa Jääskeläinen 	TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
20486922832SVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
20586922832SVesa Jääskeläinen 	uint32_t modulus_bits = 0;
20686922832SVesa Jääskeläinen 	TEE_Attribute tee_attrs[1] = { };
20786922832SVesa Jääskeläinen 	uint32_t tee_count = 0;
20886922832SVesa Jääskeläinen 
20986922832SVesa Jääskeläinen 	if (!proc_params || !*pub_head || !*priv_head)
21086922832SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
21186922832SVesa Jääskeläinen 
21286922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_MODULUS_BITS, &a_ptr,
21386922832SVesa Jääskeläinen 			       &a_size);
21486922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK || a_size != sizeof(uint32_t))
21586922832SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
21686922832SVesa Jääskeläinen 
21786922832SVesa Jääskeläinen 	TEE_MemMove(&modulus_bits, a_ptr, sizeof(uint32_t));
21886922832SVesa Jääskeläinen 
21986922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr,
22086922832SVesa Jääskeläinen 			       &a_size);
22186922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
22286922832SVesa Jääskeläinen 		return rc;
22386922832SVesa Jääskeläinen 
22486922832SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK && a_ptr) {
22586922832SVesa Jääskeläinen 		TEE_InitRefAttribute(&tee_attrs[tee_count],
22686922832SVesa Jääskeläinen 				     TEE_ATTR_RSA_PUBLIC_EXPONENT,
22786922832SVesa Jääskeläinen 				     a_ptr, a_size);
22886922832SVesa Jääskeläinen 		tee_count++;
22986922832SVesa Jääskeläinen 	}
23086922832SVesa Jääskeläinen 
23186922832SVesa Jääskeläinen 	if (remove_empty_attribute(priv_head, PKCS11_CKA_MODULUS) ||
23286922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT) ||
23386922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT) ||
23486922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_1) ||
23586922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_2) ||
23686922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_1) ||
23786922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_2) ||
23886922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_COEFFICIENT)) {
23986922832SVesa Jääskeläinen 		EMSG("Unexpected attribute(s) found");
24086922832SVesa Jääskeläinen 		rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
24186922832SVesa Jääskeläinen 		goto out;
24286922832SVesa Jääskeläinen 	}
24386922832SVesa Jääskeläinen 
24486922832SVesa Jääskeläinen 	/* Create an RSA TEE key */
24586922832SVesa Jääskeläinen 	res = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, modulus_bits,
24686922832SVesa Jääskeläinen 					  &tee_obj);
24786922832SVesa Jääskeläinen 	if (res) {
24886922832SVesa Jääskeläinen 		DMSG("TEE_AllocateTransientObject failed %#"PRIx32, res);
24986922832SVesa Jääskeläinen 
25086922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
25186922832SVesa Jääskeläinen 		goto out;
25286922832SVesa Jääskeläinen 	}
25386922832SVesa Jääskeläinen 
25486922832SVesa Jääskeläinen 	res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
25586922832SVesa Jääskeläinen 	if (res) {
25686922832SVesa Jääskeläinen 		DMSG("TEE_RestrictObjectUsage1 failed %#"PRIx32, res);
25786922832SVesa Jääskeläinen 
25886922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
25986922832SVesa Jääskeläinen 		goto out;
26086922832SVesa Jääskeläinen 	}
26186922832SVesa Jääskeläinen 
26286922832SVesa Jääskeläinen 	res = TEE_GenerateKey(tee_obj, modulus_bits, tee_attrs, tee_count);
26386922832SVesa Jääskeläinen 	if (res) {
26486922832SVesa Jääskeläinen 		DMSG("TEE_GenerateKey failed %#"PRIx32, res);
26586922832SVesa Jääskeläinen 
26686922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
26786922832SVesa Jääskeläinen 		goto out;
26886922832SVesa Jääskeläinen 	}
26986922832SVesa Jääskeläinen 
27086922832SVesa Jääskeläinen 	rc = tee2pkcs_rsa_attributes(pub_head, priv_head, tee_obj);
27186922832SVesa Jääskeläinen 
27286922832SVesa Jääskeläinen out:
27386922832SVesa Jääskeläinen 	if (tee_obj != TEE_HANDLE_NULL)
27486922832SVesa Jääskeläinen 		TEE_CloseObject(tee_obj);
27586922832SVesa Jääskeläinen 
27686922832SVesa Jääskeläinen 	return rc;
27786922832SVesa Jääskeläinen }
278*0442c956SVesa Jääskeläinen 
279*0442c956SVesa Jääskeläinen size_t rsa_get_input_max_byte_size(TEE_OperationHandle op)
280*0442c956SVesa Jääskeläinen {
281*0442c956SVesa Jääskeläinen 	TEE_OperationInfo info = { };
282*0442c956SVesa Jääskeläinen 
283*0442c956SVesa Jääskeläinen 	TEE_GetOperationInfo(op, &info);
284*0442c956SVesa Jääskeläinen 
285*0442c956SVesa Jääskeläinen 	return info.maxKeySize / 8;
286*0442c956SVesa Jääskeläinen }
287