xref: /optee_os/ta/pkcs11/src/processing.c (revision 689f4e5b067fea8c8c0566e968ef2bf5303b2082)
1512cbf1dSJens Wiklander // SPDX-License-Identifier: BSD-2-Clause
2512cbf1dSJens Wiklander /*
3512cbf1dSJens Wiklander  * Copyright (c) 2017-2020, Linaro Limited
4512cbf1dSJens Wiklander  */
5512cbf1dSJens Wiklander 
6512cbf1dSJens Wiklander #include <assert.h>
7512cbf1dSJens Wiklander #include <pkcs11_ta.h>
8512cbf1dSJens Wiklander #include <string.h>
9512cbf1dSJens Wiklander #include <tee_api_defines.h>
10512cbf1dSJens Wiklander #include <tee_internal_api.h>
11512cbf1dSJens Wiklander #include <tee_internal_api_extensions.h>
12512cbf1dSJens Wiklander #include <util.h>
13512cbf1dSJens Wiklander 
14512cbf1dSJens Wiklander #include "attributes.h"
15512cbf1dSJens Wiklander #include "object.h"
16512cbf1dSJens Wiklander #include "pkcs11_attributes.h"
17512cbf1dSJens Wiklander #include "pkcs11_helpers.h"
18512cbf1dSJens Wiklander #include "pkcs11_token.h"
19512cbf1dSJens Wiklander #include "processing.h"
20512cbf1dSJens Wiklander #include "serializer.h"
21512cbf1dSJens Wiklander 
22512cbf1dSJens Wiklander static enum pkcs11_rc get_ready_session(struct pkcs11_session *session)
23512cbf1dSJens Wiklander {
24512cbf1dSJens Wiklander 	if (session_is_active(session))
25512cbf1dSJens Wiklander 		return PKCS11_CKR_OPERATION_ACTIVE;
26512cbf1dSJens Wiklander 
27512cbf1dSJens Wiklander 	return PKCS11_CKR_OK;
28512cbf1dSJens Wiklander }
29512cbf1dSJens Wiklander 
30512cbf1dSJens Wiklander static bool func_matches_state(enum processing_func function,
31512cbf1dSJens Wiklander 			       enum pkcs11_proc_state state)
32512cbf1dSJens Wiklander {
33512cbf1dSJens Wiklander 	switch (function) {
34512cbf1dSJens Wiklander 	case PKCS11_FUNCTION_ENCRYPT:
35512cbf1dSJens Wiklander 		return state == PKCS11_SESSION_ENCRYPTING ||
36512cbf1dSJens Wiklander 		       state == PKCS11_SESSION_DIGESTING_ENCRYPTING ||
37512cbf1dSJens Wiklander 		       state == PKCS11_SESSION_SIGNING_ENCRYPTING;
38512cbf1dSJens Wiklander 	case PKCS11_FUNCTION_DECRYPT:
39512cbf1dSJens Wiklander 		return state == PKCS11_SESSION_DECRYPTING ||
40512cbf1dSJens Wiklander 		       state == PKCS11_SESSION_DECRYPTING_DIGESTING ||
41512cbf1dSJens Wiklander 		       state == PKCS11_SESSION_DECRYPTING_VERIFYING;
42512cbf1dSJens Wiklander 	case PKCS11_FUNCTION_DIGEST:
43512cbf1dSJens Wiklander 		return state == PKCS11_SESSION_DIGESTING ||
44512cbf1dSJens Wiklander 		       state == PKCS11_SESSION_DIGESTING_ENCRYPTING;
45512cbf1dSJens Wiklander 	case PKCS11_FUNCTION_SIGN:
46512cbf1dSJens Wiklander 		return state == PKCS11_SESSION_SIGNING ||
47512cbf1dSJens Wiklander 		       state == PKCS11_SESSION_SIGNING_ENCRYPTING;
48512cbf1dSJens Wiklander 	case PKCS11_FUNCTION_VERIFY:
49512cbf1dSJens Wiklander 		return state == PKCS11_SESSION_VERIFYING ||
50512cbf1dSJens Wiklander 		       state == PKCS11_SESSION_DECRYPTING_VERIFYING;
51512cbf1dSJens Wiklander 	case PKCS11_FUNCTION_SIGN_RECOVER:
52512cbf1dSJens Wiklander 		return state == PKCS11_SESSION_SIGNING_RECOVER;
53512cbf1dSJens Wiklander 	case PKCS11_FUNCTION_VERIFY_RECOVER:
54512cbf1dSJens Wiklander 		return state == PKCS11_SESSION_SIGNING_RECOVER;
55512cbf1dSJens Wiklander 	default:
56512cbf1dSJens Wiklander 		TEE_Panic(function);
57512cbf1dSJens Wiklander 		return false;
58512cbf1dSJens Wiklander 	}
59512cbf1dSJens Wiklander }
60512cbf1dSJens Wiklander 
61512cbf1dSJens Wiklander static enum pkcs11_rc get_active_session(struct pkcs11_session *session,
62512cbf1dSJens Wiklander 					 enum processing_func function)
63512cbf1dSJens Wiklander {
64512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OPERATION_NOT_INITIALIZED;
65512cbf1dSJens Wiklander 
66512cbf1dSJens Wiklander 	if (session->processing &&
67512cbf1dSJens Wiklander 	    func_matches_state(function, session->processing->state))
68512cbf1dSJens Wiklander 		rc = PKCS11_CKR_OK;
69512cbf1dSJens Wiklander 
70512cbf1dSJens Wiklander 	return rc;
71512cbf1dSJens Wiklander }
72512cbf1dSJens Wiklander 
73512cbf1dSJens Wiklander void release_active_processing(struct pkcs11_session *session)
74512cbf1dSJens Wiklander {
75512cbf1dSJens Wiklander 	if (!session->processing)
76512cbf1dSJens Wiklander 		return;
77512cbf1dSJens Wiklander 
78512cbf1dSJens Wiklander 	switch (session->processing->mecha_type) {
79512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTR:
80512cbf1dSJens Wiklander 		tee_release_ctr_operation(session->processing);
81512cbf1dSJens Wiklander 		break;
82512cbf1dSJens Wiklander 	default:
83512cbf1dSJens Wiklander 		break;
84512cbf1dSJens Wiklander 	}
85512cbf1dSJens Wiklander 
86512cbf1dSJens Wiklander 	if (session->processing->tee_op_handle != TEE_HANDLE_NULL) {
87512cbf1dSJens Wiklander 		TEE_FreeOperation(session->processing->tee_op_handle);
88512cbf1dSJens Wiklander 		session->processing->tee_op_handle = TEE_HANDLE_NULL;
89512cbf1dSJens Wiklander 	}
90512cbf1dSJens Wiklander 
91512cbf1dSJens Wiklander 	TEE_Free(session->processing);
92512cbf1dSJens Wiklander 	session->processing = NULL;
93512cbf1dSJens Wiklander }
94512cbf1dSJens Wiklander 
95512cbf1dSJens Wiklander size_t get_object_key_bit_size(struct pkcs11_object *obj)
96512cbf1dSJens Wiklander {
97512cbf1dSJens Wiklander 	uint32_t a_size = 0;
98512cbf1dSJens Wiklander 	struct obj_attrs *attrs = obj->attributes;
99512cbf1dSJens Wiklander 
100512cbf1dSJens Wiklander 	switch (get_key_type(attrs)) {
101512cbf1dSJens Wiklander 	case PKCS11_CKK_AES:
102*689f4e5bSRuchika Gupta 	case PKCS11_CKK_GENERIC_SECRET:
103*689f4e5bSRuchika Gupta 	case PKCS11_CKK_MD5_HMAC:
104*689f4e5bSRuchika Gupta 	case PKCS11_CKK_SHA_1_HMAC:
105*689f4e5bSRuchika Gupta 	case PKCS11_CKK_SHA224_HMAC:
106*689f4e5bSRuchika Gupta 	case PKCS11_CKK_SHA256_HMAC:
107*689f4e5bSRuchika Gupta 	case PKCS11_CKK_SHA384_HMAC:
108*689f4e5bSRuchika Gupta 	case PKCS11_CKK_SHA512_HMAC:
109512cbf1dSJens Wiklander 		if (get_attribute_ptr(attrs, PKCS11_CKA_VALUE, NULL, &a_size))
110512cbf1dSJens Wiklander 			return 0;
111512cbf1dSJens Wiklander 
112512cbf1dSJens Wiklander 		return a_size * 8;
113512cbf1dSJens Wiklander 	default:
114512cbf1dSJens Wiklander 		TEE_Panic(0);
115512cbf1dSJens Wiklander 		return 0;
116512cbf1dSJens Wiklander 	}
117512cbf1dSJens Wiklander }
118512cbf1dSJens Wiklander 
119512cbf1dSJens Wiklander /*
120512cbf1dSJens Wiklander  * entry_processing_init - Generic entry for initializing a processing
121512cbf1dSJens Wiklander  *
122512cbf1dSJens Wiklander  * @client = client reference
123512cbf1dSJens Wiklander  * @ptype = Invocation parameter types
124512cbf1dSJens Wiklander  * @params = Invocation parameters reference
125512cbf1dSJens Wiklander  * @function - encrypt, decrypt, sign, verify, digest, ...
126512cbf1dSJens Wiklander  */
127512cbf1dSJens Wiklander enum pkcs11_rc entry_processing_init(struct pkcs11_client *client,
128512cbf1dSJens Wiklander 				     uint32_t ptypes, TEE_Param *params,
129512cbf1dSJens Wiklander 				     enum processing_func function)
130512cbf1dSJens Wiklander {
131512cbf1dSJens Wiklander 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
132512cbf1dSJens Wiklander 						TEE_PARAM_TYPE_NONE,
133512cbf1dSJens Wiklander 						TEE_PARAM_TYPE_NONE,
134512cbf1dSJens Wiklander 						TEE_PARAM_TYPE_NONE);
135512cbf1dSJens Wiklander 	TEE_Param *ctrl = params;
136512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
137512cbf1dSJens Wiklander 	struct serialargs ctrlargs = { };
138512cbf1dSJens Wiklander 	struct pkcs11_session *session = NULL;
139512cbf1dSJens Wiklander 	struct pkcs11_attribute_head *proc_params = NULL;
140512cbf1dSJens Wiklander 	uint32_t key_handle = 0;
141512cbf1dSJens Wiklander 	struct pkcs11_object *obj = NULL;
142512cbf1dSJens Wiklander 
143512cbf1dSJens Wiklander 	if (!client || ptypes != exp_pt)
144512cbf1dSJens Wiklander 		return PKCS11_CKR_ARGUMENTS_BAD;
145512cbf1dSJens Wiklander 
146512cbf1dSJens Wiklander 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
147512cbf1dSJens Wiklander 
148512cbf1dSJens Wiklander 	rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
149512cbf1dSJens Wiklander 	if (rc)
150512cbf1dSJens Wiklander 		return rc;
151512cbf1dSJens Wiklander 
152512cbf1dSJens Wiklander 	rc = serialargs_get(&ctrlargs, &key_handle, sizeof(uint32_t));
153512cbf1dSJens Wiklander 	if (rc)
154512cbf1dSJens Wiklander 		return rc;
155512cbf1dSJens Wiklander 
156512cbf1dSJens Wiklander 	rc = serialargs_alloc_get_one_attribute(&ctrlargs, &proc_params);
157512cbf1dSJens Wiklander 	if (rc)
158512cbf1dSJens Wiklander 		return rc;
159512cbf1dSJens Wiklander 
160512cbf1dSJens Wiklander 	if (serialargs_remaining_bytes(&ctrlargs)) {
161512cbf1dSJens Wiklander 		rc = PKCS11_CKR_ARGUMENTS_BAD;
162512cbf1dSJens Wiklander 		goto out;
163512cbf1dSJens Wiklander 	}
164512cbf1dSJens Wiklander 
165512cbf1dSJens Wiklander 	rc = get_ready_session(session);
166512cbf1dSJens Wiklander 	if (rc)
167512cbf1dSJens Wiklander 		goto out;
168512cbf1dSJens Wiklander 
169512cbf1dSJens Wiklander 	obj = pkcs11_handle2object(key_handle, session);
170512cbf1dSJens Wiklander 	if (!obj) {
171512cbf1dSJens Wiklander 		rc = PKCS11_CKR_KEY_HANDLE_INVALID;
172512cbf1dSJens Wiklander 		goto out;
173512cbf1dSJens Wiklander 	}
174512cbf1dSJens Wiklander 
175512cbf1dSJens Wiklander 	rc = set_processing_state(session, function, obj, NULL);
176512cbf1dSJens Wiklander 	if (rc)
177512cbf1dSJens Wiklander 		goto out;
178512cbf1dSJens Wiklander 
179512cbf1dSJens Wiklander 	rc = check_mechanism_against_processing(session, proc_params->id,
180512cbf1dSJens Wiklander 						function,
181512cbf1dSJens Wiklander 						PKCS11_FUNC_STEP_INIT);
182512cbf1dSJens Wiklander 	if (rc)
183512cbf1dSJens Wiklander 		goto out;
184512cbf1dSJens Wiklander 
185512cbf1dSJens Wiklander 	rc = check_parent_attrs_against_processing(proc_params->id, function,
186512cbf1dSJens Wiklander 						   obj->attributes);
187512cbf1dSJens Wiklander 	if (rc)
188512cbf1dSJens Wiklander 		goto out;
189512cbf1dSJens Wiklander 
190512cbf1dSJens Wiklander 	rc = check_access_attrs_against_token(session, obj->attributes);
191512cbf1dSJens Wiklander 	if (rc)
192512cbf1dSJens Wiklander 		goto out;
193512cbf1dSJens Wiklander 
194512cbf1dSJens Wiklander 	if (processing_is_tee_symm(proc_params->id))
195512cbf1dSJens Wiklander 		rc = init_symm_operation(session, function, proc_params, obj);
196512cbf1dSJens Wiklander 	else
197512cbf1dSJens Wiklander 		rc = PKCS11_CKR_MECHANISM_INVALID;
198512cbf1dSJens Wiklander 
199512cbf1dSJens Wiklander 	if (rc == PKCS11_CKR_OK) {
200512cbf1dSJens Wiklander 		session->processing->mecha_type = proc_params->id;
201512cbf1dSJens Wiklander 		DMSG("PKCS11 session %"PRIu32": init processing %s %s",
202512cbf1dSJens Wiklander 		     session->handle, id2str_proc(proc_params->id),
203512cbf1dSJens Wiklander 		     id2str_function(function));
204512cbf1dSJens Wiklander 	}
205512cbf1dSJens Wiklander 
206512cbf1dSJens Wiklander out:
207512cbf1dSJens Wiklander 	if (rc && session)
208512cbf1dSJens Wiklander 		release_active_processing(session);
209512cbf1dSJens Wiklander 
210512cbf1dSJens Wiklander 	TEE_Free(proc_params);
211512cbf1dSJens Wiklander 
212512cbf1dSJens Wiklander 	return rc;
213512cbf1dSJens Wiklander }
214512cbf1dSJens Wiklander 
215512cbf1dSJens Wiklander /*
216512cbf1dSJens Wiklander  * entry_processing_step - Generic entry on active processing
217512cbf1dSJens Wiklander  *
218512cbf1dSJens Wiklander  * @client = client reference
219512cbf1dSJens Wiklander  * @ptype = Invocation parameter types
220512cbf1dSJens Wiklander  * @params = Invocation parameters reference
221512cbf1dSJens Wiklander  * @function - encrypt, decrypt, sign, verify, digest, ...
222512cbf1dSJens Wiklander  * @step - update, oneshot, final
223512cbf1dSJens Wiklander  */
224512cbf1dSJens Wiklander enum pkcs11_rc entry_processing_step(struct pkcs11_client *client,
225512cbf1dSJens Wiklander 				     uint32_t ptypes, TEE_Param *params,
226512cbf1dSJens Wiklander 				     enum processing_func function,
227512cbf1dSJens Wiklander 				     enum processing_step step)
228512cbf1dSJens Wiklander {
229512cbf1dSJens Wiklander 	TEE_Param *ctrl = params;
230512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
231512cbf1dSJens Wiklander 	struct serialargs ctrlargs = { };
232512cbf1dSJens Wiklander 	struct pkcs11_session *session = NULL;
233512cbf1dSJens Wiklander 	enum pkcs11_mechanism_id mecha_type = PKCS11_CKM_UNDEFINED_ID;
234512cbf1dSJens Wiklander 
235512cbf1dSJens Wiklander 	if (!client ||
236512cbf1dSJens Wiklander 	    TEE_PARAM_TYPE_GET(ptypes, 0) != TEE_PARAM_TYPE_MEMREF_INOUT)
237512cbf1dSJens Wiklander 		return PKCS11_CKR_ARGUMENTS_BAD;
238512cbf1dSJens Wiklander 
239512cbf1dSJens Wiklander 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
240512cbf1dSJens Wiklander 
241512cbf1dSJens Wiklander 	rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
242512cbf1dSJens Wiklander 	if (rc)
243512cbf1dSJens Wiklander 		return rc;
244512cbf1dSJens Wiklander 
245512cbf1dSJens Wiklander 	if (serialargs_remaining_bytes(&ctrlargs))
246512cbf1dSJens Wiklander 		return PKCS11_CKR_ARGUMENTS_BAD;
247512cbf1dSJens Wiklander 
248512cbf1dSJens Wiklander 	rc = get_active_session(session, function);
249512cbf1dSJens Wiklander 	if (rc)
250512cbf1dSJens Wiklander 		return rc;
251512cbf1dSJens Wiklander 
252512cbf1dSJens Wiklander 	mecha_type = session->processing->mecha_type;
253512cbf1dSJens Wiklander 	rc = check_mechanism_against_processing(session, mecha_type,
254512cbf1dSJens Wiklander 						function, step);
255512cbf1dSJens Wiklander 	if (rc)
256512cbf1dSJens Wiklander 		goto out;
257512cbf1dSJens Wiklander 
258512cbf1dSJens Wiklander 	if (processing_is_tee_symm(mecha_type))
259512cbf1dSJens Wiklander 		rc = step_symm_operation(session, function, step,
260512cbf1dSJens Wiklander 					 ptypes, params);
261512cbf1dSJens Wiklander 	else
262512cbf1dSJens Wiklander 		rc = PKCS11_CKR_MECHANISM_INVALID;
263512cbf1dSJens Wiklander 
264*689f4e5bSRuchika Gupta 	if (rc == PKCS11_CKR_OK && step == PKCS11_FUNC_STEP_UPDATE) {
265512cbf1dSJens Wiklander 		session->processing->updated = true;
266512cbf1dSJens Wiklander 		DMSG("PKCS11 session%"PRIu32": processing %s %s",
267512cbf1dSJens Wiklander 		     session->handle, id2str_proc(mecha_type),
268512cbf1dSJens Wiklander 		     id2str_function(function));
269512cbf1dSJens Wiklander 	}
270512cbf1dSJens Wiklander 
271512cbf1dSJens Wiklander out:
272512cbf1dSJens Wiklander 	switch (step) {
273512cbf1dSJens Wiklander 	case PKCS11_FUNC_STEP_UPDATE:
274512cbf1dSJens Wiklander 		if (rc != PKCS11_CKR_OK && rc != PKCS11_CKR_BUFFER_TOO_SMALL)
275512cbf1dSJens Wiklander 			release_active_processing(session);
276512cbf1dSJens Wiklander 		break;
277512cbf1dSJens Wiklander 	default:
278512cbf1dSJens Wiklander 		/* ONESHOT and FINAL terminates processing on success */
279512cbf1dSJens Wiklander 		if (rc != PKCS11_CKR_BUFFER_TOO_SMALL)
280512cbf1dSJens Wiklander 			release_active_processing(session);
281512cbf1dSJens Wiklander 		break;
282512cbf1dSJens Wiklander 	}
283512cbf1dSJens Wiklander 
284512cbf1dSJens Wiklander 	return rc;
285512cbf1dSJens Wiklander }
286512cbf1dSJens Wiklander 
287512cbf1dSJens Wiklander /*
288512cbf1dSJens Wiklander  * entry_verify_oneshot - Run a single part verification processing
289512cbf1dSJens Wiklander  *
290512cbf1dSJens Wiklander  * @client = client reference
291512cbf1dSJens Wiklander  * @ptype = Invocation parameter types
292512cbf1dSJens Wiklander  * @params = Invocation parameters reference
293512cbf1dSJens Wiklander  * @function - encrypt, decrypt, sign, verify, digest, ...
294512cbf1dSJens Wiklander  * @step - update, oneshot, final
295512cbf1dSJens Wiklander  */
296512cbf1dSJens Wiklander enum pkcs11_rc entry_verify_oneshot(struct pkcs11_client *client,
297512cbf1dSJens Wiklander 				    uint32_t ptypes, TEE_Param *params,
298512cbf1dSJens Wiklander 				    enum processing_func function,
299512cbf1dSJens Wiklander 				    enum processing_step step)
300512cbf1dSJens Wiklander 
301512cbf1dSJens Wiklander {
302512cbf1dSJens Wiklander 	TEE_Param *ctrl = params;
303512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
304512cbf1dSJens Wiklander 	struct serialargs ctrlargs = { };
305512cbf1dSJens Wiklander 	struct pkcs11_session *session = NULL;
306512cbf1dSJens Wiklander 	enum pkcs11_mechanism_id mecha_type = PKCS11_CKM_UNDEFINED_ID;
307512cbf1dSJens Wiklander 
308512cbf1dSJens Wiklander 	assert(function == PKCS11_FUNCTION_VERIFY);
309512cbf1dSJens Wiklander 	if (!client ||
310512cbf1dSJens Wiklander 	    TEE_PARAM_TYPE_GET(ptypes, 0) != TEE_PARAM_TYPE_MEMREF_INOUT)
311512cbf1dSJens Wiklander 		return PKCS11_CKR_ARGUMENTS_BAD;
312512cbf1dSJens Wiklander 
313512cbf1dSJens Wiklander 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
314512cbf1dSJens Wiklander 
315512cbf1dSJens Wiklander 	rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
316512cbf1dSJens Wiklander 	if (rc)
317512cbf1dSJens Wiklander 		return rc;
318512cbf1dSJens Wiklander 
319512cbf1dSJens Wiklander 	if (serialargs_remaining_bytes(&ctrlargs))
320512cbf1dSJens Wiklander 		return PKCS11_CKR_ARGUMENTS_BAD;
321512cbf1dSJens Wiklander 
322512cbf1dSJens Wiklander 	rc = get_active_session(session, function);
323512cbf1dSJens Wiklander 	if (rc)
324512cbf1dSJens Wiklander 		return rc;
325512cbf1dSJens Wiklander 
326512cbf1dSJens Wiklander 	mecha_type = session->processing->mecha_type;
327512cbf1dSJens Wiklander 	rc = check_mechanism_against_processing(session, mecha_type,
328512cbf1dSJens Wiklander 						function, step);
329512cbf1dSJens Wiklander 	if (rc)
330512cbf1dSJens Wiklander 		goto out;
331512cbf1dSJens Wiklander 
332512cbf1dSJens Wiklander 	if (processing_is_tee_symm(mecha_type))
333512cbf1dSJens Wiklander 		rc = step_symm_operation(session, function, step,
334512cbf1dSJens Wiklander 					 ptypes, params);
335512cbf1dSJens Wiklander 	else
336512cbf1dSJens Wiklander 		rc = PKCS11_CKR_MECHANISM_INVALID;
337512cbf1dSJens Wiklander 
338512cbf1dSJens Wiklander 	DMSG("PKCS11 session %"PRIu32": verify %s %s: %s", session->handle,
339512cbf1dSJens Wiklander 	     id2str_proc(mecha_type), id2str_function(function),
340512cbf1dSJens Wiklander 	     id2str_rc(rc));
341512cbf1dSJens Wiklander 
342512cbf1dSJens Wiklander out:
343512cbf1dSJens Wiklander 	if (rc != PKCS11_CKR_BUFFER_TOO_SMALL)
344512cbf1dSJens Wiklander 		release_active_processing(session);
345512cbf1dSJens Wiklander 
346512cbf1dSJens Wiklander 	return rc;
347512cbf1dSJens Wiklander }
348