blob: 69079aae7a4b47682e88136c5b05ba9babc14f93 [file] [log] [blame]
Paul Bakker8123e9d2011-01-06 15:37:30 +00001/**
2 * \file cipher.c
Paul Bakker7dc4c442014-02-01 22:50:26 +01003 *
Manuel Pégourié-Gonnardb4fe3cb2015-01-22 16:11:05 +00004 * \brief Generic cipher wrapper for mbed TLS
Paul Bakker8123e9d2011-01-06 15:37:30 +00005 *
6 * \author Adriaan de Jong <dejong@fox-it.com>
7 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02008 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02009 * SPDX-License-Identifier: Apache-2.0
10 *
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.
Paul Bakker8123e9d2011-01-06 15:37:30 +000022 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000023 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker8123e9d2011-01-06 15:37:30 +000024 */
25
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020026#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000027#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020028#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020029#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#endif
Paul Bakker8123e9d2011-01-06 15:37:30 +000031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if defined(MBEDTLS_CIPHER_C)
Paul Bakker8123e9d2011-01-06 15:37:30 +000033
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000034#include "mbedtls/cipher.h"
Manuel Pégourié-Gonnard50518f42015-05-26 11:04:15 +020035#include "mbedtls/cipher_internal.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050036#include "mbedtls/platform_util.h"
Paul Bakker8123e9d2011-01-06 15:37:30 +000037
Rich Evans00ab4702015-02-06 13:43:58 +000038#include <stdlib.h>
39#include <string.h>
40
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +020041#if defined(MBEDTLS_CHACHAPOLY_C)
42#include "mbedtls/chachapoly.h"
Daniel King8fe47012016-05-17 20:33:28 -030043#endif
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_GCM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/gcm.h"
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +020047#endif
48
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#if defined(MBEDTLS_CCM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000050#include "mbedtls/ccm.h"
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +020051#endif
52
Daniel Kingbd920622016-05-15 19:56:20 -030053#if defined(MBEDTLS_CHACHA20_C)
54#include "mbedtls/chacha20.h"
55#endif
56
Simon Butcher327398a2016-10-05 14:09:11 +010057#if defined(MBEDTLS_CMAC_C)
58#include "mbedtls/cmac.h"
59#endif
60
Hanno Becker4ccfc402018-11-09 16:10:57 +000061#if defined(MBEDTLS_USE_PSA_CRYPTO)
62#include "psa/crypto.h"
Hanno Beckeredda8b82018-11-12 11:59:30 +000063#include "mbedtls/psa_util.h"
Hanno Becker4ccfc402018-11-09 16:10:57 +000064#endif /* MBEDTLS_USE_PSA_CRYPTO */
65
Jack Lloydffdf2882019-03-07 17:00:32 -050066#if defined(MBEDTLS_NIST_KW_C)
67#include "mbedtls/nist_kw.h"
68#endif
69
Simon Butcher327398a2016-10-05 14:09:11 +010070#if defined(MBEDTLS_PLATFORM_C)
71#include "mbedtls/platform.h"
72#else
73#define mbedtls_calloc calloc
74#define mbedtls_free free
75#endif
76
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050077#define CIPHER_VALIDATE_RET( cond ) \
78 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA )
79#define CIPHER_VALIDATE( cond ) \
80 MBEDTLS_INTERNAL_VALIDATE( cond )
81
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +020082#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
Daniel King8fe47012016-05-17 20:33:28 -030083/* Compare the contents of two buffers in constant time.
84 * Returns 0 if the contents are bitwise identical, otherwise returns
Daniel King16b04ce2016-05-18 13:38:22 -030085 * a non-zero value.
86 * This is currently only used by GCM and ChaCha20+Poly1305.
87 */
Hanno Becker18597cd2018-11-09 16:36:33 +000088static int mbedtls_constant_time_memcmp( const void *v1, const void *v2,
89 size_t len )
Daniel King8fe47012016-05-17 20:33:28 -030090{
91 const unsigned char *p1 = (const unsigned char*) v1;
92 const unsigned char *p2 = (const unsigned char*) v2;
93 size_t i;
94 unsigned char diff;
95
96 for( diff = 0, i = 0; i < len; i++ )
97 diff |= p1[i] ^ p2[i];
98
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050099 return( (int)diff );
Daniel King8fe47012016-05-17 20:33:28 -0300100}
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200101#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
Daniel King8fe47012016-05-17 20:33:28 -0300102
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +0200103static int supported_init = 0;
Paul Bakker72f62662011-01-16 21:27:44 +0000104
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200105const int *mbedtls_cipher_list( void )
Paul Bakker72f62662011-01-16 21:27:44 +0000106{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200107 const mbedtls_cipher_definition_t *def;
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +0200108 int *type;
109
110 if( ! supported_init )
111 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200112 def = mbedtls_cipher_definitions;
113 type = mbedtls_cipher_supported;
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +0200114
115 while( def->type != 0 )
116 *type++ = (*def++).type;
117
118 *type = 0;
119
120 supported_init = 1;
121 }
122
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200123 return( mbedtls_cipher_supported );
Paul Bakker72f62662011-01-16 21:27:44 +0000124}
125
Hanno Becker18597cd2018-11-09 16:36:33 +0000126const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type(
127 const mbedtls_cipher_type_t cipher_type )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000128{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200129 const mbedtls_cipher_definition_t *def;
Paul Bakker5e0efa72013-09-08 23:04:04 +0200130
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200131 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +0200132 if( def->type == cipher_type )
133 return( def->info );
Paul Bakker343a8702011-06-09 14:27:58 +0000134
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200135 return( NULL );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000136}
137
Hanno Becker18597cd2018-11-09 16:36:33 +0000138const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string(
139 const char *cipher_name )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000140{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200141 const mbedtls_cipher_definition_t *def;
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +0200142
Paul Bakker8123e9d2011-01-06 15:37:30 +0000143 if( NULL == cipher_name )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200144 return( NULL );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000145
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200146 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200147 if( ! strcmp( def->info->name, cipher_name ) )
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +0200148 return( def->info );
Paul Bakkerfab5c822012-02-06 16:45:10 +0000149
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200150 return( NULL );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000151}
152
Hanno Becker18597cd2018-11-09 16:36:33 +0000153const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values(
154 const mbedtls_cipher_id_t cipher_id,
155 int key_bitlen,
156 const mbedtls_cipher_mode_t mode )
Paul Bakkerf46b6952013-09-09 00:08:26 +0200157{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200158 const mbedtls_cipher_definition_t *def;
Paul Bakkerf46b6952013-09-09 00:08:26 +0200159
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200160 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +0200161 if( def->info->base->cipher == cipher_id &&
Manuel Pégourié-Gonnard898e0aa2015-06-18 15:28:12 +0200162 def->info->key_bitlen == (unsigned) key_bitlen &&
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +0200163 def->info->mode == mode )
164 return( def->info );
Paul Bakkerf46b6952013-09-09 00:08:26 +0200165
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200166 return( NULL );
Paul Bakkerf46b6952013-09-09 00:08:26 +0200167}
168
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200169void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx )
Paul Bakker84bbeb52014-07-01 14:53:22 +0200170{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500171 CIPHER_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200172 memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
Paul Bakker84bbeb52014-07-01 14:53:22 +0200173}
174
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200175void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
Paul Bakker84bbeb52014-07-01 14:53:22 +0200176{
177 if( ctx == NULL )
178 return;
179
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000180#if defined(MBEDTLS_USE_PSA_CRYPTO)
181 if( ctx->psa_enabled == 1 )
182 {
Hanno Becker6118e432018-11-09 16:47:20 +0000183 if( ctx->cipher_ctx != NULL )
184 {
185 mbedtls_cipher_context_psa * const cipher_psa =
186 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
187
Hanno Becker19086552018-11-17 22:11:16 +0000188 if( cipher_psa->slot_state == MBEDTLS_CIPHER_PSA_KEY_OWNED )
Hanno Becker6118e432018-11-09 16:47:20 +0000189 {
Hanno Beckeredda8b82018-11-12 11:59:30 +0000190 /* xxx_free() doesn't allow to return failures. */
191 (void) psa_destroy_key( cipher_psa->slot );
Hanno Becker6118e432018-11-09 16:47:20 +0000192 }
193
194 mbedtls_platform_zeroize( cipher_psa, sizeof( *cipher_psa ) );
195 mbedtls_free( cipher_psa );
196 }
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000197
198 mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
199 return;
200 }
201#endif /* MBEDTLS_USE_PSA_CRYPTO */
202
Simon Butcher327398a2016-10-05 14:09:11 +0100203#if defined(MBEDTLS_CMAC_C)
204 if( ctx->cmac_ctx )
205 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500206 mbedtls_platform_zeroize( ctx->cmac_ctx,
207 sizeof( mbedtls_cmac_context_t ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100208 mbedtls_free( ctx->cmac_ctx );
209 }
210#endif
211
Paul Bakker84bbeb52014-07-01 14:53:22 +0200212 if( ctx->cipher_ctx )
213 ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx );
214
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500215 mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
Paul Bakker84bbeb52014-07-01 14:53:22 +0200216}
217
Hanno Becker18597cd2018-11-09 16:36:33 +0000218int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
219 const mbedtls_cipher_info_t *cipher_info )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000220{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500221 CIPHER_VALIDATE_RET( ctx != NULL );
222 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200223 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000224
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200225 memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000226
Paul Bakker343a8702011-06-09 14:27:58 +0000227 if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200228 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000229
230 ctx->cipher_info = cipher_info;
231
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200232#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +0200233 /*
234 * Ignore possible errors caused by a cipher mode that doesn't use padding
235 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200236#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
237 (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 );
Paul Bakker48e93c82013-08-14 12:21:18 +0200238#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200239 (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE );
Paul Bakker48e93c82013-08-14 12:21:18 +0200240#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200241#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +0200242
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200243 return( 0 );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000244}
245
Hanno Becker4ccfc402018-11-09 16:10:57 +0000246#if defined(MBEDTLS_USE_PSA_CRYPTO)
247int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx,
Hanno Becker20120b32018-11-12 16:26:27 +0000248 const mbedtls_cipher_info_t *cipher_info,
249 size_t taglen )
Hanno Becker4ccfc402018-11-09 16:10:57 +0000250{
Hanno Beckeredda8b82018-11-12 11:59:30 +0000251 psa_algorithm_t alg;
252 mbedtls_cipher_context_psa *cipher_psa;
253
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000254 if( NULL == cipher_info || NULL == ctx )
255 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
256
Hanno Becker4ee7e762018-11-17 22:00:38 +0000257 /* Check that the underlying cipher mode and cipher type are
258 * supported by the underlying PSA Crypto implementation. */
Hanno Becker20120b32018-11-12 16:26:27 +0000259 alg = mbedtls_psa_translate_cipher_mode( cipher_info->mode, taglen );
Hanno Becker4ee7e762018-11-17 22:00:38 +0000260 if( alg == 0 )
261 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
262 if( mbedtls_psa_translate_cipher_type( cipher_info->type ) == 0 )
Hanno Beckeredda8b82018-11-12 11:59:30 +0000263 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Hanno Becker6118e432018-11-09 16:47:20 +0000264
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000265 memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
266
Hanno Beckeredda8b82018-11-12 11:59:30 +0000267 cipher_psa = mbedtls_calloc( 1, sizeof(mbedtls_cipher_context_psa ) );
268 if( cipher_psa == NULL )
269 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
270 cipher_psa->alg = alg;
271 ctx->cipher_ctx = cipher_psa;
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000272 ctx->cipher_info = cipher_info;
273 ctx->psa_enabled = 1;
274 return( 0 );
Hanno Becker4ccfc402018-11-09 16:10:57 +0000275}
276#endif /* MBEDTLS_USE_PSA_CRYPTO */
277
Hanno Becker18597cd2018-11-09 16:36:33 +0000278int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
279 const unsigned char *key,
280 int key_bitlen,
281 const mbedtls_operation_t operation )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000282{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500283 CIPHER_VALIDATE_RET( ctx != NULL );
284 CIPHER_VALIDATE_RET( key != NULL );
285 CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT ||
Krzysztof Stachowiake0215d72018-12-17 10:20:30 +0100286 operation == MBEDTLS_DECRYPT );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500287 if( ctx->cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200288 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000289
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000290#if defined(MBEDTLS_USE_PSA_CRYPTO)
291 if( ctx->psa_enabled == 1 )
292 {
Hanno Beckeredda8b82018-11-12 11:59:30 +0000293 mbedtls_cipher_context_psa * const cipher_psa =
294 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
295
296 size_t const key_bytelen = ( (size_t) key_bitlen + 7 ) / 8;
297
298 psa_status_t status;
299 psa_key_type_t key_type;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200300 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Hanno Beckeredda8b82018-11-12 11:59:30 +0000301
302 /* PSA Crypto API only accepts byte-aligned keys. */
303 if( key_bitlen % 8 != 0 )
304 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
305
306 /* Don't allow keys to be set multiple times. */
Hanno Becker19086552018-11-17 22:11:16 +0000307 if( cipher_psa->slot_state != MBEDTLS_CIPHER_PSA_KEY_UNSET )
Hanno Beckeredda8b82018-11-12 11:59:30 +0000308 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
309
Andrzej Kurekc7509322019-01-08 09:36:01 -0500310 key_type = mbedtls_psa_translate_cipher_type(
311 ctx->cipher_info->type );
312 if( key_type == 0 )
313 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Gilles Peskined2d45c12019-05-27 14:53:13 +0200314 psa_set_key_type( &attributes, key_type );
Hanno Beckera395d8f2018-11-12 13:33:16 +0000315
316 /* Mbed TLS' cipher layer doesn't enforce the mode of operation
Andrzej Kurekf410a5c2019-01-15 03:33:35 -0500317 * (encrypt vs. decrypt): it is possible to setup a key for encryption
318 * and use it for AEAD decryption. Until tests relying on this
319 * are changed, allow any usage in PSA. */
Gilles Peskined2d45c12019-05-27 14:53:13 +0200320 psa_set_key_usage_flags( &attributes,
321 /* mbedtls_psa_translate_cipher_operation( operation ); */
322 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
323 psa_set_key_algorithm( &attributes, cipher_psa->alg );
Hanno Beckeredda8b82018-11-12 11:59:30 +0000324
Gilles Peskined2d45c12019-05-27 14:53:13 +0200325 status = psa_import_key( &attributes, key, key_bytelen,
326 &cipher_psa->slot );
327 switch( status )
328 {
329 case PSA_SUCCESS:
330 break;
331 case PSA_ERROR_INSUFFICIENT_MEMORY:
332 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
333 case PSA_ERROR_NOT_SUPPORTED:
334 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
335 default:
336 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
337 }
338 /* Indicate that we own the key slot and need to
339 * destroy it in mbedtls_cipher_free(). */
340 cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED;
Hanno Beckeredda8b82018-11-12 11:59:30 +0000341
342 ctx->key_bitlen = key_bitlen;
343 ctx->operation = operation;
344 return( 0 );
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000345 }
346#endif /* MBEDTLS_USE_PSA_CRYPTO */
347
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200348 if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 &&
Manuel Pégourié-Gonnard898e0aa2015-06-18 15:28:12 +0200349 (int) ctx->cipher_info->key_bitlen != key_bitlen )
Manuel Pégourié-Gonnard398c57b2014-06-23 12:10:59 +0200350 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200351 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard398c57b2014-06-23 12:10:59 +0200352 }
Manuel Pégourié-Gonnarddd0f57f2013-09-16 11:47:43 +0200353
Manuel Pégourié-Gonnard898e0aa2015-06-18 15:28:12 +0200354 ctx->key_bitlen = key_bitlen;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000355 ctx->operation = operation;
356
Paul Bakker343a8702011-06-09 14:27:58 +0000357 /*
Simon Butcher8c0fd1e2018-04-22 22:58:07 +0100358 * For OFB, CFB and CTR mode always use the encryption key schedule
Paul Bakker343a8702011-06-09 14:27:58 +0000359 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360 if( MBEDTLS_ENCRYPT == operation ||
361 MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
Simon Butcher8c0fd1e2018-04-22 22:58:07 +0100362 MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200363 MBEDTLS_MODE_CTR == ctx->cipher_info->mode )
Paul Bakker343a8702011-06-09 14:27:58 +0000364 {
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500365 return( ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
366 ctx->key_bitlen ) );
Paul Bakker343a8702011-06-09 14:27:58 +0000367 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000368
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200369 if( MBEDTLS_DECRYPT == operation )
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500370 return( ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
371 ctx->key_bitlen ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000372
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200373 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000374}
375
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200376int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500377 const unsigned char *iv,
378 size_t iv_len )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000379{
Manuel Pégourié-Gonnarda235b5b2013-09-03 13:25:52 +0200380 size_t actual_iv_size;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000381
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500382 CIPHER_VALIDATE_RET( ctx != NULL );
383 CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
384 if( ctx->cipher_info == NULL )
385 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000386#if defined(MBEDTLS_USE_PSA_CRYPTO)
387 if( ctx->psa_enabled == 1 )
388 {
389 /* While PSA Crypto has an API for multipart
390 * operations, we currently don't make it
391 * accessible through the cipher layer. */
392 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
393 }
394#endif /* MBEDTLS_USE_PSA_CRYPTO */
395
Manuel Pégourié-Gonnarde0dca4a2013-10-24 16:54:25 +0200396 /* avoid buffer overflow in ctx->iv */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397 if( iv_len > MBEDTLS_MAX_IV_LENGTH )
398 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnarde0dca4a2013-10-24 16:54:25 +0200399
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200400 if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 )
Manuel Pégourié-Gonnarda235b5b2013-09-03 13:25:52 +0200401 actual_iv_size = iv_len;
402 else
Manuel Pégourié-Gonnarde0dca4a2013-10-24 16:54:25 +0200403 {
Manuel Pégourié-Gonnarda235b5b2013-09-03 13:25:52 +0200404 actual_iv_size = ctx->cipher_info->iv_size;
Manuel Pégourié-Gonnard9c853b92013-09-03 13:04:44 +0200405
Manuel Pégourié-Gonnarde0dca4a2013-10-24 16:54:25 +0200406 /* avoid reading past the end of input buffer */
407 if( actual_iv_size > iv_len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200408 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde0dca4a2013-10-24 16:54:25 +0200409 }
410
Daniel Kingbd920622016-05-15 19:56:20 -0300411#if defined(MBEDTLS_CHACHA20_C)
412 if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
413 {
414 if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx,
415 iv,
416 0U ) ) /* Initial counter value */
417 {
418 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
419 }
420 }
421#endif
422
Ron Eldorbb4bbbb2017-10-01 17:04:54 +0300423 if ( actual_iv_size != 0 )
Ron Eldor4e64e0b2017-09-25 18:22:32 +0300424 {
425 memcpy( ctx->iv, iv, actual_iv_size );
426 ctx->iv_size = actual_iv_size;
427 }
Manuel Pégourié-Gonnard9c853b92013-09-03 13:04:44 +0200428
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200429 return( 0 );
Manuel Pégourié-Gonnard9c853b92013-09-03 13:04:44 +0200430}
431
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
Manuel Pégourié-Gonnard9c853b92013-09-03 13:04:44 +0200433{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500434 CIPHER_VALIDATE_RET( ctx != NULL );
435 if( ctx->cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200436 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard2adc40c2013-09-03 13:54:12 +0200437
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000438#if defined(MBEDTLS_USE_PSA_CRYPTO)
439 if( ctx->psa_enabled == 1 )
440 {
441 /* We don't support resetting PSA-based
442 * cipher contexts, yet. */
443 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
444 }
445#endif /* MBEDTLS_USE_PSA_CRYPTO */
446
Paul Bakker8123e9d2011-01-06 15:37:30 +0000447 ctx->unprocessed_len = 0;
448
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200449 return( 0 );
Manuel Pégourié-Gonnard2adc40c2013-09-03 13:54:12 +0200450}
451
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200452#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
Manuel Pégourié-Gonnard2adc40c2013-09-03 13:54:12 +0200454 const unsigned char *ad, size_t ad_len )
455{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500456 CIPHER_VALIDATE_RET( ctx != NULL );
457 CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
458 if( ctx->cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200459 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard2adc40c2013-09-03 13:54:12 +0200460
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000461#if defined(MBEDTLS_USE_PSA_CRYPTO)
462 if( ctx->psa_enabled == 1 )
463 {
464 /* While PSA Crypto has an API for multipart
465 * operations, we currently don't make it
466 * accessible through the cipher layer. */
467 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
468 }
469#endif /* MBEDTLS_USE_PSA_CRYPTO */
470
Daniel King8fe47012016-05-17 20:33:28 -0300471#if defined(MBEDTLS_GCM_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200473 {
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500474 return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
475 ctx->iv, ctx->iv_size, ad, ad_len ) );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200476 }
Daniel King8fe47012016-05-17 20:33:28 -0300477#endif
478
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200479#if defined(MBEDTLS_CHACHAPOLY_C)
Daniel King8fe47012016-05-17 20:33:28 -0300480 if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
481 {
482 int result;
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200483 mbedtls_chachapoly_mode_t mode;
Daniel King8fe47012016-05-17 20:33:28 -0300484
485 mode = ( ctx->operation == MBEDTLS_ENCRYPT )
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200486 ? MBEDTLS_CHACHAPOLY_ENCRYPT
487 : MBEDTLS_CHACHAPOLY_DECRYPT;
Daniel King8fe47012016-05-17 20:33:28 -0300488
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200489 result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
Daniel King8fe47012016-05-17 20:33:28 -0300490 ctx->iv,
491 mode );
492 if ( result != 0 )
493 return( result );
494
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500495 return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
496 ad, ad_len ) );
Daniel King8fe47012016-05-17 20:33:28 -0300497 }
498#endif
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200499
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200500 return( 0 );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000501}
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200502#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
Paul Bakker8123e9d2011-01-06 15:37:30 +0000503
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200505 size_t ilen, unsigned char *output, size_t *olen )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000506{
Paul Bakkerff61a782011-06-09 15:42:02 +0000507 int ret;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500508 size_t block_size;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000509
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500510 CIPHER_VALIDATE_RET( ctx != NULL );
511 CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
512 CIPHER_VALIDATE_RET( output != NULL );
513 CIPHER_VALIDATE_RET( olen != NULL );
514 if( ctx->cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200515 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000516
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000517#if defined(MBEDTLS_USE_PSA_CRYPTO)
518 if( ctx->psa_enabled == 1 )
519 {
520 /* While PSA Crypto has an API for multipart
521 * operations, we currently don't make it
522 * accessible through the cipher layer. */
523 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
524 }
525#endif /* MBEDTLS_USE_PSA_CRYPTO */
526
Paul Bakker6c212762013-12-16 15:24:50 +0100527 *olen = 0;
Janos Follath98e28a72016-05-31 14:03:54 +0100528 block_size = mbedtls_cipher_get_block_size( ctx );
Paul Bakker6c212762013-12-16 15:24:50 +0100529
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200530 if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB )
Paul Bakker5e0efa72013-09-08 23:04:04 +0200531 {
Janos Follath98e28a72016-05-31 14:03:54 +0100532 if( ilen != block_size )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200533 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
Paul Bakker5e0efa72013-09-08 23:04:04 +0200534
535 *olen = ilen;
536
537 if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx,
538 ctx->operation, input, output ) ) )
539 {
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200540 return( ret );
Paul Bakker5e0efa72013-09-08 23:04:04 +0200541 }
542
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200543 return( 0 );
Paul Bakker5e0efa72013-09-08 23:04:04 +0200544 }
545
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200546#if defined(MBEDTLS_GCM_C)
547 if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM )
Manuel Pégourié-Gonnardb8bd5932013-09-05 13:38:15 +0200548 {
549 *olen = ilen;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500550 return( mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
551 output ) );
Manuel Pégourié-Gonnardb8bd5932013-09-05 13:38:15 +0200552 }
553#endif
554
Manuel Pégourié-Gonnard32902e62018-05-10 12:30:19 +0200555#if defined(MBEDTLS_CHACHAPOLY_C)
556 if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 )
557 {
558 *olen = ilen;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500559 return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
560 ilen, input, output ) );
Manuel Pégourié-Gonnard32902e62018-05-10 12:30:19 +0200561 }
562#endif
563
Janos Follath98e28a72016-05-31 14:03:54 +0100564 if ( 0 == block_size )
565 {
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500566 return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
Janos Follath98e28a72016-05-31 14:03:54 +0100567 }
568
Paul Bakker68884e32013-01-07 18:20:04 +0100569 if( input == output &&
Janos Follath98e28a72016-05-31 14:03:54 +0100570 ( ctx->unprocessed_len != 0 || ilen % block_size ) )
Paul Bakker68884e32013-01-07 18:20:04 +0100571 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200572 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Paul Bakker68884e32013-01-07 18:20:04 +0100573 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000574
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200575#if defined(MBEDTLS_CIPHER_MODE_CBC)
576 if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000577 {
Manuel Pégourié-Gonnard989ed382013-09-13 14:41:45 +0200578 size_t copy_len = 0;
579
Paul Bakker8123e9d2011-01-06 15:37:30 +0000580 /*
581 * If there is not enough data for a full block, cache it.
582 */
Andy Leiserson79e77892017-04-28 20:01:49 -0700583 if( ( ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding &&
Andres Amaya Garcia6a543362017-01-17 23:04:22 +0000584 ilen <= block_size - ctx->unprocessed_len ) ||
Andy Leiserson79e77892017-04-28 20:01:49 -0700585 ( ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding &&
586 ilen < block_size - ctx->unprocessed_len ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200587 ( ctx->operation == MBEDTLS_ENCRYPT &&
Andres Amaya Garcia6a543362017-01-17 23:04:22 +0000588 ilen < block_size - ctx->unprocessed_len ) )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000589 {
590 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
591 ilen );
592
593 ctx->unprocessed_len += ilen;
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200594 return( 0 );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000595 }
596
597 /*
598 * Process cached data first
599 */
Janos Follath98e28a72016-05-31 14:03:54 +0100600 if( 0 != ctx->unprocessed_len )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000601 {
Janos Follath98e28a72016-05-31 14:03:54 +0100602 copy_len = block_size - ctx->unprocessed_len;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000603
604 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
605 copy_len );
606
Paul Bakkerff61a782011-06-09 15:42:02 +0000607 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
Janos Follath98e28a72016-05-31 14:03:54 +0100608 ctx->operation, block_size, ctx->iv,
Paul Bakkerff61a782011-06-09 15:42:02 +0000609 ctx->unprocessed_data, output ) ) )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000610 {
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200611 return( ret );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000612 }
613
Janos Follath98e28a72016-05-31 14:03:54 +0100614 *olen += block_size;
615 output += block_size;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000616 ctx->unprocessed_len = 0;
617
618 input += copy_len;
619 ilen -= copy_len;
620 }
621
622 /*
623 * Cache final, incomplete block
624 */
625 if( 0 != ilen )
626 {
Janos Follath98e28a72016-05-31 14:03:54 +0100627 if( 0 == block_size )
628 {
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500629 return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
Janos Follath98e28a72016-05-31 14:03:54 +0100630 }
631
Andy Leiserson79e77892017-04-28 20:01:49 -0700632 /* Encryption: only cache partial blocks
633 * Decryption w/ padding: always keep at least one whole block
634 * Decryption w/o padding: only cache partial blocks
635 */
Janos Follath98e28a72016-05-31 14:03:54 +0100636 copy_len = ilen % block_size;
Andy Leiserson79e77892017-04-28 20:01:49 -0700637 if( copy_len == 0 &&
638 ctx->operation == MBEDTLS_DECRYPT &&
639 NULL != ctx->add_padding)
640 {
Janos Follath98e28a72016-05-31 14:03:54 +0100641 copy_len = block_size;
Andy Leiserson79e77892017-04-28 20:01:49 -0700642 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000643
644 memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
645 copy_len );
646
647 ctx->unprocessed_len += copy_len;
648 ilen -= copy_len;
649 }
650
651 /*
652 * Process remaining full blocks
653 */
654 if( ilen )
655 {
Paul Bakkerff61a782011-06-09 15:42:02 +0000656 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
657 ctx->operation, ilen, ctx->iv, input, output ) ) )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000658 {
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200659 return( ret );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000660 }
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200661
Paul Bakker8123e9d2011-01-06 15:37:30 +0000662 *olen += ilen;
663 }
664
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200665 return( 0 );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000666 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200667#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker8123e9d2011-01-06 15:37:30 +0000668
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200669#if defined(MBEDTLS_CIPHER_MODE_CFB)
670 if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB )
Paul Bakker343a8702011-06-09 14:27:58 +0000671 {
Paul Bakker6132d0a2012-07-04 17:10:40 +0000672 if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx,
Paul Bakker343a8702011-06-09 14:27:58 +0000673 ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv,
Paul Bakkerff61a782011-06-09 15:42:02 +0000674 input, output ) ) )
Paul Bakker343a8702011-06-09 14:27:58 +0000675 {
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200676 return( ret );
Paul Bakker343a8702011-06-09 14:27:58 +0000677 }
678
679 *olen = ilen;
680
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200681 return( 0 );
Paul Bakker343a8702011-06-09 14:27:58 +0000682 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200683#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakker343a8702011-06-09 14:27:58 +0000684
Simon Butcher8c0fd1e2018-04-22 22:58:07 +0100685#if defined(MBEDTLS_CIPHER_MODE_OFB)
686 if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB )
687 {
688 if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx,
689 ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) )
690 {
691 return( ret );
692 }
693
694 *olen = ilen;
695
696 return( 0 );
697 }
698#endif /* MBEDTLS_CIPHER_MODE_OFB */
699
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200700#if defined(MBEDTLS_CIPHER_MODE_CTR)
701 if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR )
Paul Bakker343a8702011-06-09 14:27:58 +0000702 {
Paul Bakkerff61a782011-06-09 15:42:02 +0000703 if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx,
Paul Bakker343a8702011-06-09 14:27:58 +0000704 ilen, &ctx->unprocessed_len, ctx->iv,
Paul Bakkerff61a782011-06-09 15:42:02 +0000705 ctx->unprocessed_data, input, output ) ) )
Paul Bakker343a8702011-06-09 14:27:58 +0000706 {
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200707 return( ret );
Paul Bakker343a8702011-06-09 14:27:58 +0000708 }
709
710 *olen = ilen;
711
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200712 return( 0 );
Paul Bakker343a8702011-06-09 14:27:58 +0000713 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200714#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker343a8702011-06-09 14:27:58 +0000715
Jaeden Ameroc6539902018-04-30 17:17:41 +0100716#if defined(MBEDTLS_CIPHER_MODE_XTS)
717 if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS )
718 {
719 if( ctx->unprocessed_len > 0 ) {
720 /* We can only process an entire data unit at a time. */
721 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
722 }
723
724 ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx,
725 ctx->operation, ilen, ctx->iv, input, output );
726 if( ret != 0 )
727 {
728 return( ret );
729 }
730
731 *olen = ilen;
732
733 return( 0 );
734 }
735#endif /* MBEDTLS_CIPHER_MODE_XTS */
736
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200737#if defined(MBEDTLS_CIPHER_MODE_STREAM)
738 if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM )
Manuel Pégourié-Gonnard37e230c2013-08-28 13:50:42 +0200739 {
740 if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx,
741 ilen, input, output ) ) )
742 {
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200743 return( ret );
Manuel Pégourié-Gonnard37e230c2013-08-28 13:50:42 +0200744 }
745
746 *olen = ilen;
747
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200748 return( 0 );
Manuel Pégourié-Gonnard37e230c2013-08-28 13:50:42 +0200749 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200750#endif /* MBEDTLS_CIPHER_MODE_STREAM */
Manuel Pégourié-Gonnard37e230c2013-08-28 13:50:42 +0200751
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200752 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000753}
754
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200755#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
756#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200757/*
758 * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len
759 */
Paul Bakker23986e52011-04-24 08:57:21 +0000760static void add_pkcs_padding( unsigned char *output, size_t output_len,
761 size_t data_len )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000762{
Paul Bakker23986e52011-04-24 08:57:21 +0000763 size_t padding_len = output_len - data_len;
Manuel Pégourié-Gonnardf8ab0692013-10-27 17:21:14 +0100764 unsigned char i;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000765
766 for( i = 0; i < padding_len; i++ )
Paul Bakker23986e52011-04-24 08:57:21 +0000767 output[data_len + i] = (unsigned char) padding_len;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000768}
769
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +0200770static int get_pkcs_padding( unsigned char *input, size_t input_len,
771 size_t *data_len )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000772{
Manuel Pégourié-Gonnardf8ab0692013-10-27 17:21:14 +0100773 size_t i, pad_idx;
774 unsigned char padding_len, bad = 0;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000775
Paul Bakkera885d682011-01-20 16:35:05 +0000776 if( NULL == input || NULL == data_len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200777 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000778
779 padding_len = input[input_len - 1];
Paul Bakker8123e9d2011-01-06 15:37:30 +0000780 *data_len = input_len - padding_len;
781
Manuel Pégourié-Gonnardf8ab0692013-10-27 17:21:14 +0100782 /* Avoid logical || since it results in a branch */
783 bad |= padding_len > input_len;
784 bad |= padding_len == 0;
785
786 /* The number of bytes checked must be independent of padding_len,
787 * so pick input_len, which is usually 8 or 16 (one block) */
788 pad_idx = input_len - padding_len;
789 for( i = 0; i < input_len; i++ )
790 bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx );
791
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200792 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000793}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200794#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
Paul Bakker8123e9d2011-01-06 15:37:30 +0000795
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200796#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200797/*
798 * One and zeros padding: fill with 80 00 ... 00
799 */
800static void add_one_and_zeros_padding( unsigned char *output,
801 size_t output_len, size_t data_len )
802{
803 size_t padding_len = output_len - data_len;
804 unsigned char i = 0;
805
806 output[data_len] = 0x80;
807 for( i = 1; i < padding_len; i++ )
808 output[data_len + i] = 0x00;
809}
810
811static int get_one_and_zeros_padding( unsigned char *input, size_t input_len,
812 size_t *data_len )
813{
Manuel Pégourié-Gonnard6c329902013-10-27 18:25:03 +0100814 size_t i;
815 unsigned char done = 0, prev_done, bad;
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200816
817 if( NULL == input || NULL == data_len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200818 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200819
Micha Krausba8316f2017-12-23 23:40:08 +0100820 bad = 0x80;
Manuel Pégourié-Gonnard6c329902013-10-27 18:25:03 +0100821 *data_len = 0;
822 for( i = input_len; i > 0; i-- )
823 {
824 prev_done = done;
Micha Krausba8316f2017-12-23 23:40:08 +0100825 done |= ( input[i - 1] != 0 );
Manuel Pégourié-Gonnard6c329902013-10-27 18:25:03 +0100826 *data_len |= ( i - 1 ) * ( done != prev_done );
Micha Krausba8316f2017-12-23 23:40:08 +0100827 bad ^= input[i - 1] * ( done != prev_done );
Manuel Pégourié-Gonnard6c329902013-10-27 18:25:03 +0100828 }
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200829
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200830 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200831
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200832}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200833#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200834
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200835#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200836/*
837 * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length
838 */
839static void add_zeros_and_len_padding( unsigned char *output,
840 size_t output_len, size_t data_len )
841{
842 size_t padding_len = output_len - data_len;
843 unsigned char i = 0;
844
845 for( i = 1; i < padding_len; i++ )
846 output[data_len + i - 1] = 0x00;
847 output[output_len - 1] = (unsigned char) padding_len;
848}
849
850static int get_zeros_and_len_padding( unsigned char *input, size_t input_len,
851 size_t *data_len )
852{
Manuel Pégourié-Gonnardd17df512013-10-27 17:32:43 +0100853 size_t i, pad_idx;
854 unsigned char padding_len, bad = 0;
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200855
856 if( NULL == input || NULL == data_len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200857 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200858
859 padding_len = input[input_len - 1];
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200860 *data_len = input_len - padding_len;
861
Manuel Pégourié-Gonnardd17df512013-10-27 17:32:43 +0100862 /* Avoid logical || since it results in a branch */
863 bad |= padding_len > input_len;
864 bad |= padding_len == 0;
865
866 /* The number of bytes checked must be independent of padding_len */
867 pad_idx = input_len - padding_len;
868 for( i = 0; i < input_len - 1; i++ )
869 bad |= input[i] * ( i >= pad_idx );
870
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200871 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200872}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200873#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200874
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200875#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200876/*
877 * Zero padding: fill with 00 ... 00
878 */
879static void add_zeros_padding( unsigned char *output,
880 size_t output_len, size_t data_len )
881{
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200882 size_t i;
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200883
884 for( i = data_len; i < output_len; i++ )
885 output[i] = 0x00;
886}
887
888static int get_zeros_padding( unsigned char *input, size_t input_len,
889 size_t *data_len )
890{
Manuel Pégourié-Gonnarde68bf172013-10-27 18:26:39 +0100891 size_t i;
892 unsigned char done = 0, prev_done;
893
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200894 if( NULL == input || NULL == data_len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200895 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200896
Manuel Pégourié-Gonnarde68bf172013-10-27 18:26:39 +0100897 *data_len = 0;
898 for( i = input_len; i > 0; i-- )
899 {
900 prev_done = done;
901 done |= ( input[i-1] != 0 );
902 *data_len |= i * ( done != prev_done );
903 }
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200904
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200905 return( 0 );
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200906}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200907#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200908
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200909/*
910 * No padding: don't pad :)
911 *
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200912 * There is no add_padding function (check for NULL in mbedtls_cipher_finish)
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200913 * but a trivial get_padding function
914 */
915static int get_no_padding( unsigned char *input, size_t input_len,
916 size_t *data_len )
917{
918 if( NULL == input || NULL == data_len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200919 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200920
921 *data_len = input_len;
922
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200923 return( 0 );
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200924}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200925#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200926
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +0200928 unsigned char *output, size_t *olen )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000929{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500930 CIPHER_VALIDATE_RET( ctx != NULL );
931 CIPHER_VALIDATE_RET( output != NULL );
932 CIPHER_VALIDATE_RET( olen != NULL );
933 if( ctx->cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200934 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000935
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000936#if defined(MBEDTLS_USE_PSA_CRYPTO)
937 if( ctx->psa_enabled == 1 )
938 {
939 /* While PSA Crypto has an API for multipart
940 * operations, we currently don't make it
941 * accessible through the cipher layer. */
942 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
943 }
944#endif /* MBEDTLS_USE_PSA_CRYPTO */
945
Paul Bakker8123e9d2011-01-06 15:37:30 +0000946 *olen = 0;
947
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200948 if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
Simon Butcher8c0fd1e2018-04-22 22:58:07 +0100949 MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200950 MBEDTLS_MODE_CTR == ctx->cipher_info->mode ||
951 MBEDTLS_MODE_GCM == ctx->cipher_info->mode ||
Jaeden Ameroc6539902018-04-30 17:17:41 +0100952 MBEDTLS_MODE_XTS == ctx->cipher_info->mode ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200953 MBEDTLS_MODE_STREAM == ctx->cipher_info->mode )
Paul Bakker343a8702011-06-09 14:27:58 +0000954 {
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200955 return( 0 );
Paul Bakker343a8702011-06-09 14:27:58 +0000956 }
957
Daniel King8fe47012016-05-17 20:33:28 -0300958 if ( ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) ||
959 ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) )
Daniel Kingbd920622016-05-15 19:56:20 -0300960 {
961 return( 0 );
962 }
963
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200964 if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode )
Paul Bakker5e0efa72013-09-08 23:04:04 +0200965 {
966 if( ctx->unprocessed_len != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200967 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
Paul Bakker5e0efa72013-09-08 23:04:04 +0200968
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200969 return( 0 );
Paul Bakker5e0efa72013-09-08 23:04:04 +0200970 }
971
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200972#if defined(MBEDTLS_CIPHER_MODE_CBC)
973 if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000974 {
Manuel Pégourié-Gonnard989ed382013-09-13 14:41:45 +0200975 int ret = 0;
976
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200977 if( MBEDTLS_ENCRYPT == ctx->operation )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000978 {
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200979 /* check for 'no padding' mode */
980 if( NULL == ctx->add_padding )
981 {
982 if( 0 != ctx->unprocessed_len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200983 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200984
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200985 return( 0 );
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200986 }
987
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200988 ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ),
Paul Bakker8123e9d2011-01-06 15:37:30 +0000989 ctx->unprocessed_len );
990 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200991 else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000992 {
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200993 /*
994 * For decrypt operations, expect a full block,
995 * or an empty block if no padding
996 */
997 if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200998 return( 0 );
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200999
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001000 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
Paul Bakker8123e9d2011-01-06 15:37:30 +00001001 }
1002
1003 /* cipher block */
Paul Bakkerff61a782011-06-09 15:42:02 +00001004 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001005 ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv,
Paul Bakkerff61a782011-06-09 15:42:02 +00001006 ctx->unprocessed_data, output ) ) )
Paul Bakker8123e9d2011-01-06 15:37:30 +00001007 {
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001008 return( ret );
Paul Bakker8123e9d2011-01-06 15:37:30 +00001009 }
1010
1011 /* Set output size for decryption */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001012 if( MBEDTLS_DECRYPT == ctx->operation )
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001013 return( ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
1014 olen ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +00001015
1016 /* Set output size for encryption */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001017 *olen = mbedtls_cipher_get_block_size( ctx );
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001018 return( 0 );
Paul Bakker8123e9d2011-01-06 15:37:30 +00001019 }
Manuel Pégourié-Gonnard989ed382013-09-13 14:41:45 +02001020#else
1021 ((void) output);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001022#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker8123e9d2011-01-06 15:37:30 +00001023
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001024 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Paul Bakker8123e9d2011-01-06 15:37:30 +00001025}
1026
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001027#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Hanno Becker18597cd2018-11-09 16:36:33 +00001028int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
1029 mbedtls_cipher_padding_t mode )
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001030{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001031 CIPHER_VALIDATE_RET( ctx != NULL );
1032
1033 if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001034 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001035 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001036 }
1037
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001038#if defined(MBEDTLS_USE_PSA_CRYPTO)
1039 if( ctx->psa_enabled == 1 )
1040 {
1041 /* While PSA Crypto knows about CBC padding
1042 * schemes, we currently don't make them
1043 * accessible through the cipher layer. */
1044 if( mode != MBEDTLS_PADDING_NONE )
1045 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1046
1047 return( 0 );
1048 }
1049#endif /* MBEDTLS_USE_PSA_CRYPTO */
1050
Paul Bakker1a45d912013-08-14 12:04:26 +02001051 switch( mode )
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001052 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001053#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
1054 case MBEDTLS_PADDING_PKCS7:
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001055 ctx->add_padding = add_pkcs_padding;
1056 ctx->get_padding = get_pkcs_padding;
Paul Bakker1a45d912013-08-14 12:04:26 +02001057 break;
Paul Bakker48e93c82013-08-14 12:21:18 +02001058#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001059#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
1060 case MBEDTLS_PADDING_ONE_AND_ZEROS:
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +02001061 ctx->add_padding = add_one_and_zeros_padding;
1062 ctx->get_padding = get_one_and_zeros_padding;
Paul Bakker1a45d912013-08-14 12:04:26 +02001063 break;
Paul Bakker48e93c82013-08-14 12:21:18 +02001064#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001065#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
1066 case MBEDTLS_PADDING_ZEROS_AND_LEN:
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +02001067 ctx->add_padding = add_zeros_and_len_padding;
1068 ctx->get_padding = get_zeros_and_len_padding;
Paul Bakker1a45d912013-08-14 12:04:26 +02001069 break;
Paul Bakker48e93c82013-08-14 12:21:18 +02001070#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001071#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
1072 case MBEDTLS_PADDING_ZEROS:
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +02001073 ctx->add_padding = add_zeros_padding;
1074 ctx->get_padding = get_zeros_padding;
Paul Bakker1a45d912013-08-14 12:04:26 +02001075 break;
Paul Bakker48e93c82013-08-14 12:21:18 +02001076#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001077 case MBEDTLS_PADDING_NONE:
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001078 ctx->add_padding = NULL;
1079 ctx->get_padding = get_no_padding;
Paul Bakker1a45d912013-08-14 12:04:26 +02001080 break;
1081
1082 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001083 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001084 }
1085
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001086 return( 0 );
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001087}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001088#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001089
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001090#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001091int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001092 unsigned char *tag, size_t tag_len )
1093{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001094 CIPHER_VALIDATE_RET( ctx != NULL );
1095 CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
1096 if( ctx->cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001097 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001098
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001099 if( MBEDTLS_ENCRYPT != ctx->operation )
1100 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001101
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001102#if defined(MBEDTLS_USE_PSA_CRYPTO)
1103 if( ctx->psa_enabled == 1 )
1104 {
1105 /* While PSA Crypto has an API for multipart
1106 * operations, we currently don't make it
1107 * accessible through the cipher layer. */
1108 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001109 }
1110#endif /* MBEDTLS_USE_PSA_CRYPTO */
1111
Daniel King8fe47012016-05-17 20:33:28 -03001112#if defined(MBEDTLS_GCM_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001113 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
Hanno Becker18597cd2018-11-09 16:36:33 +00001114 return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
1115 tag, tag_len ) );
Daniel King8fe47012016-05-17 20:33:28 -03001116#endif
1117
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001118#if defined(MBEDTLS_CHACHAPOLY_C)
Daniel King8fe47012016-05-17 20:33:28 -03001119 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
1120 {
1121 /* Don't allow truncated MAC for Poly1305 */
1122 if ( tag_len != 16U )
1123 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1124
Hanno Becker18597cd2018-11-09 16:36:33 +00001125 return( mbedtls_chachapoly_finish(
1126 (mbedtls_chachapoly_context*) ctx->cipher_ctx, tag ) );
Daniel King8fe47012016-05-17 20:33:28 -03001127 }
1128#endif
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001129
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001130 return( 0 );
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001131}
Paul Bakker9af723c2014-05-01 13:03:14 +02001132
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001133int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001134 const unsigned char *tag, size_t tag_len )
1135{
Daniel King8fe47012016-05-17 20:33:28 -03001136 unsigned char check_tag[16];
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001137 int ret;
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001138
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001139 CIPHER_VALIDATE_RET( ctx != NULL );
1140 CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
1141 if( ctx->cipher_info == NULL )
1142 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1143
1144 if( MBEDTLS_DECRYPT != ctx->operation )
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001145 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001146 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001147 }
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001148
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001149#if defined(MBEDTLS_USE_PSA_CRYPTO)
1150 if( ctx->psa_enabled == 1 )
1151 {
1152 /* While PSA Crypto has an API for multipart
1153 * operations, we currently don't make it
1154 * accessible through the cipher layer. */
1155 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1156 }
1157#endif /* MBEDTLS_USE_PSA_CRYPTO */
1158
Daniel King8fe47012016-05-17 20:33:28 -03001159#if defined(MBEDTLS_GCM_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001160 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001161 {
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001162 if( tag_len > sizeof( check_tag ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001163 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001164
Hanno Becker18597cd2018-11-09 16:36:33 +00001165 if( 0 != ( ret = mbedtls_gcm_finish(
1166 (mbedtls_gcm_context *) ctx->cipher_ctx,
1167 check_tag, tag_len ) ) )
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001168 {
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001169 return( ret );
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001170 }
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001171
1172 /* Check the tag in "constant-time" */
Daniel King8fe47012016-05-17 20:33:28 -03001173 if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001174 return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001175
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001176 return( 0 );
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001177 }
Daniel King8fe47012016-05-17 20:33:28 -03001178#endif /* MBEDTLS_GCM_C */
1179
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001180#if defined(MBEDTLS_CHACHAPOLY_C)
Daniel King8fe47012016-05-17 20:33:28 -03001181 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
1182 {
1183 /* Don't allow truncated MAC for Poly1305 */
1184 if ( tag_len != sizeof( check_tag ) )
1185 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1186
Hanno Becker18597cd2018-11-09 16:36:33 +00001187 ret = mbedtls_chachapoly_finish(
1188 (mbedtls_chachapoly_context*) ctx->cipher_ctx, check_tag );
Daniel King8fe47012016-05-17 20:33:28 -03001189 if ( ret != 0 )
1190 {
1191 return( ret );
1192 }
1193
1194 /* Check the tag in "constant-time" */
1195 if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
1196 return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
1197
1198 return( 0 );
1199 }
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001200#endif /* MBEDTLS_CHACHAPOLY_C */
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001201
1202 return( 0 );
1203}
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001204#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001205
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001206/*
1207 * Packet-oriented wrapper for non-AEAD modes
1208 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001209int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001210 const unsigned char *iv, size_t iv_len,
1211 const unsigned char *input, size_t ilen,
1212 unsigned char *output, size_t *olen )
1213{
1214 int ret;
1215 size_t finish_olen;
1216
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001217 CIPHER_VALIDATE_RET( ctx != NULL );
1218 CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
1219 CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
1220 CIPHER_VALIDATE_RET( output != NULL );
1221 CIPHER_VALIDATE_RET( olen != NULL );
1222
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001223#if defined(MBEDTLS_USE_PSA_CRYPTO)
1224 if( ctx->psa_enabled == 1 )
1225 {
Hanno Becker55e2e3d2018-11-12 12:36:17 +00001226 /* As in the non-PSA case, we don't check that
1227 * a key has been set. If not, the key slot will
1228 * still be in its default state of 0, which is
1229 * guaranteed to be invalid, hence the PSA-call
1230 * below will gracefully fail. */
1231 mbedtls_cipher_context_psa * const cipher_psa =
1232 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
1233
1234 psa_status_t status;
Jaeden Amerofe96fbe2019-02-20 10:32:28 +00001235 psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT;
Hanno Becker55e2e3d2018-11-12 12:36:17 +00001236 size_t part_len;
1237
1238 if( ctx->operation == MBEDTLS_DECRYPT )
1239 {
1240 status = psa_cipher_decrypt_setup( &cipher_op,
1241 cipher_psa->slot,
1242 cipher_psa->alg );
1243 }
1244 else if( ctx->operation == MBEDTLS_ENCRYPT )
1245 {
1246 status = psa_cipher_encrypt_setup( &cipher_op,
1247 cipher_psa->slot,
1248 cipher_psa->alg );
1249 }
1250 else
1251 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1252
1253 /* In the following, we can immediately return on an error,
1254 * because the PSA Crypto API guarantees that cipher operations
1255 * are terminated by unsuccessful calls to psa_cipher_update(),
1256 * and by any call to psa_cipher_finish(). */
1257 if( status != PSA_SUCCESS )
1258 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
1259
1260 status = psa_cipher_set_iv( &cipher_op, iv, iv_len );
1261 if( status != PSA_SUCCESS )
1262 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
1263
1264 status = psa_cipher_update( &cipher_op,
1265 input, ilen,
1266 output, ilen, olen );
1267 if( status != PSA_SUCCESS )
1268 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
1269
1270 status = psa_cipher_finish( &cipher_op,
1271 output + *olen, ilen - *olen,
1272 &part_len );
1273 if( status != PSA_SUCCESS )
1274 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
1275
1276 *olen += part_len;
1277 return( 0 );
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001278 }
1279#endif /* MBEDTLS_USE_PSA_CRYPTO */
1280
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001281 if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001282 return( ret );
1283
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001284 if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 )
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001285 return( ret );
1286
Hanno Becker18597cd2018-11-09 16:36:33 +00001287 if( ( ret = mbedtls_cipher_update( ctx, input, ilen,
1288 output, olen ) ) != 0 )
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001289 return( ret );
1290
Hanno Becker18597cd2018-11-09 16:36:33 +00001291 if( ( ret = mbedtls_cipher_finish( ctx, output + *olen,
1292 &finish_olen ) ) != 0 )
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001293 return( ret );
1294
1295 *olen += finish_olen;
1296
1297 return( 0 );
1298}
1299
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001300#if defined(MBEDTLS_CIPHER_MODE_AEAD)
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001301/*
1302 * Packet-oriented encryption for AEAD modes
1303 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001304int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001305 const unsigned char *iv, size_t iv_len,
1306 const unsigned char *ad, size_t ad_len,
1307 const unsigned char *input, size_t ilen,
1308 unsigned char *output, size_t *olen,
1309 unsigned char *tag, size_t tag_len )
1310{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001311 CIPHER_VALIDATE_RET( ctx != NULL );
1312 CIPHER_VALIDATE_RET( iv != NULL );
1313 CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
1314 CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
1315 CIPHER_VALIDATE_RET( output != NULL );
1316 CIPHER_VALIDATE_RET( olen != NULL );
1317 CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
1318
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001319#if defined(MBEDTLS_USE_PSA_CRYPTO)
1320 if( ctx->psa_enabled == 1 )
1321 {
Hanno Beckerfe73ade2018-11-12 16:26:46 +00001322 /* As in the non-PSA case, we don't check that
1323 * a key has been set. If not, the key slot will
1324 * still be in its default state of 0, which is
1325 * guaranteed to be invalid, hence the PSA-call
1326 * below will gracefully fail. */
1327 mbedtls_cipher_context_psa * const cipher_psa =
1328 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
1329
1330 psa_status_t status;
1331
1332 /* PSA Crypto API always writes the authentication tag
1333 * at the end of the encrypted message. */
1334 if( tag != output + ilen )
1335 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1336
1337 status = psa_aead_encrypt( cipher_psa->slot,
1338 cipher_psa->alg,
1339 iv, iv_len,
1340 ad, ad_len,
1341 input, ilen,
1342 output, ilen + tag_len, olen );
1343 if( status != PSA_SUCCESS )
1344 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
1345
1346 *olen -= tag_len;
1347 return( 0 );
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001348 }
1349#endif /* MBEDTLS_USE_PSA_CRYPTO */
1350
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001351#if defined(MBEDTLS_GCM_C)
1352 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001353 {
1354 *olen = ilen;
Hanno Becker18597cd2018-11-09 16:36:33 +00001355 return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT,
1356 ilen, iv, iv_len, ad, ad_len,
1357 input, output, tag_len, tag ) );
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001358 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001359#endif /* MBEDTLS_GCM_C */
1360#if defined(MBEDTLS_CCM_C)
1361 if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001362 {
1363 *olen = ilen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001364 return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen,
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001365 iv, iv_len, ad, ad_len, input, output,
1366 tag, tag_len ) );
1367 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001368#endif /* MBEDTLS_CCM_C */
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001369#if defined(MBEDTLS_CHACHAPOLY_C)
Daniel King8fe47012016-05-17 20:33:28 -03001370 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
1371 {
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001372 /* ChachaPoly has fixed length nonce and MAC (tag) */
Daniel King8fe47012016-05-17 20:33:28 -03001373 if ( ( iv_len != ctx->cipher_info->iv_size ) ||
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001374 ( tag_len != 16U ) )
Daniel King8fe47012016-05-17 20:33:28 -03001375 {
1376 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1377 }
1378
1379 *olen = ilen;
Manuel Pégourié-Gonnard3dc62a02018-06-04 12:18:19 +02001380 return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx,
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001381 ilen, iv, ad, ad_len, input, output, tag ) );
Daniel King8fe47012016-05-17 20:33:28 -03001382 }
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001383#endif /* MBEDTLS_CHACHAPOLY_C */
Jack Lloydffdf2882019-03-07 17:00:32 -05001384#if defined(MBEDTLS_NIST_KW_C)
Jack Lloyd5f289992019-04-02 10:07:28 -07001385 if( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
1386 MBEDTLS_MODE_KWP == ctx->cipher_info->mode )
Jack Lloydffdf2882019-03-07 17:00:32 -05001387 {
1388 mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
1389 MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
1390
1391 /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */
1392 if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
1393 {
1394 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1395 }
1396
1397 return( mbedtls_nist_kw_wrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) );
1398 }
1399#endif /* MBEDTLS_NIST_KW_C */
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001400
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001401 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001402}
1403
1404/*
1405 * Packet-oriented decryption for AEAD modes
1406 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001407int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001408 const unsigned char *iv, size_t iv_len,
1409 const unsigned char *ad, size_t ad_len,
1410 const unsigned char *input, size_t ilen,
1411 unsigned char *output, size_t *olen,
1412 const unsigned char *tag, size_t tag_len )
1413{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001414 CIPHER_VALIDATE_RET( ctx != NULL );
1415 CIPHER_VALIDATE_RET( iv != NULL );
1416 CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
1417 CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
1418 CIPHER_VALIDATE_RET( output != NULL );
1419 CIPHER_VALIDATE_RET( olen != NULL );
1420 CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
Krzysztof Stachowiake0215d72018-12-17 10:20:30 +01001421
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001422#if defined(MBEDTLS_USE_PSA_CRYPTO)
1423 if( ctx->psa_enabled == 1 )
1424 {
Hanno Beckerfe73ade2018-11-12 16:26:46 +00001425 /* As in the non-PSA case, we don't check that
1426 * a key has been set. If not, the key slot will
1427 * still be in its default state of 0, which is
1428 * guaranteed to be invalid, hence the PSA-call
1429 * below will gracefully fail. */
1430 mbedtls_cipher_context_psa * const cipher_psa =
1431 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
1432
1433 psa_status_t status;
1434
1435 /* PSA Crypto API always writes the authentication tag
1436 * at the end of the encrypted message. */
1437 if( tag != input + ilen )
1438 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1439
1440 status = psa_aead_decrypt( cipher_psa->slot,
1441 cipher_psa->alg,
1442 iv, iv_len,
1443 ad, ad_len,
1444 input, ilen + tag_len,
1445 output, ilen, olen );
1446 if( status == PSA_ERROR_INVALID_SIGNATURE )
1447 return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
1448 else if( status != PSA_SUCCESS )
1449 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
1450
1451 return( 0 );
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001452 }
1453#endif /* MBEDTLS_USE_PSA_CRYPTO */
1454
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001455#if defined(MBEDTLS_GCM_C)
1456 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001457 {
1458 int ret;
1459
1460 *olen = ilen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001461 ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen,
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001462 iv, iv_len, ad, ad_len,
1463 tag, tag_len, input, output );
1464
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001465 if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED )
1466 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001467
1468 return( ret );
1469 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001470#endif /* MBEDTLS_GCM_C */
1471#if defined(MBEDTLS_CCM_C)
1472 if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001473 {
1474 int ret;
1475
1476 *olen = ilen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001477 ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen,
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001478 iv, iv_len, ad, ad_len,
1479 input, output, tag, tag_len );
1480
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001481 if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED )
1482 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001483
1484 return( ret );
1485 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001486#endif /* MBEDTLS_CCM_C */
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001487#if defined(MBEDTLS_CHACHAPOLY_C)
Daniel King8fe47012016-05-17 20:33:28 -03001488 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
1489 {
Daniel King8fe47012016-05-17 20:33:28 -03001490 int ret;
1491
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001492 /* ChachaPoly has fixed length nonce and MAC (tag) */
Daniel King8fe47012016-05-17 20:33:28 -03001493 if ( ( iv_len != ctx->cipher_info->iv_size ) ||
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001494 ( tag_len != 16U ) )
Daniel King8fe47012016-05-17 20:33:28 -03001495 {
1496 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1497 }
1498
1499 *olen = ilen;
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001500 ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen,
1501 iv, ad, ad_len, tag, input, output );
Daniel King8fe47012016-05-17 20:33:28 -03001502
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001503 if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED )
1504 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
Daniel King8fe47012016-05-17 20:33:28 -03001505
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001506 return( ret );
Daniel King8fe47012016-05-17 20:33:28 -03001507 }
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001508#endif /* MBEDTLS_CHACHAPOLY_C */
Jack Lloydffdf2882019-03-07 17:00:32 -05001509#if defined(MBEDTLS_NIST_KW_C)
Jack Lloyd5f289992019-04-02 10:07:28 -07001510 if( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
1511 MBEDTLS_MODE_KWP == ctx->cipher_info->mode )
Jack Lloydffdf2882019-03-07 17:00:32 -05001512 {
1513 mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
1514 MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
1515
1516 /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */
1517 if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
1518 {
1519 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1520 }
1521
1522 return( mbedtls_nist_kw_unwrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) );
1523 }
1524#endif /* MBEDTLS_NIST_KW_C */
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001525
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001526 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001527}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001528#endif /* MBEDTLS_CIPHER_MODE_AEAD */
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001529
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001530#endif /* MBEDTLS_CIPHER_C */