1 /*
2 * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include <string.h>
9
10 #include "flash_fs/its_flash_fs.h"
11 #include "flash/its_flash.h"
12 #include "its_utils.h"
13 #include "psa_manifest/pid.h"
14 #include "tfm_hal_its_encryption.h"
15 #include "tfm_hal_ps.h"
16 #include "tfm_internal_trusted_storage.h"
17 #include "tfm_its_defs.h"
18 #include "tfm_sp_log.h"
19
20 /**
21 * \brief Fills the AEAD additional data used for the encryption/decryption
22 *
23 * \details The additional data are not encypted their integrity is checked.
24 * For the ITS encryption we use the file id, the file flags and the
25 * data size of the file as addditional data.
26 *
27 * \param[out] add Additional data
28 * \param[in] add_size Additional data size in bytes
29 * \param[in] fid Identifier of the file
30 * \param[in] fid_size Identifier of the file size in bytes
31 * \param[in] flags Flags of the file
32 * \param[in] data_size Data size in bytes
33 *
34 * \retval PSA_SUCCESS On success
35 * \retval PSA_ERROR_INVALID_ARGUMENT When the addditional data buffer does not
36 * have the correct size of the add/fid
37 * buffers are NULL
38 *
39 */
tfm_its_fill_enc_add(uint8_t * add,const size_t add_size,const uint8_t * fid,const size_t fid_size,const uint32_t flags,const size_t data_size)40 static psa_status_t tfm_its_fill_enc_add(uint8_t *add,
41 const size_t add_size,
42 const uint8_t *fid,
43 const size_t fid_size,
44 const uint32_t flags,
45 const size_t data_size)
46
47 {
48 /* Only the user flags are populated in the function which
49 * gets the file info from ITS (see its_flash_fs_file_get_info).
50 * We use the same flags for conformity.
51 */
52 uint32_t user_flags = flags & ITS_FLASH_FS_USER_FLAGS_MASK;
53
54 /* The additional data consist of the file id, the flags and the
55 * data size of the file.
56 */
57 size_t add_expected_size = ITS_FILE_ID_SIZE +
58 sizeof(user_flags) +
59 sizeof(data_size);
60
61 if (add_size != add_expected_size || add == NULL || fid == NULL) {
62 return PSA_ERROR_INVALID_ARGUMENT;
63 }
64
65 memcpy(add, fid, fid_size);
66 memcpy(add + fid_size, &user_flags, sizeof(user_flags));
67 memcpy(add + fid_size + sizeof(user_flags),
68 &data_size,
69 sizeof(data_size));
70
71 return PSA_SUCCESS;
72 }
73
tfm_hal_to_psa_error(enum tfm_hal_status_t tfm_hal_err)74 static psa_status_t tfm_hal_to_psa_error(enum tfm_hal_status_t tfm_hal_err)
75 {
76 switch (tfm_hal_err) {
77 case TFM_HAL_SUCCESS:
78 return PSA_SUCCESS;
79 case TFM_HAL_ERROR_INVALID_INPUT:
80 return PSA_ERROR_INVALID_ARGUMENT;
81 default:
82 return PSA_ERROR_GENERIC_ERROR;
83 }
84 }
85
tfm_its_crypt_file(struct its_flash_fs_file_info_t * finfo,uint8_t * fid,const size_t fid_size,const uint8_t * input,const size_t input_size,uint8_t * output,const size_t output_size,const bool is_encrypt)86 psa_status_t tfm_its_crypt_file(struct its_flash_fs_file_info_t *finfo,
87 uint8_t *fid,
88 const size_t fid_size,
89 const uint8_t *input,
90 const size_t input_size,
91 uint8_t *output,
92 const size_t output_size,
93 const bool is_encrypt)
94 {
95 struct tfm_hal_its_auth_crypt_ctx aead_ctx = {0};
96 enum tfm_hal_status_t err;
97 size_t file_size;
98
99 if (finfo == NULL) {
100 return PSA_ERROR_INVALID_ARGUMENT;
101 }
102
103 /* The file size is not known yet when encrypting */
104 if (is_encrypt) {
105 file_size = input_size;
106 } else {
107 file_size = finfo->size_current;
108 }
109
110 err = tfm_its_fill_enc_add(finfo->aad,
111 sizeof(finfo->aad),
112 fid,
113 fid_size,
114 finfo->flags,
115 file_size);
116 if (err != TFM_HAL_SUCCESS) {
117 return tfm_hal_to_psa_error(err);
118 }
119
120 if (is_encrypt) {
121 err = tfm_hal_its_aead_generate_nonce(finfo->nonce,
122 sizeof(finfo->nonce));
123
124 if (err != TFM_HAL_SUCCESS) {
125 return tfm_hal_to_psa_error(err);
126 }
127 }
128
129 /* Set all required parameters for the aead operation context */
130 aead_ctx.nonce = finfo->nonce;
131 aead_ctx.nonce_size = sizeof(finfo->nonce);
132 aead_ctx.deriv_label = fid;
133 aead_ctx.deriv_label_size = fid_size;
134 aead_ctx.aad = finfo->aad;
135 aead_ctx.aad_size = sizeof(finfo->aad);
136
137
138 if (is_encrypt) {
139 err = tfm_hal_its_aead_encrypt(&aead_ctx,
140 input,
141 input_size,
142 output,
143 output_size,
144 finfo->tag,
145 sizeof(finfo->tag));
146 } else {
147 err = tfm_hal_its_aead_decrypt(&aead_ctx,
148 input,
149 input_size,
150 finfo->tag,
151 sizeof(finfo->tag),
152 output,
153 output_size);
154 }
155
156 if (err != TFM_HAL_SUCCESS) {
157 return tfm_hal_to_psa_error(err);
158 }
159
160 if (is_encrypt) {
161 finfo->size_max = input_size;
162 }
163
164 return PSA_SUCCESS;
165 }
166
167