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