xref: /optee_os/ta/pkcs11/src/processing.c (revision 512cbf1d30ddce3513abf2b08d4063d5c8415a40)
1*512cbf1dSJens Wiklander // SPDX-License-Identifier: BSD-2-Clause
2*512cbf1dSJens Wiklander /*
3*512cbf1dSJens Wiklander  * Copyright (c) 2017-2020, Linaro Limited
4*512cbf1dSJens Wiklander  */
5*512cbf1dSJens Wiklander 
6*512cbf1dSJens Wiklander #include <assert.h>
7*512cbf1dSJens Wiklander #include <pkcs11_ta.h>
8*512cbf1dSJens Wiklander #include <string.h>
9*512cbf1dSJens Wiklander #include <tee_api_defines.h>
10*512cbf1dSJens Wiklander #include <tee_internal_api.h>
11*512cbf1dSJens Wiklander #include <tee_internal_api_extensions.h>
12*512cbf1dSJens Wiklander #include <util.h>
13*512cbf1dSJens Wiklander 
14*512cbf1dSJens Wiklander #include "attributes.h"
15*512cbf1dSJens Wiklander #include "object.h"
16*512cbf1dSJens Wiklander #include "pkcs11_attributes.h"
17*512cbf1dSJens Wiklander #include "pkcs11_helpers.h"
18*512cbf1dSJens Wiklander #include "pkcs11_token.h"
19*512cbf1dSJens Wiklander #include "processing.h"
20*512cbf1dSJens Wiklander #include "serializer.h"
21*512cbf1dSJens Wiklander 
22*512cbf1dSJens Wiklander static enum pkcs11_rc get_ready_session(struct pkcs11_session *session)
23*512cbf1dSJens Wiklander {
24*512cbf1dSJens Wiklander 	if (session_is_active(session))
25*512cbf1dSJens Wiklander 		return PKCS11_CKR_OPERATION_ACTIVE;
26*512cbf1dSJens Wiklander 
27*512cbf1dSJens Wiklander 	return PKCS11_CKR_OK;
28*512cbf1dSJens Wiklander }
29*512cbf1dSJens Wiklander 
30*512cbf1dSJens Wiklander static bool func_matches_state(enum processing_func function,
31*512cbf1dSJens Wiklander 			       enum pkcs11_proc_state state)
32*512cbf1dSJens Wiklander {
33*512cbf1dSJens Wiklander 	switch (function) {
34*512cbf1dSJens Wiklander 	case PKCS11_FUNCTION_ENCRYPT:
35*512cbf1dSJens Wiklander 		return state == PKCS11_SESSION_ENCRYPTING ||
36*512cbf1dSJens Wiklander 		       state == PKCS11_SESSION_DIGESTING_ENCRYPTING ||
37*512cbf1dSJens Wiklander 		       state == PKCS11_SESSION_SIGNING_ENCRYPTING;
38*512cbf1dSJens Wiklander 	case PKCS11_FUNCTION_DECRYPT:
39*512cbf1dSJens Wiklander 		return state == PKCS11_SESSION_DECRYPTING ||
40*512cbf1dSJens Wiklander 		       state == PKCS11_SESSION_DECRYPTING_DIGESTING ||
41*512cbf1dSJens Wiklander 		       state == PKCS11_SESSION_DECRYPTING_VERIFYING;
42*512cbf1dSJens Wiklander 	case PKCS11_FUNCTION_DIGEST:
43*512cbf1dSJens Wiklander 		return state == PKCS11_SESSION_DIGESTING ||
44*512cbf1dSJens Wiklander 		       state == PKCS11_SESSION_DIGESTING_ENCRYPTING;
45*512cbf1dSJens Wiklander 	case PKCS11_FUNCTION_SIGN:
46*512cbf1dSJens Wiklander 		return state == PKCS11_SESSION_SIGNING ||
47*512cbf1dSJens Wiklander 		       state == PKCS11_SESSION_SIGNING_ENCRYPTING;
48*512cbf1dSJens Wiklander 	case PKCS11_FUNCTION_VERIFY:
49*512cbf1dSJens Wiklander 		return state == PKCS11_SESSION_VERIFYING ||
50*512cbf1dSJens Wiklander 		       state == PKCS11_SESSION_DECRYPTING_VERIFYING;
51*512cbf1dSJens Wiklander 	case PKCS11_FUNCTION_SIGN_RECOVER:
52*512cbf1dSJens Wiklander 		return state == PKCS11_SESSION_SIGNING_RECOVER;
53*512cbf1dSJens Wiklander 	case PKCS11_FUNCTION_VERIFY_RECOVER:
54*512cbf1dSJens Wiklander 		return state == PKCS11_SESSION_SIGNING_RECOVER;
55*512cbf1dSJens Wiklander 	default:
56*512cbf1dSJens Wiklander 		TEE_Panic(function);
57*512cbf1dSJens Wiklander 		return false;
58*512cbf1dSJens Wiklander 	}
59*512cbf1dSJens Wiklander }
60*512cbf1dSJens Wiklander 
61*512cbf1dSJens Wiklander static enum pkcs11_rc get_active_session(struct pkcs11_session *session,
62*512cbf1dSJens Wiklander 					 enum processing_func function)
63*512cbf1dSJens Wiklander {
64*512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OPERATION_NOT_INITIALIZED;
65*512cbf1dSJens Wiklander 
66*512cbf1dSJens Wiklander 	if (session->processing &&
67*512cbf1dSJens Wiklander 	    func_matches_state(function, session->processing->state))
68*512cbf1dSJens Wiklander 		rc = PKCS11_CKR_OK;
69*512cbf1dSJens Wiklander 
70*512cbf1dSJens Wiklander 	return rc;
71*512cbf1dSJens Wiklander }
72*512cbf1dSJens Wiklander 
73*512cbf1dSJens Wiklander void release_active_processing(struct pkcs11_session *session)
74*512cbf1dSJens Wiklander {
75*512cbf1dSJens Wiklander 	if (!session->processing)
76*512cbf1dSJens Wiklander 		return;
77*512cbf1dSJens Wiklander 
78*512cbf1dSJens Wiklander 	switch (session->processing->mecha_type) {
79*512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTR:
80*512cbf1dSJens Wiklander 		tee_release_ctr_operation(session->processing);
81*512cbf1dSJens Wiklander 		break;
82*512cbf1dSJens Wiklander 	default:
83*512cbf1dSJens Wiklander 		break;
84*512cbf1dSJens Wiklander 	}
85*512cbf1dSJens Wiklander 
86*512cbf1dSJens Wiklander 	if (session->processing->tee_op_handle != TEE_HANDLE_NULL) {
87*512cbf1dSJens Wiklander 		TEE_FreeOperation(session->processing->tee_op_handle);
88*512cbf1dSJens Wiklander 		session->processing->tee_op_handle = TEE_HANDLE_NULL;
89*512cbf1dSJens Wiklander 	}
90*512cbf1dSJens Wiklander 
91*512cbf1dSJens Wiklander 	TEE_Free(session->processing);
92*512cbf1dSJens Wiklander 	session->processing = NULL;
93*512cbf1dSJens Wiklander }
94*512cbf1dSJens Wiklander 
95*512cbf1dSJens Wiklander size_t get_object_key_bit_size(struct pkcs11_object *obj)
96*512cbf1dSJens Wiklander {
97*512cbf1dSJens Wiklander 	uint32_t a_size = 0;
98*512cbf1dSJens Wiklander 	struct obj_attrs *attrs = obj->attributes;
99*512cbf1dSJens Wiklander 
100*512cbf1dSJens Wiklander 	switch (get_key_type(attrs)) {
101*512cbf1dSJens Wiklander 	case PKCS11_CKK_AES:
102*512cbf1dSJens Wiklander 		if (get_attribute_ptr(attrs, PKCS11_CKA_VALUE, NULL, &a_size))
103*512cbf1dSJens Wiklander 			return 0;
104*512cbf1dSJens Wiklander 
105*512cbf1dSJens Wiklander 		return a_size * 8;
106*512cbf1dSJens Wiklander 	default:
107*512cbf1dSJens Wiklander 		TEE_Panic(0);
108*512cbf1dSJens Wiklander 		return 0;
109*512cbf1dSJens Wiklander 	}
110*512cbf1dSJens Wiklander }
111*512cbf1dSJens Wiklander 
112*512cbf1dSJens Wiklander /*
113*512cbf1dSJens Wiklander  * entry_processing_init - Generic entry for initializing a processing
114*512cbf1dSJens Wiklander  *
115*512cbf1dSJens Wiklander  * @client = client reference
116*512cbf1dSJens Wiklander  * @ptype = Invocation parameter types
117*512cbf1dSJens Wiklander  * @params = Invocation parameters reference
118*512cbf1dSJens Wiklander  * @function - encrypt, decrypt, sign, verify, digest, ...
119*512cbf1dSJens Wiklander  */
120*512cbf1dSJens Wiklander enum pkcs11_rc entry_processing_init(struct pkcs11_client *client,
121*512cbf1dSJens Wiklander 				     uint32_t ptypes, TEE_Param *params,
122*512cbf1dSJens Wiklander 				     enum processing_func function)
123*512cbf1dSJens Wiklander {
124*512cbf1dSJens Wiklander 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
125*512cbf1dSJens Wiklander 						TEE_PARAM_TYPE_NONE,
126*512cbf1dSJens Wiklander 						TEE_PARAM_TYPE_NONE,
127*512cbf1dSJens Wiklander 						TEE_PARAM_TYPE_NONE);
128*512cbf1dSJens Wiklander 	TEE_Param *ctrl = params;
129*512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
130*512cbf1dSJens Wiklander 	struct serialargs ctrlargs = { };
131*512cbf1dSJens Wiklander 	struct pkcs11_session *session = NULL;
132*512cbf1dSJens Wiklander 	struct pkcs11_attribute_head *proc_params = NULL;
133*512cbf1dSJens Wiklander 	uint32_t key_handle = 0;
134*512cbf1dSJens Wiklander 	struct pkcs11_object *obj = NULL;
135*512cbf1dSJens Wiklander 
136*512cbf1dSJens Wiklander 	if (!client || ptypes != exp_pt)
137*512cbf1dSJens Wiklander 		return PKCS11_CKR_ARGUMENTS_BAD;
138*512cbf1dSJens Wiklander 
139*512cbf1dSJens Wiklander 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
140*512cbf1dSJens Wiklander 
141*512cbf1dSJens Wiklander 	rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
142*512cbf1dSJens Wiklander 	if (rc)
143*512cbf1dSJens Wiklander 		return rc;
144*512cbf1dSJens Wiklander 
145*512cbf1dSJens Wiklander 	rc = serialargs_get(&ctrlargs, &key_handle, sizeof(uint32_t));
146*512cbf1dSJens Wiklander 	if (rc)
147*512cbf1dSJens Wiklander 		return rc;
148*512cbf1dSJens Wiklander 
149*512cbf1dSJens Wiklander 	rc = serialargs_alloc_get_one_attribute(&ctrlargs, &proc_params);
150*512cbf1dSJens Wiklander 	if (rc)
151*512cbf1dSJens Wiklander 		return rc;
152*512cbf1dSJens Wiklander 
153*512cbf1dSJens Wiklander 	if (serialargs_remaining_bytes(&ctrlargs)) {
154*512cbf1dSJens Wiklander 		rc = PKCS11_CKR_ARGUMENTS_BAD;
155*512cbf1dSJens Wiklander 		goto out;
156*512cbf1dSJens Wiklander 	}
157*512cbf1dSJens Wiklander 
158*512cbf1dSJens Wiklander 	rc = get_ready_session(session);
159*512cbf1dSJens Wiklander 	if (rc)
160*512cbf1dSJens Wiklander 		goto out;
161*512cbf1dSJens Wiklander 
162*512cbf1dSJens Wiklander 	obj = pkcs11_handle2object(key_handle, session);
163*512cbf1dSJens Wiklander 	if (!obj) {
164*512cbf1dSJens Wiklander 		rc = PKCS11_CKR_KEY_HANDLE_INVALID;
165*512cbf1dSJens Wiklander 		goto out;
166*512cbf1dSJens Wiklander 	}
167*512cbf1dSJens Wiklander 
168*512cbf1dSJens Wiklander 	rc = set_processing_state(session, function, obj, NULL);
169*512cbf1dSJens Wiklander 	if (rc)
170*512cbf1dSJens Wiklander 		goto out;
171*512cbf1dSJens Wiklander 
172*512cbf1dSJens Wiklander 	rc = check_mechanism_against_processing(session, proc_params->id,
173*512cbf1dSJens Wiklander 						function,
174*512cbf1dSJens Wiklander 						PKCS11_FUNC_STEP_INIT);
175*512cbf1dSJens Wiklander 	if (rc)
176*512cbf1dSJens Wiklander 		goto out;
177*512cbf1dSJens Wiklander 
178*512cbf1dSJens Wiklander 	rc = check_parent_attrs_against_processing(proc_params->id, function,
179*512cbf1dSJens Wiklander 						   obj->attributes);
180*512cbf1dSJens Wiklander 	if (rc)
181*512cbf1dSJens Wiklander 		goto out;
182*512cbf1dSJens Wiklander 
183*512cbf1dSJens Wiklander 	rc = check_access_attrs_against_token(session, obj->attributes);
184*512cbf1dSJens Wiklander 	if (rc)
185*512cbf1dSJens Wiklander 		goto out;
186*512cbf1dSJens Wiklander 
187*512cbf1dSJens Wiklander 	if (processing_is_tee_symm(proc_params->id))
188*512cbf1dSJens Wiklander 		rc = init_symm_operation(session, function, proc_params, obj);
189*512cbf1dSJens Wiklander 	else
190*512cbf1dSJens Wiklander 		rc = PKCS11_CKR_MECHANISM_INVALID;
191*512cbf1dSJens Wiklander 
192*512cbf1dSJens Wiklander 	if (rc == PKCS11_CKR_OK) {
193*512cbf1dSJens Wiklander 		session->processing->mecha_type = proc_params->id;
194*512cbf1dSJens Wiklander 		DMSG("PKCS11 session %"PRIu32": init processing %s %s",
195*512cbf1dSJens Wiklander 		     session->handle, id2str_proc(proc_params->id),
196*512cbf1dSJens Wiklander 		     id2str_function(function));
197*512cbf1dSJens Wiklander 	}
198*512cbf1dSJens Wiklander 
199*512cbf1dSJens Wiklander out:
200*512cbf1dSJens Wiklander 	if (rc && session)
201*512cbf1dSJens Wiklander 		release_active_processing(session);
202*512cbf1dSJens Wiklander 
203*512cbf1dSJens Wiklander 	TEE_Free(proc_params);
204*512cbf1dSJens Wiklander 
205*512cbf1dSJens Wiklander 	return rc;
206*512cbf1dSJens Wiklander }
207*512cbf1dSJens Wiklander 
208*512cbf1dSJens Wiklander /*
209*512cbf1dSJens Wiklander  * entry_processing_step - Generic entry on active processing
210*512cbf1dSJens Wiklander  *
211*512cbf1dSJens Wiklander  * @client = client reference
212*512cbf1dSJens Wiklander  * @ptype = Invocation parameter types
213*512cbf1dSJens Wiklander  * @params = Invocation parameters reference
214*512cbf1dSJens Wiklander  * @function - encrypt, decrypt, sign, verify, digest, ...
215*512cbf1dSJens Wiklander  * @step - update, oneshot, final
216*512cbf1dSJens Wiklander  */
217*512cbf1dSJens Wiklander enum pkcs11_rc entry_processing_step(struct pkcs11_client *client,
218*512cbf1dSJens Wiklander 				     uint32_t ptypes, TEE_Param *params,
219*512cbf1dSJens Wiklander 				     enum processing_func function,
220*512cbf1dSJens Wiklander 				     enum processing_step step)
221*512cbf1dSJens Wiklander {
222*512cbf1dSJens Wiklander 	TEE_Param *ctrl = params;
223*512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
224*512cbf1dSJens Wiklander 	struct serialargs ctrlargs = { };
225*512cbf1dSJens Wiklander 	struct pkcs11_session *session = NULL;
226*512cbf1dSJens Wiklander 	enum pkcs11_mechanism_id mecha_type = PKCS11_CKM_UNDEFINED_ID;
227*512cbf1dSJens Wiklander 
228*512cbf1dSJens Wiklander 	if (!client ||
229*512cbf1dSJens Wiklander 	    TEE_PARAM_TYPE_GET(ptypes, 0) != TEE_PARAM_TYPE_MEMREF_INOUT)
230*512cbf1dSJens Wiklander 		return PKCS11_CKR_ARGUMENTS_BAD;
231*512cbf1dSJens Wiklander 
232*512cbf1dSJens Wiklander 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
233*512cbf1dSJens Wiklander 
234*512cbf1dSJens Wiklander 	rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
235*512cbf1dSJens Wiklander 	if (rc)
236*512cbf1dSJens Wiklander 		return rc;
237*512cbf1dSJens Wiklander 
238*512cbf1dSJens Wiklander 	if (serialargs_remaining_bytes(&ctrlargs))
239*512cbf1dSJens Wiklander 		return PKCS11_CKR_ARGUMENTS_BAD;
240*512cbf1dSJens Wiklander 
241*512cbf1dSJens Wiklander 	rc = get_active_session(session, function);
242*512cbf1dSJens Wiklander 	if (rc)
243*512cbf1dSJens Wiklander 		return rc;
244*512cbf1dSJens Wiklander 
245*512cbf1dSJens Wiklander 	mecha_type = session->processing->mecha_type;
246*512cbf1dSJens Wiklander 	rc = check_mechanism_against_processing(session, mecha_type,
247*512cbf1dSJens Wiklander 						function, step);
248*512cbf1dSJens Wiklander 	if (rc)
249*512cbf1dSJens Wiklander 		goto out;
250*512cbf1dSJens Wiklander 
251*512cbf1dSJens Wiklander 	if (processing_is_tee_symm(mecha_type))
252*512cbf1dSJens Wiklander 		rc = step_symm_operation(session, function, step,
253*512cbf1dSJens Wiklander 					 ptypes, params);
254*512cbf1dSJens Wiklander 	else
255*512cbf1dSJens Wiklander 		rc = PKCS11_CKR_MECHANISM_INVALID;
256*512cbf1dSJens Wiklander 
257*512cbf1dSJens Wiklander 	if (rc == PKCS11_CKR_OK) {
258*512cbf1dSJens Wiklander 		session->processing->updated = true;
259*512cbf1dSJens Wiklander 		DMSG("PKCS11 session%"PRIu32": processing %s %s",
260*512cbf1dSJens Wiklander 		     session->handle, id2str_proc(mecha_type),
261*512cbf1dSJens Wiklander 		     id2str_function(function));
262*512cbf1dSJens Wiklander 	}
263*512cbf1dSJens Wiklander 
264*512cbf1dSJens Wiklander out:
265*512cbf1dSJens Wiklander 	switch (step) {
266*512cbf1dSJens Wiklander 	case PKCS11_FUNC_STEP_UPDATE:
267*512cbf1dSJens Wiklander 		if (rc != PKCS11_CKR_OK && rc != PKCS11_CKR_BUFFER_TOO_SMALL)
268*512cbf1dSJens Wiklander 			release_active_processing(session);
269*512cbf1dSJens Wiklander 		break;
270*512cbf1dSJens Wiklander 	default:
271*512cbf1dSJens Wiklander 		/* ONESHOT and FINAL terminates processing on success */
272*512cbf1dSJens Wiklander 		if (rc != PKCS11_CKR_BUFFER_TOO_SMALL)
273*512cbf1dSJens Wiklander 			release_active_processing(session);
274*512cbf1dSJens Wiklander 		break;
275*512cbf1dSJens Wiklander 	}
276*512cbf1dSJens Wiklander 
277*512cbf1dSJens Wiklander 	return rc;
278*512cbf1dSJens Wiklander }
279*512cbf1dSJens Wiklander 
280*512cbf1dSJens Wiklander /*
281*512cbf1dSJens Wiklander  * entry_verify_oneshot - Run a single part verification processing
282*512cbf1dSJens Wiklander  *
283*512cbf1dSJens Wiklander  * @client = client reference
284*512cbf1dSJens Wiklander  * @ptype = Invocation parameter types
285*512cbf1dSJens Wiklander  * @params = Invocation parameters reference
286*512cbf1dSJens Wiklander  * @function - encrypt, decrypt, sign, verify, digest, ...
287*512cbf1dSJens Wiklander  * @step - update, oneshot, final
288*512cbf1dSJens Wiklander  */
289*512cbf1dSJens Wiklander enum pkcs11_rc entry_verify_oneshot(struct pkcs11_client *client,
290*512cbf1dSJens Wiklander 				    uint32_t ptypes, TEE_Param *params,
291*512cbf1dSJens Wiklander 				    enum processing_func function,
292*512cbf1dSJens Wiklander 				    enum processing_step step)
293*512cbf1dSJens Wiklander 
294*512cbf1dSJens Wiklander {
295*512cbf1dSJens Wiklander 	TEE_Param *ctrl = params;
296*512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
297*512cbf1dSJens Wiklander 	struct serialargs ctrlargs = { };
298*512cbf1dSJens Wiklander 	struct pkcs11_session *session = NULL;
299*512cbf1dSJens Wiklander 	enum pkcs11_mechanism_id mecha_type = PKCS11_CKM_UNDEFINED_ID;
300*512cbf1dSJens Wiklander 
301*512cbf1dSJens Wiklander 	assert(function == PKCS11_FUNCTION_VERIFY);
302*512cbf1dSJens Wiklander 	if (!client ||
303*512cbf1dSJens Wiklander 	    TEE_PARAM_TYPE_GET(ptypes, 0) != TEE_PARAM_TYPE_MEMREF_INOUT)
304*512cbf1dSJens Wiklander 		return PKCS11_CKR_ARGUMENTS_BAD;
305*512cbf1dSJens Wiklander 
306*512cbf1dSJens Wiklander 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
307*512cbf1dSJens Wiklander 
308*512cbf1dSJens Wiklander 	rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
309*512cbf1dSJens Wiklander 	if (rc)
310*512cbf1dSJens Wiklander 		return rc;
311*512cbf1dSJens Wiklander 
312*512cbf1dSJens Wiklander 	if (serialargs_remaining_bytes(&ctrlargs))
313*512cbf1dSJens Wiklander 		return PKCS11_CKR_ARGUMENTS_BAD;
314*512cbf1dSJens Wiklander 
315*512cbf1dSJens Wiklander 	rc = get_active_session(session, function);
316*512cbf1dSJens Wiklander 	if (rc)
317*512cbf1dSJens Wiklander 		return rc;
318*512cbf1dSJens Wiklander 
319*512cbf1dSJens Wiklander 	mecha_type = session->processing->mecha_type;
320*512cbf1dSJens Wiklander 	rc = check_mechanism_against_processing(session, mecha_type,
321*512cbf1dSJens Wiklander 						function, step);
322*512cbf1dSJens Wiklander 	if (rc)
323*512cbf1dSJens Wiklander 		goto out;
324*512cbf1dSJens Wiklander 
325*512cbf1dSJens Wiklander 	if (processing_is_tee_symm(mecha_type))
326*512cbf1dSJens Wiklander 		rc = step_symm_operation(session, function, step,
327*512cbf1dSJens Wiklander 					 ptypes, params);
328*512cbf1dSJens Wiklander 	else
329*512cbf1dSJens Wiklander 		rc = PKCS11_CKR_MECHANISM_INVALID;
330*512cbf1dSJens Wiklander 
331*512cbf1dSJens Wiklander 	DMSG("PKCS11 session %"PRIu32": verify %s %s: %s", session->handle,
332*512cbf1dSJens Wiklander 	     id2str_proc(mecha_type), id2str_function(function),
333*512cbf1dSJens Wiklander 	     id2str_rc(rc));
334*512cbf1dSJens Wiklander 
335*512cbf1dSJens Wiklander out:
336*512cbf1dSJens Wiklander 	if (rc != PKCS11_CKR_BUFFER_TOO_SMALL)
337*512cbf1dSJens Wiklander 		release_active_processing(session);
338*512cbf1dSJens Wiklander 
339*512cbf1dSJens Wiklander 	return rc;
340*512cbf1dSJens Wiklander }
341