blob: b81df6bde70a9d81e47847cbbee830a79f6b2e97 [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
Simon Butcher327398a2016-10-05 14:09:11 +010066#if defined(MBEDTLS_PLATFORM_C)
67#include "mbedtls/platform.h"
68#else
69#define mbedtls_calloc calloc
70#define mbedtls_free free
71#endif
72
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +020073#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
Daniel King8fe47012016-05-17 20:33:28 -030074/* Compare the contents of two buffers in constant time.
75 * Returns 0 if the contents are bitwise identical, otherwise returns
Daniel King16b04ce2016-05-18 13:38:22 -030076 * a non-zero value.
77 * This is currently only used by GCM and ChaCha20+Poly1305.
78 */
Hanno Becker18597cd2018-11-09 16:36:33 +000079static int mbedtls_constant_time_memcmp( const void *v1, const void *v2,
80 size_t len )
Daniel King8fe47012016-05-17 20:33:28 -030081{
82 const unsigned char *p1 = (const unsigned char*) v1;
83 const unsigned char *p2 = (const unsigned char*) v2;
84 size_t i;
85 unsigned char diff;
86
87 for( diff = 0, i = 0; i < len; i++ )
88 diff |= p1[i] ^ p2[i];
89
90 return (int)diff;
91}
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +020092#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
Daniel King8fe47012016-05-17 20:33:28 -030093
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +020094static int supported_init = 0;
Paul Bakker72f62662011-01-16 21:27:44 +000095
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020096const int *mbedtls_cipher_list( void )
Paul Bakker72f62662011-01-16 21:27:44 +000097{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020098 const mbedtls_cipher_definition_t *def;
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +020099 int *type;
100
101 if( ! supported_init )
102 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200103 def = mbedtls_cipher_definitions;
104 type = mbedtls_cipher_supported;
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +0200105
106 while( def->type != 0 )
107 *type++ = (*def++).type;
108
109 *type = 0;
110
111 supported_init = 1;
112 }
113
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200114 return( mbedtls_cipher_supported );
Paul Bakker72f62662011-01-16 21:27:44 +0000115}
116
Hanno Becker18597cd2018-11-09 16:36:33 +0000117const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type(
118 const mbedtls_cipher_type_t cipher_type )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000119{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200120 const mbedtls_cipher_definition_t *def;
Paul Bakker5e0efa72013-09-08 23:04:04 +0200121
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200122 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +0200123 if( def->type == cipher_type )
124 return( def->info );
Paul Bakker343a8702011-06-09 14:27:58 +0000125
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200126 return( NULL );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000127}
128
Hanno Becker18597cd2018-11-09 16:36:33 +0000129const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string(
130 const char *cipher_name )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000131{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200132 const mbedtls_cipher_definition_t *def;
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +0200133
Paul Bakker8123e9d2011-01-06 15:37:30 +0000134 if( NULL == cipher_name )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200135 return( NULL );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000136
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200137 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200138 if( ! strcmp( def->info->name, cipher_name ) )
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +0200139 return( def->info );
Paul Bakkerfab5c822012-02-06 16:45:10 +0000140
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200141 return( NULL );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000142}
143
Hanno Becker18597cd2018-11-09 16:36:33 +0000144const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values(
145 const mbedtls_cipher_id_t cipher_id,
146 int key_bitlen,
147 const mbedtls_cipher_mode_t mode )
Paul Bakkerf46b6952013-09-09 00:08:26 +0200148{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200149 const mbedtls_cipher_definition_t *def;
Paul Bakkerf46b6952013-09-09 00:08:26 +0200150
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200151 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +0200152 if( def->info->base->cipher == cipher_id &&
Manuel Pégourié-Gonnard898e0aa2015-06-18 15:28:12 +0200153 def->info->key_bitlen == (unsigned) key_bitlen &&
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +0200154 def->info->mode == mode )
155 return( def->info );
Paul Bakkerf46b6952013-09-09 00:08:26 +0200156
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200157 return( NULL );
Paul Bakkerf46b6952013-09-09 00:08:26 +0200158}
159
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200160void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx )
Paul Bakker84bbeb52014-07-01 14:53:22 +0200161{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200162 memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
Paul Bakker84bbeb52014-07-01 14:53:22 +0200163}
164
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200165void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
Paul Bakker84bbeb52014-07-01 14:53:22 +0200166{
167 if( ctx == NULL )
168 return;
169
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000170#if defined(MBEDTLS_USE_PSA_CRYPTO)
171 if( ctx->psa_enabled == 1 )
172 {
Hanno Becker6118e432018-11-09 16:47:20 +0000173 if( ctx->cipher_ctx != NULL )
174 {
175 mbedtls_cipher_context_psa * const cipher_psa =
176 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
177
Hanno Becker19086552018-11-17 22:11:16 +0000178 if( cipher_psa->slot_state == MBEDTLS_CIPHER_PSA_KEY_OWNED )
Hanno Becker6118e432018-11-09 16:47:20 +0000179 {
Hanno Beckeredda8b82018-11-12 11:59:30 +0000180 /* xxx_free() doesn't allow to return failures. */
181 (void) psa_destroy_key( cipher_psa->slot );
Hanno Becker6118e432018-11-09 16:47:20 +0000182 }
183
184 mbedtls_platform_zeroize( cipher_psa, sizeof( *cipher_psa ) );
185 mbedtls_free( cipher_psa );
186 }
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000187
188 mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
189 return;
190 }
191#endif /* MBEDTLS_USE_PSA_CRYPTO */
192
Simon Butcher327398a2016-10-05 14:09:11 +0100193#if defined(MBEDTLS_CMAC_C)
194 if( ctx->cmac_ctx )
195 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500196 mbedtls_platform_zeroize( ctx->cmac_ctx,
197 sizeof( mbedtls_cmac_context_t ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100198 mbedtls_free( ctx->cmac_ctx );
199 }
200#endif
201
Paul Bakker84bbeb52014-07-01 14:53:22 +0200202 if( ctx->cipher_ctx )
203 ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx );
204
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500205 mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
Paul Bakker84bbeb52014-07-01 14:53:22 +0200206}
207
Hanno Becker18597cd2018-11-09 16:36:33 +0000208int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
209 const mbedtls_cipher_info_t *cipher_info )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000210{
211 if( NULL == cipher_info || NULL == ctx )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200212 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000213
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200214 memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000215
Paul Bakker343a8702011-06-09 14:27:58 +0000216 if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200217 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000218
219 ctx->cipher_info = cipher_info;
220
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200221#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +0200222 /*
223 * Ignore possible errors caused by a cipher mode that doesn't use padding
224 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200225#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
226 (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 );
Paul Bakker48e93c82013-08-14 12:21:18 +0200227#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200228 (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE );
Paul Bakker48e93c82013-08-14 12:21:18 +0200229#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200230#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +0200231
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200232 return( 0 );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000233}
234
Hanno Becker4ccfc402018-11-09 16:10:57 +0000235#if defined(MBEDTLS_USE_PSA_CRYPTO)
236int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx,
Hanno Becker20120b32018-11-12 16:26:27 +0000237 const mbedtls_cipher_info_t *cipher_info,
238 size_t taglen )
Hanno Becker4ccfc402018-11-09 16:10:57 +0000239{
Hanno Beckeredda8b82018-11-12 11:59:30 +0000240 psa_algorithm_t alg;
241 mbedtls_cipher_context_psa *cipher_psa;
242
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000243 if( NULL == cipher_info || NULL == ctx )
244 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
245
Hanno Becker4ee7e762018-11-17 22:00:38 +0000246 /* Check that the underlying cipher mode and cipher type are
247 * supported by the underlying PSA Crypto implementation. */
Hanno Becker20120b32018-11-12 16:26:27 +0000248 alg = mbedtls_psa_translate_cipher_mode( cipher_info->mode, taglen );
Hanno Becker4ee7e762018-11-17 22:00:38 +0000249 if( alg == 0 )
250 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
251 if( mbedtls_psa_translate_cipher_type( cipher_info->type ) == 0 )
Hanno Beckeredda8b82018-11-12 11:59:30 +0000252 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Hanno Becker6118e432018-11-09 16:47:20 +0000253
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000254 memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
255
Hanno Beckeredda8b82018-11-12 11:59:30 +0000256 cipher_psa = mbedtls_calloc( 1, sizeof(mbedtls_cipher_context_psa ) );
257 if( cipher_psa == NULL )
258 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
259 cipher_psa->alg = alg;
260 ctx->cipher_ctx = cipher_psa;
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000261 ctx->cipher_info = cipher_info;
262 ctx->psa_enabled = 1;
263 return( 0 );
Hanno Becker4ccfc402018-11-09 16:10:57 +0000264}
265#endif /* MBEDTLS_USE_PSA_CRYPTO */
266
Hanno Becker18597cd2018-11-09 16:36:33 +0000267int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
268 const unsigned char *key,
269 int key_bitlen,
270 const mbedtls_operation_t operation )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000271{
Hanno Beckeredda8b82018-11-12 11:59:30 +0000272 if( NULL == ctx || NULL == ctx->cipher_info ||
273 NULL == ctx->cipher_ctx )
274 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200275 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Hanno Beckeredda8b82018-11-12 11:59:30 +0000276 }
277
278 if( operation != MBEDTLS_DECRYPT &&
279 operation != MBEDTLS_ENCRYPT )
280 {
281 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
282 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000283
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000284#if defined(MBEDTLS_USE_PSA_CRYPTO)
285 if( ctx->psa_enabled == 1 )
286 {
Hanno Beckeredda8b82018-11-12 11:59:30 +0000287 mbedtls_cipher_context_psa * const cipher_psa =
288 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
289
290 size_t const key_bytelen = ( (size_t) key_bitlen + 7 ) / 8;
291
292 psa_status_t status;
293 psa_key_type_t key_type;
294 psa_key_usage_t key_usage;
295 psa_key_policy_t key_policy;
296
297 /* PSA Crypto API only accepts byte-aligned keys. */
298 if( key_bitlen % 8 != 0 )
299 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
300
301 /* Don't allow keys to be set multiple times. */
Hanno Becker19086552018-11-17 22:11:16 +0000302 if( cipher_psa->slot_state != MBEDTLS_CIPHER_PSA_KEY_UNSET )
Hanno Beckeredda8b82018-11-12 11:59:30 +0000303 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
304
Andrzej Kurekc7509322019-01-08 09:36:01 -0500305 key_type = mbedtls_psa_translate_cipher_type(
306 ctx->cipher_info->type );
307 if( key_type == 0 )
308 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
309
310 /* Allocate a key slot to use. */
311 status = psa_allocate_key( key_type, key_bitlen, &cipher_psa->slot );
Hanno Beckeredda8b82018-11-12 11:59:30 +0000312 if( status != PSA_SUCCESS )
313 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
Hanno Beckeredda8b82018-11-12 11:59:30 +0000314
Andrzej Kurek08dfcea2019-01-14 05:01:28 -0500315 /* Indicate that we own the key slot and need to
316 * destroy it in mbedtls_cipher_free(). */
317 cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED;
318
319 /* From that point on, the responsibility for destroying the
320 * key slot is on mbedtls_cipher_free(). This includes the case
321 * where the policy setup or key import below fail, as
322 * mbedtls_cipher_free() needs to be called in any case. */
323
Hanno Beckeredda8b82018-11-12 11:59:30 +0000324 /* Setup policy for the new key slot. */
325 psa_key_policy_init( &key_policy );
Hanno Beckera395d8f2018-11-12 13:33:16 +0000326
327 /* Mbed TLS' cipher layer doesn't enforce the mode of operation
Andrzej Kurekc7509322019-01-08 09:36:01 -0500328 * (encrypt vs. decrypt): it is possible to setup a key for encryption
329 * and use it for AEAD decryption. Until tests relying on this
330 * are changed, allow any usage in PSA. */
Hanno Beckera395d8f2018-11-12 13:33:16 +0000331 /* key_usage = mbedtls_psa_translate_cipher_operation( operation ); */
332 key_usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
Hanno Beckeredda8b82018-11-12 11:59:30 +0000333 psa_key_policy_set_usage( &key_policy, key_usage, cipher_psa->alg );
334 status = psa_set_key_policy( cipher_psa->slot, &key_policy );
335 if( status != PSA_SUCCESS )
336 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
337
338 /* Populate new key slot. */
Hanno Beckeredda8b82018-11-12 11:59:30 +0000339 status = psa_import_key( cipher_psa->slot,
340 key_type, key, key_bytelen );
341 if( status != PSA_SUCCESS )
342 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
343
344 ctx->key_bitlen = key_bitlen;
345 ctx->operation = operation;
346 return( 0 );
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000347 }
348#endif /* MBEDTLS_USE_PSA_CRYPTO */
349
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200350 if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 &&
Manuel Pégourié-Gonnard898e0aa2015-06-18 15:28:12 +0200351 (int) ctx->cipher_info->key_bitlen != key_bitlen )
Manuel Pégourié-Gonnard398c57b2014-06-23 12:10:59 +0200352 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard398c57b2014-06-23 12:10:59 +0200354 }
Manuel Pégourié-Gonnarddd0f57f2013-09-16 11:47:43 +0200355
Manuel Pégourié-Gonnard898e0aa2015-06-18 15:28:12 +0200356 ctx->key_bitlen = key_bitlen;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000357 ctx->operation = operation;
358
Paul Bakker343a8702011-06-09 14:27:58 +0000359 /*
Simon Butcher8c0fd1e2018-04-22 22:58:07 +0100360 * For OFB, CFB and CTR mode always use the encryption key schedule
Paul Bakker343a8702011-06-09 14:27:58 +0000361 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200362 if( MBEDTLS_ENCRYPT == operation ||
363 MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
Simon Butcher8c0fd1e2018-04-22 22:58:07 +0100364 MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200365 MBEDTLS_MODE_CTR == ctx->cipher_info->mode )
Paul Bakker343a8702011-06-09 14:27:58 +0000366 {
367 return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
Hanno Becker18597cd2018-11-09 16:36:33 +0000368 ctx->key_bitlen );
Paul Bakker343a8702011-06-09 14:27:58 +0000369 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000370
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200371 if( MBEDTLS_DECRYPT == operation )
Paul Bakker343a8702011-06-09 14:27:58 +0000372 return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
Hanno Becker18597cd2018-11-09 16:36:33 +0000373 ctx->key_bitlen );
374
Paul Bakker8123e9d2011-01-06 15:37:30 +0000375
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200376 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000377}
378
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200379int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
Manuel Pégourié-Gonnard9c853b92013-09-03 13:04:44 +0200380 const unsigned char *iv, size_t iv_len )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000381{
Manuel Pégourié-Gonnarda235b5b2013-09-03 13:25:52 +0200382 size_t actual_iv_size;
Ron Eldor4e64e0b2017-09-25 18:22:32 +0300383 if( NULL == ctx || NULL == ctx->cipher_info )
384 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
385 else if( NULL == iv && iv_len != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200386 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000387
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000388#if defined(MBEDTLS_USE_PSA_CRYPTO)
389 if( ctx->psa_enabled == 1 )
390 {
391 /* While PSA Crypto has an API for multipart
392 * operations, we currently don't make it
393 * accessible through the cipher layer. */
394 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
395 }
396#endif /* MBEDTLS_USE_PSA_CRYPTO */
397
Ron Eldorbb4bbbb2017-10-01 17:04:54 +0300398 if( NULL == iv && iv_len == 0 )
399 ctx->iv_size = 0;
400
Manuel Pégourié-Gonnarde0dca4a2013-10-24 16:54:25 +0200401 /* avoid buffer overflow in ctx->iv */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200402 if( iv_len > MBEDTLS_MAX_IV_LENGTH )
403 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnarde0dca4a2013-10-24 16:54:25 +0200404
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405 if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 )
Manuel Pégourié-Gonnarda235b5b2013-09-03 13:25:52 +0200406 actual_iv_size = iv_len;
407 else
Manuel Pégourié-Gonnarde0dca4a2013-10-24 16:54:25 +0200408 {
Manuel Pégourié-Gonnarda235b5b2013-09-03 13:25:52 +0200409 actual_iv_size = ctx->cipher_info->iv_size;
Manuel Pégourié-Gonnard9c853b92013-09-03 13:04:44 +0200410
Manuel Pégourié-Gonnarde0dca4a2013-10-24 16:54:25 +0200411 /* avoid reading past the end of input buffer */
412 if( actual_iv_size > iv_len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200413 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde0dca4a2013-10-24 16:54:25 +0200414 }
415
Daniel Kingbd920622016-05-15 19:56:20 -0300416#if defined(MBEDTLS_CHACHA20_C)
417 if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
418 {
419 if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx,
420 iv,
421 0U ) ) /* Initial counter value */
422 {
423 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
424 }
425 }
426#endif
427
Ron Eldorbb4bbbb2017-10-01 17:04:54 +0300428 if ( actual_iv_size != 0 )
Ron Eldor4e64e0b2017-09-25 18:22:32 +0300429 {
430 memcpy( ctx->iv, iv, actual_iv_size );
431 ctx->iv_size = actual_iv_size;
432 }
Manuel Pégourié-Gonnard9c853b92013-09-03 13:04:44 +0200433
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200434 return( 0 );
Manuel Pégourié-Gonnard9c853b92013-09-03 13:04:44 +0200435}
436
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
Manuel Pégourié-Gonnard9c853b92013-09-03 13:04:44 +0200438{
Manuel Pégourié-Gonnard2adc40c2013-09-03 13:54:12 +0200439 if( NULL == ctx || NULL == ctx->cipher_info )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard2adc40c2013-09-03 13:54:12 +0200441
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000442#if defined(MBEDTLS_USE_PSA_CRYPTO)
443 if( ctx->psa_enabled == 1 )
444 {
445 /* We don't support resetting PSA-based
446 * cipher contexts, yet. */
447 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
448 }
449#endif /* MBEDTLS_USE_PSA_CRYPTO */
450
Paul Bakker8123e9d2011-01-06 15:37:30 +0000451 ctx->unprocessed_len = 0;
452
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200453 return( 0 );
Manuel Pégourié-Gonnard2adc40c2013-09-03 13:54:12 +0200454}
455
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200456#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200457int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
Manuel Pégourié-Gonnard2adc40c2013-09-03 13:54:12 +0200458 const unsigned char *ad, size_t ad_len )
459{
460 if( NULL == ctx || NULL == ctx->cipher_info )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard2adc40c2013-09-03 13:54:12 +0200462
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000463#if defined(MBEDTLS_USE_PSA_CRYPTO)
464 if( ctx->psa_enabled == 1 )
465 {
466 /* While PSA Crypto has an API for multipart
467 * operations, we currently don't make it
468 * accessible through the cipher layer. */
469 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
470 }
471#endif /* MBEDTLS_USE_PSA_CRYPTO */
472
Daniel King8fe47012016-05-17 20:33:28 -0300473#if defined(MBEDTLS_GCM_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200475 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200476 return mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
Manuel Pégourié-Gonnard9c853b92013-09-03 13:04:44 +0200477 ctx->iv, ctx->iv_size, ad, ad_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200478 }
Daniel King8fe47012016-05-17 20:33:28 -0300479#endif
480
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200481#if defined(MBEDTLS_CHACHAPOLY_C)
Daniel King8fe47012016-05-17 20:33:28 -0300482 if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
483 {
484 int result;
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200485 mbedtls_chachapoly_mode_t mode;
Daniel King8fe47012016-05-17 20:33:28 -0300486
487 mode = ( ctx->operation == MBEDTLS_ENCRYPT )
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200488 ? MBEDTLS_CHACHAPOLY_ENCRYPT
489 : MBEDTLS_CHACHAPOLY_DECRYPT;
Daniel King8fe47012016-05-17 20:33:28 -0300490
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200491 result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
Daniel King8fe47012016-05-17 20:33:28 -0300492 ctx->iv,
493 mode );
494 if ( result != 0 )
495 return( result );
496
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200497 return mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
Manuel Pégourié-Gonnard5ef92d32018-05-09 09:34:25 +0200498 ad, ad_len );
Daniel King8fe47012016-05-17 20:33:28 -0300499 }
500#endif
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200501
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200502 return( 0 );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000503}
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200504#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
Paul Bakker8123e9d2011-01-06 15:37:30 +0000505
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200506int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200507 size_t ilen, unsigned char *output, size_t *olen )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000508{
Paul Bakkerff61a782011-06-09 15:42:02 +0000509 int ret;
Janos Follath98e28a72016-05-31 14:03:54 +0100510 size_t block_size = 0;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000511
Paul Bakker68884e32013-01-07 18:20:04 +0100512 if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
Paul Bakkera885d682011-01-20 16:35:05 +0000513 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200514 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Paul Bakkera885d682011-01-20 16:35:05 +0000515 }
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;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200550 return mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200551 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;
559 return mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
560 ilen, input, output );
561 }
562#endif
563
Janos Follath98e28a72016-05-31 14:03:54 +0100564 if ( 0 == block_size )
565 {
566 return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
567 }
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 {
629 return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
630 }
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{
930 if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200931 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000932
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000933#if defined(MBEDTLS_USE_PSA_CRYPTO)
934 if( ctx->psa_enabled == 1 )
935 {
936 /* While PSA Crypto has an API for multipart
937 * operations, we currently don't make it
938 * accessible through the cipher layer. */
939 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
940 }
941#endif /* MBEDTLS_USE_PSA_CRYPTO */
942
Paul Bakker8123e9d2011-01-06 15:37:30 +0000943 *olen = 0;
944
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200945 if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
Simon Butcher8c0fd1e2018-04-22 22:58:07 +0100946 MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200947 MBEDTLS_MODE_CTR == ctx->cipher_info->mode ||
948 MBEDTLS_MODE_GCM == ctx->cipher_info->mode ||
Jaeden Ameroc6539902018-04-30 17:17:41 +0100949 MBEDTLS_MODE_XTS == ctx->cipher_info->mode ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200950 MBEDTLS_MODE_STREAM == ctx->cipher_info->mode )
Paul Bakker343a8702011-06-09 14:27:58 +0000951 {
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200952 return( 0 );
Paul Bakker343a8702011-06-09 14:27:58 +0000953 }
954
Daniel King8fe47012016-05-17 20:33:28 -0300955 if ( ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) ||
956 ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) )
Daniel Kingbd920622016-05-15 19:56:20 -0300957 {
958 return( 0 );
959 }
960
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200961 if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode )
Paul Bakker5e0efa72013-09-08 23:04:04 +0200962 {
963 if( ctx->unprocessed_len != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200964 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
Paul Bakker5e0efa72013-09-08 23:04:04 +0200965
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200966 return( 0 );
Paul Bakker5e0efa72013-09-08 23:04:04 +0200967 }
968
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200969#if defined(MBEDTLS_CIPHER_MODE_CBC)
970 if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000971 {
Manuel Pégourié-Gonnard989ed382013-09-13 14:41:45 +0200972 int ret = 0;
973
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200974 if( MBEDTLS_ENCRYPT == ctx->operation )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000975 {
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200976 /* check for 'no padding' mode */
977 if( NULL == ctx->add_padding )
978 {
979 if( 0 != ctx->unprocessed_len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200980 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200981
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200982 return( 0 );
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200983 }
984
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200985 ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ),
Paul Bakker8123e9d2011-01-06 15:37:30 +0000986 ctx->unprocessed_len );
987 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200988 else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000989 {
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200990 /*
991 * For decrypt operations, expect a full block,
992 * or an empty block if no padding
993 */
994 if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200995 return( 0 );
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200996
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200997 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000998 }
999
1000 /* cipher block */
Paul Bakkerff61a782011-06-09 15:42:02 +00001001 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001002 ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv,
Paul Bakkerff61a782011-06-09 15:42:02 +00001003 ctx->unprocessed_data, output ) ) )
Paul Bakker8123e9d2011-01-06 15:37:30 +00001004 {
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001005 return( ret );
Paul Bakker8123e9d2011-01-06 15:37:30 +00001006 }
1007
1008 /* Set output size for decryption */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001009 if( MBEDTLS_DECRYPT == ctx->operation )
1010 return ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001011 olen );
Paul Bakker8123e9d2011-01-06 15:37:30 +00001012
1013 /* Set output size for encryption */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001014 *olen = mbedtls_cipher_get_block_size( ctx );
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001015 return( 0 );
Paul Bakker8123e9d2011-01-06 15:37:30 +00001016 }
Manuel Pégourié-Gonnard989ed382013-09-13 14:41:45 +02001017#else
1018 ((void) output);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker8123e9d2011-01-06 15:37:30 +00001020
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001021 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Paul Bakker8123e9d2011-01-06 15:37:30 +00001022}
1023
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001024#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Hanno Becker18597cd2018-11-09 16:36:33 +00001025int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
1026 mbedtls_cipher_padding_t mode )
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001027{
1028 if( NULL == ctx ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001029 MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001030 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001031 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001032 }
1033
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001034#if defined(MBEDTLS_USE_PSA_CRYPTO)
1035 if( ctx->psa_enabled == 1 )
1036 {
1037 /* While PSA Crypto knows about CBC padding
1038 * schemes, we currently don't make them
1039 * accessible through the cipher layer. */
1040 if( mode != MBEDTLS_PADDING_NONE )
1041 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1042
1043 return( 0 );
1044 }
1045#endif /* MBEDTLS_USE_PSA_CRYPTO */
1046
Paul Bakker1a45d912013-08-14 12:04:26 +02001047 switch( mode )
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001048 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001049#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
1050 case MBEDTLS_PADDING_PKCS7:
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001051 ctx->add_padding = add_pkcs_padding;
1052 ctx->get_padding = get_pkcs_padding;
Paul Bakker1a45d912013-08-14 12:04:26 +02001053 break;
Paul Bakker48e93c82013-08-14 12:21:18 +02001054#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001055#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
1056 case MBEDTLS_PADDING_ONE_AND_ZEROS:
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +02001057 ctx->add_padding = add_one_and_zeros_padding;
1058 ctx->get_padding = get_one_and_zeros_padding;
Paul Bakker1a45d912013-08-14 12:04:26 +02001059 break;
Paul Bakker48e93c82013-08-14 12:21:18 +02001060#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001061#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
1062 case MBEDTLS_PADDING_ZEROS_AND_LEN:
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +02001063 ctx->add_padding = add_zeros_and_len_padding;
1064 ctx->get_padding = get_zeros_and_len_padding;
Paul Bakker1a45d912013-08-14 12:04:26 +02001065 break;
Paul Bakker48e93c82013-08-14 12:21:18 +02001066#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001067#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
1068 case MBEDTLS_PADDING_ZEROS:
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +02001069 ctx->add_padding = add_zeros_padding;
1070 ctx->get_padding = get_zeros_padding;
Paul Bakker1a45d912013-08-14 12:04:26 +02001071 break;
Paul Bakker48e93c82013-08-14 12:21:18 +02001072#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001073 case MBEDTLS_PADDING_NONE:
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001074 ctx->add_padding = NULL;
1075 ctx->get_padding = get_no_padding;
Paul Bakker1a45d912013-08-14 12:04:26 +02001076 break;
1077
1078 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001079 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001080 }
1081
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001082 return( 0 );
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001083}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001084#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001085
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001086#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001087int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001088 unsigned char *tag, size_t tag_len )
1089{
1090 if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001091 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001092
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001093 if( MBEDTLS_ENCRYPT != ctx->operation )
1094 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001095
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001096#if defined(MBEDTLS_USE_PSA_CRYPTO)
1097 if( ctx->psa_enabled == 1 )
1098 {
1099 /* While PSA Crypto has an API for multipart
1100 * operations, we currently don't make it
1101 * accessible through the cipher layer. */
1102 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1103
1104 return( 0 );
1105 }
1106#endif /* MBEDTLS_USE_PSA_CRYPTO */
1107
Daniel King8fe47012016-05-17 20:33:28 -03001108#if defined(MBEDTLS_GCM_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001109 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
Hanno Becker18597cd2018-11-09 16:36:33 +00001110 return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
1111 tag, tag_len ) );
Daniel King8fe47012016-05-17 20:33:28 -03001112#endif
1113
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001114#if defined(MBEDTLS_CHACHAPOLY_C)
Daniel King8fe47012016-05-17 20:33:28 -03001115 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
1116 {
1117 /* Don't allow truncated MAC for Poly1305 */
1118 if ( tag_len != 16U )
1119 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1120
Hanno Becker18597cd2018-11-09 16:36:33 +00001121 return( mbedtls_chachapoly_finish(
1122 (mbedtls_chachapoly_context*) ctx->cipher_ctx, tag ) );
Daniel King8fe47012016-05-17 20:33:28 -03001123 }
1124#endif
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001125
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001126 return( 0 );
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001127}
Paul Bakker9af723c2014-05-01 13:03:14 +02001128
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001129int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001130 const unsigned char *tag, size_t tag_len )
1131{
Daniel King8fe47012016-05-17 20:33:28 -03001132 unsigned char check_tag[16];
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001133 int ret;
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001134
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001135 if( NULL == ctx || NULL == ctx->cipher_info ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001136 MBEDTLS_DECRYPT != ctx->operation )
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001137 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001138 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001139 }
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001140
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001141#if defined(MBEDTLS_USE_PSA_CRYPTO)
1142 if( ctx->psa_enabled == 1 )
1143 {
1144 /* While PSA Crypto has an API for multipart
1145 * operations, we currently don't make it
1146 * accessible through the cipher layer. */
1147 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1148 }
1149#endif /* MBEDTLS_USE_PSA_CRYPTO */
1150
Daniel King8fe47012016-05-17 20:33:28 -03001151#if defined(MBEDTLS_GCM_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001152 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001153 {
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001154 if( tag_len > sizeof( check_tag ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001155 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001156
Hanno Becker18597cd2018-11-09 16:36:33 +00001157 if( 0 != ( ret = mbedtls_gcm_finish(
1158 (mbedtls_gcm_context *) ctx->cipher_ctx,
1159 check_tag, tag_len ) ) )
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001160 {
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001161 return( ret );
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001162 }
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001163
1164 /* Check the tag in "constant-time" */
Daniel King8fe47012016-05-17 20:33:28 -03001165 if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001166 return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001167
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001168 return( 0 );
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001169 }
Daniel King8fe47012016-05-17 20:33:28 -03001170#endif /* MBEDTLS_GCM_C */
1171
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001172#if defined(MBEDTLS_CHACHAPOLY_C)
Daniel King8fe47012016-05-17 20:33:28 -03001173 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
1174 {
1175 /* Don't allow truncated MAC for Poly1305 */
1176 if ( tag_len != sizeof( check_tag ) )
1177 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1178
Hanno Becker18597cd2018-11-09 16:36:33 +00001179 ret = mbedtls_chachapoly_finish(
1180 (mbedtls_chachapoly_context*) ctx->cipher_ctx, check_tag );
Daniel King8fe47012016-05-17 20:33:28 -03001181 if ( ret != 0 )
1182 {
1183 return( ret );
1184 }
1185
1186 /* Check the tag in "constant-time" */
1187 if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
1188 return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
1189
1190 return( 0 );
1191 }
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001192#endif /* MBEDTLS_CHACHAPOLY_C */
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001193
1194 return( 0 );
1195}
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001196#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001197
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001198/*
1199 * Packet-oriented wrapper for non-AEAD modes
1200 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001201int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001202 const unsigned char *iv, size_t iv_len,
1203 const unsigned char *input, size_t ilen,
1204 unsigned char *output, size_t *olen )
1205{
1206 int ret;
1207 size_t finish_olen;
1208
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001209#if defined(MBEDTLS_USE_PSA_CRYPTO)
1210 if( ctx->psa_enabled == 1 )
1211 {
Hanno Becker55e2e3d2018-11-12 12:36:17 +00001212 /* As in the non-PSA case, we don't check that
1213 * a key has been set. If not, the key slot will
1214 * still be in its default state of 0, which is
1215 * guaranteed to be invalid, hence the PSA-call
1216 * below will gracefully fail. */
1217 mbedtls_cipher_context_psa * const cipher_psa =
1218 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
1219
1220 psa_status_t status;
1221 psa_cipher_operation_t cipher_op;
1222 size_t part_len;
1223
1224 if( ctx->operation == MBEDTLS_DECRYPT )
1225 {
1226 status = psa_cipher_decrypt_setup( &cipher_op,
1227 cipher_psa->slot,
1228 cipher_psa->alg );
1229 }
1230 else if( ctx->operation == MBEDTLS_ENCRYPT )
1231 {
1232 status = psa_cipher_encrypt_setup( &cipher_op,
1233 cipher_psa->slot,
1234 cipher_psa->alg );
1235 }
1236 else
1237 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1238
1239 /* In the following, we can immediately return on an error,
1240 * because the PSA Crypto API guarantees that cipher operations
1241 * are terminated by unsuccessful calls to psa_cipher_update(),
1242 * and by any call to psa_cipher_finish(). */
1243 if( status != PSA_SUCCESS )
1244 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
1245
1246 status = psa_cipher_set_iv( &cipher_op, iv, iv_len );
1247 if( status != PSA_SUCCESS )
1248 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
1249
1250 status = psa_cipher_update( &cipher_op,
1251 input, ilen,
1252 output, ilen, olen );
1253 if( status != PSA_SUCCESS )
1254 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
1255
1256 status = psa_cipher_finish( &cipher_op,
1257 output + *olen, ilen - *olen,
1258 &part_len );
1259 if( status != PSA_SUCCESS )
1260 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
1261
1262 *olen += part_len;
1263 return( 0 );
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001264 }
1265#endif /* MBEDTLS_USE_PSA_CRYPTO */
1266
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001267 if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001268 return( ret );
1269
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001270 if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 )
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001271 return( ret );
1272
Hanno Becker18597cd2018-11-09 16:36:33 +00001273 if( ( ret = mbedtls_cipher_update( ctx, input, ilen,
1274 output, olen ) ) != 0 )
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001275 return( ret );
1276
Hanno Becker18597cd2018-11-09 16:36:33 +00001277 if( ( ret = mbedtls_cipher_finish( ctx, output + *olen,
1278 &finish_olen ) ) != 0 )
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001279 return( ret );
1280
1281 *olen += finish_olen;
1282
1283 return( 0 );
1284}
1285
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001286#if defined(MBEDTLS_CIPHER_MODE_AEAD)
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001287/*
1288 * Packet-oriented encryption for AEAD modes
1289 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001290int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001291 const unsigned char *iv, size_t iv_len,
1292 const unsigned char *ad, size_t ad_len,
1293 const unsigned char *input, size_t ilen,
1294 unsigned char *output, size_t *olen,
1295 unsigned char *tag, size_t tag_len )
1296{
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001297#if defined(MBEDTLS_USE_PSA_CRYPTO)
1298 if( ctx->psa_enabled == 1 )
1299 {
Hanno Beckerfe73ade2018-11-12 16:26:46 +00001300 /* As in the non-PSA case, we don't check that
1301 * a key has been set. If not, the key slot will
1302 * still be in its default state of 0, which is
1303 * guaranteed to be invalid, hence the PSA-call
1304 * below will gracefully fail. */
1305 mbedtls_cipher_context_psa * const cipher_psa =
1306 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
1307
1308 psa_status_t status;
1309
1310 /* PSA Crypto API always writes the authentication tag
1311 * at the end of the encrypted message. */
1312 if( tag != output + ilen )
1313 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1314
1315 status = psa_aead_encrypt( cipher_psa->slot,
1316 cipher_psa->alg,
1317 iv, iv_len,
1318 ad, ad_len,
1319 input, ilen,
1320 output, ilen + tag_len, olen );
1321 if( status != PSA_SUCCESS )
1322 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
1323
1324 *olen -= tag_len;
1325 return( 0 );
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001326 }
1327#endif /* MBEDTLS_USE_PSA_CRYPTO */
1328
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001329#if defined(MBEDTLS_GCM_C)
1330 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001331 {
1332 *olen = ilen;
Hanno Becker18597cd2018-11-09 16:36:33 +00001333 return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT,
1334 ilen, iv, iv_len, ad, ad_len,
1335 input, output, tag_len, tag ) );
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001336 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001337#endif /* MBEDTLS_GCM_C */
1338#if defined(MBEDTLS_CCM_C)
1339 if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001340 {
1341 *olen = ilen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001342 return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen,
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001343 iv, iv_len, ad, ad_len, input, output,
1344 tag, tag_len ) );
1345 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001346#endif /* MBEDTLS_CCM_C */
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001347#if defined(MBEDTLS_CHACHAPOLY_C)
Daniel King8fe47012016-05-17 20:33:28 -03001348 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
1349 {
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001350 /* ChachaPoly has fixed length nonce and MAC (tag) */
Daniel King8fe47012016-05-17 20:33:28 -03001351 if ( ( iv_len != ctx->cipher_info->iv_size ) ||
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001352 ( tag_len != 16U ) )
Daniel King8fe47012016-05-17 20:33:28 -03001353 {
1354 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1355 }
1356
1357 *olen = ilen;
Manuel Pégourié-Gonnard3dc62a02018-06-04 12:18:19 +02001358 return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx,
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001359 ilen, iv, ad, ad_len, input, output, tag ) );
Daniel King8fe47012016-05-17 20:33:28 -03001360 }
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001361#endif /* MBEDTLS_CHACHAPOLY_C */
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001362
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001363 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001364}
1365
1366/*
1367 * Packet-oriented decryption for AEAD modes
1368 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001369int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001370 const unsigned char *iv, size_t iv_len,
1371 const unsigned char *ad, size_t ad_len,
1372 const unsigned char *input, size_t ilen,
1373 unsigned char *output, size_t *olen,
1374 const unsigned char *tag, size_t tag_len )
1375{
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001376#if defined(MBEDTLS_USE_PSA_CRYPTO)
1377 if( ctx->psa_enabled == 1 )
1378 {
Hanno Beckerfe73ade2018-11-12 16:26:46 +00001379 /* As in the non-PSA case, we don't check that
1380 * a key has been set. If not, the key slot will
1381 * still be in its default state of 0, which is
1382 * guaranteed to be invalid, hence the PSA-call
1383 * below will gracefully fail. */
1384 mbedtls_cipher_context_psa * const cipher_psa =
1385 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
1386
1387 psa_status_t status;
1388
1389 /* PSA Crypto API always writes the authentication tag
1390 * at the end of the encrypted message. */
1391 if( tag != input + ilen )
1392 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1393
1394 status = psa_aead_decrypt( cipher_psa->slot,
1395 cipher_psa->alg,
1396 iv, iv_len,
1397 ad, ad_len,
1398 input, ilen + tag_len,
1399 output, ilen, olen );
1400 if( status == PSA_ERROR_INVALID_SIGNATURE )
1401 return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
1402 else if( status != PSA_SUCCESS )
1403 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
1404
1405 return( 0 );
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001406 }
1407#endif /* MBEDTLS_USE_PSA_CRYPTO */
1408
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001409#if defined(MBEDTLS_GCM_C)
1410 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001411 {
1412 int ret;
1413
1414 *olen = ilen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001415 ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen,
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001416 iv, iv_len, ad, ad_len,
1417 tag, tag_len, input, output );
1418
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001419 if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED )
1420 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001421
1422 return( ret );
1423 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001424#endif /* MBEDTLS_GCM_C */
1425#if defined(MBEDTLS_CCM_C)
1426 if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001427 {
1428 int ret;
1429
1430 *olen = ilen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001431 ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen,
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001432 iv, iv_len, ad, ad_len,
1433 input, output, tag, tag_len );
1434
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001435 if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED )
1436 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001437
1438 return( ret );
1439 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001440#endif /* MBEDTLS_CCM_C */
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001441#if defined(MBEDTLS_CHACHAPOLY_C)
Daniel King8fe47012016-05-17 20:33:28 -03001442 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
1443 {
Daniel King8fe47012016-05-17 20:33:28 -03001444 int ret;
1445
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001446 /* ChachaPoly has fixed length nonce and MAC (tag) */
Daniel King8fe47012016-05-17 20:33:28 -03001447 if ( ( iv_len != ctx->cipher_info->iv_size ) ||
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001448 ( tag_len != 16U ) )
Daniel King8fe47012016-05-17 20:33:28 -03001449 {
1450 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1451 }
1452
1453 *olen = ilen;
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001454 ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen,
1455 iv, ad, ad_len, tag, input, output );
Daniel King8fe47012016-05-17 20:33:28 -03001456
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001457 if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED )
1458 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
Daniel King8fe47012016-05-17 20:33:28 -03001459
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001460 return( ret );
Daniel King8fe47012016-05-17 20:33:28 -03001461 }
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001462#endif /* MBEDTLS_CHACHAPOLY_C */
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001463
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001464 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001465}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001466#endif /* MBEDTLS_CIPHER_MODE_AEAD */
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001467
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001468#endif /* MBEDTLS_CIPHER_C */