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