Branch data Line data Source code
1 : : /*
2 : : * PSA AEAD entry points
3 : : */
4 : : /*
5 : : * Copyright The Mbed TLS Contributors
6 : : * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
7 : : */
8 : :
9 : : #include "common.h"
10 : :
11 : : #if defined(MBEDTLS_PSA_CRYPTO_C)
12 : :
13 : : #include "psa_crypto_aead.h"
14 : : #include "psa_crypto_core.h"
15 : : #include "psa_crypto_cipher.h"
16 : :
17 : : #include <string.h>
18 : : #include "mbedtls/platform.h"
19 : :
20 : : #include "mbedtls/ccm.h"
21 : : #include "mbedtls/chachapoly.h"
22 : : #include "mbedtls/cipher.h"
23 : : #include "mbedtls/gcm.h"
24 : : #include "mbedtls/error.h"
25 : :
26 : 34 : static psa_status_t psa_aead_setup(
27 : : mbedtls_psa_aead_operation_t *operation,
28 : : const psa_key_attributes_t *attributes,
29 : : const uint8_t *key_buffer,
30 : : size_t key_buffer_size,
31 : : psa_algorithm_t alg)
32 : : {
33 : 34 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
34 : 34 : mbedtls_cipher_id_t cipher_id;
35 : 34 : mbedtls_cipher_mode_t mode;
36 : 34 : size_t key_bits = attributes->bits;
37 : 34 : (void) key_buffer_size;
38 : :
39 : 34 : status = mbedtls_cipher_values_from_psa(alg, attributes->type,
40 : : &key_bits, &mode, &cipher_id);
41 [ + - ]: 34 : if (status != PSA_SUCCESS) {
42 : : return status;
43 : : }
44 : :
45 [ + - ]: 34 : switch (PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0)) {
46 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
47 : 34 : case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
48 : 34 : operation->alg = PSA_ALG_CCM;
49 : : /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
50 : : * The call to mbedtls_ccm_encrypt_and_tag or
51 : : * mbedtls_ccm_auth_decrypt will validate the tag length. */
52 [ + - + - ]: 34 : if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) {
53 : : return PSA_ERROR_INVALID_ARGUMENT;
54 : : }
55 : :
56 : 34 : mbedtls_ccm_init(&operation->ctx.ccm);
57 : 34 : status = mbedtls_to_psa_error(
58 : : mbedtls_ccm_setkey(&operation->ctx.ccm, cipher_id,
59 : : key_buffer, (unsigned int) key_bits));
60 [ + - ]: 34 : if (status != PSA_SUCCESS) {
61 : : return status;
62 : : }
63 : 34 : break;
64 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
65 : :
66 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
67 : : case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
68 : : operation->alg = PSA_ALG_GCM;
69 : : /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
70 : : * The call to mbedtls_gcm_crypt_and_tag or
71 : : * mbedtls_gcm_auth_decrypt will validate the tag length. */
72 : : if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) {
73 : : return PSA_ERROR_INVALID_ARGUMENT;
74 : : }
75 : :
76 : : mbedtls_gcm_init(&operation->ctx.gcm);
77 : : status = mbedtls_to_psa_error(
78 : : mbedtls_gcm_setkey(&operation->ctx.gcm, cipher_id,
79 : : key_buffer, (unsigned int) key_bits));
80 : : if (status != PSA_SUCCESS) {
81 : : return status;
82 : : }
83 : : break;
84 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
85 : :
86 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
87 : : case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
88 : : operation->alg = PSA_ALG_CHACHA20_POLY1305;
89 : : /* We only support the default tag length. */
90 : : if (alg != PSA_ALG_CHACHA20_POLY1305) {
91 : : return PSA_ERROR_NOT_SUPPORTED;
92 : : }
93 : :
94 : : mbedtls_chachapoly_init(&operation->ctx.chachapoly);
95 : : status = mbedtls_to_psa_error(
96 : : mbedtls_chachapoly_setkey(&operation->ctx.chachapoly,
97 : : key_buffer));
98 : : if (status != PSA_SUCCESS) {
99 : : return status;
100 : : }
101 : : break;
102 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
103 : :
104 : : default:
105 : : (void) status;
106 : : (void) key_buffer;
107 : : return PSA_ERROR_NOT_SUPPORTED;
108 : : }
109 : :
110 : 34 : operation->key_type = psa_get_key_type(attributes);
111 : :
112 : 34 : operation->tag_length = PSA_ALG_AEAD_GET_TAG_LENGTH(alg);
113 : :
114 : 34 : return PSA_SUCCESS;
115 : : }
116 : :
117 : 18 : psa_status_t mbedtls_psa_aead_encrypt(
118 : : const psa_key_attributes_t *attributes,
119 : : const uint8_t *key_buffer, size_t key_buffer_size,
120 : : psa_algorithm_t alg,
121 : : const uint8_t *nonce, size_t nonce_length,
122 : : const uint8_t *additional_data, size_t additional_data_length,
123 : : const uint8_t *plaintext, size_t plaintext_length,
124 : : uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length)
125 : : {
126 : 18 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
127 : 18 : mbedtls_psa_aead_operation_t operation = MBEDTLS_PSA_AEAD_OPERATION_INIT;
128 : 18 : uint8_t *tag;
129 : :
130 : 18 : status = psa_aead_setup(&operation, attributes, key_buffer,
131 : : key_buffer_size, alg);
132 : :
133 [ - + ]: 18 : if (status != PSA_SUCCESS) {
134 : 0 : goto exit;
135 : : }
136 : :
137 : : /* For all currently supported modes, the tag is at the end of the
138 : : * ciphertext. */
139 [ - + ]: 18 : if (ciphertext_size < (plaintext_length + operation.tag_length)) {
140 : 0 : status = PSA_ERROR_BUFFER_TOO_SMALL;
141 : 0 : goto exit;
142 : : }
143 : 18 : tag = ciphertext + plaintext_length;
144 : :
145 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
146 [ + - ]: 18 : if (operation.alg == PSA_ALG_CCM) {
147 : 18 : status = mbedtls_to_psa_error(
148 : : mbedtls_ccm_encrypt_and_tag(&operation.ctx.ccm,
149 : : plaintext_length,
150 : : nonce, nonce_length,
151 : : additional_data,
152 : : additional_data_length,
153 : : plaintext, ciphertext,
154 : : tag, operation.tag_length));
155 : : } else
156 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
157 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
158 : : if (operation.alg == PSA_ALG_GCM) {
159 : : status = mbedtls_to_psa_error(
160 : : mbedtls_gcm_crypt_and_tag(&operation.ctx.gcm,
161 : : MBEDTLS_GCM_ENCRYPT,
162 : : plaintext_length,
163 : : nonce, nonce_length,
164 : : additional_data, additional_data_length,
165 : : plaintext, ciphertext,
166 : : operation.tag_length, tag));
167 : : } else
168 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
169 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
170 : : if (operation.alg == PSA_ALG_CHACHA20_POLY1305) {
171 : : if (operation.tag_length != 16) {
172 : : status = PSA_ERROR_NOT_SUPPORTED;
173 : : goto exit;
174 : : }
175 : : status = mbedtls_to_psa_error(
176 : : mbedtls_chachapoly_encrypt_and_tag(&operation.ctx.chachapoly,
177 : : plaintext_length,
178 : : nonce,
179 : : additional_data,
180 : : additional_data_length,
181 : : plaintext,
182 : : ciphertext,
183 : : tag));
184 : : } else
185 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
186 : : {
187 : : (void) tag;
188 : : (void) nonce;
189 : : (void) nonce_length;
190 : : (void) additional_data;
191 : : (void) additional_data_length;
192 : : (void) plaintext;
193 : : return PSA_ERROR_NOT_SUPPORTED;
194 : : }
195 : :
196 [ - + ]: 18 : if (status == PSA_SUCCESS) {
197 : 18 : *ciphertext_length = plaintext_length + operation.tag_length;
198 : : }
199 : :
200 : 0 : exit:
201 : 18 : mbedtls_psa_aead_abort(&operation);
202 : :
203 : 18 : return status;
204 : : }
205 : :
206 : : /* Locate the tag in a ciphertext buffer containing the encrypted data
207 : : * followed by the tag. Return the length of the part preceding the tag in
208 : : * *plaintext_length. This is the size of the plaintext in modes where
209 : : * the encrypted data has the same size as the plaintext, such as
210 : : * CCM and GCM. */
211 : 16 : static psa_status_t psa_aead_unpadded_locate_tag(size_t tag_length,
212 : : const uint8_t *ciphertext,
213 : : size_t ciphertext_length,
214 : : size_t plaintext_size,
215 : : const uint8_t **p_tag)
216 : : {
217 : 16 : size_t payload_length;
218 [ + - ]: 16 : if (tag_length > ciphertext_length) {
219 : : return PSA_ERROR_INVALID_ARGUMENT;
220 : : }
221 : 16 : payload_length = ciphertext_length - tag_length;
222 [ + - ]: 16 : if (payload_length > plaintext_size) {
223 : : return PSA_ERROR_BUFFER_TOO_SMALL;
224 : : }
225 : 16 : *p_tag = ciphertext + payload_length;
226 : 16 : return PSA_SUCCESS;
227 : : }
228 : :
229 : 16 : psa_status_t mbedtls_psa_aead_decrypt(
230 : : const psa_key_attributes_t *attributes,
231 : : const uint8_t *key_buffer, size_t key_buffer_size,
232 : : psa_algorithm_t alg,
233 : : const uint8_t *nonce, size_t nonce_length,
234 : : const uint8_t *additional_data, size_t additional_data_length,
235 : : const uint8_t *ciphertext, size_t ciphertext_length,
236 : : uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length)
237 : : {
238 : 16 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
239 : 16 : mbedtls_psa_aead_operation_t operation = MBEDTLS_PSA_AEAD_OPERATION_INIT;
240 : 16 : const uint8_t *tag = NULL;
241 : :
242 : 16 : status = psa_aead_setup(&operation, attributes, key_buffer,
243 : : key_buffer_size, alg);
244 : :
245 [ - + ]: 16 : if (status != PSA_SUCCESS) {
246 : 0 : goto exit;
247 : : }
248 : :
249 : 16 : status = psa_aead_unpadded_locate_tag(operation.tag_length,
250 : : ciphertext, ciphertext_length,
251 : : plaintext_size, &tag);
252 [ - + ]: 16 : if (status != PSA_SUCCESS) {
253 : 0 : goto exit;
254 : : }
255 : :
256 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
257 [ + - ]: 16 : if (operation.alg == PSA_ALG_CCM) {
258 : 16 : status = mbedtls_to_psa_error(
259 : : mbedtls_ccm_auth_decrypt(&operation.ctx.ccm,
260 : : ciphertext_length - operation.tag_length,
261 : : nonce, nonce_length,
262 : : additional_data,
263 : : additional_data_length,
264 : : ciphertext, plaintext,
265 : : tag, operation.tag_length));
266 : : } else
267 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
268 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
269 : : if (operation.alg == PSA_ALG_GCM) {
270 : : status = mbedtls_to_psa_error(
271 : : mbedtls_gcm_auth_decrypt(&operation.ctx.gcm,
272 : : ciphertext_length - operation.tag_length,
273 : : nonce, nonce_length,
274 : : additional_data,
275 : : additional_data_length,
276 : : tag, operation.tag_length,
277 : : ciphertext, plaintext));
278 : : } else
279 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
280 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
281 : : if (operation.alg == PSA_ALG_CHACHA20_POLY1305) {
282 : : if (operation.tag_length != 16) {
283 : : status = PSA_ERROR_NOT_SUPPORTED;
284 : : goto exit;
285 : : }
286 : : status = mbedtls_to_psa_error(
287 : : mbedtls_chachapoly_auth_decrypt(&operation.ctx.chachapoly,
288 : : ciphertext_length - operation.tag_length,
289 : : nonce,
290 : : additional_data,
291 : : additional_data_length,
292 : : tag,
293 : : ciphertext,
294 : : plaintext));
295 : : } else
296 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
297 : : {
298 : : (void) nonce;
299 : : (void) nonce_length;
300 : : (void) additional_data;
301 : : (void) additional_data_length;
302 : : (void) plaintext;
303 : : return PSA_ERROR_NOT_SUPPORTED;
304 : : }
305 : :
306 [ - + ]: 16 : if (status == PSA_SUCCESS) {
307 : 16 : *plaintext_length = ciphertext_length - operation.tag_length;
308 : : }
309 : :
310 : 0 : exit:
311 : 16 : mbedtls_psa_aead_abort(&operation);
312 : :
313 [ + - ]: 16 : if (status == PSA_SUCCESS) {
314 : 16 : *plaintext_length = ciphertext_length - operation.tag_length;
315 : : }
316 : : return status;
317 : : }
318 : :
319 : : /* Set the key and algorithm for a multipart authenticated encryption
320 : : * operation. */
321 : 0 : psa_status_t mbedtls_psa_aead_encrypt_setup(
322 : : mbedtls_psa_aead_operation_t *operation,
323 : : const psa_key_attributes_t *attributes,
324 : : const uint8_t *key_buffer,
325 : : size_t key_buffer_size,
326 : : psa_algorithm_t alg)
327 : : {
328 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
329 : :
330 : 0 : status = psa_aead_setup(operation, attributes, key_buffer,
331 : : key_buffer_size, alg);
332 : :
333 [ # # ]: 0 : if (status == PSA_SUCCESS) {
334 : 0 : operation->is_encrypt = 1;
335 : : }
336 : :
337 : 0 : return status;
338 : : }
339 : :
340 : : /* Set the key and algorithm for a multipart authenticated decryption
341 : : * operation. */
342 : 0 : psa_status_t mbedtls_psa_aead_decrypt_setup(
343 : : mbedtls_psa_aead_operation_t *operation,
344 : : const psa_key_attributes_t *attributes,
345 : : const uint8_t *key_buffer,
346 : : size_t key_buffer_size,
347 : : psa_algorithm_t alg)
348 : : {
349 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
350 : :
351 : 0 : status = psa_aead_setup(operation, attributes, key_buffer,
352 : : key_buffer_size, alg);
353 : :
354 [ # # ]: 0 : if (status == PSA_SUCCESS) {
355 : 0 : operation->is_encrypt = 0;
356 : : }
357 : :
358 : 0 : return status;
359 : : }
360 : :
361 : : /* Set a nonce for the multipart AEAD operation*/
362 : 0 : psa_status_t mbedtls_psa_aead_set_nonce(
363 : : mbedtls_psa_aead_operation_t *operation,
364 : : const uint8_t *nonce,
365 : : size_t nonce_length)
366 : : {
367 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
368 : :
369 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
370 : : if (operation->alg == PSA_ALG_GCM) {
371 : : status = mbedtls_to_psa_error(
372 : : mbedtls_gcm_starts(&operation->ctx.gcm,
373 : : operation->is_encrypt ?
374 : : MBEDTLS_GCM_ENCRYPT : MBEDTLS_GCM_DECRYPT,
375 : : nonce,
376 : : nonce_length));
377 : : } else
378 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
379 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
380 [ # # ]: 0 : if (operation->alg == PSA_ALG_CCM) {
381 : 0 : status = mbedtls_to_psa_error(
382 : : mbedtls_ccm_starts(&operation->ctx.ccm,
383 : 0 : operation->is_encrypt ?
384 : : MBEDTLS_CCM_ENCRYPT : MBEDTLS_CCM_DECRYPT,
385 : : nonce,
386 : : nonce_length));
387 : : } else
388 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
389 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
390 : : if (operation->alg == PSA_ALG_CHACHA20_POLY1305) {
391 : : /* Note - ChaChaPoly allows an 8 byte nonce, but we would have to
392 : : * allocate a buffer in the operation, copy the nonce to it and pad
393 : : * it, so for now check the nonce is 12 bytes, as
394 : : * mbedtls_chachapoly_starts() assumes it can read 12 bytes from the
395 : : * passed in buffer. */
396 : : if (nonce_length != 12) {
397 : : return PSA_ERROR_INVALID_ARGUMENT;
398 : : }
399 : :
400 : : status = mbedtls_to_psa_error(
401 : : mbedtls_chachapoly_starts(&operation->ctx.chachapoly,
402 : : nonce,
403 : : operation->is_encrypt ?
404 : : MBEDTLS_CHACHAPOLY_ENCRYPT :
405 : : MBEDTLS_CHACHAPOLY_DECRYPT));
406 : : } else
407 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
408 : : {
409 : : (void) operation;
410 : : (void) nonce;
411 : : (void) nonce_length;
412 : :
413 : : return PSA_ERROR_NOT_SUPPORTED;
414 : : }
415 : :
416 : 0 : return status;
417 : : }
418 : :
419 : : /* Declare the lengths of the message and additional data for AEAD. */
420 : 0 : psa_status_t mbedtls_psa_aead_set_lengths(
421 : : mbedtls_psa_aead_operation_t *operation,
422 : : size_t ad_length,
423 : : size_t plaintext_length)
424 : : {
425 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
426 [ # # ]: 0 : if (operation->alg == PSA_ALG_CCM) {
427 : 0 : return mbedtls_to_psa_error(
428 : : mbedtls_ccm_set_lengths(&operation->ctx.ccm,
429 : : ad_length,
430 : : plaintext_length,
431 : 0 : operation->tag_length));
432 : :
433 : : }
434 : : #else /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
435 : : (void) operation;
436 : : (void) ad_length;
437 : : (void) plaintext_length;
438 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
439 : :
440 : : return PSA_SUCCESS;
441 : : }
442 : :
443 : : /* Pass additional data to an active multipart AEAD operation. */
444 : 0 : psa_status_t mbedtls_psa_aead_update_ad(
445 : : mbedtls_psa_aead_operation_t *operation,
446 : : const uint8_t *input,
447 : : size_t input_length)
448 : : {
449 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
450 : :
451 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
452 : : if (operation->alg == PSA_ALG_GCM) {
453 : : status = mbedtls_to_psa_error(
454 : : mbedtls_gcm_update_ad(&operation->ctx.gcm, input, input_length));
455 : : } else
456 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
457 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
458 [ # # ]: 0 : if (operation->alg == PSA_ALG_CCM) {
459 : 0 : status = mbedtls_to_psa_error(
460 : : mbedtls_ccm_update_ad(&operation->ctx.ccm, input, input_length));
461 : : } else
462 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
463 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
464 : : if (operation->alg == PSA_ALG_CHACHA20_POLY1305) {
465 : : status = mbedtls_to_psa_error(
466 : : mbedtls_chachapoly_update_aad(&operation->ctx.chachapoly,
467 : : input,
468 : : input_length));
469 : : } else
470 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
471 : : {
472 : : (void) operation;
473 : : (void) input;
474 : : (void) input_length;
475 : :
476 : : return PSA_ERROR_NOT_SUPPORTED;
477 : : }
478 : :
479 : 0 : return status;
480 : : }
481 : :
482 : : /* Encrypt or decrypt a message fragment in an active multipart AEAD
483 : : * operation.*/
484 : 0 : psa_status_t mbedtls_psa_aead_update(
485 : : mbedtls_psa_aead_operation_t *operation,
486 : : const uint8_t *input,
487 : : size_t input_length,
488 : : uint8_t *output,
489 : : size_t output_size,
490 : : size_t *output_length)
491 : : {
492 : 0 : size_t update_output_length;
493 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
494 : :
495 : 0 : update_output_length = input_length;
496 : :
497 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
498 : : if (operation->alg == PSA_ALG_GCM) {
499 : : status = mbedtls_to_psa_error(
500 : : mbedtls_gcm_update(&operation->ctx.gcm,
501 : : input, input_length,
502 : : output, output_size,
503 : : &update_output_length));
504 : : } else
505 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
506 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
507 [ # # ]: 0 : if (operation->alg == PSA_ALG_CCM) {
508 [ # # ]: 0 : if (output_size < input_length) {
509 : : return PSA_ERROR_BUFFER_TOO_SMALL;
510 : : }
511 : :
512 : 0 : status = mbedtls_to_psa_error(
513 : : mbedtls_ccm_update(&operation->ctx.ccm,
514 : : input, input_length,
515 : : output, output_size,
516 : : &update_output_length));
517 : : } else
518 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
519 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
520 : : if (operation->alg == PSA_ALG_CHACHA20_POLY1305) {
521 : : if (output_size < input_length) {
522 : : return PSA_ERROR_BUFFER_TOO_SMALL;
523 : : }
524 : :
525 : : status = mbedtls_to_psa_error(
526 : : mbedtls_chachapoly_update(&operation->ctx.chachapoly,
527 : : input_length,
528 : : input,
529 : : output));
530 : : } else
531 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
532 : : {
533 : : (void) operation;
534 : : (void) input;
535 : : (void) output;
536 : : (void) output_size;
537 : :
538 : : return PSA_ERROR_NOT_SUPPORTED;
539 : : }
540 : :
541 [ # # ]: 0 : if (status == PSA_SUCCESS) {
542 : 0 : *output_length = update_output_length;
543 : : }
544 : :
545 : : return status;
546 : : }
547 : :
548 : : /* Finish encrypting a message in a multipart AEAD operation. */
549 : 0 : psa_status_t mbedtls_psa_aead_finish(
550 : : mbedtls_psa_aead_operation_t *operation,
551 : : uint8_t *ciphertext,
552 : : size_t ciphertext_size,
553 : : size_t *ciphertext_length,
554 : : uint8_t *tag,
555 : : size_t tag_size,
556 : : size_t *tag_length)
557 : : {
558 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
559 : 0 : size_t finish_output_size = 0;
560 : :
561 [ # # ]: 0 : if (tag_size < operation->tag_length) {
562 : : return PSA_ERROR_BUFFER_TOO_SMALL;
563 : : }
564 : :
565 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
566 : : if (operation->alg == PSA_ALG_GCM) {
567 : : status = mbedtls_to_psa_error(
568 : : mbedtls_gcm_finish(&operation->ctx.gcm,
569 : : ciphertext, ciphertext_size, ciphertext_length,
570 : : tag, operation->tag_length));
571 : : } else
572 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
573 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
574 [ # # ]: 0 : if (operation->alg == PSA_ALG_CCM) {
575 : : /* tag must be big enough to store a tag of size passed into set
576 : : * lengths. */
577 : 0 : if (tag_size < operation->tag_length) {
578 : : return PSA_ERROR_BUFFER_TOO_SMALL;
579 : : }
580 : :
581 : 0 : status = mbedtls_to_psa_error(
582 : : mbedtls_ccm_finish(&operation->ctx.ccm,
583 : : tag, operation->tag_length));
584 : : } else
585 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
586 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
587 : : if (operation->alg == PSA_ALG_CHACHA20_POLY1305) {
588 : : /* Belt and braces. Although the above tag_size check should have
589 : : * already done this, if we later start supporting smaller tag sizes
590 : : * for chachapoly, then passing a tag buffer smaller than 16 into here
591 : : * could cause a buffer overflow, so better safe than sorry. */
592 : : if (tag_size < 16) {
593 : : return PSA_ERROR_BUFFER_TOO_SMALL;
594 : : }
595 : :
596 : : status = mbedtls_to_psa_error(
597 : : mbedtls_chachapoly_finish(&operation->ctx.chachapoly,
598 : : tag));
599 : : } else
600 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
601 : : {
602 : : (void) ciphertext;
603 : : (void) ciphertext_size;
604 : : (void) ciphertext_length;
605 : : (void) tag;
606 : : (void) tag_size;
607 : : (void) tag_length;
608 : :
609 : : return PSA_ERROR_NOT_SUPPORTED;
610 : : }
611 : :
612 [ # # ]: 0 : if (status == PSA_SUCCESS) {
613 : : /* This will be zero for all supported algorithms currently, but left
614 : : * here for future support. */
615 : 0 : *ciphertext_length = finish_output_size;
616 : 0 : *tag_length = operation->tag_length;
617 : : }
618 : :
619 : : return status;
620 : : }
621 : :
622 : : /* Abort an AEAD operation */
623 : 34 : psa_status_t mbedtls_psa_aead_abort(
624 : : mbedtls_psa_aead_operation_t *operation)
625 : : {
626 [ + - ]: 34 : switch (operation->alg) {
627 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
628 : 34 : case PSA_ALG_CCM:
629 : 34 : mbedtls_ccm_free(&operation->ctx.ccm);
630 : 34 : break;
631 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
632 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
633 : : case PSA_ALG_GCM:
634 : : mbedtls_gcm_free(&operation->ctx.gcm);
635 : : break;
636 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
637 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
638 : : case PSA_ALG_CHACHA20_POLY1305:
639 : : mbedtls_chachapoly_free(&operation->ctx.chachapoly);
640 : : break;
641 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
642 : : }
643 : :
644 : 34 : operation->is_encrypt = 0;
645 : :
646 : 34 : return PSA_SUCCESS;
647 : : }
648 : :
649 : : #endif /* MBEDTLS_PSA_CRYPTO_C */
|