blob: a0e2a5c35c4791a661fcb9c95aa20dab61b0b0da [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
19/*!
20 * \defgroup public_psa Public functions, PSA
21 *
22 */
23
24/*!@{*/
25enum tfm_crypto_err_t tfm_crypto_aead_encrypt(psa_key_slot_t key,
26 psa_algorithm_t alg,
27 const uint8_t *nonce,
28 size_t nonce_length,
29 const uint8_t *additional_data,
30 size_t additional_data_length,
31 const uint8_t *plaintext,
32 size_t plaintext_length,
33 uint8_t *ciphertext,
34 size_t ciphertext_size,
35 size_t *ciphertext_length)
36{
37 psa_status_t status = PSA_SUCCESS;
38 enum tfm_crypto_err_t err;
39 uint8_t key_data[TFM_CRYPTO_MAX_KEY_LENGTH];
40 uint32_t key_size;
41 psa_key_type_t key_type;
42
43 if (PSA_ALG_IS_AEAD(alg) == 0) {
44 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
45 }
46
47 if (PSA_AEAD_TAG_SIZE(alg) == 0) {
48 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
49 }
50
51 if (PSA_AEAD_ENCRYPT_OUTPUT_SIZE(alg, plaintext_length) > ciphertext_size) {
52 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
53 }
54
55 if ((nonce_length == 0) ||
56 ((additional_data_length == 0) && (additional_data != NULL))) {
57 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
58 }
59
60 /* Validate pointers */
61 err = tfm_crypto_memory_check((void *)nonce,
62 nonce_length,
63 TFM_MEMORY_ACCESS_RO);
64 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
65 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
66 }
67
68 if ((additional_data != NULL) || (additional_data_length != 0)) {
69 err = tfm_crypto_memory_check((void *)additional_data,
70 additional_data_length,
71 TFM_MEMORY_ACCESS_RO);
72 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
73 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
74 }
75 }
76
77 err = tfm_crypto_memory_check((void *)plaintext,
78 plaintext_length,
79 TFM_MEMORY_ACCESS_RO);
80 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
81 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
82 }
83
84 err = tfm_crypto_memory_check((void *)ciphertext,
85 ciphertext_size,
86 TFM_MEMORY_ACCESS_RW);
87 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
88 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
89 }
90
91 err = tfm_crypto_memory_check((void *)ciphertext_length,
92 sizeof(size_t),
93 TFM_MEMORY_ACCESS_RW);
94 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
95 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
96 }
97
98 /* Access the key data */
99 err = tfm_crypto_get_key_information(key, &key_type, (size_t *)&key_size);
100 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
101 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
102 }
103
104 /* Access the crypto service key module to retrieve key data */
105 err = tfm_crypto_export_key(key,
106 &key_data[0],
107 TFM_CRYPTO_MAX_KEY_LENGTH,
108 (size_t *)&key_size);
109 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
110 return err;
111 }
112
113 /* Request AEAD encryption on the crypto engine */
114 status = tfm_crypto_engine_aead_encrypt(key_type,
115 alg,
116 key_data,
117 key_size,
118 nonce,
119 nonce_length,
120 additional_data,
121 additional_data_length,
122 plaintext,
123 plaintext_length,
124 ciphertext,
125 ciphertext_size,
126 (uint32_t *)ciphertext_length);
127
128 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
129}
130
131enum tfm_crypto_err_t tfm_crypto_aead_decrypt(psa_key_slot_t key,
132 psa_algorithm_t alg,
133 const uint8_t *nonce,
134 size_t nonce_length,
135 const uint8_t *additional_data,
136 size_t additional_data_length,
137 const uint8_t *ciphertext,
138 size_t ciphertext_length,
139 uint8_t *plaintext,
140 size_t plaintext_size,
141 size_t *plaintext_length)
142{
143 psa_status_t status = PSA_SUCCESS;
144 enum tfm_crypto_err_t err;
145 uint8_t key_data[TFM_CRYPTO_MAX_KEY_LENGTH];
146 uint32_t key_size;
147 psa_key_type_t key_type;
148
149 if (PSA_ALG_IS_AEAD(alg) == 0) {
150 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
151 }
152
153 if (PSA_AEAD_TAG_SIZE(alg) == 0) {
154 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
155 }
156
157 if (PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length) > plaintext_size) {
158 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
159 }
160
161 if ((nonce_length == 0) ||
162 ((additional_data_length == 0) && (additional_data != NULL))) {
163 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
164 }
165
166 /* Validate pointers */
167 err = tfm_crypto_memory_check((void *)nonce,
168 nonce_length,
169 TFM_MEMORY_ACCESS_RO);
170 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
171 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
172 }
173
174 if ((additional_data != NULL) || (additional_data_length != 0)) {
175 err = tfm_crypto_memory_check((void *)additional_data,
176 additional_data_length,
177 TFM_MEMORY_ACCESS_RO);
178 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
179 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
180 }
181 }
182
183 err = tfm_crypto_memory_check((void *)ciphertext,
184 ciphertext_length,
185 TFM_MEMORY_ACCESS_RO);
186 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
187 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
188 }
189
190 err = tfm_crypto_memory_check((void *)plaintext,
191 plaintext_size,
192 TFM_MEMORY_ACCESS_RW);
193 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
194 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
195 }
196
197 err = tfm_crypto_memory_check((void *)plaintext_length,
198 sizeof(size_t),
199 TFM_MEMORY_ACCESS_RW);
200 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
201 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
202 }
203
204 /* Access the key data */
205 err = tfm_crypto_get_key_information(key, &key_type, (size_t *)&key_size);
206 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
207 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
208 }
209
210 /* Access the crypto service key module to retrieve key data */
211 err = tfm_crypto_export_key(key,
212 &key_data[0],
213 TFM_CRYPTO_MAX_KEY_LENGTH,
214 (size_t *)&key_size);
215 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
216 return err;
217 }
218
219 /* Request AEAD decryption on the crypto engine */
220 status = tfm_crypto_engine_aead_decrypt(key_type,
221 alg,
222 key_data,
223 key_size,
224 nonce,
225 nonce_length,
226 additional_data,
227 additional_data_length,
228 ciphertext,
229 ciphertext_length,
230 plaintext,
231 plaintext_size,
232 (uint32_t *)plaintext_length);
233
234 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
235}
236/*!@}*/