blob: ec8b3a12fa42dc73bbe6a492965b0614d4f33c11 [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 */
Jamie Foxefd82732018-11-26 10:34:32 +0000105 err = tfm_crypto_get_key(key,
106 PSA_KEY_USAGE_ENCRYPT,
107 alg,
108 key_data,
109 TFM_CRYPTO_MAX_KEY_LENGTH,
110 (size_t *)&key_size);
Antonio de Angelis3a480992018-11-07 11:53:28 +0000111 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
112 return err;
113 }
114
115 /* Request AEAD encryption on the crypto engine */
116 status = tfm_crypto_engine_aead_encrypt(key_type,
117 alg,
118 key_data,
119 key_size,
120 nonce,
121 nonce_length,
122 additional_data,
123 additional_data_length,
124 plaintext,
125 plaintext_length,
126 ciphertext,
127 ciphertext_size,
128 (uint32_t *)ciphertext_length);
129
130 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
131}
132
133enum tfm_crypto_err_t tfm_crypto_aead_decrypt(psa_key_slot_t key,
134 psa_algorithm_t alg,
135 const uint8_t *nonce,
136 size_t nonce_length,
137 const uint8_t *additional_data,
138 size_t additional_data_length,
139 const uint8_t *ciphertext,
140 size_t ciphertext_length,
141 uint8_t *plaintext,
142 size_t plaintext_size,
143 size_t *plaintext_length)
144{
145 psa_status_t status = PSA_SUCCESS;
146 enum tfm_crypto_err_t err;
147 uint8_t key_data[TFM_CRYPTO_MAX_KEY_LENGTH];
148 uint32_t key_size;
149 psa_key_type_t key_type;
150
151 if (PSA_ALG_IS_AEAD(alg) == 0) {
152 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
153 }
154
155 if (PSA_AEAD_TAG_SIZE(alg) == 0) {
156 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
157 }
158
159 if (PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length) > plaintext_size) {
160 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
161 }
162
163 if ((nonce_length == 0) ||
164 ((additional_data_length == 0) && (additional_data != NULL))) {
165 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
166 }
167
168 /* Validate pointers */
169 err = tfm_crypto_memory_check((void *)nonce,
170 nonce_length,
171 TFM_MEMORY_ACCESS_RO);
172 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
173 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
174 }
175
176 if ((additional_data != NULL) || (additional_data_length != 0)) {
177 err = tfm_crypto_memory_check((void *)additional_data,
178 additional_data_length,
179 TFM_MEMORY_ACCESS_RO);
180 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
181 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
182 }
183 }
184
185 err = tfm_crypto_memory_check((void *)ciphertext,
186 ciphertext_length,
187 TFM_MEMORY_ACCESS_RO);
188 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
189 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
190 }
191
192 err = tfm_crypto_memory_check((void *)plaintext,
193 plaintext_size,
194 TFM_MEMORY_ACCESS_RW);
195 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
196 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
197 }
198
199 err = tfm_crypto_memory_check((void *)plaintext_length,
200 sizeof(size_t),
201 TFM_MEMORY_ACCESS_RW);
202 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
203 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
204 }
205
206 /* Access the key data */
207 err = tfm_crypto_get_key_information(key, &key_type, (size_t *)&key_size);
208 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
209 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
210 }
211
212 /* Access the crypto service key module to retrieve key data */
Jamie Foxefd82732018-11-26 10:34:32 +0000213 err = tfm_crypto_get_key(key,
214 PSA_KEY_USAGE_DECRYPT,
215 alg,
216 key_data,
217 TFM_CRYPTO_MAX_KEY_LENGTH,
218 (size_t *)&key_size);
Antonio de Angelis3a480992018-11-07 11:53:28 +0000219 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
220 return err;
221 }
222
223 /* Request AEAD decryption on the crypto engine */
224 status = tfm_crypto_engine_aead_decrypt(key_type,
225 alg,
226 key_data,
227 key_size,
228 nonce,
229 nonce_length,
230 additional_data,
231 additional_data_length,
232 ciphertext,
233 ciphertext_length,
234 plaintext,
235 plaintext_size,
236 (uint32_t *)plaintext_length);
237
238 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
239}
240/*!@}*/