blob: 2ad1efb765749a917b5f681e80d35845e10a70af [file] [log] [blame]
Brad Bishopbec4ebc2022-08-03 09:55:16 -04001From 00b4f777b377c69f948f5a9d68cbfc8fa8c38a86 Mon Sep 17 00:00:00 2001
2From: Julian Hall <julian.hall@arm.com>
3Date: Fri, 11 Feb 2022 14:24:53 +0000
4Subject: [PATCH] Integrate AEAD operation support
5
6Resolves issues and integrates AEAD support into the crypto service
7provider and clients.
8
9Signed-off-by: Julian Hall <julian.hall@arm.com>
10Change-Id: I5fbe78a2dd825f592e26fd665f60c18b576f9de9
11
12Upstream-Status: Pending [Not submitted to upstream yet]
13Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
14
15
16---
17 .../caller/packed-c/crypto_caller_aead.h | 70 +++---
18 .../client/caller/stub/crypto_caller_aead.h | 12 +-
19 .../service/crypto/client/psa/psa_aead.c | 221 +++++++++++++++---
20 .../factory/full/crypto_provider_factory.c | 16 +-
21 .../component-test/component-test.cmake | 4 +-
22 deployments/crypto/opteesp/CMakeLists.txt | 4 +-
23 deployments/libts/linux-pc/CMakeLists.txt | 4 +-
24 deployments/se-proxy/opteesp/CMakeLists.txt | 4 +-
25 8 files changed, 263 insertions(+), 72 deletions(-)
26
27diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h b/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h
28index 3d9947d5..c4ffb20c 100644
29--- a/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h
30+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h
31@@ -1,5 +1,5 @@
32 /*
33- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
34+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
35 *
36 * SPDX-License-Identifier: BSD-3-Clause
37 */
38@@ -20,38 +20,6 @@
39 extern "C" {
40 #endif
41
42-static inline psa_status_t crypto_caller_aead_encrypt(struct service_client *context,
43- psa_key_id_t key,
44- psa_algorithm_t alg,
45- const uint8_t *nonce,
46- size_t nonce_length,
47- const uint8_t *additional_data,
48- size_t additional_data_length,
49- const uint8_t *plaintext,
50- size_t plaintext_length,
51- uint8_t *aeadtext,
52- size_t aeadtext_size,
53- size_t *aeadtext_length)
54-{
55- return PSA_ERROR_NOT_SUPPORTED;
56-}
57-
58-static inline psa_status_t crypto_caller_aead_decrypt(struct service_client *context,
59- psa_key_id_t key,
60- psa_algorithm_t alg,
61- const uint8_t *nonce,
62- size_t nonce_length,
63- const uint8_t *additional_data,
64- size_t additional_data_length,
65- const uint8_t *aeadtext,
66- size_t aeadtext_length,
67- uint8_t *plaintext,
68- size_t plaintext_size,
69- size_t *plaintext_length)
70-{
71- return PSA_ERROR_NOT_SUPPORTED;
72-}
73-
74 static inline psa_status_t common_aead_setup(struct service_client *context,
75 uint32_t *op_handle,
76 psa_key_id_t key,
77@@ -247,7 +215,7 @@ static inline psa_status_t crypto_caller_aead_set_lengths(struct service_client
78 {
79 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
80 struct ts_crypto_aead_set_lengths_in req_msg;
81- size_t req_fixed_len = sizeof(struct ts_crypto_aead_abort_in);
82+ size_t req_fixed_len = sizeof(struct ts_crypto_aead_set_lengths_in);
83 size_t req_len = req_fixed_len;
84
85 req_msg.op_handle = op_handle;
86@@ -611,6 +579,40 @@ static inline psa_status_t crypto_caller_aead_abort(struct service_client *conte
87 return psa_status;
88 }
89
90+/**
91+ * The maximum data length that may be carried in an update operation will be
92+ * constrained by the maximum call payload capacity imposed by the end-to-end
93+ * RPC call path. These functions return the maximum update size when serialization
94+ * overheads are considered. This allows large paylaods to be processed in
95+ * maximum size chunks.
96+ */
97+static inline size_t crypto_caller_aead_max_update_ad_size(const struct service_client *context)
98+{
99+ /* Returns the maximum number of bytes of additional data that may be
100+ * carried as a parameter of the aead_update_ad operation
101+ * using the packed-c encoding.
102+ */
103+ size_t payload_space = context->service_info.max_payload;
104+ size_t overhead = sizeof(struct ts_crypto_aead_update_ad_in) + TLV_HDR_LEN;
105+
106+ return (payload_space > overhead) ? payload_space - overhead : 0;
107+}
108+
109+static inline size_t crypto_caller_aead_max_update_size(const struct service_client *context)
110+{
111+ /* Returns the maximum number of bytes that may be
112+ * carried as a parameter of the aead_update operation
113+ * using the packed-c encoding.
114+ */
115+ size_t payload_space = context->service_info.max_payload;
116+ size_t overhead = sizeof(struct ts_crypto_aead_update_in) + TLV_HDR_LEN;
117+
118+ /* Allow for output to be a whole number of blocks */
119+ overhead += PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE;
120+
121+ return (payload_space > overhead) ? payload_space - overhead : 0;
122+}
123+
124 #ifdef __cplusplus
125 }
126 #endif
127diff --git a/components/service/crypto/client/caller/stub/crypto_caller_aead.h b/components/service/crypto/client/caller/stub/crypto_caller_aead.h
128index 18aa8cec..455e7ac1 100644
129--- a/components/service/crypto/client/caller/stub/crypto_caller_aead.h
130+++ b/components/service/crypto/client/caller/stub/crypto_caller_aead.h
131@@ -1,5 +1,5 @@
132 /*
133- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
134+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
135 *
136 * SPDX-License-Identifier: BSD-3-Clause
137 */
138@@ -135,6 +135,16 @@ static inline psa_status_t crypto_caller_aead_abort(struct service_client *conte
139 return PSA_ERROR_NOT_SUPPORTED;
140 }
141
142+static inline size_t crypto_caller_aead_max_update_ad_size(const struct service_client *context)
143+{
144+ return 0;
145+}
146+
147+static inline size_t crypto_caller_aead_max_update_size(const struct service_client *context)
148+{
149+ return 0;
150+}
151+
152 #ifdef __cplusplus
153 }
154 #endif
155diff --git a/components/service/crypto/client/psa/psa_aead.c b/components/service/crypto/client/psa/psa_aead.c
156index 22fd3da1..e4579e63 100644
157--- a/components/service/crypto/client/psa/psa_aead.c
158+++ b/components/service/crypto/client/psa/psa_aead.c
159@@ -1,5 +1,5 @@
160 /*
161- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
162+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
163 *
164 * SPDX-License-Identifier: BSD-3-Clause
165 */
166@@ -8,37 +8,6 @@
167 #include "psa_crypto_client.h"
168 #include "crypto_caller_selector.h"
169
170-
171-psa_status_t psa_aead_encrypt(psa_key_id_t key,
172- psa_algorithm_t alg,
173- const uint8_t *nonce,
174- size_t nonce_length,
175- const uint8_t *additional_data,
176- size_t additional_data_length,
177- const uint8_t *plaintext,
178- size_t plaintext_length,
179- uint8_t *aeadtext,
180- size_t aeadtext_size,
181- size_t *aeadtext_length)
182-{
183- return PSA_ERROR_NOT_SUPPORTED;
184-}
185-
186-psa_status_t psa_aead_decrypt(psa_key_id_t key,
187- psa_algorithm_t alg,
188- const uint8_t *nonce,
189- size_t nonce_length,
190- const uint8_t *additional_data,
191- size_t additional_data_length,
192- const uint8_t *aeadtext,
193- size_t aeadtext_length,
194- uint8_t *plaintext,
195- size_t plaintext_size,
196- size_t *plaintext_length)
197-{
198- return PSA_ERROR_NOT_SUPPORTED;
199-}
200-
201 psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation,
202 psa_key_id_t key,
203 psa_algorithm_t alg)
204@@ -143,3 +112,191 @@ psa_status_t psa_aead_abort(psa_aead_operation_t *operation)
205 return crypto_caller_aead_abort(&psa_crypto_client_instance.base,
206 operation->handle);
207 }
208+
209+static psa_status_t multi_aead_update_ad(psa_aead_operation_t *operation,
210+ const uint8_t *input,
211+ size_t input_length)
212+{
213+ psa_status_t psa_status = PSA_SUCCESS;
214+ size_t max_update_size =
215+ crypto_caller_aead_max_update_ad_size(&psa_crypto_client_instance.base);
216+ size_t bytes_input = 0;
217+
218+ if (!max_update_size) {
219+
220+ /* Don't know the max update size so assume that the entire
221+ * input and output can be handled in a single update. If
222+ * this isn't true, the first aead update operation will fail
223+ * safely.
224+ */
225+ max_update_size = input_length;
226+ }
227+
228+ while (bytes_input < input_length) {
229+
230+ size_t bytes_remaining = input_length - bytes_input;
231+ size_t update_len = (bytes_remaining < max_update_size) ?
232+ bytes_remaining :
233+ max_update_size;
234+
235+ psa_status = psa_aead_update_ad(operation,
236+ &input[bytes_input], update_len);
237+
238+ if (psa_status != PSA_SUCCESS) break;
239+
240+ bytes_input += update_len;
241+ }
242+
243+ return psa_status;
244+}
245+
246+static psa_status_t multi_aead_update(psa_aead_operation_t *operation,
247+ const uint8_t *input,
248+ size_t input_length,
249+ uint8_t *output,
250+ size_t output_size,
251+ size_t *output_length)
252+{
253+ psa_status_t psa_status = PSA_SUCCESS;
254+ size_t max_update_size =
255+ crypto_caller_aead_max_update_size(&psa_crypto_client_instance.base);
256+ size_t bytes_input = 0;
257+ size_t bytes_output = 0;
258+
259+ *output_length = 0;
260+
261+ if (!max_update_size) {
262+
263+ /* Don't know the max update size so assume that the entire
264+ * input and output can be handled in a single update. If
265+ * this isn't true, the first aead update operation will fail
266+ * safely.
267+ */
268+ max_update_size = input_length;
269+ }
270+
271+ while ((bytes_input < input_length) && (bytes_output < output_size)) {
272+
273+ size_t update_output_len = 0;
274+ size_t bytes_remaining = input_length - bytes_input;
275+ size_t update_len = (bytes_remaining < max_update_size) ?
276+ bytes_remaining :
277+ max_update_size;
278+
279+ psa_status = psa_aead_update(operation,
280+ &input[bytes_input], update_len,
281+ &output[bytes_output], output_size - bytes_output, &update_output_len);
282+
283+ if (psa_status != PSA_SUCCESS) break;
284+
285+ bytes_input += update_len;
286+ bytes_output += update_output_len;
287+ }
288+
289+ if (psa_status == PSA_SUCCESS) {
290+
291+ *output_length = bytes_output;
292+ }
293+
294+ return psa_status;
295+}
296+
297+psa_status_t psa_aead_encrypt(psa_key_id_t key,
298+ psa_algorithm_t alg,
299+ const uint8_t *nonce,
300+ size_t nonce_length,
301+ const uint8_t *additional_data,
302+ size_t additional_data_length,
303+ const uint8_t *plaintext,
304+ size_t plaintext_length,
305+ uint8_t *aeadtext,
306+ size_t aeadtext_size,
307+ size_t *aeadtext_length)
308+{
309+ psa_aead_operation_t operation = psa_aead_operation_init();
310+ size_t bytes_output = 0;
311+ *aeadtext_length = 0;
312+
313+ psa_status_t psa_status = psa_aead_encrypt_setup(&operation, key, alg);
314+ if (psa_status != PSA_SUCCESS) return psa_status;
315+
316+ if ((psa_status = psa_aead_set_lengths(&operation, additional_data_length, plaintext_length),
317+ psa_status == PSA_SUCCESS) &&
318+ (psa_status = psa_aead_set_nonce(&operation, nonce, nonce_length),
319+ psa_status == PSA_SUCCESS) &&
320+ (psa_status = multi_aead_update_ad(&operation, additional_data, additional_data_length),
321+ psa_status == PSA_SUCCESS) &&
322+ (psa_status = multi_aead_update(&operation, plaintext, plaintext_length,
323+ aeadtext, aeadtext_size, &bytes_output),
324+ psa_status == PSA_SUCCESS))
325+ {
326+ size_t remaining_aead_len = 0;
327+ size_t tag_len = 0;
328+
329+ psa_status = psa_aead_finish(&operation,
330+ NULL, 0, &remaining_aead_len,
331+ &aeadtext[bytes_output], aeadtext_size - bytes_output, &tag_len);
332+
333+ if (psa_status == PSA_SUCCESS) {
334+
335+ *aeadtext_length = bytes_output + remaining_aead_len + tag_len;
336+ }
337+ }
338+ else {
339+
340+ psa_aead_abort(&operation);
341+ }
342+
343+ return psa_status;
344+}
345+
346+psa_status_t psa_aead_decrypt(psa_key_id_t key,
347+ psa_algorithm_t alg,
348+ const uint8_t *nonce,
349+ size_t nonce_length,
350+ const uint8_t *additional_data,
351+ size_t additional_data_length,
352+ const uint8_t *aeadtext,
353+ size_t aeadtext_length,
354+ uint8_t *plaintext,
355+ size_t plaintext_size,
356+ size_t *plaintext_length)
357+{
358+ psa_aead_operation_t operation = psa_aead_operation_init();
359+ size_t bytes_output = 0;
360+ *plaintext_length = 0;
361+
362+ psa_status_t psa_status = psa_aead_decrypt_setup(&operation, key, alg);
363+ if (psa_status != PSA_SUCCESS) return psa_status;
364+
365+ size_t tag_len = PSA_ALG_AEAD_GET_TAG_LENGTH(alg);
366+ size_t ciphertext_len = (aeadtext_length > tag_len) ? aeadtext_length - tag_len : 0;
367+
368+ if ((psa_status = psa_aead_set_lengths(&operation, additional_data_length, ciphertext_len),
369+ psa_status == PSA_SUCCESS) &&
370+ (psa_status = psa_aead_set_nonce(&operation, nonce, nonce_length),
371+ psa_status == PSA_SUCCESS) &&
372+ (psa_status = multi_aead_update_ad(&operation, additional_data, additional_data_length),
373+ psa_status == PSA_SUCCESS) &&
374+ (psa_status = multi_aead_update(&operation, aeadtext, ciphertext_len,
375+ plaintext, plaintext_size, &bytes_output),
376+ psa_status == PSA_SUCCESS))
377+ {
378+ size_t remaining_plaintext_len = 0;
379+
380+ psa_status = psa_aead_verify(&operation,
381+ NULL, 0, &remaining_plaintext_len,
382+ &aeadtext[bytes_output], aeadtext_length - bytes_output);
383+
384+ if (psa_status == PSA_SUCCESS) {
385+
386+ *plaintext_length = bytes_output + remaining_plaintext_len;
387+ }
388+ }
389+ else {
390+
391+ psa_aead_abort(&operation);
392+ }
393+
394+ return psa_status;
395+}
396diff --git a/components/service/crypto/factory/full/crypto_provider_factory.c b/components/service/crypto/factory/full/crypto_provider_factory.c
397index 2d926eb6..ee2b4473 100644
398--- a/components/service/crypto/factory/full/crypto_provider_factory.c
399+++ b/components/service/crypto/factory/full/crypto_provider_factory.c
400@@ -1,5 +1,5 @@
401 /*
402- * Copyright (c) 2021, Arm Limited. All rights reserved.
403+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
404 *
405 * SPDX-License-Identifier: BSD-3-Clause
406 *
407@@ -17,6 +17,8 @@
408 #include <service/crypto/provider/extension/key_derivation/serializer/packed-c/packedc_key_derivation_provider_serializer.h>
409 #include <service/crypto/provider/extension/mac/mac_provider.h>
410 #include <service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.h>
411+#include <service/crypto/provider/extension/aead/aead_provider.h>
412+#include <service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.h>
413 #include <service/discovery/provider/discovery_provider.h>
414 #include <service/discovery/provider/serializer/packed-c/packedc_discovery_provider_serializer.h>
415
416@@ -34,6 +36,7 @@ static struct full_crypto_provider
417 struct cipher_provider cipher_provider;
418 struct key_derivation_provider key_derivation_provider;
419 struct mac_provider mac_provider;
420+ struct aead_provider aead_provider;
421
422 } instance;
423
424@@ -98,6 +101,17 @@ struct crypto_provider *crypto_provider_factory_create(void)
425 crypto_provider_extend(&instance.crypto_provider,
426 &instance.mac_provider.base_provider);
427
428+ /**
429+ * Extend with aead operations
430+ */
431+ aead_provider_init(&instance.aead_provider);
432+
433+ aead_provider_register_serializer(&instance.aead_provider,
434+ TS_RPC_ENCODING_PACKED_C, packedc_aead_provider_serializer_instance());
435+
436+ crypto_provider_extend(&instance.crypto_provider,
437+ &instance.aead_provider.base_provider);
438+
439 return &instance.crypto_provider;
440 }
441
442diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake
443index a0233c34..c3b015ab 100644
444--- a/deployments/component-test/component-test.cmake
445+++ b/deployments/component-test/component-test.cmake
446@@ -1,5 +1,5 @@
447 #-------------------------------------------------------------------------------
448-# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
449+# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
450 #
451 # SPDX-License-Identifier: BSD-3-Clause
452 #
453@@ -85,6 +85,8 @@ add_components(
454 "components/service/crypto/provider/extension/key_derivation/serializer/packed-c"
455 "components/service/crypto/provider/extension/mac"
456 "components/service/crypto/provider/extension/mac/serializer/packed-c"
457+ "components/service/crypto/provider/extension/aead"
458+ "components/service/crypto/provider/extension/aead/serializer/packed-c"
459 "components/service/crypto/provider/test"
460 "components/service/crypto/backend/mbedcrypto"
461 "components/service/crypto/factory/full"
462diff --git a/deployments/crypto/opteesp/CMakeLists.txt b/deployments/crypto/opteesp/CMakeLists.txt
463index 8ada74e9..eb5d0847 100644
464--- a/deployments/crypto/opteesp/CMakeLists.txt
465+++ b/deployments/crypto/opteesp/CMakeLists.txt
466@@ -1,5 +1,5 @@
467 #-------------------------------------------------------------------------------
468-# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
469+# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
470 #
471 # SPDX-License-Identifier: BSD-3-Clause
472 #
473@@ -62,6 +62,8 @@ add_components(TARGET "crypto-sp"
474 "components/service/crypto/provider/extension/key_derivation/serializer/packed-c"
475 "components/service/crypto/provider/extension/mac"
476 "components/service/crypto/provider/extension/mac/serializer/packed-c"
477+ "components/service/crypto/provider/extension/aead"
478+ "components/service/crypto/provider/extension/aead/serializer/packed-c"
479 "components/service/crypto/factory/full"
480 "components/service/crypto/backend/mbedcrypto"
481 "components/service/crypto/backend/mbedcrypto/trng_adapter/platform"
482diff --git a/deployments/libts/linux-pc/CMakeLists.txt b/deployments/libts/linux-pc/CMakeLists.txt
483index fc98407c..97eaaa73 100644
484--- a/deployments/libts/linux-pc/CMakeLists.txt
485+++ b/deployments/libts/linux-pc/CMakeLists.txt
486@@ -1,5 +1,5 @@
487 #-------------------------------------------------------------------------------
488-# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
489+# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
490 #
491 # SPDX-License-Identifier: BSD-3-Clause
492 #
493@@ -71,6 +71,8 @@ add_components(
494 "components/service/crypto/provider/extension/key_derivation/serializer/packed-c"
495 "components/service/crypto/provider/extension/mac"
496 "components/service/crypto/provider/extension/mac/serializer/packed-c"
497+ "components/service/crypto/provider/extension/aead"
498+ "components/service/crypto/provider/extension/aead/serializer/packed-c"
499 "components/service/crypto/factory/full"
500 "components/service/crypto/backend/mbedcrypto"
501 "components/service/crypto/backend/mbedcrypto/trng_adapter/linux"
502diff --git a/deployments/se-proxy/opteesp/CMakeLists.txt b/deployments/se-proxy/opteesp/CMakeLists.txt
503index 953bb716..24a8ca65 100644
504--- a/deployments/se-proxy/opteesp/CMakeLists.txt
505+++ b/deployments/se-proxy/opteesp/CMakeLists.txt
506@@ -1,5 +1,5 @@
507 #-------------------------------------------------------------------------------
508-# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
509+# Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
510 #
511 # SPDX-License-Identifier: BSD-3-Clause
512 #
513@@ -70,6 +70,8 @@ add_components(TARGET "se-proxy"
514 "components/service/crypto/provider/extension/key_derivation/serializer/packed-c"
515 "components/service/crypto/provider/extension/mac"
516 "components/service/crypto/provider/extension/mac/serializer/packed-c"
517+ "components/service/crypto/provider/extension/aead"
518+ "components/service/crypto/provider/extension/aead/serializer/packed-c"
519 "components/service/crypto/factory/full"
520 "components/service/secure_storage/include"
521 "components/service/secure_storage/frontend/secure_storage_provider"