blob: 7978d7fb4e31470c1f9e484c6a56e570aab0d251 [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"
Antonio de Angelis3a480992018-11-07 11:53:28 +000017
Jamie Fox82b87ca2018-12-11 16:41:11 +000018/**
19 * \def CRYPTO_AEAD_MAX_KEY_LENGTH
20 *
21 * \brief Specifies the maximum key length supported by the
22 * AEAD operations in this implementation
23 */
24#ifndef CRYPTO_AEAD_MAX_KEY_LENGTH
25#define CRYPTO_AEAD_MAX_KEY_LENGTH (32)
26#endif
27
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000028static psa_status_t _psa_get_key_information(psa_key_slot_t key,
29 psa_key_type_t *type,
30 size_t *bits)
31{
32 psa_invec in_vec[] = {
33 {.base = &key, .len = sizeof(psa_key_slot_t)},
34 };
35 psa_outvec out_vec[] = {
36 {.base = type, .len = sizeof(psa_key_type_t)},
37 {.base = bits, .len = sizeof(size_t)}
38 };
39
40 return tfm_crypto_get_key_information(
41 in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
42 out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
43}
44
Antonio de Angelis3a480992018-11-07 11:53:28 +000045/*!
46 * \defgroup public_psa Public functions, PSA
47 *
48 */
49
50/*!@{*/
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000051psa_status_t tfm_crypto_aead_encrypt(psa_invec in_vec[],
52 size_t in_len,
53 psa_outvec out_vec[],
54 size_t out_len)
Antonio de Angelis3a480992018-11-07 11:53:28 +000055{
56 psa_status_t status = PSA_SUCCESS;
Jamie Fox82b87ca2018-12-11 16:41:11 +000057 uint8_t key_data[CRYPTO_AEAD_MAX_KEY_LENGTH];
Antonio de Angelis3a480992018-11-07 11:53:28 +000058 uint32_t key_size;
59 psa_key_type_t key_type;
60
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000061 if ((in_len != 3) || (out_len != 1)) {
62 return PSA_CONNECTION_REFUSED;
63 }
64
65 if ((in_vec[0].len < (sizeof(psa_key_slot_t) + sizeof(psa_algorithm_t))) ||
66 (in_vec[0].len > (TFM_CRYPTO_MAX_NONCE_LENGTH
67 + (sizeof(psa_key_slot_t) + sizeof(psa_algorithm_t))))) {
68 return PSA_CONNECTION_REFUSED;
69 }
70
71 const struct tfm_crypto_aead_pack_input *input_s = in_vec[0].base;
72 psa_key_slot_t key = input_s->key;
73 psa_algorithm_t alg = input_s->alg;
74 const uint8_t *nonce = input_s->nonce;
75 size_t nonce_length = in_vec[0].len - sizeof(psa_key_slot_t)
76 - sizeof(psa_algorithm_t);
77 const uint8_t *additional_data = in_vec[1].base;
78 size_t additional_data_length = in_vec[1].len;
79 const uint8_t *plaintext = in_vec[2].base;
80 size_t plaintext_length = in_vec[2].len;
81 uint8_t *ciphertext = out_vec[0].base;
82 size_t ciphertext_size = out_vec[0].len;
83
Jamie Fox82b87ca2018-12-11 16:41:11 +000084 /* Initialise ciphertext_length to zero */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000085 out_vec[0].len = 0;
Jamie Fox82b87ca2018-12-11 16:41:11 +000086
Antonio de Angelis3a480992018-11-07 11:53:28 +000087 if (PSA_ALG_IS_AEAD(alg) == 0) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000088 return PSA_ERROR_NOT_SUPPORTED;
Antonio de Angelis3a480992018-11-07 11:53:28 +000089 }
90
91 if (PSA_AEAD_TAG_SIZE(alg) == 0) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000092 return PSA_ERROR_INVALID_ARGUMENT;
Antonio de Angelis3a480992018-11-07 11:53:28 +000093 }
94
95 if (PSA_AEAD_ENCRYPT_OUTPUT_SIZE(alg, plaintext_length) > ciphertext_size) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000096 return PSA_ERROR_BUFFER_TOO_SMALL;
Antonio de Angelis3a480992018-11-07 11:53:28 +000097 }
98
99 if ((nonce_length == 0) ||
100 ((additional_data_length == 0) && (additional_data != NULL))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000101 return PSA_ERROR_INVALID_ARGUMENT;
Antonio de Angelis3a480992018-11-07 11:53:28 +0000102 }
103
104 /* Access the key data */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000105 status = _psa_get_key_information(key, &key_type, (size_t *)&key_size);
106 if (status != PSA_SUCCESS) {
107 return status;
Jamie Fox82b87ca2018-12-11 16:41:11 +0000108 }
109
110 /* Support only AES based AEAD */
111 if (key_type != PSA_KEY_TYPE_AES) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000112 return PSA_ERROR_NOT_SUPPORTED;
Antonio de Angelis3a480992018-11-07 11:53:28 +0000113 }
114
115 /* Access the crypto service key module to retrieve key data */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000116 status = tfm_crypto_get_key(key,
117 PSA_KEY_USAGE_ENCRYPT,
118 alg,
119 key_data,
120 CRYPTO_AEAD_MAX_KEY_LENGTH,
121 (size_t *)&key_size);
122 if (status != PSA_SUCCESS) {
123 return status;
Antonio de Angelis3a480992018-11-07 11:53:28 +0000124 }
125
126 /* Request AEAD encryption on the crypto engine */
127 status = tfm_crypto_engine_aead_encrypt(key_type,
128 alg,
129 key_data,
130 key_size,
131 nonce,
132 nonce_length,
133 additional_data,
134 additional_data_length,
135 plaintext,
136 plaintext_length,
137 ciphertext,
138 ciphertext_size,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000139 (uint32_t *)&(out_vec[0].len));
Jamie Fox82b87ca2018-12-11 16:41:11 +0000140 if (status == PSA_SUCCESS) {
141 /* The ciphertext_length needs to take into account the tag length */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000142 out_vec[0].len += PSA_AEAD_TAG_SIZE(alg);
Jamie Fox82b87ca2018-12-11 16:41:11 +0000143 } else {
144 /* In case of failure set the ciphertext_length to zero */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000145 out_vec[0].len = 0;
Jamie Fox82b87ca2018-12-11 16:41:11 +0000146 }
Antonio de Angelis3a480992018-11-07 11:53:28 +0000147
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000148 return status;
Antonio de Angelis3a480992018-11-07 11:53:28 +0000149}
150
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000151psa_status_t tfm_crypto_aead_decrypt(psa_invec in_vec[],
152 size_t in_len,
153 psa_outvec out_vec[],
154 size_t out_len)
Antonio de Angelis3a480992018-11-07 11:53:28 +0000155{
156 psa_status_t status = PSA_SUCCESS;
Jamie Fox82b87ca2018-12-11 16:41:11 +0000157 uint8_t key_data[CRYPTO_AEAD_MAX_KEY_LENGTH];
Antonio de Angelis3a480992018-11-07 11:53:28 +0000158 uint32_t key_size;
159 psa_key_type_t key_type;
160
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000161 if ((in_vec[0].len < (sizeof(psa_key_slot_t) + sizeof(psa_algorithm_t))) ||
162 (in_vec[0].len > (TFM_CRYPTO_MAX_NONCE_LENGTH
163 + (sizeof(psa_key_slot_t) + sizeof(psa_algorithm_t))))) {
164 return PSA_CONNECTION_REFUSED;
165 }
166
167 const struct tfm_crypto_aead_pack_input *input_s = in_vec[0].base;
168 psa_key_slot_t key = input_s->key;
169 psa_algorithm_t alg = input_s->alg;
170 const uint8_t *nonce = input_s->nonce;
171 size_t nonce_length = in_vec[0].len - sizeof(psa_key_slot_t)
172 - sizeof(psa_algorithm_t);
173 const uint8_t *additional_data = in_vec[1].base;
174 size_t additional_data_length = in_vec[1].len;
175 const uint8_t *ciphertext = in_vec[2].base;
176 size_t ciphertext_length = in_vec[2].len;
177 uint8_t *plaintext = out_vec[0].base;
178 size_t plaintext_size = out_vec[0].len;
179
Jamie Fox82b87ca2018-12-11 16:41:11 +0000180 /* Initialise plaintext_length to zero */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000181 out_vec[0].len = 0;
Jamie Fox82b87ca2018-12-11 16:41:11 +0000182
Antonio de Angelis3a480992018-11-07 11:53:28 +0000183 if (PSA_ALG_IS_AEAD(alg) == 0) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000184 return PSA_ERROR_NOT_SUPPORTED;
Jamie Fox82b87ca2018-12-11 16:41:11 +0000185 }
186
187 if ((PSA_AEAD_TAG_SIZE(alg) == 0) ||
188 (ciphertext_length < PSA_AEAD_TAG_SIZE(alg))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000189 return PSA_ERROR_INVALID_ARGUMENT;
Antonio de Angelis3a480992018-11-07 11:53:28 +0000190 }
191
Jamie Fox82b87ca2018-12-11 16:41:11 +0000192 if (PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg,ciphertext_length) > plaintext_size) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000193 return PSA_ERROR_BUFFER_TOO_SMALL;
Antonio de Angelis3a480992018-11-07 11:53:28 +0000194 }
195
196 if ((nonce_length == 0) ||
197 ((additional_data_length == 0) && (additional_data != NULL))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000198 return PSA_ERROR_INVALID_ARGUMENT;
Antonio de Angelis3a480992018-11-07 11:53:28 +0000199 }
200
201 /* Access the key data */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000202 status = _psa_get_key_information(key, &key_type, (size_t *)&key_size);
203 if (status != PSA_SUCCESS) {
204 return status;
Jamie Fox82b87ca2018-12-11 16:41:11 +0000205 }
206
207 /* Support only AES based AEAD */
208 if (key_type != PSA_KEY_TYPE_AES) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000209 return PSA_ERROR_NOT_SUPPORTED;
Antonio de Angelis3a480992018-11-07 11:53:28 +0000210 }
211
212 /* Access the crypto service key module to retrieve key data */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000213 status = tfm_crypto_get_key(key,
214 PSA_KEY_USAGE_DECRYPT,
215 alg,
216 key_data,
217 CRYPTO_AEAD_MAX_KEY_LENGTH,
218 (size_t *)&key_size);
219 if (status != PSA_SUCCESS) {
220 return status;
Antonio de Angelis3a480992018-11-07 11:53:28 +0000221 }
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,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000236 (uint32_t *)&(out_vec[0].len));
Jamie Fox82b87ca2018-12-11 16:41:11 +0000237 if (status != PSA_SUCCESS) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000238 out_vec[0].len = 0;
Jamie Fox82b87ca2018-12-11 16:41:11 +0000239 }
Antonio de Angelis3a480992018-11-07 11:53:28 +0000240
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000241 return status;
Antonio de Angelis3a480992018-11-07 11:53:28 +0000242}
243/*!@}*/