xref: /optee_os/ta/pkcs11/src/processing_aes.c (revision 04e46975d8f02e25209af552aaea4acb4d70c7f9)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2018-2020, Linaro Limited
4  */
5 
6 #include <assert.h>
7 #include <compiler.h>
8 #include <tee_internal_api.h>
9 #include <tee_internal_api_extensions.h>
10 #include <trace.h>
11 #include <util.h>
12 
13 #include "pkcs11_helpers.h"
14 #include "pkcs11_token.h"
15 #include "processing.h"
16 #include "serializer.h"
17 
18 /*
19  * Authenticated ciphering: (AES GCM)
20  *
21  * As per PKCS#11, GCM decryption shall not reveal the data until the
22  * decryption is completed and the MAC verified. The pkcs11 TA retains the
23  * ciphered data until the operation is completed. Therefore every chunk of
24  * decrypted data is saved in a allocated buffer during AE update processing
25  * and only copied into the client's output buffer at AE finalization when
26  * tag is authenticated.
27  *
28  * As per PKCS#11, GCM decryption expect the tag data to be provided
29  * inside the input data for C_DecryptUpdate() and friends, appended to the
30  * input encyprted data hence we do not know which is the last call to
31  * C_DecryptUpdate() where last bytes are not ciphered data but the requested
32  * tag bytes for message autehntication. To handle this, the TA saves
33  * the last input data bytes (length is defined by the tag byte size) in the
34  * AE context and waits the C_DecryptFinal() to either treat these as data
35  * bytes or tag/MAC bytes. Refer to pending_tag and pending_size in struct
36  * ae_aes_context.
37  */
38 
39 /*
40  * struct out_data_ref - AE decyrption output data chunks
41  * @size - byte size of the allocated buffer
42  * @data - pointer to allocated data
43  */
44 struct out_data_ref {
45 	size_t size;
46 	void *data;
47 };
48 
49 /*
50  * struct ae_aes_context - Extra context data got AE operations
51  * @tag_byte_len - Tag size in byte
52  * @pending_tag - Input data that could be the appended tag
53  * @pending_size - Size of pending input data that could be the tag
54  * @out_data - Pointer to an array of output data references.
55  * @out_count - Number of buffer references in out_data
56  */
57 struct ae_aes_context {
58 	size_t tag_byte_len;
59 	char *pending_tag;
60 	size_t pending_size;
61 	struct out_data_ref *out_data;
62 	size_t out_count;
63 };
64 
init_ae_aes_context(struct ae_aes_context * ctx)65 static enum pkcs11_rc init_ae_aes_context(struct ae_aes_context *ctx)
66 {
67 	struct out_data_ref *out_data = NULL;
68 	char *pending_tag = NULL;
69 
70 	assert(!ctx->out_data && !ctx->out_count &&
71 	       !ctx->pending_tag && !ctx->pending_size);
72 
73 	out_data = TEE_Malloc(sizeof(*out_data), TEE_MALLOC_FILL_ZERO);
74 	pending_tag = TEE_Malloc(ctx->tag_byte_len, TEE_MALLOC_FILL_ZERO);
75 
76 	if (!out_data || !pending_tag) {
77 		TEE_Free(out_data);
78 		TEE_Free(pending_tag);
79 		return PKCS11_CKR_DEVICE_MEMORY;
80 	}
81 
82 	ctx->pending_tag = pending_tag;
83 	ctx->out_data = out_data;
84 
85 	return PKCS11_CKR_OK;
86 }
87 
release_ae_aes_context(struct ae_aes_context * ctx)88 static void release_ae_aes_context(struct ae_aes_context *ctx)
89 {
90 	size_t n = 0;
91 
92 	for (n = 0; n < ctx->out_count; n++)
93 		TEE_Free(ctx->out_data[n].data);
94 
95 	TEE_Free(ctx->out_data);
96 	ctx->out_data = NULL;
97 	ctx->out_count = 0;
98 
99 	TEE_Free(ctx->pending_tag);
100 	ctx->pending_tag = NULL;
101 	ctx->pending_size = 0;
102 }
103 
104 /*
105  * This function feeds the AE decryption processing with client
106  * input data. There are 2 constraints to consider.
107  *
108  * Firstly we don't know yet which are the ciphered data and which are
109  * the tag data. GP TEE Internal API function requires we split data and
110  * tag when TEE_AEDecryptFinal() will be called.
111  *
112  * Secondly any generated data must be kept in the TA and only revealed
113  * once tag if succefully processed.
114  */
tee_ae_decrypt_update(struct pkcs11_session * session,void * in,size_t in_size)115 enum pkcs11_rc tee_ae_decrypt_update(struct pkcs11_session *session,
116 				     void *in, size_t in_size)
117 {
118 	struct ae_aes_context *ctx = session->processing->extra_ctx;
119 	TEE_Result res = TEE_ERROR_GENERIC;
120 	enum pkcs11_rc rc = PKCS11_CKR_OK;
121 	size_t data_len = 0;
122 	size_t ct_size = 0;
123 	void *ptr = NULL;
124 	char *ct = NULL;
125 
126 	if (!in_size)
127 		return PKCS11_CKR_OK;
128 
129 	if (!in)
130 		return PKCS11_CKR_ARGUMENTS_BAD;
131 
132 	/*
133 	 * Save the last input bytes in case they are the tag
134 	 * bytes and not ciphered data bytes to be decrypted.
135 	 */
136 
137 	if (ctx->pending_size + in_size <= ctx->tag_byte_len) {
138 		/*
139 		 * Data bytes are all potential tag bytes.
140 		 * We only need to update the pending_tag buffer,
141 		 * and cannot treat any byte as data byte.
142 		 */
143 		TEE_MemMove(ctx->pending_tag + ctx->pending_size, in, in_size);
144 
145 		ctx->pending_size += in_size;
146 
147 		return PKCS11_CKR_OK;
148 	}
149 
150 	/* Size of data that are not potential tag in pending and input data */
151 	data_len = in_size + ctx->pending_size - ctx->tag_byte_len;
152 
153 	/* Process pending bytes that are effective data byte */
154 	if (ctx->pending_size &&
155 	    (ctx->pending_size + in_size) >= ctx->tag_byte_len) {
156 		uint32_t len = MIN(data_len, ctx->pending_size);
157 
158 		res = TEE_AEUpdate(session->processing->tee_op_handle,
159 				   ctx->pending_tag, len, NULL, &ct_size);
160 		if (res && res != TEE_ERROR_SHORT_BUFFER) {
161 			rc = tee2pkcs_error(res);
162 			goto out;
163 		}
164 		assert(res == TEE_ERROR_SHORT_BUFFER || !ct_size);
165 
166 		/*
167 		 * If output data to store (not revealed yet), redo with
168 		 * an allocated temporary reference.
169 		 */
170 		if (ct_size) {
171 			ct = TEE_Malloc(ct_size, TEE_MALLOC_FILL_ZERO);
172 			if (!ct) {
173 				rc = PKCS11_CKR_DEVICE_MEMORY;
174 				goto out;
175 			}
176 
177 			res = TEE_AEUpdate(session->processing->tee_op_handle,
178 					   ctx->pending_tag, len, ct, &ct_size);
179 			if (res) {
180 				rc = tee2pkcs_error(res);
181 				goto out;
182 			}
183 			assert(ct_size);
184 		}
185 
186 		/* Save potential tag bytes for later */
187 		TEE_MemMove(ctx->pending_tag, ctx->pending_tag + len,
188 			    ctx->pending_size - len);
189 
190 		ctx->pending_size -= len;
191 		data_len -= len;
192 	}
193 
194 	/* Process input data that are not potential tag bytes */
195 	if (data_len) {
196 		size_t size = 0;
197 
198 		res = TEE_AEUpdate(session->processing->tee_op_handle,
199 				   in, data_len, NULL, &size);
200 		if (res != TEE_ERROR_SHORT_BUFFER &&
201 		    (res != TEE_SUCCESS || size)) {
202 			/* This is not expected */
203 			rc = PKCS11_CKR_GENERAL_ERROR;
204 			goto out;
205 		}
206 
207 		if (size) {
208 			ptr = TEE_Realloc(ct, ct_size + size);
209 			if (!ptr) {
210 				rc = PKCS11_CKR_DEVICE_MEMORY;
211 				goto out;
212 			}
213 			ct = ptr;
214 
215 			res = TEE_AEUpdate(session->processing->tee_op_handle,
216 					   in, data_len, ct + ct_size, &size);
217 			if (res) {
218 				rc = tee2pkcs_error(res);
219 				goto out;
220 			}
221 
222 			ct_size += size;
223 		}
224 	}
225 
226 	/* Update pending tag in context if any */
227 	data_len = in_size - data_len;
228 	if (data_len > (ctx->tag_byte_len - ctx->pending_size)) {
229 		/* This is not expected */
230 		rc = PKCS11_CKR_GENERAL_ERROR;
231 		goto out;
232 	}
233 
234 	if (data_len) {
235 		TEE_MemMove(ctx->pending_tag + ctx->pending_size,
236 			    (char *)in + in_size - data_len, data_len);
237 
238 		ctx->pending_size += data_len;
239 	}
240 
241 	/* Save output data reference in the context */
242 	if (ct_size) {
243 		ptr = TEE_Realloc(ctx->out_data, (ctx->out_count + 1) *
244 				  sizeof(struct out_data_ref));
245 		if (!ptr) {
246 			rc = PKCS11_CKR_DEVICE_MEMORY;
247 			goto out;
248 		}
249 		ctx->out_data = ptr;
250 		ctx->out_data[ctx->out_count].size = ct_size;
251 		ctx->out_data[ctx->out_count].data = ct;
252 		ctx->out_count++;
253 	}
254 
255 	rc = PKCS11_CKR_OK;
256 
257 out:
258 	if (rc)
259 		TEE_Free(ct);
260 
261 	return rc;
262 }
263 
reveal_ae_data(struct ae_aes_context * ctx,void * out,size_t * out_size)264 static enum pkcs11_rc reveal_ae_data(struct ae_aes_context *ctx,
265 				     void *out, size_t *out_size)
266 {
267 	uint32_t req_size = 0;
268 	char *out_ptr = out;
269 	size_t n = 0;
270 
271 	for (req_size = 0, n = 0; n < ctx->out_count; n++)
272 		req_size += ctx->out_data[n].size;
273 
274 	if (*out_size < req_size) {
275 		*out_size = req_size;
276 		return PKCS11_CKR_BUFFER_TOO_SMALL;
277 	}
278 
279 	if (!out_ptr)
280 		return PKCS11_CKR_ARGUMENTS_BAD;
281 
282 	for (n = 0; n < ctx->out_count; n++) {
283 		TEE_MemMove(out_ptr, ctx->out_data[n].data,
284 			    ctx->out_data[n].size);
285 		out_ptr += ctx->out_data[n].size;
286 	}
287 
288 	release_ae_aes_context(ctx);
289 
290 	*out_size = req_size;
291 
292 	return PKCS11_CKR_OK;
293 }
294 
tee_ae_decrypt_final(struct pkcs11_session * session,void * out,size_t * out_size)295 enum pkcs11_rc tee_ae_decrypt_final(struct pkcs11_session *session,
296 				    void *out, size_t *out_size)
297 {
298 	struct ae_aes_context *ctx = session->processing->extra_ctx;
299 	TEE_Result res = TEE_ERROR_GENERIC;
300 	enum pkcs11_rc rc = 0;
301 	void *data_ptr = NULL;
302 	size_t data_size = 0;
303 
304 	if (!out_size) {
305 		DMSG("Expect at least a buffer for the output data");
306 		return PKCS11_CKR_ARGUMENTS_BAD;
307 	}
308 
309 	/* Final is already completed, only need to output the data */
310 	if (!ctx->pending_tag)
311 		return reveal_ae_data(ctx, out, out_size);
312 
313 	if (ctx->pending_size != ctx->tag_byte_len) {
314 		DMSG("Not enough samples: %zu/%zu",
315 		     ctx->pending_size, ctx->tag_byte_len);
316 		return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
317 	}
318 
319 	/* Query tag size if any */
320 	data_size = 0;
321 	res = TEE_AEDecryptFinal(session->processing->tee_op_handle,
322 				 NULL, 0, NULL, &data_size,
323 				 ctx->pending_tag, ctx->tag_byte_len);
324 
325 	if (res == TEE_ERROR_SHORT_BUFFER) {
326 		data_ptr = TEE_Malloc(data_size, TEE_MALLOC_FILL_ZERO);
327 		if (!data_ptr) {
328 			rc = PKCS11_CKR_DEVICE_MEMORY;
329 			goto out;
330 		}
331 
332 		res = TEE_AEDecryptFinal(session->processing->tee_op_handle,
333 					 NULL, 0, data_ptr, &data_size,
334 					 ctx->pending_tag, ctx->tag_byte_len);
335 		assert(res || data_size);
336 	}
337 
338 	/* AE decryption is completed */
339 	TEE_Free(ctx->pending_tag);
340 	ctx->pending_tag = NULL;
341 
342 	rc = tee2pkcs_error(res);
343 	if (rc)
344 		goto out;
345 
346 	if (data_ptr) {
347 		void *tmp_ptr = NULL;
348 
349 		tmp_ptr = TEE_Realloc(ctx->out_data, (ctx->out_count + 1) *
350 				sizeof(struct out_data_ref));
351 		if (!tmp_ptr) {
352 			rc = PKCS11_CKR_DEVICE_MEMORY;
353 			goto out;
354 		}
355 		ctx->out_data = tmp_ptr;
356 		ctx->out_data[ctx->out_count].size = data_size;
357 		ctx->out_data[ctx->out_count].data = data_ptr;
358 		ctx->out_count++;
359 
360 		data_ptr = NULL;
361 	}
362 
363 	rc = reveal_ae_data(ctx, out, out_size);
364 
365 out:
366 	TEE_Free(data_ptr);
367 
368 	return rc;
369 }
370 
tee_ae_encrypt_final(struct pkcs11_session * session,void * out,size_t * out_size)371 enum pkcs11_rc tee_ae_encrypt_final(struct pkcs11_session *session,
372 				    void *out, size_t *out_size)
373 {
374 	struct ae_aes_context *ctx = session->processing->extra_ctx;
375 	TEE_Result res = TEE_ERROR_GENERIC;
376 	uint8_t *tag = NULL;
377 	size_t tag_len = 0;
378 	size_t size = 0;
379 
380 	if (!out || !out_size)
381 		return PKCS11_CKR_ARGUMENTS_BAD;
382 
383 	/* Check the required sizes (warning: 2 output len: data + tag) */
384 	res = TEE_AEEncryptFinal(session->processing->tee_op_handle,
385 				 NULL, 0, NULL, &size,
386 				 &tag, &tag_len);
387 
388 	if (tag_len != ctx->tag_byte_len ||
389 	    (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER)) {
390 		EMSG("Unexpected tag length %zu/%zu or rc 0x%" PRIx32,
391 		     tag_len, ctx->tag_byte_len, res);
392 		return PKCS11_CKR_GENERAL_ERROR;
393 	}
394 
395 	if (*out_size < size + tag_len) {
396 		*out_size = size + tag_len;
397 		return PKCS11_CKR_BUFFER_TOO_SMALL;
398 	}
399 
400 	/* Process data and tag input the client output buffer */
401 	tag = (uint8_t *)out + size;
402 
403 	res = TEE_AEEncryptFinal(session->processing->tee_op_handle,
404 				 NULL, 0, out, &size, tag, &tag_len);
405 
406 	if (tag_len != ctx->tag_byte_len) {
407 		EMSG("Unexpected tag length");
408 		return PKCS11_CKR_GENERAL_ERROR;
409 	}
410 
411 	if (!res)
412 		*out_size = size + tag_len;
413 
414 	return tee2pkcs_error(res);
415 }
416 
tee_init_ctr_operation(struct active_processing * processing,void * proc_params,size_t params_size)417 enum pkcs11_rc tee_init_ctr_operation(struct active_processing *processing,
418 				      void *proc_params, size_t params_size)
419 {
420 	struct serialargs args = { };
421 	enum pkcs11_rc rc = PKCS11_CKR_OK;
422 	/* CTR parameters */
423 	uint32_t incr_counter = 0;
424 	void *counter_bits = NULL;
425 
426 	if (!proc_params)
427 		return PKCS11_CKR_ARGUMENTS_BAD;
428 
429 	serialargs_init(&args, proc_params, params_size);
430 
431 	rc = serialargs_get(&args, &incr_counter, sizeof(uint32_t));
432 	if (rc)
433 		return rc;
434 
435 	rc = serialargs_get_ptr(&args, &counter_bits, 16);
436 	if (rc)
437 		return rc;
438 
439 	if (serialargs_remaining_bytes(&args))
440 		return PKCS11_CKR_ARGUMENTS_BAD;
441 
442 	if (incr_counter != 1) {
443 		DMSG("Supports only 1 bit increment counter: %"PRIu32,
444 		     incr_counter);
445 
446 		return PKCS11_CKR_MECHANISM_PARAM_INVALID;
447 	}
448 
449 	TEE_CipherInit(processing->tee_op_handle, counter_bits, 16);
450 
451 	return PKCS11_CKR_OK;
452 }
453 
tee_init_gcm_operation(struct pkcs11_session * session,void * proc_params,size_t params_size)454 enum pkcs11_rc tee_init_gcm_operation(struct pkcs11_session *session,
455 				      void *proc_params, size_t params_size)
456 {
457 	struct ae_aes_context *params = NULL;
458 	enum pkcs11_rc rc = PKCS11_CKR_OK;
459 	struct serialargs args = { };
460 	/* GCM parameters */
461 	uint32_t tag_bitlen = 0;
462 	uint32_t tag_len = 0;
463 	uint32_t iv_len = 0;
464 	void *iv = NULL;
465 	uint32_t aad_len = 0;
466 	void *aad = NULL;
467 
468 	TEE_MemFill(&args, 0, sizeof(args));
469 
470 	if (!proc_params)
471 		return PKCS11_CKR_ARGUMENTS_BAD;
472 
473 	serialargs_init(&args, proc_params, params_size);
474 
475 	rc = serialargs_get(&args, &iv_len, sizeof(uint32_t));
476 	if (rc)
477 		goto out;
478 
479 	rc = serialargs_get_ptr(&args, &iv, iv_len);
480 	if (rc)
481 		goto out;
482 
483 	rc = serialargs_get(&args, &aad_len, sizeof(uint32_t));
484 	if (rc)
485 		goto out;
486 
487 	rc = serialargs_get_ptr(&args, &aad, aad_len);
488 	if (rc)
489 		goto out;
490 
491 	rc = serialargs_get(&args, &tag_bitlen, sizeof(uint32_t));
492 	if (rc)
493 		goto out;
494 
495 	tag_len = ROUNDUP_DIV(tag_bitlen, 8);
496 
497 	/* As per pkcs#11 mechanism specification */
498 	if (tag_bitlen > 128 || !iv_len || iv_len > 256) {
499 		DMSG("Invalid parameters: tag_bit_len %"PRIu32
500 		     ", iv_len %"PRIu32, tag_bitlen, iv_len);
501 		rc = PKCS11_CKR_MECHANISM_PARAM_INVALID;
502 		goto out;
503 	}
504 
505 	params = TEE_Malloc(sizeof(*params), TEE_MALLOC_FILL_ZERO);
506 	if (!params) {
507 		rc = PKCS11_CKR_DEVICE_MEMORY;
508 		goto out;
509 	}
510 
511 	/* Store the byte round up byte length for the tag */
512 	params->tag_byte_len = tag_len;
513 	rc = init_ae_aes_context(params);
514 	if (rc)
515 		goto out;
516 
517 	/* Session processing owns the active processing params */
518 	assert(!session->processing->extra_ctx);
519 	session->processing->extra_ctx = params;
520 
521 	TEE_AEInit(session->processing->tee_op_handle,
522 		   iv, iv_len, tag_bitlen, 0, 0);
523 
524 	if (aad_len)
525 		TEE_AEUpdateAAD(session->processing->tee_op_handle,
526 				aad, aad_len);
527 
528 	/*
529 	 * Save initialized operation state to reset to this state
530 	 * on one-shot AE request that queries its output buffer size.
531 	 */
532 	TEE_CopyOperation(session->processing->tee_op_handle2,
533 			  session->processing->tee_op_handle);
534 
535 	rc = PKCS11_CKR_OK;
536 
537 out:
538 	if (rc && params) {
539 		release_ae_aes_context(params);
540 		TEE_Free(params);
541 	}
542 
543 	return rc;
544 }
545 
546 /* Release extra resources related to the GCM processing*/
tee_release_gcm_operation(struct pkcs11_session * session)547 void tee_release_gcm_operation(struct pkcs11_session *session)
548 {
549 	struct ae_aes_context *ctx = session->processing->extra_ctx;
550 
551 	release_ae_aes_context(ctx);
552 	TEE_Free(session->processing->extra_ctx);
553 	session->processing->extra_ctx = NULL;
554 }
555 
556 /* Reset processing state to the state it was after initialization */
tee_ae_reinit_gcm_operation(struct pkcs11_session * session)557 enum pkcs11_rc tee_ae_reinit_gcm_operation(struct pkcs11_session *session)
558 {
559 	struct ae_aes_context *ctx = session->processing->extra_ctx;
560 
561 	TEE_CopyOperation(session->processing->tee_op_handle,
562 			  session->processing->tee_op_handle2);
563 
564 	release_ae_aes_context(ctx);
565 
566 	return init_ae_aes_context(ctx);
567 }
568