blob: 21235ff2b84e92a95bc5256010a7ee902aa967cf [file] [log] [blame]
Edison Aic6672fd2018-02-28 15:01:47 +08001// SPDX-License-Identifier: Apache-2.0
Jens Wiklander817466c2018-05-22 13:49:31 +02002/**
3 * \file cipher.c
4 *
5 * \brief Generic cipher wrapper for mbed TLS
6 *
7 * \author Adriaan de Jong <dejong@fox-it.com>
8 *
9 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Jens Wiklander817466c2018-05-22 13:49:31 +020010 *
11 * Licensed under the Apache License, Version 2.0 (the "License"); you may
12 * not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
19 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 *
23 * This file is part of mbed TLS (https://tls.mbed.org)
24 */
25
26#if !defined(MBEDTLS_CONFIG_FILE)
27#include "mbedtls/config.h"
28#else
29#include MBEDTLS_CONFIG_FILE
30#endif
31
32#if defined(MBEDTLS_CIPHER_C)
33
34#include "mbedtls/cipher.h"
35#include "mbedtls/cipher_internal.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010036#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020037#include "mbedtls/error.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020038
39#include <stdlib.h>
40#include <string.h>
41
Jens Wiklander3d3b0592019-03-20 15:30:29 +010042#if defined(MBEDTLS_CHACHAPOLY_C)
43#include "mbedtls/chachapoly.h"
44#endif
45
Jens Wiklander817466c2018-05-22 13:49:31 +020046#if defined(MBEDTLS_GCM_C)
47#include "mbedtls/gcm.h"
48#endif
49
50#if defined(MBEDTLS_CCM_C)
51#include "mbedtls/ccm.h"
52#endif
53
Jens Wiklander3d3b0592019-03-20 15:30:29 +010054#if defined(MBEDTLS_CHACHA20_C)
55#include "mbedtls/chacha20.h"
56#endif
57
Jens Wiklander817466c2018-05-22 13:49:31 +020058#if defined(MBEDTLS_CMAC_C)
59#include "mbedtls/cmac.h"
60#endif
61
Jerome Forissier11fa71b2020-04-20 17:17:56 +020062#if defined(MBEDTLS_USE_PSA_CRYPTO)
63#include "psa/crypto.h"
64#include "mbedtls/psa_util.h"
65#endif /* MBEDTLS_USE_PSA_CRYPTO */
66
67#if defined(MBEDTLS_NIST_KW_C)
68#include "mbedtls/nist_kw.h"
69#endif
70
Jens Wiklander817466c2018-05-22 13:49:31 +020071#if defined(MBEDTLS_PLATFORM_C)
72#include "mbedtls/platform.h"
73#else
74#define mbedtls_calloc calloc
75#define mbedtls_free free
76#endif
77
Jens Wiklander3d3b0592019-03-20 15:30:29 +010078#define CIPHER_VALIDATE_RET( cond ) \
79 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA )
80#define CIPHER_VALIDATE( cond ) \
81 MBEDTLS_INTERNAL_VALIDATE( cond )
Jens Wiklander817466c2018-05-22 13:49:31 +020082
Jens Wiklander3d3b0592019-03-20 15:30:29 +010083#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
84/* Compare the contents of two buffers in constant time.
85 * Returns 0 if the contents are bitwise identical, otherwise returns
86 * a non-zero value.
87 * This is currently only used by GCM and ChaCha20+Poly1305.
88 */
Jerome Forissier11fa71b2020-04-20 17:17:56 +020089static int mbedtls_constant_time_memcmp( const void *v1, const void *v2,
90 size_t len )
Jens Wiklander3d3b0592019-03-20 15:30:29 +010091{
92 const unsigned char *p1 = (const unsigned char*) v1;
93 const unsigned char *p2 = (const unsigned char*) v2;
94 size_t i;
95 unsigned char diff;
96
97 for( diff = 0, i = 0; i < len; i++ )
98 diff |= p1[i] ^ p2[i];
99
100 return( (int)diff );
Jens Wiklander817466c2018-05-22 13:49:31 +0200101}
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100102#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
Jens Wiklander817466c2018-05-22 13:49:31 +0200103
104static int supported_init = 0;
105
106const int *mbedtls_cipher_list( void )
107{
108 const mbedtls_cipher_definition_t *def;
109 int *type;
110
111 if( ! supported_init )
112 {
113 def = mbedtls_cipher_definitions;
114 type = mbedtls_cipher_supported;
115
116 while( def->type != 0 )
117 *type++ = (*def++).type;
118
119 *type = 0;
120
121 supported_init = 1;
122 }
123
124 return( mbedtls_cipher_supported );
125}
126
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200127const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type(
128 const mbedtls_cipher_type_t cipher_type )
Jens Wiklander817466c2018-05-22 13:49:31 +0200129{
130 const mbedtls_cipher_definition_t *def;
131
132 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
133 if( def->type == cipher_type )
134 return( def->info );
135
136 return( NULL );
137}
138
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200139const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string(
140 const char *cipher_name )
Jens Wiklander817466c2018-05-22 13:49:31 +0200141{
142 const mbedtls_cipher_definition_t *def;
143
144 if( NULL == cipher_name )
145 return( NULL );
146
147 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
148 if( ! strcmp( def->info->name, cipher_name ) )
149 return( def->info );
150
151 return( NULL );
152}
153
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200154const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values(
155 const mbedtls_cipher_id_t cipher_id,
156 int key_bitlen,
157 const mbedtls_cipher_mode_t mode )
Jens Wiklander817466c2018-05-22 13:49:31 +0200158{
159 const mbedtls_cipher_definition_t *def;
160
161 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
162 if( def->info->base->cipher == cipher_id &&
163 def->info->key_bitlen == (unsigned) key_bitlen &&
164 def->info->mode == mode )
165 return( def->info );
166
167 return( NULL );
168}
169
170void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx )
171{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100172 CIPHER_VALIDATE( ctx != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200173 memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
174}
175
176void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
177{
178 if( ctx == NULL )
179 return;
180
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200181#if defined(MBEDTLS_USE_PSA_CRYPTO)
182 if( ctx->psa_enabled == 1 )
183 {
184 if( ctx->cipher_ctx != NULL )
185 {
186 mbedtls_cipher_context_psa * const cipher_psa =
187 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
188
189 if( cipher_psa->slot_state == MBEDTLS_CIPHER_PSA_KEY_OWNED )
190 {
191 /* xxx_free() doesn't allow to return failures. */
192 (void) psa_destroy_key( cipher_psa->slot );
193 }
194
195 mbedtls_platform_zeroize( cipher_psa, sizeof( *cipher_psa ) );
196 mbedtls_free( cipher_psa );
197 }
198
199 mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
200 return;
201 }
202#endif /* MBEDTLS_USE_PSA_CRYPTO */
203
Jens Wiklander817466c2018-05-22 13:49:31 +0200204#if defined(MBEDTLS_CMAC_C)
205 if( ctx->cmac_ctx )
206 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100207 mbedtls_platform_zeroize( ctx->cmac_ctx,
208 sizeof( mbedtls_cmac_context_t ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200209 mbedtls_free( ctx->cmac_ctx );
210 }
211#endif
212
213 if( ctx->cipher_ctx )
214 ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx );
215
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100216 mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200217}
218
Edison Ai12484fc2018-12-19 15:36:28 +0800219int mbedtls_cipher_clone( mbedtls_cipher_context_t *dst,
220 const mbedtls_cipher_context_t *src )
221{
222 if( dst == NULL || dst->cipher_info == NULL ||
223 src == NULL || src->cipher_info == NULL)
224 {
225 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
226 }
227
228 dst->cipher_info = src->cipher_info;
229 dst->key_bitlen = src->key_bitlen;
230 dst->operation = src->operation;
231#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
232 dst->add_padding = src->add_padding;
233 dst->get_padding = src->get_padding;
234#endif
235 memcpy( dst->unprocessed_data, src->unprocessed_data, MBEDTLS_MAX_BLOCK_LENGTH );
236 dst->unprocessed_len = src->unprocessed_len;
237 memcpy( dst->iv, src->iv, MBEDTLS_MAX_IV_LENGTH );
238 dst->iv_size = src->iv_size;
239 if( dst->cipher_info->base->ctx_clone_func )
240 dst->cipher_info->base->ctx_clone_func( dst->cipher_ctx, src->cipher_ctx );
241
242#if defined(MBEDTLS_CMAC_C)
243 if( dst->cmac_ctx != NULL && src->cmac_ctx != NULL )
244 memcpy( dst->cmac_ctx, src->cmac_ctx, sizeof( mbedtls_cmac_context_t ) );
245#endif
246 return( 0 );
247}
248
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200249int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
250 const mbedtls_cipher_info_t *cipher_info )
Jens Wiklander817466c2018-05-22 13:49:31 +0200251{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100252 CIPHER_VALIDATE_RET( ctx != NULL );
253 if( cipher_info == NULL )
Jens Wiklander817466c2018-05-22 13:49:31 +0200254 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
255
256 memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
257
258 if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) )
259 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
260
261 ctx->cipher_info = cipher_info;
262
263#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
264 /*
265 * Ignore possible errors caused by a cipher mode that doesn't use padding
266 */
267#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
268 (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 );
269#else
270 (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE );
271#endif
272#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
273
274 return( 0 );
275}
276
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200277#if defined(MBEDTLS_USE_PSA_CRYPTO)
278int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx,
279 const mbedtls_cipher_info_t *cipher_info,
280 size_t taglen )
281{
282 psa_algorithm_t alg;
283 mbedtls_cipher_context_psa *cipher_psa;
284
285 if( NULL == cipher_info || NULL == ctx )
286 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
287
288 /* Check that the underlying cipher mode and cipher type are
289 * supported by the underlying PSA Crypto implementation. */
290 alg = mbedtls_psa_translate_cipher_mode( cipher_info->mode, taglen );
291 if( alg == 0 )
292 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
293 if( mbedtls_psa_translate_cipher_type( cipher_info->type ) == 0 )
294 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
295
296 memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
297
298 cipher_psa = mbedtls_calloc( 1, sizeof(mbedtls_cipher_context_psa ) );
299 if( cipher_psa == NULL )
300 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
301 cipher_psa->alg = alg;
302 ctx->cipher_ctx = cipher_psa;
303 ctx->cipher_info = cipher_info;
304 ctx->psa_enabled = 1;
305 return( 0 );
306}
307#endif /* MBEDTLS_USE_PSA_CRYPTO */
308
Edison Ai12484fc2018-12-19 15:36:28 +0800309int mbedtls_cipher_setup_info( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info )
310{
311 if( NULL == cipher_info || NULL == ctx )
312 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
313
314 ctx->cipher_info = cipher_info;
315 return( 0 );
316}
317
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100318int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
319 const unsigned char *key,
320 int key_bitlen,
321 const mbedtls_operation_t operation )
Jens Wiklander817466c2018-05-22 13:49:31 +0200322{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100323 CIPHER_VALIDATE_RET( ctx != NULL );
324 CIPHER_VALIDATE_RET( key != NULL );
325 CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT ||
326 operation == MBEDTLS_DECRYPT );
327 if( ctx->cipher_info == NULL )
Jens Wiklander817466c2018-05-22 13:49:31 +0200328 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
329
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200330#if defined(MBEDTLS_USE_PSA_CRYPTO)
331 if( ctx->psa_enabled == 1 )
332 {
333 mbedtls_cipher_context_psa * const cipher_psa =
334 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
335
336 size_t const key_bytelen = ( (size_t) key_bitlen + 7 ) / 8;
337
338 psa_status_t status;
339 psa_key_type_t key_type;
340 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
341
342 /* PSA Crypto API only accepts byte-aligned keys. */
343 if( key_bitlen % 8 != 0 )
344 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
345
346 /* Don't allow keys to be set multiple times. */
347 if( cipher_psa->slot_state != MBEDTLS_CIPHER_PSA_KEY_UNSET )
348 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
349
350 key_type = mbedtls_psa_translate_cipher_type(
351 ctx->cipher_info->type );
352 if( key_type == 0 )
353 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
354 psa_set_key_type( &attributes, key_type );
355
356 /* Mbed TLS' cipher layer doesn't enforce the mode of operation
357 * (encrypt vs. decrypt): it is possible to setup a key for encryption
358 * and use it for AEAD decryption. Until tests relying on this
359 * are changed, allow any usage in PSA. */
360 psa_set_key_usage_flags( &attributes,
361 /* mbedtls_psa_translate_cipher_operation( operation ); */
362 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
363 psa_set_key_algorithm( &attributes, cipher_psa->alg );
364
365 status = psa_import_key( &attributes, key, key_bytelen,
366 &cipher_psa->slot );
367 switch( status )
368 {
369 case PSA_SUCCESS:
370 break;
371 case PSA_ERROR_INSUFFICIENT_MEMORY:
372 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
373 case PSA_ERROR_NOT_SUPPORTED:
374 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
375 default:
376 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
377 }
378 /* Indicate that we own the key slot and need to
379 * destroy it in mbedtls_cipher_free(). */
380 cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED;
381
382 ctx->key_bitlen = key_bitlen;
383 ctx->operation = operation;
384 return( 0 );
385 }
386#endif /* MBEDTLS_USE_PSA_CRYPTO */
387
Jens Wiklander817466c2018-05-22 13:49:31 +0200388 if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 &&
389 (int) ctx->cipher_info->key_bitlen != key_bitlen )
390 {
391 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
392 }
393
394 ctx->key_bitlen = key_bitlen;
395 ctx->operation = operation;
396
397 /*
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100398 * For OFB, CFB and CTR mode always use the encryption key schedule
Jens Wiklander817466c2018-05-22 13:49:31 +0200399 */
400 if( MBEDTLS_ENCRYPT == operation ||
401 MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100402 MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
Jens Wiklander817466c2018-05-22 13:49:31 +0200403 MBEDTLS_MODE_CTR == ctx->cipher_info->mode )
404 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100405 return( ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
406 ctx->key_bitlen ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200407 }
408
409 if( MBEDTLS_DECRYPT == operation )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100410 return( ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
411 ctx->key_bitlen ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200412
413 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
414}
415
416int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100417 const unsigned char *iv,
418 size_t iv_len )
Jens Wiklander817466c2018-05-22 13:49:31 +0200419{
420 size_t actual_iv_size;
421
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100422 CIPHER_VALIDATE_RET( ctx != NULL );
423 CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
424 if( ctx->cipher_info == NULL )
Jens Wiklander817466c2018-05-22 13:49:31 +0200425 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200426#if defined(MBEDTLS_USE_PSA_CRYPTO)
427 if( ctx->psa_enabled == 1 )
428 {
429 /* While PSA Crypto has an API for multipart
430 * operations, we currently don't make it
431 * accessible through the cipher layer. */
432 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
433 }
434#endif /* MBEDTLS_USE_PSA_CRYPTO */
Jens Wiklander817466c2018-05-22 13:49:31 +0200435
436 /* avoid buffer overflow in ctx->iv */
437 if( iv_len > MBEDTLS_MAX_IV_LENGTH )
438 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
439
440 if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 )
441 actual_iv_size = iv_len;
442 else
443 {
444 actual_iv_size = ctx->cipher_info->iv_size;
445
446 /* avoid reading past the end of input buffer */
447 if( actual_iv_size > iv_len )
448 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
449 }
450
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100451#if defined(MBEDTLS_CHACHA20_C)
452 if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
453 {
454 if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx,
455 iv,
456 0U ) ) /* Initial counter value */
457 {
458 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
459 }
460 }
461#endif
462
463 if ( actual_iv_size != 0 )
464 {
465 memcpy( ctx->iv, iv, actual_iv_size );
466 ctx->iv_size = actual_iv_size;
467 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200468
469 return( 0 );
470}
471
472int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
473{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100474 CIPHER_VALIDATE_RET( ctx != NULL );
475 if( ctx->cipher_info == NULL )
Jens Wiklander817466c2018-05-22 13:49:31 +0200476 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
477
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200478#if defined(MBEDTLS_USE_PSA_CRYPTO)
479 if( ctx->psa_enabled == 1 )
480 {
481 /* We don't support resetting PSA-based
482 * cipher contexts, yet. */
483 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
484 }
485#endif /* MBEDTLS_USE_PSA_CRYPTO */
486
Jens Wiklander817466c2018-05-22 13:49:31 +0200487 ctx->unprocessed_len = 0;
488
489 return( 0 );
490}
491
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100492#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
Jens Wiklander817466c2018-05-22 13:49:31 +0200493int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
494 const unsigned char *ad, size_t ad_len )
495{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100496 CIPHER_VALIDATE_RET( ctx != NULL );
497 CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
498 if( ctx->cipher_info == NULL )
Jens Wiklander817466c2018-05-22 13:49:31 +0200499 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
500
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200501#if defined(MBEDTLS_USE_PSA_CRYPTO)
502 if( ctx->psa_enabled == 1 )
503 {
504 /* While PSA Crypto has an API for multipart
505 * operations, we currently don't make it
506 * accessible through the cipher layer. */
507 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
508 }
509#endif /* MBEDTLS_USE_PSA_CRYPTO */
510
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100511#if defined(MBEDTLS_GCM_C)
Jens Wiklander817466c2018-05-22 13:49:31 +0200512 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
513 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100514 return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
515 ctx->iv, ctx->iv_size, ad, ad_len ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200516 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100517#endif
518
519#if defined(MBEDTLS_CHACHAPOLY_C)
520 if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
521 {
522 int result;
523 mbedtls_chachapoly_mode_t mode;
524
525 mode = ( ctx->operation == MBEDTLS_ENCRYPT )
526 ? MBEDTLS_CHACHAPOLY_ENCRYPT
527 : MBEDTLS_CHACHAPOLY_DECRYPT;
528
529 result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
530 ctx->iv,
531 mode );
532 if ( result != 0 )
533 return( result );
534
535 return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
536 ad, ad_len ) );
537 }
538#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200539
540 return( 0 );
541}
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100542#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
Jens Wiklander817466c2018-05-22 13:49:31 +0200543
544int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
545 size_t ilen, unsigned char *output, size_t *olen )
546{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200547 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100548 size_t block_size;
Jens Wiklander817466c2018-05-22 13:49:31 +0200549
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100550 CIPHER_VALIDATE_RET( ctx != NULL );
551 CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
552 CIPHER_VALIDATE_RET( output != NULL );
553 CIPHER_VALIDATE_RET( olen != NULL );
554 if( ctx->cipher_info == NULL )
Jens Wiklander817466c2018-05-22 13:49:31 +0200555 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Jens Wiklander817466c2018-05-22 13:49:31 +0200556
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200557#if defined(MBEDTLS_USE_PSA_CRYPTO)
558 if( ctx->psa_enabled == 1 )
559 {
560 /* While PSA Crypto has an API for multipart
561 * operations, we currently don't make it
562 * accessible through the cipher layer. */
563 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
564 }
565#endif /* MBEDTLS_USE_PSA_CRYPTO */
566
Jens Wiklander817466c2018-05-22 13:49:31 +0200567 *olen = 0;
568 block_size = mbedtls_cipher_get_block_size( ctx );
Jerome Forissier5b25c762020-04-07 11:18:49 +0200569 if ( 0 == block_size )
570 {
571 return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
572 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200573
574 if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB )
575 {
576 if( ilen != block_size )
577 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
578
579 *olen = ilen;
580
581 if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx,
582 ctx->operation, input, output ) ) )
583 {
584 return( ret );
585 }
586
587 return( 0 );
588 }
589
590#if defined(MBEDTLS_GCM_C)
591 if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM )
592 {
593 *olen = ilen;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100594 return( mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
595 output ) );
596 }
597#endif
598
599#if defined(MBEDTLS_CHACHAPOLY_C)
600 if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 )
601 {
602 *olen = ilen;
603 return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
604 ilen, input, output ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200605 }
606#endif
607
Jens Wiklander817466c2018-05-22 13:49:31 +0200608 if( input == output &&
609 ( ctx->unprocessed_len != 0 || ilen % block_size ) )
610 {
611 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
612 }
613
614#if defined(MBEDTLS_CIPHER_MODE_CBC)
615 if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC )
616 {
617 size_t copy_len = 0;
618
619 /*
620 * If there is not enough data for a full block, cache it.
621 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100622 if( ( ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding &&
Jens Wiklander817466c2018-05-22 13:49:31 +0200623 ilen <= block_size - ctx->unprocessed_len ) ||
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100624 ( ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding &&
625 ilen < block_size - ctx->unprocessed_len ) ||
Jens Wiklander817466c2018-05-22 13:49:31 +0200626 ( ctx->operation == MBEDTLS_ENCRYPT &&
627 ilen < block_size - ctx->unprocessed_len ) )
628 {
629 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
630 ilen );
631
632 ctx->unprocessed_len += ilen;
633 return( 0 );
634 }
635
636 /*
637 * Process cached data first
638 */
639 if( 0 != ctx->unprocessed_len )
640 {
641 copy_len = block_size - ctx->unprocessed_len;
642
643 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
644 copy_len );
645
646 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
647 ctx->operation, block_size, ctx->iv,
648 ctx->unprocessed_data, output ) ) )
649 {
650 return( ret );
651 }
652
653 *olen += block_size;
654 output += block_size;
655 ctx->unprocessed_len = 0;
656
657 input += copy_len;
658 ilen -= copy_len;
659 }
660
661 /*
662 * Cache final, incomplete block
663 */
664 if( 0 != ilen )
665 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100666 /* Encryption: only cache partial blocks
667 * Decryption w/ padding: always keep at least one whole block
668 * Decryption w/o padding: only cache partial blocks
669 */
Jens Wiklander817466c2018-05-22 13:49:31 +0200670 copy_len = ilen % block_size;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100671 if( copy_len == 0 &&
672 ctx->operation == MBEDTLS_DECRYPT &&
673 NULL != ctx->add_padding)
674 {
Jens Wiklander817466c2018-05-22 13:49:31 +0200675 copy_len = block_size;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100676 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200677
678 memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
679 copy_len );
680
681 ctx->unprocessed_len += copy_len;
682 ilen -= copy_len;
683 }
684
685 /*
686 * Process remaining full blocks
687 */
688 if( ilen )
689 {
690 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
691 ctx->operation, ilen, ctx->iv, input, output ) ) )
692 {
693 return( ret );
694 }
695
696 *olen += ilen;
697 }
698
699 return( 0 );
700 }
701#endif /* MBEDTLS_CIPHER_MODE_CBC */
702
703#if defined(MBEDTLS_CIPHER_MODE_CFB)
704 if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB )
705 {
706 if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx,
707 ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv,
708 input, output ) ) )
709 {
710 return( ret );
711 }
712
713 *olen = ilen;
714
715 return( 0 );
716 }
717#endif /* MBEDTLS_CIPHER_MODE_CFB */
718
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100719#if defined(MBEDTLS_CIPHER_MODE_OFB)
720 if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB )
721 {
722 if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx,
723 ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) )
724 {
725 return( ret );
726 }
727
728 *olen = ilen;
729
730 return( 0 );
731 }
732#endif /* MBEDTLS_CIPHER_MODE_OFB */
733
Jens Wiklander817466c2018-05-22 13:49:31 +0200734#if defined(MBEDTLS_CIPHER_MODE_CTR)
735 if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR )
736 {
737 if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx,
738 ilen, &ctx->unprocessed_len, ctx->iv,
739 ctx->unprocessed_data, input, output ) ) )
740 {
741 return( ret );
742 }
743
744 *olen = ilen;
745
746 return( 0 );
747 }
748#endif /* MBEDTLS_CIPHER_MODE_CTR */
749
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100750#if defined(MBEDTLS_CIPHER_MODE_XTS)
751 if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS )
752 {
753 if( ctx->unprocessed_len > 0 ) {
754 /* We can only process an entire data unit at a time. */
755 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
756 }
757
758 ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx,
759 ctx->operation, ilen, ctx->iv, input, output );
760 if( ret != 0 )
761 {
762 return( ret );
763 }
764
765 *olen = ilen;
766
767 return( 0 );
768 }
769#endif /* MBEDTLS_CIPHER_MODE_XTS */
770
Jens Wiklander817466c2018-05-22 13:49:31 +0200771#if defined(MBEDTLS_CIPHER_MODE_STREAM)
772 if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM )
773 {
774 if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx,
775 ilen, input, output ) ) )
776 {
777 return( ret );
778 }
779
780 *olen = ilen;
781
782 return( 0 );
783 }
784#endif /* MBEDTLS_CIPHER_MODE_STREAM */
785
786 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
787}
788
789#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
790#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
791/*
792 * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len
793 */
794static void add_pkcs_padding( unsigned char *output, size_t output_len,
795 size_t data_len )
796{
797 size_t padding_len = output_len - data_len;
798 unsigned char i;
799
800 for( i = 0; i < padding_len; i++ )
801 output[data_len + i] = (unsigned char) padding_len;
802}
803
804static int get_pkcs_padding( unsigned char *input, size_t input_len,
805 size_t *data_len )
806{
807 size_t i, pad_idx;
808 unsigned char padding_len, bad = 0;
809
810 if( NULL == input || NULL == data_len )
811 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
812
813 padding_len = input[input_len - 1];
814 *data_len = input_len - padding_len;
815
816 /* Avoid logical || since it results in a branch */
817 bad |= padding_len > input_len;
818 bad |= padding_len == 0;
819
820 /* The number of bytes checked must be independent of padding_len,
821 * so pick input_len, which is usually 8 or 16 (one block) */
822 pad_idx = input_len - padding_len;
823 for( i = 0; i < input_len; i++ )
824 bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx );
825
826 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
827}
828#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
829
830#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
831/*
832 * One and zeros padding: fill with 80 00 ... 00
833 */
834static void add_one_and_zeros_padding( unsigned char *output,
835 size_t output_len, size_t data_len )
836{
837 size_t padding_len = output_len - data_len;
838 unsigned char i = 0;
839
840 output[data_len] = 0x80;
841 for( i = 1; i < padding_len; i++ )
842 output[data_len + i] = 0x00;
843}
844
845static int get_one_and_zeros_padding( unsigned char *input, size_t input_len,
846 size_t *data_len )
847{
848 size_t i;
849 unsigned char done = 0, prev_done, bad;
850
851 if( NULL == input || NULL == data_len )
852 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
853
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100854 bad = 0x80;
Jens Wiklander817466c2018-05-22 13:49:31 +0200855 *data_len = 0;
856 for( i = input_len; i > 0; i-- )
857 {
858 prev_done = done;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100859 done |= ( input[i - 1] != 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200860 *data_len |= ( i - 1 ) * ( done != prev_done );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100861 bad ^= input[i - 1] * ( done != prev_done );
Jens Wiklander817466c2018-05-22 13:49:31 +0200862 }
863
864 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
865
866}
867#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
868
869#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
870/*
871 * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length
872 */
873static void add_zeros_and_len_padding( unsigned char *output,
874 size_t output_len, size_t data_len )
875{
876 size_t padding_len = output_len - data_len;
877 unsigned char i = 0;
878
879 for( i = 1; i < padding_len; i++ )
880 output[data_len + i - 1] = 0x00;
881 output[output_len - 1] = (unsigned char) padding_len;
882}
883
884static int get_zeros_and_len_padding( unsigned char *input, size_t input_len,
885 size_t *data_len )
886{
887 size_t i, pad_idx;
888 unsigned char padding_len, bad = 0;
889
890 if( NULL == input || NULL == data_len )
891 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
892
893 padding_len = input[input_len - 1];
894 *data_len = input_len - padding_len;
895
896 /* Avoid logical || since it results in a branch */
897 bad |= padding_len > input_len;
898 bad |= padding_len == 0;
899
900 /* The number of bytes checked must be independent of padding_len */
901 pad_idx = input_len - padding_len;
902 for( i = 0; i < input_len - 1; i++ )
903 bad |= input[i] * ( i >= pad_idx );
904
905 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
906}
907#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
908
909#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
910/*
911 * Zero padding: fill with 00 ... 00
912 */
913static void add_zeros_padding( unsigned char *output,
914 size_t output_len, size_t data_len )
915{
916 size_t i;
917
918 for( i = data_len; i < output_len; i++ )
919 output[i] = 0x00;
920}
921
922static int get_zeros_padding( unsigned char *input, size_t input_len,
923 size_t *data_len )
924{
925 size_t i;
926 unsigned char done = 0, prev_done;
927
928 if( NULL == input || NULL == data_len )
929 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
930
931 *data_len = 0;
932 for( i = input_len; i > 0; i-- )
933 {
934 prev_done = done;
935 done |= ( input[i-1] != 0 );
936 *data_len |= i * ( done != prev_done );
937 }
938
939 return( 0 );
940}
941#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
942
943/*
944 * No padding: don't pad :)
945 *
946 * There is no add_padding function (check for NULL in mbedtls_cipher_finish)
947 * but a trivial get_padding function
948 */
949static int get_no_padding( unsigned char *input, size_t input_len,
950 size_t *data_len )
951{
952 if( NULL == input || NULL == data_len )
953 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
954
955 *data_len = input_len;
956
957 return( 0 );
958}
959#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
960
961int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
962 unsigned char *output, size_t *olen )
963{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100964 CIPHER_VALIDATE_RET( ctx != NULL );
965 CIPHER_VALIDATE_RET( output != NULL );
966 CIPHER_VALIDATE_RET( olen != NULL );
967 if( ctx->cipher_info == NULL )
Jens Wiklander817466c2018-05-22 13:49:31 +0200968 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
969
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200970#if defined(MBEDTLS_USE_PSA_CRYPTO)
971 if( ctx->psa_enabled == 1 )
972 {
973 /* While PSA Crypto has an API for multipart
974 * operations, we currently don't make it
975 * accessible through the cipher layer. */
976 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
977 }
978#endif /* MBEDTLS_USE_PSA_CRYPTO */
979
Jens Wiklander817466c2018-05-22 13:49:31 +0200980 *olen = 0;
981
982 if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100983 MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
Jens Wiklander817466c2018-05-22 13:49:31 +0200984 MBEDTLS_MODE_CTR == ctx->cipher_info->mode ||
985 MBEDTLS_MODE_GCM == ctx->cipher_info->mode ||
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100986 MBEDTLS_MODE_XTS == ctx->cipher_info->mode ||
Jens Wiklander817466c2018-05-22 13:49:31 +0200987 MBEDTLS_MODE_STREAM == ctx->cipher_info->mode )
988 {
989 return( 0 );
990 }
991
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100992 if ( ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) ||
993 ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) )
994 {
995 return( 0 );
996 }
997
Jens Wiklander817466c2018-05-22 13:49:31 +0200998 if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode )
999 {
1000 if( ctx->unprocessed_len != 0 )
1001 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
1002
1003 return( 0 );
1004 }
1005
1006#if defined(MBEDTLS_CIPHER_MODE_CBC)
1007 if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode )
1008 {
1009 int ret = 0;
1010
1011 if( MBEDTLS_ENCRYPT == ctx->operation )
1012 {
1013 /* check for 'no padding' mode */
1014 if( NULL == ctx->add_padding )
1015 {
1016 if( 0 != ctx->unprocessed_len )
1017 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
1018
1019 return( 0 );
1020 }
1021
1022 ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ),
1023 ctx->unprocessed_len );
1024 }
1025 else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len )
1026 {
1027 /*
1028 * For decrypt operations, expect a full block,
1029 * or an empty block if no padding
1030 */
1031 if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len )
1032 return( 0 );
1033
1034 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
1035 }
1036
1037 /* cipher block */
1038 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
1039 ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv,
1040 ctx->unprocessed_data, output ) ) )
1041 {
1042 return( ret );
1043 }
1044
1045 /* Set output size for decryption */
1046 if( MBEDTLS_DECRYPT == ctx->operation )
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001047 return( ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
1048 olen ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001049
1050 /* Set output size for encryption */
1051 *olen = mbedtls_cipher_get_block_size( ctx );
1052 return( 0 );
1053 }
1054#else
1055 ((void) output);
1056#endif /* MBEDTLS_CIPHER_MODE_CBC */
1057
1058 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1059}
1060
1061#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001062int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
1063 mbedtls_cipher_padding_t mode )
Jens Wiklander817466c2018-05-22 13:49:31 +02001064{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001065 CIPHER_VALIDATE_RET( ctx != NULL );
1066
1067 if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
Jens Wiklander817466c2018-05-22 13:49:31 +02001068 {
1069 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1070 }
1071
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001072#if defined(MBEDTLS_USE_PSA_CRYPTO)
1073 if( ctx->psa_enabled == 1 )
1074 {
1075 /* While PSA Crypto knows about CBC padding
1076 * schemes, we currently don't make them
1077 * accessible through the cipher layer. */
1078 if( mode != MBEDTLS_PADDING_NONE )
1079 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1080
1081 return( 0 );
1082 }
1083#endif /* MBEDTLS_USE_PSA_CRYPTO */
1084
Jens Wiklander817466c2018-05-22 13:49:31 +02001085 switch( mode )
1086 {
1087#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
1088 case MBEDTLS_PADDING_PKCS7:
1089 ctx->add_padding = add_pkcs_padding;
1090 ctx->get_padding = get_pkcs_padding;
1091 break;
1092#endif
1093#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
1094 case MBEDTLS_PADDING_ONE_AND_ZEROS:
1095 ctx->add_padding = add_one_and_zeros_padding;
1096 ctx->get_padding = get_one_and_zeros_padding;
1097 break;
1098#endif
1099#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
1100 case MBEDTLS_PADDING_ZEROS_AND_LEN:
1101 ctx->add_padding = add_zeros_and_len_padding;
1102 ctx->get_padding = get_zeros_and_len_padding;
1103 break;
1104#endif
1105#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
1106 case MBEDTLS_PADDING_ZEROS:
1107 ctx->add_padding = add_zeros_padding;
1108 ctx->get_padding = get_zeros_padding;
1109 break;
1110#endif
1111 case MBEDTLS_PADDING_NONE:
1112 ctx->add_padding = NULL;
1113 ctx->get_padding = get_no_padding;
1114 break;
1115
1116 default:
1117 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1118 }
1119
1120 return( 0 );
1121}
1122#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
1123
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001124#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
Jens Wiklander817466c2018-05-22 13:49:31 +02001125int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
1126 unsigned char *tag, size_t tag_len )
1127{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001128 CIPHER_VALIDATE_RET( ctx != NULL );
1129 CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
1130 if( ctx->cipher_info == NULL )
Jens Wiklander817466c2018-05-22 13:49:31 +02001131 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1132
1133 if( MBEDTLS_ENCRYPT != ctx->operation )
1134 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1135
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001136#if defined(MBEDTLS_USE_PSA_CRYPTO)
1137 if( ctx->psa_enabled == 1 )
1138 {
1139 /* While PSA Crypto has an API for multipart
1140 * operations, we currently don't make it
1141 * accessible through the cipher layer. */
1142 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1143 }
1144#endif /* MBEDTLS_USE_PSA_CRYPTO */
1145
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001146#if defined(MBEDTLS_GCM_C)
Jens Wiklander817466c2018-05-22 13:49:31 +02001147 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001148 return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
1149 tag, tag_len ) );
1150#endif
1151
1152#if defined(MBEDTLS_CHACHAPOLY_C)
1153 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
1154 {
1155 /* Don't allow truncated MAC for Poly1305 */
1156 if ( tag_len != 16U )
1157 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1158
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001159 return( mbedtls_chachapoly_finish(
1160 (mbedtls_chachapoly_context*) ctx->cipher_ctx, tag ) );
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001161 }
1162#endif
Jens Wiklander817466c2018-05-22 13:49:31 +02001163
1164 return( 0 );
1165}
1166
1167int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
1168 const unsigned char *tag, size_t tag_len )
1169{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001170 unsigned char check_tag[16];
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001171 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001172
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001173 CIPHER_VALIDATE_RET( ctx != NULL );
1174 CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
1175 if( ctx->cipher_info == NULL )
1176 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1177
1178 if( MBEDTLS_DECRYPT != ctx->operation )
Jens Wiklander817466c2018-05-22 13:49:31 +02001179 {
1180 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1181 }
1182
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001183#if defined(MBEDTLS_USE_PSA_CRYPTO)
1184 if( ctx->psa_enabled == 1 )
1185 {
1186 /* While PSA Crypto has an API for multipart
1187 * operations, we currently don't make it
1188 * accessible through the cipher layer. */
1189 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1190 }
1191#endif /* MBEDTLS_USE_PSA_CRYPTO */
1192
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001193#if defined(MBEDTLS_GCM_C)
Jens Wiklander817466c2018-05-22 13:49:31 +02001194 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
1195 {
Jens Wiklander817466c2018-05-22 13:49:31 +02001196 if( tag_len > sizeof( check_tag ) )
1197 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1198
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001199 if( 0 != ( ret = mbedtls_gcm_finish(
1200 (mbedtls_gcm_context *) ctx->cipher_ctx,
1201 check_tag, tag_len ) ) )
Jens Wiklander817466c2018-05-22 13:49:31 +02001202 {
1203 return( ret );
1204 }
1205
1206 /* Check the tag in "constant-time" */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001207 if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +02001208 return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
1209
1210 return( 0 );
1211 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001212#endif /* MBEDTLS_GCM_C */
1213
1214#if defined(MBEDTLS_CHACHAPOLY_C)
1215 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
1216 {
1217 /* Don't allow truncated MAC for Poly1305 */
1218 if ( tag_len != sizeof( check_tag ) )
1219 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1220
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001221 ret = mbedtls_chachapoly_finish(
1222 (mbedtls_chachapoly_context*) ctx->cipher_ctx, check_tag );
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001223 if ( ret != 0 )
1224 {
1225 return( ret );
1226 }
1227
1228 /* Check the tag in "constant-time" */
1229 if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
1230 return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
1231
1232 return( 0 );
1233 }
1234#endif /* MBEDTLS_CHACHAPOLY_C */
Jens Wiklander817466c2018-05-22 13:49:31 +02001235
1236 return( 0 );
1237}
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001238#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
Jens Wiklander817466c2018-05-22 13:49:31 +02001239
1240/*
1241 * Packet-oriented wrapper for non-AEAD modes
1242 */
1243int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
1244 const unsigned char *iv, size_t iv_len,
1245 const unsigned char *input, size_t ilen,
1246 unsigned char *output, size_t *olen )
1247{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001248 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001249 size_t finish_olen;
1250
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001251 CIPHER_VALIDATE_RET( ctx != NULL );
1252 CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
1253 CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
1254 CIPHER_VALIDATE_RET( output != NULL );
1255 CIPHER_VALIDATE_RET( olen != NULL );
1256
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001257#if defined(MBEDTLS_USE_PSA_CRYPTO)
1258 if( ctx->psa_enabled == 1 )
1259 {
1260 /* As in the non-PSA case, we don't check that
1261 * a key has been set. If not, the key slot will
1262 * still be in its default state of 0, which is
1263 * guaranteed to be invalid, hence the PSA-call
1264 * below will gracefully fail. */
1265 mbedtls_cipher_context_psa * const cipher_psa =
1266 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
1267
1268 psa_status_t status;
1269 psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT;
1270 size_t part_len;
1271
1272 if( ctx->operation == MBEDTLS_DECRYPT )
1273 {
1274 status = psa_cipher_decrypt_setup( &cipher_op,
1275 cipher_psa->slot,
1276 cipher_psa->alg );
1277 }
1278 else if( ctx->operation == MBEDTLS_ENCRYPT )
1279 {
1280 status = psa_cipher_encrypt_setup( &cipher_op,
1281 cipher_psa->slot,
1282 cipher_psa->alg );
1283 }
1284 else
1285 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1286
1287 /* In the following, we can immediately return on an error,
1288 * because the PSA Crypto API guarantees that cipher operations
1289 * are terminated by unsuccessful calls to psa_cipher_update(),
1290 * and by any call to psa_cipher_finish(). */
1291 if( status != PSA_SUCCESS )
1292 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
1293
1294 status = psa_cipher_set_iv( &cipher_op, iv, iv_len );
1295 if( status != PSA_SUCCESS )
1296 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
1297
1298 status = psa_cipher_update( &cipher_op,
1299 input, ilen,
1300 output, ilen, olen );
1301 if( status != PSA_SUCCESS )
1302 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
1303
1304 status = psa_cipher_finish( &cipher_op,
1305 output + *olen, ilen - *olen,
1306 &part_len );
1307 if( status != PSA_SUCCESS )
1308 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
1309
1310 *olen += part_len;
1311 return( 0 );
1312 }
1313#endif /* MBEDTLS_USE_PSA_CRYPTO */
1314
Jens Wiklander817466c2018-05-22 13:49:31 +02001315 if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
1316 return( ret );
1317
1318 if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 )
1319 return( ret );
1320
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001321 if( ( ret = mbedtls_cipher_update( ctx, input, ilen,
1322 output, olen ) ) != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +02001323 return( ret );
1324
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001325 if( ( ret = mbedtls_cipher_finish( ctx, output + *olen,
1326 &finish_olen ) ) != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +02001327 return( ret );
1328
1329 *olen += finish_olen;
1330
1331 return( 0 );
1332}
1333
1334#if defined(MBEDTLS_CIPHER_MODE_AEAD)
1335/*
1336 * Packet-oriented encryption for AEAD modes
1337 */
1338int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
1339 const unsigned char *iv, size_t iv_len,
1340 const unsigned char *ad, size_t ad_len,
1341 const unsigned char *input, size_t ilen,
1342 unsigned char *output, size_t *olen,
1343 unsigned char *tag, size_t tag_len )
1344{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001345 CIPHER_VALIDATE_RET( ctx != NULL );
1346 CIPHER_VALIDATE_RET( iv != NULL );
1347 CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
1348 CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
1349 CIPHER_VALIDATE_RET( output != NULL );
1350 CIPHER_VALIDATE_RET( olen != NULL );
1351 CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
1352
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001353#if defined(MBEDTLS_USE_PSA_CRYPTO)
1354 if( ctx->psa_enabled == 1 )
1355 {
1356 /* As in the non-PSA case, we don't check that
1357 * a key has been set. If not, the key slot will
1358 * still be in its default state of 0, which is
1359 * guaranteed to be invalid, hence the PSA-call
1360 * below will gracefully fail. */
1361 mbedtls_cipher_context_psa * const cipher_psa =
1362 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
1363
1364 psa_status_t status;
1365
1366 /* PSA Crypto API always writes the authentication tag
1367 * at the end of the encrypted message. */
1368 if( tag != output + ilen )
1369 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1370
1371 status = psa_aead_encrypt( cipher_psa->slot,
1372 cipher_psa->alg,
1373 iv, iv_len,
1374 ad, ad_len,
1375 input, ilen,
1376 output, ilen + tag_len, olen );
1377 if( status != PSA_SUCCESS )
1378 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
1379
1380 *olen -= tag_len;
1381 return( 0 );
1382 }
1383#endif /* MBEDTLS_USE_PSA_CRYPTO */
1384
Jens Wiklander817466c2018-05-22 13:49:31 +02001385#if defined(MBEDTLS_GCM_C)
1386 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
1387 {
1388 *olen = ilen;
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001389 return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT,
1390 ilen, iv, iv_len, ad, ad_len,
1391 input, output, tag_len, tag ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001392 }
1393#endif /* MBEDTLS_GCM_C */
1394#if defined(MBEDTLS_CCM_C)
1395 if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
1396 {
1397 *olen = ilen;
1398 return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen,
1399 iv, iv_len, ad, ad_len, input, output,
1400 tag, tag_len ) );
1401 }
1402#endif /* MBEDTLS_CCM_C */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001403#if defined(MBEDTLS_CHACHAPOLY_C)
1404 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
1405 {
1406 /* ChachaPoly has fixed length nonce and MAC (tag) */
1407 if ( ( iv_len != ctx->cipher_info->iv_size ) ||
1408 ( tag_len != 16U ) )
1409 {
1410 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1411 }
1412
1413 *olen = ilen;
1414 return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx,
1415 ilen, iv, ad, ad_len, input, output, tag ) );
1416 }
1417#endif /* MBEDTLS_CHACHAPOLY_C */
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001418#if defined(MBEDTLS_NIST_KW_C)
1419 if( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
1420 MBEDTLS_MODE_KWP == ctx->cipher_info->mode )
1421 {
1422 mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
1423 MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
1424
1425 /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */
1426 if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
1427 {
1428 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1429 }
1430
1431 return( mbedtls_nist_kw_wrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) );
1432 }
1433#endif /* MBEDTLS_NIST_KW_C */
Jens Wiklander817466c2018-05-22 13:49:31 +02001434
1435 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1436}
1437
1438/*
1439 * Packet-oriented decryption for AEAD modes
1440 */
1441int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
1442 const unsigned char *iv, size_t iv_len,
1443 const unsigned char *ad, size_t ad_len,
1444 const unsigned char *input, size_t ilen,
1445 unsigned char *output, size_t *olen,
1446 const unsigned char *tag, size_t tag_len )
1447{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001448 CIPHER_VALIDATE_RET( ctx != NULL );
1449 CIPHER_VALIDATE_RET( iv != NULL );
1450 CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
1451 CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
1452 CIPHER_VALIDATE_RET( output != NULL );
1453 CIPHER_VALIDATE_RET( olen != NULL );
1454 CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
1455
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001456#if defined(MBEDTLS_USE_PSA_CRYPTO)
1457 if( ctx->psa_enabled == 1 )
1458 {
1459 /* As in the non-PSA case, we don't check that
1460 * a key has been set. If not, the key slot will
1461 * still be in its default state of 0, which is
1462 * guaranteed to be invalid, hence the PSA-call
1463 * below will gracefully fail. */
1464 mbedtls_cipher_context_psa * const cipher_psa =
1465 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
1466
1467 psa_status_t status;
1468
1469 /* PSA Crypto API always writes the authentication tag
1470 * at the end of the encrypted message. */
1471 if( tag != input + ilen )
1472 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1473
1474 status = psa_aead_decrypt( cipher_psa->slot,
1475 cipher_psa->alg,
1476 iv, iv_len,
1477 ad, ad_len,
1478 input, ilen + tag_len,
1479 output, ilen, olen );
1480 if( status == PSA_ERROR_INVALID_SIGNATURE )
1481 return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
1482 else if( status != PSA_SUCCESS )
1483 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
1484
1485 return( 0 );
1486 }
1487#endif /* MBEDTLS_USE_PSA_CRYPTO */
1488
Jens Wiklander817466c2018-05-22 13:49:31 +02001489#if defined(MBEDTLS_GCM_C)
1490 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
1491 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001492 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001493
1494 *olen = ilen;
1495 ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen,
1496 iv, iv_len, ad, ad_len,
1497 tag, tag_len, input, output );
1498
1499 if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED )
1500 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
1501
1502 return( ret );
1503 }
1504#endif /* MBEDTLS_GCM_C */
1505#if defined(MBEDTLS_CCM_C)
1506 if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
1507 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001508 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001509
1510 *olen = ilen;
1511 ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen,
1512 iv, iv_len, ad, ad_len,
1513 input, output, tag, tag_len );
1514
1515 if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED )
1516 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
1517
1518 return( ret );
1519 }
1520#endif /* MBEDTLS_CCM_C */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001521#if defined(MBEDTLS_CHACHAPOLY_C)
1522 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
1523 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001524 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001525
1526 /* ChachaPoly has fixed length nonce and MAC (tag) */
1527 if ( ( iv_len != ctx->cipher_info->iv_size ) ||
1528 ( tag_len != 16U ) )
1529 {
1530 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1531 }
1532
1533 *olen = ilen;
1534 ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen,
1535 iv, ad, ad_len, tag, input, output );
1536
1537 if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED )
1538 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
1539
1540 return( ret );
1541 }
1542#endif /* MBEDTLS_CHACHAPOLY_C */
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001543#if defined(MBEDTLS_NIST_KW_C)
1544 if( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
1545 MBEDTLS_MODE_KWP == ctx->cipher_info->mode )
1546 {
1547 mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
1548 MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
1549
1550 /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */
1551 if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
1552 {
1553 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1554 }
1555
1556 return( mbedtls_nist_kw_unwrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) );
1557 }
1558#endif /* MBEDTLS_NIST_KW_C */
Jens Wiklander817466c2018-05-22 13:49:31 +02001559
1560 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1561}
1562#endif /* MBEDTLS_CIPHER_MODE_AEAD */
1563
1564#endif /* MBEDTLS_CIPHER_C */