blob: 1698fd0d069283b1f2324e4b6081955bf4bd93ce [file] [log] [blame]
Antonio de Angelis3a480992018-11-07 11:53:28 +00001/*
2 * Copyright (c) 2019, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include <limits.h>
9
10#include "tfm_crypto_defs.h"
11
12#include "crypto_engine.h"
13
14#include "psa_crypto.h"
15
16#include "tfm_crypto_api.h"
17#include "crypto_utils.h"
18
Jamie Fox82b87ca2018-12-11 16:41:11 +000019/**
20 * \def CRYPTO_AEAD_MAX_KEY_LENGTH
21 *
22 * \brief Specifies the maximum key length supported by the
23 * AEAD operations in this implementation
24 */
25#ifndef CRYPTO_AEAD_MAX_KEY_LENGTH
26#define CRYPTO_AEAD_MAX_KEY_LENGTH (32)
27#endif
28
Antonio de Angelis3a480992018-11-07 11:53:28 +000029/*!
30 * \defgroup public_psa Public functions, PSA
31 *
32 */
33
34/*!@{*/
35enum tfm_crypto_err_t tfm_crypto_aead_encrypt(psa_key_slot_t key,
36 psa_algorithm_t alg,
37 const uint8_t *nonce,
38 size_t nonce_length,
39 const uint8_t *additional_data,
40 size_t additional_data_length,
41 const uint8_t *plaintext,
42 size_t plaintext_length,
43 uint8_t *ciphertext,
44 size_t ciphertext_size,
45 size_t *ciphertext_length)
46{
47 psa_status_t status = PSA_SUCCESS;
48 enum tfm_crypto_err_t err;
Jamie Fox82b87ca2018-12-11 16:41:11 +000049 uint8_t key_data[CRYPTO_AEAD_MAX_KEY_LENGTH];
Antonio de Angelis3a480992018-11-07 11:53:28 +000050 uint32_t key_size;
51 psa_key_type_t key_type;
52
Jamie Fox82b87ca2018-12-11 16:41:11 +000053 /* Initialise ciphertext_length to zero */
54 *ciphertext_length = 0;
55
Antonio de Angelis3a480992018-11-07 11:53:28 +000056 if (PSA_ALG_IS_AEAD(alg) == 0) {
Jamie Fox82b87ca2018-12-11 16:41:11 +000057 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
Antonio de Angelis3a480992018-11-07 11:53:28 +000058 }
59
60 if (PSA_AEAD_TAG_SIZE(alg) == 0) {
61 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
62 }
63
64 if (PSA_AEAD_ENCRYPT_OUTPUT_SIZE(alg, plaintext_length) > ciphertext_size) {
Jamie Fox82b87ca2018-12-11 16:41:11 +000065 return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
Antonio de Angelis3a480992018-11-07 11:53:28 +000066 }
67
68 if ((nonce_length == 0) ||
69 ((additional_data_length == 0) && (additional_data != NULL))) {
70 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
71 }
72
73 /* Validate pointers */
74 err = tfm_crypto_memory_check((void *)nonce,
75 nonce_length,
76 TFM_MEMORY_ACCESS_RO);
77 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
78 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
79 }
80
81 if ((additional_data != NULL) || (additional_data_length != 0)) {
82 err = tfm_crypto_memory_check((void *)additional_data,
83 additional_data_length,
84 TFM_MEMORY_ACCESS_RO);
85 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
86 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
87 }
88 }
89
90 err = tfm_crypto_memory_check((void *)plaintext,
91 plaintext_length,
92 TFM_MEMORY_ACCESS_RO);
93 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
94 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
95 }
96
97 err = tfm_crypto_memory_check((void *)ciphertext,
98 ciphertext_size,
99 TFM_MEMORY_ACCESS_RW);
100 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
101 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
102 }
103
104 err = tfm_crypto_memory_check((void *)ciphertext_length,
105 sizeof(size_t),
106 TFM_MEMORY_ACCESS_RW);
107 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
108 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
109 }
110
111 /* Access the key data */
112 err = tfm_crypto_get_key_information(key, &key_type, (size_t *)&key_size);
113 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Jamie Fox82b87ca2018-12-11 16:41:11 +0000114 return err;
115 }
116
117 /* Support only AES based AEAD */
118 if (key_type != PSA_KEY_TYPE_AES) {
119 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
Antonio de Angelis3a480992018-11-07 11:53:28 +0000120 }
121
122 /* Access the crypto service key module to retrieve key data */
Jamie Foxefd82732018-11-26 10:34:32 +0000123 err = tfm_crypto_get_key(key,
124 PSA_KEY_USAGE_ENCRYPT,
125 alg,
126 key_data,
Jamie Fox82b87ca2018-12-11 16:41:11 +0000127 CRYPTO_AEAD_MAX_KEY_LENGTH,
Jamie Foxefd82732018-11-26 10:34:32 +0000128 (size_t *)&key_size);
Antonio de Angelis3a480992018-11-07 11:53:28 +0000129 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
130 return err;
131 }
132
133 /* Request AEAD encryption on the crypto engine */
134 status = tfm_crypto_engine_aead_encrypt(key_type,
135 alg,
136 key_data,
137 key_size,
138 nonce,
139 nonce_length,
140 additional_data,
141 additional_data_length,
142 plaintext,
143 plaintext_length,
144 ciphertext,
145 ciphertext_size,
146 (uint32_t *)ciphertext_length);
Jamie Fox82b87ca2018-12-11 16:41:11 +0000147 if (status == PSA_SUCCESS) {
148 /* The ciphertext_length needs to take into account the tag length */
149 *ciphertext_length += PSA_AEAD_TAG_SIZE(alg);
150 } else {
151 /* In case of failure set the ciphertext_length to zero */
152 *ciphertext_length = 0;
153 }
Antonio de Angelis3a480992018-11-07 11:53:28 +0000154
155 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
156}
157
158enum tfm_crypto_err_t tfm_crypto_aead_decrypt(psa_key_slot_t key,
159 psa_algorithm_t alg,
160 const uint8_t *nonce,
161 size_t nonce_length,
162 const uint8_t *additional_data,
163 size_t additional_data_length,
164 const uint8_t *ciphertext,
165 size_t ciphertext_length,
166 uint8_t *plaintext,
167 size_t plaintext_size,
168 size_t *plaintext_length)
169{
170 psa_status_t status = PSA_SUCCESS;
171 enum tfm_crypto_err_t err;
Jamie Fox82b87ca2018-12-11 16:41:11 +0000172 uint8_t key_data[CRYPTO_AEAD_MAX_KEY_LENGTH];
Antonio de Angelis3a480992018-11-07 11:53:28 +0000173 uint32_t key_size;
174 psa_key_type_t key_type;
175
Jamie Fox82b87ca2018-12-11 16:41:11 +0000176 /* Initialise plaintext_length to zero */
177 *plaintext_length = 0;
178
Antonio de Angelis3a480992018-11-07 11:53:28 +0000179 if (PSA_ALG_IS_AEAD(alg) == 0) {
Jamie Fox82b87ca2018-12-11 16:41:11 +0000180 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
181 }
182
183 if ((PSA_AEAD_TAG_SIZE(alg) == 0) ||
184 (ciphertext_length < PSA_AEAD_TAG_SIZE(alg))) {
Antonio de Angelis3a480992018-11-07 11:53:28 +0000185 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
186 }
187
Jamie Fox82b87ca2018-12-11 16:41:11 +0000188 if (PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg,ciphertext_length) > plaintext_size) {
189 return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
Antonio de Angelis3a480992018-11-07 11:53:28 +0000190 }
191
192 if ((nonce_length == 0) ||
193 ((additional_data_length == 0) && (additional_data != NULL))) {
194 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
195 }
196
197 /* Validate pointers */
198 err = tfm_crypto_memory_check((void *)nonce,
199 nonce_length,
200 TFM_MEMORY_ACCESS_RO);
201 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
202 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
203 }
204
205 if ((additional_data != NULL) || (additional_data_length != 0)) {
206 err = tfm_crypto_memory_check((void *)additional_data,
207 additional_data_length,
208 TFM_MEMORY_ACCESS_RO);
209 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
210 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
211 }
212 }
213
214 err = tfm_crypto_memory_check((void *)ciphertext,
215 ciphertext_length,
216 TFM_MEMORY_ACCESS_RO);
217 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
218 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
219 }
220
221 err = tfm_crypto_memory_check((void *)plaintext,
222 plaintext_size,
223 TFM_MEMORY_ACCESS_RW);
224 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
225 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
226 }
227
228 err = tfm_crypto_memory_check((void *)plaintext_length,
229 sizeof(size_t),
230 TFM_MEMORY_ACCESS_RW);
231 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
232 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
233 }
234
235 /* Access the key data */
236 err = tfm_crypto_get_key_information(key, &key_type, (size_t *)&key_size);
237 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Jamie Fox82b87ca2018-12-11 16:41:11 +0000238 return err;
239 }
240
241 /* Support only AES based AEAD */
242 if (key_type != PSA_KEY_TYPE_AES) {
243 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
Antonio de Angelis3a480992018-11-07 11:53:28 +0000244 }
245
246 /* Access the crypto service key module to retrieve key data */
Jamie Foxefd82732018-11-26 10:34:32 +0000247 err = tfm_crypto_get_key(key,
248 PSA_KEY_USAGE_DECRYPT,
249 alg,
250 key_data,
Jamie Fox82b87ca2018-12-11 16:41:11 +0000251 CRYPTO_AEAD_MAX_KEY_LENGTH,
Jamie Foxefd82732018-11-26 10:34:32 +0000252 (size_t *)&key_size);
Antonio de Angelis3a480992018-11-07 11:53:28 +0000253 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
254 return err;
255 }
256
257 /* Request AEAD decryption on the crypto engine */
258 status = tfm_crypto_engine_aead_decrypt(key_type,
259 alg,
260 key_data,
261 key_size,
262 nonce,
263 nonce_length,
264 additional_data,
265 additional_data_length,
266 ciphertext,
267 ciphertext_length,
268 plaintext,
269 plaintext_size,
270 (uint32_t *)plaintext_length);
Jamie Fox82b87ca2018-12-11 16:41:11 +0000271 if (status != PSA_SUCCESS) {
272 *plaintext_length = 0;
273 }
Antonio de Angelis3a480992018-11-07 11:53:28 +0000274
275 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
276}
277/*!@}*/