blob: 252ac09743e5eb25cbd31d1a5766802fe998046f [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 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02008 * Copyright The Mbed TLS Contributors
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 */
23
Gilles Peskinedb09ef62020-06-03 01:43:33 +020024#include "common.h"
Paul Bakker8123e9d2011-01-06 15:37:30 +000025
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020026#if defined(MBEDTLS_CIPHER_C)
Paul Bakker8123e9d2011-01-06 15:37:30 +000027
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000028#include "mbedtls/cipher.h"
Chris Jonesdaacb592021-03-09 17:03:29 +000029#include "cipher_wrap.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050030#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000031#include "mbedtls/error.h"
Gabor Mezei765862c2021-10-19 12:22:25 +020032#include "mbedtls/constant_time.h"
Paul Bakker8123e9d2011-01-06 15:37:30 +000033
Rich Evans00ab4702015-02-06 13:43:58 +000034#include <stdlib.h>
35#include <string.h>
36
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +020037#if defined(MBEDTLS_CHACHAPOLY_C)
38#include "mbedtls/chachapoly.h"
Daniel King8fe47012016-05-17 20:33:28 -030039#endif
40
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_GCM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000042#include "mbedtls/gcm.h"
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +020043#endif
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_CCM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/ccm.h"
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +020047#endif
48
Daniel Kingbd920622016-05-15 19:56:20 -030049#if defined(MBEDTLS_CHACHA20_C)
50#include "mbedtls/chacha20.h"
51#endif
52
Simon Butcher327398a2016-10-05 14:09:11 +010053#if defined(MBEDTLS_CMAC_C)
54#include "mbedtls/cmac.h"
55#endif
56
Hanno Becker4ccfc402018-11-09 16:10:57 +000057#if defined(MBEDTLS_USE_PSA_CRYPTO)
58#include "psa/crypto.h"
Manuel Pégourié-Gonnard2be8c632023-06-07 13:07:21 +020059#include "psa_util_internal.h"
Hanno Becker4ccfc402018-11-09 16:10:57 +000060#endif /* MBEDTLS_USE_PSA_CRYPTO */
61
Jack Lloydffdf2882019-03-07 17:00:32 -050062#if defined(MBEDTLS_NIST_KW_C)
63#include "mbedtls/nist_kw.h"
64#endif
65
Simon Butcher327398a2016-10-05 14:09:11 +010066#include "mbedtls/platform.h"
Simon Butcher327398a2016-10-05 14:09:11 +010067
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +020068static int supported_init = 0;
Paul Bakker72f62662011-01-16 21:27:44 +000069
Dave Rodgman3b46b772023-06-24 13:25:06 +010070static inline const mbedtls_cipher_base_t *mbedtls_cipher_get_base(
71 const mbedtls_cipher_info_t *info)
72{
Dave Rodgmande3de772023-06-24 12:51:06 +010073 return mbedtls_cipher_base_lookup_table[info->base_idx];
74}
75
Gilles Peskine449bd832023-01-11 14:50:10 +010076const int *mbedtls_cipher_list(void)
Paul Bakker72f62662011-01-16 21:27:44 +000077{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078 const mbedtls_cipher_definition_t *def;
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +020079 int *type;
80
Gilles Peskine449bd832023-01-11 14:50:10 +010081 if (!supported_init) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020082 def = mbedtls_cipher_definitions;
83 type = mbedtls_cipher_supported;
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +020084
Gilles Peskine449bd832023-01-11 14:50:10 +010085 while (def->type != 0) {
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +020086 *type++ = (*def++).type;
Gilles Peskine449bd832023-01-11 14:50:10 +010087 }
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +020088
89 *type = 0;
90
91 supported_init = 1;
92 }
93
Gilles Peskine449bd832023-01-11 14:50:10 +010094 return mbedtls_cipher_supported;
Paul Bakker72f62662011-01-16 21:27:44 +000095}
96
Hanno Becker18597cd2018-11-09 16:36:33 +000097const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type(
Gilles Peskine449bd832023-01-11 14:50:10 +010098 const mbedtls_cipher_type_t cipher_type)
Paul Bakker8123e9d2011-01-06 15:37:30 +000099{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200100 const mbedtls_cipher_definition_t *def;
Paul Bakker5e0efa72013-09-08 23:04:04 +0200101
Gilles Peskine449bd832023-01-11 14:50:10 +0100102 for (def = mbedtls_cipher_definitions; def->info != NULL; def++) {
103 if (def->type == cipher_type) {
104 return def->info;
105 }
106 }
Paul Bakker343a8702011-06-09 14:27:58 +0000107
Gilles Peskine449bd832023-01-11 14:50:10 +0100108 return NULL;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000109}
110
Hanno Becker18597cd2018-11-09 16:36:33 +0000111const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string(
Gilles Peskine449bd832023-01-11 14:50:10 +0100112 const char *cipher_name)
Paul Bakker8123e9d2011-01-06 15:37:30 +0000113{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200114 const mbedtls_cipher_definition_t *def;
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +0200115
Gilles Peskine449bd832023-01-11 14:50:10 +0100116 if (NULL == cipher_name) {
117 return NULL;
118 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000119
Gilles Peskine449bd832023-01-11 14:50:10 +0100120 for (def = mbedtls_cipher_definitions; def->info != NULL; def++) {
121 if (!strcmp(def->info->name, cipher_name)) {
122 return def->info;
123 }
124 }
Paul Bakkerfab5c822012-02-06 16:45:10 +0000125
Gilles Peskine449bd832023-01-11 14:50:10 +0100126 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_values(
130 const mbedtls_cipher_id_t cipher_id,
131 int key_bitlen,
Gilles Peskine449bd832023-01-11 14:50:10 +0100132 const mbedtls_cipher_mode_t mode)
Paul Bakkerf46b6952013-09-09 00:08:26 +0200133{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200134 const mbedtls_cipher_definition_t *def;
Paul Bakkerf46b6952013-09-09 00:08:26 +0200135
Gilles Peskine449bd832023-01-11 14:50:10 +0100136 for (def = mbedtls_cipher_definitions; def->info != NULL; def++) {
Dave Rodgmande3de772023-06-24 12:51:06 +0100137 if (mbedtls_cipher_get_base(def->info)->cipher == cipher_id &&
Dave Rodgman9282d4f2023-06-24 11:03:04 +0100138 mbedtls_cipher_info_get_key_bitlen(def->info) == (unsigned) key_bitlen &&
Gilles Peskine449bd832023-01-11 14:50:10 +0100139 def->info->mode == mode) {
140 return def->info;
141 }
142 }
Paul Bakkerf46b6952013-09-09 00:08:26 +0200143
Gilles Peskine449bd832023-01-11 14:50:10 +0100144 return NULL;
Paul Bakkerf46b6952013-09-09 00:08:26 +0200145}
146
Manuel Pégourié-Gonnardefcc1f22023-06-07 13:20:24 +0200147#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
148static inline psa_key_type_t mbedtls_psa_translate_cipher_type(
149 mbedtls_cipher_type_t cipher)
150{
151 switch (cipher) {
152 case MBEDTLS_CIPHER_AES_128_CCM:
153 case MBEDTLS_CIPHER_AES_192_CCM:
154 case MBEDTLS_CIPHER_AES_256_CCM:
155 case MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:
156 case MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:
157 case MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:
158 case MBEDTLS_CIPHER_AES_128_GCM:
159 case MBEDTLS_CIPHER_AES_192_GCM:
160 case MBEDTLS_CIPHER_AES_256_GCM:
161 case MBEDTLS_CIPHER_AES_128_CBC:
162 case MBEDTLS_CIPHER_AES_192_CBC:
163 case MBEDTLS_CIPHER_AES_256_CBC:
164 case MBEDTLS_CIPHER_AES_128_ECB:
165 case MBEDTLS_CIPHER_AES_192_ECB:
166 case MBEDTLS_CIPHER_AES_256_ECB:
167 return PSA_KEY_TYPE_AES;
168
169 /* ARIA not yet supported in PSA. */
170 /* case MBEDTLS_CIPHER_ARIA_128_CCM:
171 case MBEDTLS_CIPHER_ARIA_192_CCM:
172 case MBEDTLS_CIPHER_ARIA_256_CCM:
173 case MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:
174 case MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:
175 case MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:
176 case MBEDTLS_CIPHER_ARIA_128_GCM:
177 case MBEDTLS_CIPHER_ARIA_192_GCM:
178 case MBEDTLS_CIPHER_ARIA_256_GCM:
179 case MBEDTLS_CIPHER_ARIA_128_CBC:
180 case MBEDTLS_CIPHER_ARIA_192_CBC:
181 case MBEDTLS_CIPHER_ARIA_256_CBC:
182 return( PSA_KEY_TYPE_ARIA ); */
183
184 default:
185 return 0;
186 }
187}
188
189static inline psa_algorithm_t mbedtls_psa_translate_cipher_mode(
190 mbedtls_cipher_mode_t mode, size_t taglen)
191{
192 switch (mode) {
193 case MBEDTLS_MODE_ECB:
194 return PSA_ALG_ECB_NO_PADDING;
195 case MBEDTLS_MODE_GCM:
196 return PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, taglen);
197 case MBEDTLS_MODE_CCM:
198 return PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen);
199 case MBEDTLS_MODE_CCM_STAR_NO_TAG:
200 return PSA_ALG_CCM_STAR_NO_TAG;
201 case MBEDTLS_MODE_CBC:
202 if (taglen == 0) {
203 return PSA_ALG_CBC_NO_PADDING;
204 } else {
205 return 0;
206 }
207 default:
208 return 0;
209 }
210}
211
212static inline psa_key_usage_t mbedtls_psa_translate_cipher_operation(
213 mbedtls_operation_t op)
214{
215 switch (op) {
216 case MBEDTLS_ENCRYPT:
217 return PSA_KEY_USAGE_ENCRYPT;
218 case MBEDTLS_DECRYPT:
219 return PSA_KEY_USAGE_DECRYPT;
220 default:
221 return 0;
222 }
223}
224#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
225
Gilles Peskine449bd832023-01-11 14:50:10 +0100226void mbedtls_cipher_init(mbedtls_cipher_context_t *ctx)
Paul Bakker84bbeb52014-07-01 14:53:22 +0200227{
Gilles Peskine449bd832023-01-11 14:50:10 +0100228 memset(ctx, 0, sizeof(mbedtls_cipher_context_t));
Paul Bakker84bbeb52014-07-01 14:53:22 +0200229}
230
Gilles Peskine449bd832023-01-11 14:50:10 +0100231void mbedtls_cipher_free(mbedtls_cipher_context_t *ctx)
Paul Bakker84bbeb52014-07-01 14:53:22 +0200232{
Gilles Peskine449bd832023-01-11 14:50:10 +0100233 if (ctx == NULL) {
Paul Bakker84bbeb52014-07-01 14:53:22 +0200234 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100235 }
Paul Bakker84bbeb52014-07-01 14:53:22 +0200236
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000237#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine449bd832023-01-11 14:50:10 +0100238 if (ctx->psa_enabled == 1) {
239 if (ctx->cipher_ctx != NULL) {
Hanno Becker6118e432018-11-09 16:47:20 +0000240 mbedtls_cipher_context_psa * const cipher_psa =
241 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
242
Gilles Peskine449bd832023-01-11 14:50:10 +0100243 if (cipher_psa->slot_state == MBEDTLS_CIPHER_PSA_KEY_OWNED) {
Hanno Beckeredda8b82018-11-12 11:59:30 +0000244 /* xxx_free() doesn't allow to return failures. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100245 (void) psa_destroy_key(cipher_psa->slot);
Hanno Becker6118e432018-11-09 16:47:20 +0000246 }
247
Gilles Peskine449bd832023-01-11 14:50:10 +0100248 mbedtls_platform_zeroize(cipher_psa, sizeof(*cipher_psa));
249 mbedtls_free(cipher_psa);
Hanno Becker6118e432018-11-09 16:47:20 +0000250 }
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000251
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t));
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000253 return;
254 }
255#endif /* MBEDTLS_USE_PSA_CRYPTO */
256
Simon Butcher327398a2016-10-05 14:09:11 +0100257#if defined(MBEDTLS_CMAC_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100258 if (ctx->cmac_ctx) {
259 mbedtls_platform_zeroize(ctx->cmac_ctx,
260 sizeof(mbedtls_cmac_context_t));
261 mbedtls_free(ctx->cmac_ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100262 }
263#endif
264
Gilles Peskine449bd832023-01-11 14:50:10 +0100265 if (ctx->cipher_ctx) {
Dave Rodgmande3de772023-06-24 12:51:06 +0100266 mbedtls_cipher_get_base(ctx->cipher_info)->ctx_free_func(ctx->cipher_ctx);
Gilles Peskine449bd832023-01-11 14:50:10 +0100267 }
Paul Bakker84bbeb52014-07-01 14:53:22 +0200268
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t));
Paul Bakker84bbeb52014-07-01 14:53:22 +0200270}
271
Gilles Peskine449bd832023-01-11 14:50:10 +0100272int mbedtls_cipher_setup(mbedtls_cipher_context_t *ctx,
273 const mbedtls_cipher_info_t *cipher_info)
Paul Bakker8123e9d2011-01-06 15:37:30 +0000274{
Gilles Peskine449bd832023-01-11 14:50:10 +0100275 if (cipher_info == NULL) {
276 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
277 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000278
Gilles Peskine449bd832023-01-11 14:50:10 +0100279 memset(ctx, 0, sizeof(mbedtls_cipher_context_t));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000280
Dave Rodgmande3de772023-06-24 12:51:06 +0100281 if (NULL == (ctx->cipher_ctx = mbedtls_cipher_get_base(cipher_info)->ctx_alloc_func())) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100282 return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
283 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000284
285 ctx->cipher_info = cipher_info;
286
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200287#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +0200288 /*
289 * Ignore possible errors caused by a cipher mode that doesn't use padding
290 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200291#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
Gilles Peskine449bd832023-01-11 14:50:10 +0100292 (void) mbedtls_cipher_set_padding_mode(ctx, MBEDTLS_PADDING_PKCS7);
Paul Bakker48e93c82013-08-14 12:21:18 +0200293#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100294 (void) mbedtls_cipher_set_padding_mode(ctx, MBEDTLS_PADDING_NONE);
Paul Bakker48e93c82013-08-14 12:21:18 +0200295#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200296#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +0200297
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 return 0;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000299}
300
Hanno Becker4ccfc402018-11-09 16:10:57 +0000301#if defined(MBEDTLS_USE_PSA_CRYPTO)
Przemek Stekielef1fb4a2022-05-06 10:55:10 +0200302#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +0100303int mbedtls_cipher_setup_psa(mbedtls_cipher_context_t *ctx,
304 const mbedtls_cipher_info_t *cipher_info,
305 size_t taglen)
Hanno Becker4ccfc402018-11-09 16:10:57 +0000306{
Hanno Beckeredda8b82018-11-12 11:59:30 +0000307 psa_algorithm_t alg;
308 mbedtls_cipher_context_psa *cipher_psa;
309
Gilles Peskine449bd832023-01-11 14:50:10 +0100310 if (NULL == cipher_info || NULL == ctx) {
311 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
312 }
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000313
Hanno Becker4ee7e762018-11-17 22:00:38 +0000314 /* Check that the underlying cipher mode and cipher type are
315 * supported by the underlying PSA Crypto implementation. */
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100316 alg = mbedtls_psa_translate_cipher_mode(((mbedtls_cipher_mode_t) cipher_info->mode), taglen);
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 if (alg == 0) {
318 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
319 }
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100320 if (mbedtls_psa_translate_cipher_type(((mbedtls_cipher_type_t) cipher_info->type)) == 0) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100321 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
322 }
Hanno Becker6118e432018-11-09 16:47:20 +0000323
Gilles Peskine449bd832023-01-11 14:50:10 +0100324 memset(ctx, 0, sizeof(mbedtls_cipher_context_t));
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000325
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 cipher_psa = mbedtls_calloc(1, sizeof(mbedtls_cipher_context_psa));
327 if (cipher_psa == NULL) {
328 return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
329 }
Hanno Beckeredda8b82018-11-12 11:59:30 +0000330 cipher_psa->alg = alg;
331 ctx->cipher_ctx = cipher_psa;
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000332 ctx->cipher_info = cipher_info;
333 ctx->psa_enabled = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +0100334 return 0;
Hanno Becker4ccfc402018-11-09 16:10:57 +0000335}
Przemek Stekielef1fb4a2022-05-06 10:55:10 +0200336#endif /* MBEDTLS_DEPRECATED_REMOVED */
Hanno Becker4ccfc402018-11-09 16:10:57 +0000337#endif /* MBEDTLS_USE_PSA_CRYPTO */
338
Gilles Peskine449bd832023-01-11 14:50:10 +0100339int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx,
340 const unsigned char *key,
341 int key_bitlen,
342 const mbedtls_operation_t operation)
Paul Bakker8123e9d2011-01-06 15:37:30 +0000343{
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 if (operation != MBEDTLS_ENCRYPT && operation != MBEDTLS_DECRYPT) {
Tuvshinzaya Erdenekhuu80a6af62022-08-05 15:31:57 +0100345 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 }
347 if (ctx->cipher_info == NULL) {
348 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
349 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000350
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000351#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 if (ctx->psa_enabled == 1) {
Hanno Beckeredda8b82018-11-12 11:59:30 +0000353 mbedtls_cipher_context_psa * const cipher_psa =
354 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
355
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 size_t const key_bytelen = ((size_t) key_bitlen + 7) / 8;
Hanno Beckeredda8b82018-11-12 11:59:30 +0000357
358 psa_status_t status;
359 psa_key_type_t key_type;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200360 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Hanno Beckeredda8b82018-11-12 11:59:30 +0000361
362 /* PSA Crypto API only accepts byte-aligned keys. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 if (key_bitlen % 8 != 0) {
364 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
365 }
Hanno Beckeredda8b82018-11-12 11:59:30 +0000366
367 /* Don't allow keys to be set multiple times. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 if (cipher_psa->slot_state != MBEDTLS_CIPHER_PSA_KEY_UNSET) {
369 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
370 }
Hanno Beckeredda8b82018-11-12 11:59:30 +0000371
Andrzej Kurekc7509322019-01-08 09:36:01 -0500372 key_type = mbedtls_psa_translate_cipher_type(
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100373 ((mbedtls_cipher_type_t) ctx->cipher_info->type));
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 if (key_type == 0) {
375 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
376 }
377 psa_set_key_type(&attributes, key_type);
Hanno Beckera395d8f2018-11-12 13:33:16 +0000378
379 /* Mbed TLS' cipher layer doesn't enforce the mode of operation
Andrzej Kurekf410a5c2019-01-15 03:33:35 -0500380 * (encrypt vs. decrypt): it is possible to setup a key for encryption
381 * and use it for AEAD decryption. Until tests relying on this
382 * are changed, allow any usage in PSA. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 psa_set_key_usage_flags(&attributes,
384 /* mbedtls_psa_translate_cipher_operation( operation ); */
385 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
386 psa_set_key_algorithm(&attributes, cipher_psa->alg);
Hanno Beckeredda8b82018-11-12 11:59:30 +0000387
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 status = psa_import_key(&attributes, key, key_bytelen,
389 &cipher_psa->slot);
390 switch (status) {
Gilles Peskined2d45c12019-05-27 14:53:13 +0200391 case PSA_SUCCESS:
392 break;
393 case PSA_ERROR_INSUFFICIENT_MEMORY:
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200395 case PSA_ERROR_NOT_SUPPORTED:
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200397 default:
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200399 }
400 /* Indicate that we own the key slot and need to
401 * destroy it in mbedtls_cipher_free(). */
402 cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED;
Hanno Beckeredda8b82018-11-12 11:59:30 +0000403
404 ctx->key_bitlen = key_bitlen;
405 ctx->operation = operation;
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 return 0;
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000407 }
408#endif /* MBEDTLS_USE_PSA_CRYPTO */
409
Gilles Peskine449bd832023-01-11 14:50:10 +0100410 if ((ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN) == 0 &&
Dave Rodgman9282d4f2023-06-24 11:03:04 +0100411 (int) mbedtls_cipher_info_get_key_bitlen(ctx->cipher_info) != key_bitlen) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard398c57b2014-06-23 12:10:59 +0200413 }
Manuel Pégourié-Gonnarddd0f57f2013-09-16 11:47:43 +0200414
Manuel Pégourié-Gonnard898e0aa2015-06-18 15:28:12 +0200415 ctx->key_bitlen = key_bitlen;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000416 ctx->operation = operation;
417
Paul Bakker343a8702011-06-09 14:27:58 +0000418 /*
Simon Butcher8c0fd1e2018-04-22 22:58:07 +0100419 * For OFB, CFB and CTR mode always use the encryption key schedule
Paul Bakker343a8702011-06-09 14:27:58 +0000420 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 if (MBEDTLS_ENCRYPT == operation ||
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100422 MBEDTLS_MODE_CFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
423 MBEDTLS_MODE_OFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
424 MBEDTLS_MODE_CTR == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Dave Rodgmande3de772023-06-24 12:51:06 +0100425 return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_enc_func(ctx->cipher_ctx, key,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100426 ctx->key_bitlen);
Paul Bakker343a8702011-06-09 14:27:58 +0000427 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000428
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 if (MBEDTLS_DECRYPT == operation) {
Dave Rodgmande3de772023-06-24 12:51:06 +0100430 return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_dec_func(ctx->cipher_ctx, key,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100431 ctx->key_bitlen);
Gilles Peskine449bd832023-01-11 14:50:10 +0100432 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000433
Gilles Peskine449bd832023-01-11 14:50:10 +0100434 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000435}
436
Gilles Peskine449bd832023-01-11 14:50:10 +0100437int mbedtls_cipher_set_iv(mbedtls_cipher_context_t *ctx,
438 const unsigned char *iv,
439 size_t iv_len)
Paul Bakker8123e9d2011-01-06 15:37:30 +0000440{
Manuel Pégourié-Gonnarda235b5b2013-09-03 13:25:52 +0200441 size_t actual_iv_size;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000442
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 if (ctx->cipher_info == NULL) {
444 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
445 }
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000446#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine449bd832023-01-11 14:50:10 +0100447 if (ctx->psa_enabled == 1) {
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000448 /* While PSA Crypto has an API for multipart
449 * operations, we currently don't make it
450 * accessible through the cipher layer. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000452 }
453#endif /* MBEDTLS_USE_PSA_CRYPTO */
454
Manuel Pégourié-Gonnarde0dca4a2013-10-24 16:54:25 +0200455 /* avoid buffer overflow in ctx->iv */
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 if (iv_len > MBEDTLS_MAX_IV_LENGTH) {
457 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
458 }
Manuel Pégourié-Gonnarde0dca4a2013-10-24 16:54:25 +0200459
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 if ((ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN) != 0) {
Manuel Pégourié-Gonnarda235b5b2013-09-03 13:25:52 +0200461 actual_iv_size = iv_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 } else {
Dave Rodgmanbb521fd2023-06-24 11:21:25 +0100463 actual_iv_size = mbedtls_cipher_info_get_iv_size(ctx->cipher_info);
Manuel Pégourié-Gonnard9c853b92013-09-03 13:04:44 +0200464
Manuel Pégourié-Gonnarde0dca4a2013-10-24 16:54:25 +0200465 /* avoid reading past the end of input buffer */
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 if (actual_iv_size > iv_len) {
467 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
468 }
Manuel Pégourié-Gonnarde0dca4a2013-10-24 16:54:25 +0200469 }
470
Daniel Kingbd920622016-05-15 19:56:20 -0300471#if defined(MBEDTLS_CHACHA20_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100472 if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20) {
Andrzej Kurek33ca6af2021-12-01 21:58:05 +0100473 /* Even though the actual_iv_size is overwritten with a correct value
474 * of 12 from the cipher info, return an error to indicate that
475 * the input iv_len is wrong. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 if (iv_len != 12) {
477 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
478 }
Andrzej Kurek33ca6af2021-12-01 21:58:05 +0100479
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 if (0 != mbedtls_chacha20_starts((mbedtls_chacha20_context *) ctx->cipher_ctx,
481 iv,
482 0U)) { /* Initial counter value */
483 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Daniel Kingbd920622016-05-15 19:56:20 -0300484 }
485 }
Andrzej Kurek63439ed2021-12-01 22:19:33 +0100486#if defined(MBEDTLS_CHACHAPOLY_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100487 if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20_POLY1305 &&
Gilles Peskine449bd832023-01-11 14:50:10 +0100488 iv_len != 12) {
489 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
490 }
Andrzej Kurek63439ed2021-12-01 22:19:33 +0100491#endif
Daniel Kingbd920622016-05-15 19:56:20 -0300492#endif
493
Gilles Peskine295fc132021-04-15 18:32:23 +0200494#if defined(MBEDTLS_GCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100495 if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 return mbedtls_gcm_starts((mbedtls_gcm_context *) ctx->cipher_ctx,
497 ctx->operation,
498 iv, iv_len);
Gilles Peskine295fc132021-04-15 18:32:23 +0200499 }
500#endif
501
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200502#if defined(MBEDTLS_CCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100503 if (MBEDTLS_MODE_CCM_STAR_NO_TAG == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200504 int set_lengths_result;
505 int ccm_star_mode;
506
507 set_lengths_result = mbedtls_ccm_set_lengths(
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 (mbedtls_ccm_context *) ctx->cipher_ctx,
509 0, 0, 0);
510 if (set_lengths_result != 0) {
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200511 return set_lengths_result;
Gilles Peskine449bd832023-01-11 14:50:10 +0100512 }
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200513
Gilles Peskine449bd832023-01-11 14:50:10 +0100514 if (ctx->operation == MBEDTLS_DECRYPT) {
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200515 ccm_star_mode = MBEDTLS_CCM_STAR_DECRYPT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 } else if (ctx->operation == MBEDTLS_ENCRYPT) {
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200517 ccm_star_mode = MBEDTLS_CCM_STAR_ENCRYPT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 } else {
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200519 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100520 }
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200521
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 return mbedtls_ccm_starts((mbedtls_ccm_context *) ctx->cipher_ctx,
523 ccm_star_mode,
524 iv, iv_len);
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200525 }
526#endif
527
Gilles Peskine449bd832023-01-11 14:50:10 +0100528 if (actual_iv_size != 0) {
529 memcpy(ctx->iv, iv, actual_iv_size);
Ron Eldor4e64e0b2017-09-25 18:22:32 +0300530 ctx->iv_size = actual_iv_size;
531 }
Manuel Pégourié-Gonnard9c853b92013-09-03 13:04:44 +0200532
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 return 0;
Manuel Pégourié-Gonnard9c853b92013-09-03 13:04:44 +0200534}
535
Gilles Peskine449bd832023-01-11 14:50:10 +0100536int mbedtls_cipher_reset(mbedtls_cipher_context_t *ctx)
Manuel Pégourié-Gonnard9c853b92013-09-03 13:04:44 +0200537{
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 if (ctx->cipher_info == NULL) {
539 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
540 }
Manuel Pégourié-Gonnard2adc40c2013-09-03 13:54:12 +0200541
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000542#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 if (ctx->psa_enabled == 1) {
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000544 /* We don't support resetting PSA-based
545 * cipher contexts, yet. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000547 }
548#endif /* MBEDTLS_USE_PSA_CRYPTO */
549
Paul Bakker8123e9d2011-01-06 15:37:30 +0000550 ctx->unprocessed_len = 0;
551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 return 0;
Manuel Pégourié-Gonnard2adc40c2013-09-03 13:54:12 +0200553}
554
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200555#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100556int mbedtls_cipher_update_ad(mbedtls_cipher_context_t *ctx,
557 const unsigned char *ad, size_t ad_len)
Manuel Pégourié-Gonnard2adc40c2013-09-03 13:54:12 +0200558{
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 if (ctx->cipher_info == NULL) {
560 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
561 }
Manuel Pégourié-Gonnard2adc40c2013-09-03 13:54:12 +0200562
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000563#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 if (ctx->psa_enabled == 1) {
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000565 /* While PSA Crypto has an API for multipart
566 * operations, we currently don't make it
567 * accessible through the cipher layer. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100568 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000569 }
570#endif /* MBEDTLS_USE_PSA_CRYPTO */
571
Daniel King8fe47012016-05-17 20:33:28 -0300572#if defined(MBEDTLS_GCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100573 if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 return mbedtls_gcm_update_ad((mbedtls_gcm_context *) ctx->cipher_ctx,
575 ad, ad_len);
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200576 }
Daniel King8fe47012016-05-17 20:33:28 -0300577#endif
578
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200579#if defined(MBEDTLS_CHACHAPOLY_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100580 if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
Daniel King8fe47012016-05-17 20:33:28 -0300581 int result;
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200582 mbedtls_chachapoly_mode_t mode;
Daniel King8fe47012016-05-17 20:33:28 -0300583
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 mode = (ctx->operation == MBEDTLS_ENCRYPT)
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200585 ? MBEDTLS_CHACHAPOLY_ENCRYPT
586 : MBEDTLS_CHACHAPOLY_DECRYPT;
Daniel King8fe47012016-05-17 20:33:28 -0300587
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 result = mbedtls_chachapoly_starts((mbedtls_chachapoly_context *) ctx->cipher_ctx,
589 ctx->iv,
590 mode);
591 if (result != 0) {
592 return result;
593 }
Daniel King8fe47012016-05-17 20:33:28 -0300594
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 return mbedtls_chachapoly_update_aad((mbedtls_chachapoly_context *) ctx->cipher_ctx,
596 ad, ad_len);
Daniel King8fe47012016-05-17 20:33:28 -0300597 }
598#endif
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200599
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000601}
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200602#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
Paul Bakker8123e9d2011-01-06 15:37:30 +0000603
Gilles Peskine449bd832023-01-11 14:50:10 +0100604int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *input,
605 size_t ilen, unsigned char *output, size_t *olen)
Paul Bakker8123e9d2011-01-06 15:37:30 +0000606{
Janos Follath24eed8d2019-11-22 13:21:35 +0000607 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500608 size_t block_size;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000609
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 if (ctx->cipher_info == NULL) {
611 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
612 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000613
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000614#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine449bd832023-01-11 14:50:10 +0100615 if (ctx->psa_enabled == 1) {
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000616 /* While PSA Crypto has an API for multipart
617 * operations, we currently don't make it
618 * accessible through the cipher layer. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100619 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000620 }
621#endif /* MBEDTLS_USE_PSA_CRYPTO */
622
Paul Bakker6c212762013-12-16 15:24:50 +0100623 *olen = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 block_size = mbedtls_cipher_get_block_size(ctx);
625 if (0 == block_size) {
626 return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
Gilles Peskinea2bdcb92020-01-21 15:02:14 +0100627 }
Paul Bakker6c212762013-12-16 15:24:50 +0100628
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100629 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_ECB) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 if (ilen != block_size) {
631 return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
632 }
Paul Bakker5e0efa72013-09-08 23:04:04 +0200633
634 *olen = ilen;
635
Dave Rodgmande3de772023-06-24 12:51:06 +0100636 if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ecb_func(ctx->cipher_ctx,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100637 ctx->operation, input,
638 output))) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 return ret;
Paul Bakker5e0efa72013-09-08 23:04:04 +0200640 }
641
Gilles Peskine449bd832023-01-11 14:50:10 +0100642 return 0;
Paul Bakker5e0efa72013-09-08 23:04:04 +0200643 }
644
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200645#if defined(MBEDTLS_GCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100646 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_GCM) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 return mbedtls_gcm_update((mbedtls_gcm_context *) ctx->cipher_ctx,
648 input, ilen,
649 output, ilen, olen);
Manuel Pégourié-Gonnardb8bd5932013-09-05 13:38:15 +0200650 }
651#endif
652
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200653#if defined(MBEDTLS_CCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100654 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CCM_STAR_NO_TAG) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 return mbedtls_ccm_update((mbedtls_ccm_context *) ctx->cipher_ctx,
656 input, ilen,
657 output, ilen, olen);
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200658 }
659#endif
660
Manuel Pégourié-Gonnard32902e62018-05-10 12:30:19 +0200661#if defined(MBEDTLS_CHACHAPOLY_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100662 if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20_POLY1305) {
Manuel Pégourié-Gonnard32902e62018-05-10 12:30:19 +0200663 *olen = ilen;
Gilles Peskine449bd832023-01-11 14:50:10 +0100664 return mbedtls_chachapoly_update((mbedtls_chachapoly_context *) ctx->cipher_ctx,
665 ilen, input, output);
Manuel Pégourié-Gonnard32902e62018-05-10 12:30:19 +0200666 }
667#endif
668
Gilles Peskine449bd832023-01-11 14:50:10 +0100669 if (input == output &&
670 (ctx->unprocessed_len != 0 || ilen % block_size)) {
671 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Paul Bakker68884e32013-01-07 18:20:04 +0100672 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000673
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200674#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100675 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CBC) {
Manuel Pégourié-Gonnard989ed382013-09-13 14:41:45 +0200676 size_t copy_len = 0;
677
Paul Bakker8123e9d2011-01-06 15:37:30 +0000678 /*
679 * If there is not enough data for a full block, cache it.
680 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100681 if ((ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding &&
682 ilen <= block_size - ctx->unprocessed_len) ||
683 (ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding &&
684 ilen < block_size - ctx->unprocessed_len) ||
685 (ctx->operation == MBEDTLS_ENCRYPT &&
686 ilen < block_size - ctx->unprocessed_len)) {
687 memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input,
688 ilen);
Paul Bakker8123e9d2011-01-06 15:37:30 +0000689
690 ctx->unprocessed_len += ilen;
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 return 0;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000692 }
693
694 /*
695 * Process cached data first
696 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 if (0 != ctx->unprocessed_len) {
Janos Follath98e28a72016-05-31 14:03:54 +0100698 copy_len = block_size - ctx->unprocessed_len;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000699
Gilles Peskine449bd832023-01-11 14:50:10 +0100700 memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input,
701 copy_len);
Paul Bakker8123e9d2011-01-06 15:37:30 +0000702
Dave Rodgmande3de772023-06-24 12:51:06 +0100703 if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100704 ctx->operation,
705 block_size, ctx->iv,
706 ctx->
707 unprocessed_data,
708 output))) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 return ret;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000710 }
711
Janos Follath98e28a72016-05-31 14:03:54 +0100712 *olen += block_size;
713 output += block_size;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000714 ctx->unprocessed_len = 0;
715
716 input += copy_len;
717 ilen -= copy_len;
718 }
719
720 /*
721 * Cache final, incomplete block
722 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 if (0 != ilen) {
Andy Leiserson79e77892017-04-28 20:01:49 -0700724 /* Encryption: only cache partial blocks
725 * Decryption w/ padding: always keep at least one whole block
726 * Decryption w/o padding: only cache partial blocks
727 */
Janos Follath98e28a72016-05-31 14:03:54 +0100728 copy_len = ilen % block_size;
Gilles Peskine449bd832023-01-11 14:50:10 +0100729 if (copy_len == 0 &&
Andy Leiserson79e77892017-04-28 20:01:49 -0700730 ctx->operation == MBEDTLS_DECRYPT &&
Gilles Peskine449bd832023-01-11 14:50:10 +0100731 NULL != ctx->add_padding) {
Janos Follath98e28a72016-05-31 14:03:54 +0100732 copy_len = block_size;
Andy Leiserson79e77892017-04-28 20:01:49 -0700733 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000734
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 memcpy(ctx->unprocessed_data, &(input[ilen - copy_len]),
736 copy_len);
Paul Bakker8123e9d2011-01-06 15:37:30 +0000737
738 ctx->unprocessed_len += copy_len;
739 ilen -= copy_len;
740 }
741
742 /*
743 * Process remaining full blocks
744 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 if (ilen) {
Dave Rodgmande3de772023-06-24 12:51:06 +0100746 if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100747 ctx->operation,
748 ilen, ctx->iv,
749 input,
750 output))) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 return ret;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000752 }
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200753
Paul Bakker8123e9d2011-01-06 15:37:30 +0000754 *olen += ilen;
755 }
756
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 return 0;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000758 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200759#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker8123e9d2011-01-06 15:37:30 +0000760
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200761#if defined(MBEDTLS_CIPHER_MODE_CFB)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100762 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CFB) {
Dave Rodgmande3de772023-06-24 12:51:06 +0100763 if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cfb_func(ctx->cipher_ctx,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100764 ctx->operation, ilen,
765 &ctx->unprocessed_len,
766 ctx->iv,
767 input, output))) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 return ret;
Paul Bakker343a8702011-06-09 14:27:58 +0000769 }
770
771 *olen = ilen;
772
Gilles Peskine449bd832023-01-11 14:50:10 +0100773 return 0;
Paul Bakker343a8702011-06-09 14:27:58 +0000774 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200775#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakker343a8702011-06-09 14:27:58 +0000776
Simon Butcher8c0fd1e2018-04-22 22:58:07 +0100777#if defined(MBEDTLS_CIPHER_MODE_OFB)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100778 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_OFB) {
Dave Rodgmande3de772023-06-24 12:51:06 +0100779 if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ofb_func(ctx->cipher_ctx,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100780 ilen,
781 &ctx->unprocessed_len,
782 ctx->iv,
783 input, output))) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100784 return ret;
Simon Butcher8c0fd1e2018-04-22 22:58:07 +0100785 }
786
787 *olen = ilen;
788
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 return 0;
Simon Butcher8c0fd1e2018-04-22 22:58:07 +0100790 }
791#endif /* MBEDTLS_CIPHER_MODE_OFB */
792
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200793#if defined(MBEDTLS_CIPHER_MODE_CTR)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100794 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CTR) {
Dave Rodgmande3de772023-06-24 12:51:06 +0100795 if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ctr_func(ctx->cipher_ctx,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100796 ilen,
797 &ctx->unprocessed_len,
798 ctx->iv,
799 ctx->unprocessed_data,
800 input, output))) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 return ret;
Paul Bakker343a8702011-06-09 14:27:58 +0000802 }
803
804 *olen = ilen;
805
Gilles Peskine449bd832023-01-11 14:50:10 +0100806 return 0;
Paul Bakker343a8702011-06-09 14:27:58 +0000807 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200808#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker343a8702011-06-09 14:27:58 +0000809
Jaeden Ameroc6539902018-04-30 17:17:41 +0100810#if defined(MBEDTLS_CIPHER_MODE_XTS)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100811 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_XTS) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100812 if (ctx->unprocessed_len > 0) {
Jaeden Ameroc6539902018-04-30 17:17:41 +0100813 /* We can only process an entire data unit at a time. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100814 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Jaeden Ameroc6539902018-04-30 17:17:41 +0100815 }
816
Dave Rodgmande3de772023-06-24 12:51:06 +0100817 ret = mbedtls_cipher_get_base(ctx->cipher_info)->xts_func(ctx->cipher_ctx,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100818 ctx->operation,
819 ilen,
820 ctx->iv,
821 input,
822 output);
Gilles Peskine449bd832023-01-11 14:50:10 +0100823 if (ret != 0) {
824 return ret;
Jaeden Ameroc6539902018-04-30 17:17:41 +0100825 }
826
827 *olen = ilen;
828
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 return 0;
Jaeden Ameroc6539902018-04-30 17:17:41 +0100830 }
831#endif /* MBEDTLS_CIPHER_MODE_XTS */
832
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200833#if defined(MBEDTLS_CIPHER_MODE_STREAM)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100834 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_STREAM) {
Dave Rodgmande3de772023-06-24 12:51:06 +0100835 if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->stream_func(ctx->cipher_ctx,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100836 ilen, input,
837 output))) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 return ret;
Manuel Pégourié-Gonnard37e230c2013-08-28 13:50:42 +0200839 }
840
841 *olen = ilen;
842
Gilles Peskine449bd832023-01-11 14:50:10 +0100843 return 0;
Manuel Pégourié-Gonnard37e230c2013-08-28 13:50:42 +0200844 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200845#endif /* MBEDTLS_CIPHER_MODE_STREAM */
Manuel Pégourié-Gonnard37e230c2013-08-28 13:50:42 +0200846
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000848}
849
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200850#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
851#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200852/*
853 * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len
854 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100855static void add_pkcs_padding(unsigned char *output, size_t output_len,
856 size_t data_len)
Paul Bakker8123e9d2011-01-06 15:37:30 +0000857{
Paul Bakker23986e52011-04-24 08:57:21 +0000858 size_t padding_len = output_len - data_len;
Manuel Pégourié-Gonnardf8ab0692013-10-27 17:21:14 +0100859 unsigned char i;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000860
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 for (i = 0; i < padding_len; i++) {
Paul Bakker23986e52011-04-24 08:57:21 +0000862 output[data_len + i] = (unsigned char) padding_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000864}
865
Gilles Peskine449bd832023-01-11 14:50:10 +0100866static int get_pkcs_padding(unsigned char *input, size_t input_len,
867 size_t *data_len)
Paul Bakker8123e9d2011-01-06 15:37:30 +0000868{
Manuel Pégourié-Gonnardf8ab0692013-10-27 17:21:14 +0100869 size_t i, pad_idx;
870 unsigned char padding_len, bad = 0;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000871
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 if (NULL == input || NULL == data_len) {
873 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
874 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000875
876 padding_len = input[input_len - 1];
Paul Bakker8123e9d2011-01-06 15:37:30 +0000877 *data_len = input_len - padding_len;
878
Manuel Pégourié-Gonnardf8ab0692013-10-27 17:21:14 +0100879 /* Avoid logical || since it results in a branch */
880 bad |= padding_len > input_len;
881 bad |= padding_len == 0;
882
883 /* The number of bytes checked must be independent of padding_len,
884 * so pick input_len, which is usually 8 or 16 (one block) */
885 pad_idx = input_len - padding_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100886 for (i = 0; i < input_len; i++) {
887 bad |= (input[i] ^ padding_len) * (i >= pad_idx);
888 }
Manuel Pégourié-Gonnardf8ab0692013-10-27 17:21:14 +0100889
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 return MBEDTLS_ERR_CIPHER_INVALID_PADDING * (bad != 0);
Paul Bakker8123e9d2011-01-06 15:37:30 +0000891}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200892#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
Paul Bakker8123e9d2011-01-06 15:37:30 +0000893
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200894#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200895/*
896 * One and zeros padding: fill with 80 00 ... 00
897 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100898static void add_one_and_zeros_padding(unsigned char *output,
899 size_t output_len, size_t data_len)
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200900{
901 size_t padding_len = output_len - data_len;
902 unsigned char i = 0;
903
904 output[data_len] = 0x80;
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 for (i = 1; i < padding_len; i++) {
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200906 output[data_len + i] = 0x00;
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 }
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200908}
909
Gilles Peskine449bd832023-01-11 14:50:10 +0100910static int get_one_and_zeros_padding(unsigned char *input, size_t input_len,
911 size_t *data_len)
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200912{
Manuel Pégourié-Gonnard6c329902013-10-27 18:25:03 +0100913 size_t i;
914 unsigned char done = 0, prev_done, bad;
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200915
Gilles Peskine449bd832023-01-11 14:50:10 +0100916 if (NULL == input || NULL == data_len) {
917 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
918 }
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200919
Micha Krausba8316f2017-12-23 23:40:08 +0100920 bad = 0x80;
Manuel Pégourié-Gonnard6c329902013-10-27 18:25:03 +0100921 *data_len = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 for (i = input_len; i > 0; i--) {
Manuel Pégourié-Gonnard6c329902013-10-27 18:25:03 +0100923 prev_done = done;
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 done |= (input[i - 1] != 0);
925 *data_len |= (i - 1) * (done != prev_done);
926 bad ^= input[i - 1] * (done != prev_done);
Manuel Pégourié-Gonnard6c329902013-10-27 18:25:03 +0100927 }
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200928
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 return MBEDTLS_ERR_CIPHER_INVALID_PADDING * (bad != 0);
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200930
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200931}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200932#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200933
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200934#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200935/*
936 * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length
937 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100938static void add_zeros_and_len_padding(unsigned char *output,
939 size_t output_len, size_t data_len)
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200940{
941 size_t padding_len = output_len - data_len;
942 unsigned char i = 0;
943
Gilles Peskine449bd832023-01-11 14:50:10 +0100944 for (i = 1; i < padding_len; i++) {
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200945 output[data_len + i - 1] = 0x00;
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 }
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200947 output[output_len - 1] = (unsigned char) padding_len;
948}
949
Gilles Peskine449bd832023-01-11 14:50:10 +0100950static int get_zeros_and_len_padding(unsigned char *input, size_t input_len,
951 size_t *data_len)
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200952{
Manuel Pégourié-Gonnardd17df512013-10-27 17:32:43 +0100953 size_t i, pad_idx;
954 unsigned char padding_len, bad = 0;
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200955
Gilles Peskine449bd832023-01-11 14:50:10 +0100956 if (NULL == input || NULL == data_len) {
957 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
958 }
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200959
960 padding_len = input[input_len - 1];
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200961 *data_len = input_len - padding_len;
962
Manuel Pégourié-Gonnardd17df512013-10-27 17:32:43 +0100963 /* Avoid logical || since it results in a branch */
964 bad |= padding_len > input_len;
965 bad |= padding_len == 0;
966
967 /* The number of bytes checked must be independent of padding_len */
968 pad_idx = input_len - padding_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100969 for (i = 0; i < input_len - 1; i++) {
970 bad |= input[i] * (i >= pad_idx);
971 }
Manuel Pégourié-Gonnardd17df512013-10-27 17:32:43 +0100972
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 return MBEDTLS_ERR_CIPHER_INVALID_PADDING * (bad != 0);
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200974}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200975#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200976
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200977#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200978/*
979 * Zero padding: fill with 00 ... 00
980 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100981static void add_zeros_padding(unsigned char *output,
982 size_t output_len, size_t data_len)
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200983{
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200984 size_t i;
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200985
Gilles Peskine449bd832023-01-11 14:50:10 +0100986 for (i = data_len; i < output_len; i++) {
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200987 output[i] = 0x00;
Gilles Peskine449bd832023-01-11 14:50:10 +0100988 }
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200989}
990
Gilles Peskine449bd832023-01-11 14:50:10 +0100991static int get_zeros_padding(unsigned char *input, size_t input_len,
992 size_t *data_len)
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200993{
Manuel Pégourié-Gonnarde68bf172013-10-27 18:26:39 +0100994 size_t i;
995 unsigned char done = 0, prev_done;
996
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 if (NULL == input || NULL == data_len) {
998 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Manuel Pégourié-Gonnarde68bf172013-10-27 18:26:39 +0100999 }
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +02001000
Gilles Peskine449bd832023-01-11 14:50:10 +01001001 *data_len = 0;
1002 for (i = input_len; i > 0; i--) {
1003 prev_done = done;
1004 done |= (input[i-1] != 0);
1005 *data_len |= i * (done != prev_done);
1006 }
1007
1008 return 0;
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +02001009}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001010#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +02001011
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001012/*
1013 * No padding: don't pad :)
1014 *
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001015 * There is no add_padding function (check for NULL in mbedtls_cipher_finish)
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001016 * but a trivial get_padding function
1017 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001018static int get_no_padding(unsigned char *input, size_t input_len,
1019 size_t *data_len)
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001020{
Gilles Peskine449bd832023-01-11 14:50:10 +01001021 if (NULL == input || NULL == data_len) {
1022 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1023 }
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001024
1025 *data_len = input_len;
1026
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 return 0;
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001028}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001029#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001030
Gilles Peskine449bd832023-01-11 14:50:10 +01001031int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx,
1032 unsigned char *output, size_t *olen)
Paul Bakker8123e9d2011-01-06 15:37:30 +00001033{
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 if (ctx->cipher_info == NULL) {
1035 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1036 }
Paul Bakker8123e9d2011-01-06 15:37:30 +00001037
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001038#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine449bd832023-01-11 14:50:10 +01001039 if (ctx->psa_enabled == 1) {
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001040 /* While PSA Crypto has an API for multipart
1041 * operations, we currently don't make it
1042 * accessible through the cipher layer. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001044 }
1045#endif /* MBEDTLS_USE_PSA_CRYPTO */
1046
Paul Bakker8123e9d2011-01-06 15:37:30 +00001047 *olen = 0;
1048
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001049 if (MBEDTLS_MODE_CFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
1050 MBEDTLS_MODE_OFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
1051 MBEDTLS_MODE_CTR == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
1052 MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
1053 MBEDTLS_MODE_CCM_STAR_NO_TAG == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
1054 MBEDTLS_MODE_XTS == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
1055 MBEDTLS_MODE_STREAM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001056 return 0;
Paul Bakker343a8702011-06-09 14:27:58 +00001057 }
1058
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001059 if ((MBEDTLS_CIPHER_CHACHA20 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) ||
1060 (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type))) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001061 return 0;
Daniel Kingbd920622016-05-15 19:56:20 -03001062 }
1063
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001064 if (MBEDTLS_MODE_ECB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001065 if (ctx->unprocessed_len != 0) {
1066 return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
1067 }
Paul Bakker5e0efa72013-09-08 23:04:04 +02001068
Gilles Peskine449bd832023-01-11 14:50:10 +01001069 return 0;
Paul Bakker5e0efa72013-09-08 23:04:04 +02001070 }
1071
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001072#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001073 if (MBEDTLS_MODE_CBC == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Manuel Pégourié-Gonnard989ed382013-09-13 14:41:45 +02001074 int ret = 0;
1075
Gilles Peskine449bd832023-01-11 14:50:10 +01001076 if (MBEDTLS_ENCRYPT == ctx->operation) {
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001077 /* check for 'no padding' mode */
Gilles Peskine449bd832023-01-11 14:50:10 +01001078 if (NULL == ctx->add_padding) {
1079 if (0 != ctx->unprocessed_len) {
1080 return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
1081 }
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001082
Gilles Peskine449bd832023-01-11 14:50:10 +01001083 return 0;
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001084 }
1085
Gilles Peskine449bd832023-01-11 14:50:10 +01001086 ctx->add_padding(ctx->unprocessed_data, mbedtls_cipher_get_iv_size(ctx),
1087 ctx->unprocessed_len);
1088 } else if (mbedtls_cipher_get_block_size(ctx) != ctx->unprocessed_len) {
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001089 /*
1090 * For decrypt operations, expect a full block,
1091 * or an empty block if no padding
1092 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 if (NULL == ctx->add_padding && 0 == ctx->unprocessed_len) {
1094 return 0;
1095 }
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001096
Gilles Peskine449bd832023-01-11 14:50:10 +01001097 return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
Paul Bakker8123e9d2011-01-06 15:37:30 +00001098 }
1099
1100 /* cipher block */
Dave Rodgmande3de772023-06-24 12:51:06 +01001101 if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx,
Dave Rodgman3b46b772023-06-24 13:25:06 +01001102 ctx->operation,
1103 mbedtls_cipher_get_block_size(
1104 ctx),
1105 ctx->iv,
1106 ctx->unprocessed_data,
1107 output))) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001108 return ret;
Paul Bakker8123e9d2011-01-06 15:37:30 +00001109 }
1110
1111 /* Set output size for decryption */
Gilles Peskine449bd832023-01-11 14:50:10 +01001112 if (MBEDTLS_DECRYPT == ctx->operation) {
1113 return ctx->get_padding(output, mbedtls_cipher_get_block_size(ctx),
1114 olen);
1115 }
Paul Bakker8123e9d2011-01-06 15:37:30 +00001116
1117 /* Set output size for encryption */
Gilles Peskine449bd832023-01-11 14:50:10 +01001118 *olen = mbedtls_cipher_get_block_size(ctx);
1119 return 0;
Paul Bakker8123e9d2011-01-06 15:37:30 +00001120 }
Manuel Pégourié-Gonnard989ed382013-09-13 14:41:45 +02001121#else
1122 ((void) output);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001123#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker8123e9d2011-01-06 15:37:30 +00001124
Gilles Peskine449bd832023-01-11 14:50:10 +01001125 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Paul Bakker8123e9d2011-01-06 15:37:30 +00001126}
1127
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001128#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Gilles Peskine449bd832023-01-11 14:50:10 +01001129int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx,
1130 mbedtls_cipher_padding_t mode)
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001131{
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001132 if (NULL == ctx->cipher_info ||
1133 MBEDTLS_MODE_CBC != ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001134 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001135 }
1136
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001137#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine449bd832023-01-11 14:50:10 +01001138 if (ctx->psa_enabled == 1) {
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001139 /* While PSA Crypto knows about CBC padding
1140 * schemes, we currently don't make them
1141 * accessible through the cipher layer. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001142 if (mode != MBEDTLS_PADDING_NONE) {
1143 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
1144 }
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001145
Gilles Peskine449bd832023-01-11 14:50:10 +01001146 return 0;
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001147 }
1148#endif /* MBEDTLS_USE_PSA_CRYPTO */
1149
Gilles Peskine449bd832023-01-11 14:50:10 +01001150 switch (mode) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001151#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
Gilles Peskine449bd832023-01-11 14:50:10 +01001152 case MBEDTLS_PADDING_PKCS7:
1153 ctx->add_padding = add_pkcs_padding;
1154 ctx->get_padding = get_pkcs_padding;
1155 break;
Paul Bakker48e93c82013-08-14 12:21:18 +02001156#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001157#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
Gilles Peskine449bd832023-01-11 14:50:10 +01001158 case MBEDTLS_PADDING_ONE_AND_ZEROS:
1159 ctx->add_padding = add_one_and_zeros_padding;
1160 ctx->get_padding = get_one_and_zeros_padding;
1161 break;
Paul Bakker48e93c82013-08-14 12:21:18 +02001162#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001163#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
Gilles Peskine449bd832023-01-11 14:50:10 +01001164 case MBEDTLS_PADDING_ZEROS_AND_LEN:
1165 ctx->add_padding = add_zeros_and_len_padding;
1166 ctx->get_padding = get_zeros_and_len_padding;
1167 break;
Paul Bakker48e93c82013-08-14 12:21:18 +02001168#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001169#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
Gilles Peskine449bd832023-01-11 14:50:10 +01001170 case MBEDTLS_PADDING_ZEROS:
1171 ctx->add_padding = add_zeros_padding;
1172 ctx->get_padding = get_zeros_padding;
1173 break;
Paul Bakker48e93c82013-08-14 12:21:18 +02001174#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001175 case MBEDTLS_PADDING_NONE:
1176 ctx->add_padding = NULL;
1177 ctx->get_padding = get_no_padding;
1178 break;
Paul Bakker1a45d912013-08-14 12:04:26 +02001179
Gilles Peskine449bd832023-01-11 14:50:10 +01001180 default:
1181 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001182 }
1183
Gilles Peskine449bd832023-01-11 14:50:10 +01001184 return 0;
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001185}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001186#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001187
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001188#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001189int mbedtls_cipher_write_tag(mbedtls_cipher_context_t *ctx,
1190 unsigned char *tag, size_t tag_len)
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001191{
Gilles Peskine449bd832023-01-11 14:50:10 +01001192 if (ctx->cipher_info == NULL) {
1193 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1194 }
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001195
Gilles Peskine449bd832023-01-11 14:50:10 +01001196 if (MBEDTLS_ENCRYPT != ctx->operation) {
1197 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1198 }
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001199
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001200#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine449bd832023-01-11 14:50:10 +01001201 if (ctx->psa_enabled == 1) {
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001202 /* While PSA Crypto has an API for multipart
1203 * operations, we currently don't make it
1204 * accessible through the cipher layer. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001205 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001206 }
1207#endif /* MBEDTLS_USE_PSA_CRYPTO */
1208
Daniel King8fe47012016-05-17 20:33:28 -03001209#if defined(MBEDTLS_GCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001210 if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Gilles Peskine5a7be102021-06-23 21:51:32 +02001211 size_t output_length;
1212 /* The code here doesn't yet support alternative implementations
1213 * that can delay up to a block of output. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001214 return mbedtls_gcm_finish((mbedtls_gcm_context *) ctx->cipher_ctx,
1215 NULL, 0, &output_length,
1216 tag, tag_len);
Gilles Peskine5a7be102021-06-23 21:51:32 +02001217 }
Daniel King8fe47012016-05-17 20:33:28 -03001218#endif
1219
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001220#if defined(MBEDTLS_CHACHAPOLY_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001221 if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
Daniel King8fe47012016-05-17 20:33:28 -03001222 /* Don't allow truncated MAC for Poly1305 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001223 if (tag_len != 16U) {
1224 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1225 }
Daniel King8fe47012016-05-17 20:33:28 -03001226
Gilles Peskine449bd832023-01-11 14:50:10 +01001227 return mbedtls_chachapoly_finish(
1228 (mbedtls_chachapoly_context *) ctx->cipher_ctx, tag);
Daniel King8fe47012016-05-17 20:33:28 -03001229 }
1230#endif
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001231
Gilles Peskine449bd832023-01-11 14:50:10 +01001232 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001233}
Paul Bakker9af723c2014-05-01 13:03:14 +02001234
Gilles Peskine449bd832023-01-11 14:50:10 +01001235int mbedtls_cipher_check_tag(mbedtls_cipher_context_t *ctx,
1236 const unsigned char *tag, size_t tag_len)
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001237{
Daniel King8fe47012016-05-17 20:33:28 -03001238 unsigned char check_tag[16];
Janos Follath24eed8d2019-11-22 13:21:35 +00001239 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001240
Gilles Peskine449bd832023-01-11 14:50:10 +01001241 if (ctx->cipher_info == NULL) {
1242 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1243 }
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001244
Gilles Peskine449bd832023-01-11 14:50:10 +01001245 if (MBEDTLS_DECRYPT != ctx->operation) {
1246 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001247 }
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001248
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001249#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine449bd832023-01-11 14:50:10 +01001250 if (ctx->psa_enabled == 1) {
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001251 /* While PSA Crypto has an API for multipart
1252 * operations, we currently don't make it
1253 * accessible through the cipher layer. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001254 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001255 }
1256#endif /* MBEDTLS_USE_PSA_CRYPTO */
1257
Denis V. Lunev2df73ae2018-11-01 12:22:27 +03001258 /* Status to return on a non-authenticated algorithm. */
1259 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee7835d92021-12-13 12:32:43 +01001260
Daniel King8fe47012016-05-17 20:33:28 -03001261#if defined(MBEDTLS_GCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001262 if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Gilles Peskine5a7be102021-06-23 21:51:32 +02001263 size_t output_length;
1264 /* The code here doesn't yet support alternative implementations
1265 * that can delay up to a block of output. */
1266
Gilles Peskine449bd832023-01-11 14:50:10 +01001267 if (tag_len > sizeof(check_tag)) {
1268 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1269 }
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001270
Gilles Peskine449bd832023-01-11 14:50:10 +01001271 if (0 != (ret = mbedtls_gcm_finish(
1272 (mbedtls_gcm_context *) ctx->cipher_ctx,
1273 NULL, 0, &output_length,
1274 check_tag, tag_len))) {
1275 return ret;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001276 }
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001277
1278 /* Check the tag in "constant-time" */
Gilles Peskine449bd832023-01-11 14:50:10 +01001279 if (mbedtls_ct_memcmp(tag, check_tag, tag_len) != 0) {
Gilles Peskinee7835d92021-12-13 12:32:43 +01001280 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
Gilles Peskinecd742982021-12-13 16:57:47 +01001281 goto exit;
1282 }
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001283 }
Daniel King8fe47012016-05-17 20:33:28 -03001284#endif /* MBEDTLS_GCM_C */
1285
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001286#if defined(MBEDTLS_CHACHAPOLY_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001287 if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
Daniel King8fe47012016-05-17 20:33:28 -03001288 /* Don't allow truncated MAC for Poly1305 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001289 if (tag_len != sizeof(check_tag)) {
1290 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1291 }
Daniel King8fe47012016-05-17 20:33:28 -03001292
Hanno Becker18597cd2018-11-09 16:36:33 +00001293 ret = mbedtls_chachapoly_finish(
Gilles Peskine449bd832023-01-11 14:50:10 +01001294 (mbedtls_chachapoly_context *) ctx->cipher_ctx, check_tag);
1295 if (ret != 0) {
1296 return ret;
Daniel King8fe47012016-05-17 20:33:28 -03001297 }
1298
1299 /* Check the tag in "constant-time" */
Gilles Peskine449bd832023-01-11 14:50:10 +01001300 if (mbedtls_ct_memcmp(tag, check_tag, tag_len) != 0) {
Gilles Peskinee7835d92021-12-13 12:32:43 +01001301 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
Gilles Peskinecd742982021-12-13 16:57:47 +01001302 goto exit;
1303 }
Daniel King8fe47012016-05-17 20:33:28 -03001304 }
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001305#endif /* MBEDTLS_CHACHAPOLY_C */
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001306
Gilles Peskinecd742982021-12-13 16:57:47 +01001307exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001308 mbedtls_platform_zeroize(check_tag, tag_len);
1309 return ret;
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001310}
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001311#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001312
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001313/*
1314 * Packet-oriented wrapper for non-AEAD modes
1315 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001316int mbedtls_cipher_crypt(mbedtls_cipher_context_t *ctx,
1317 const unsigned char *iv, size_t iv_len,
1318 const unsigned char *input, size_t ilen,
1319 unsigned char *output, size_t *olen)
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001320{
Janos Follath24eed8d2019-11-22 13:21:35 +00001321 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001322 size_t finish_olen;
1323
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001324#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine449bd832023-01-11 14:50:10 +01001325 if (ctx->psa_enabled == 1) {
Hanno Becker55e2e3d2018-11-12 12:36:17 +00001326 /* As in the non-PSA case, we don't check that
1327 * a key has been set. If not, the key slot will
1328 * still be in its default state of 0, which is
1329 * guaranteed to be invalid, hence the PSA-call
1330 * below will gracefully fail. */
1331 mbedtls_cipher_context_psa * const cipher_psa =
1332 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
1333
1334 psa_status_t status;
Jaeden Amerofe96fbe2019-02-20 10:32:28 +00001335 psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT;
Hanno Becker55e2e3d2018-11-12 12:36:17 +00001336 size_t part_len;
1337
Gilles Peskine449bd832023-01-11 14:50:10 +01001338 if (ctx->operation == MBEDTLS_DECRYPT) {
1339 status = psa_cipher_decrypt_setup(&cipher_op,
1340 cipher_psa->slot,
1341 cipher_psa->alg);
1342 } else if (ctx->operation == MBEDTLS_ENCRYPT) {
1343 status = psa_cipher_encrypt_setup(&cipher_op,
1344 cipher_psa->slot,
1345 cipher_psa->alg);
1346 } else {
1347 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Hanno Becker55e2e3d2018-11-12 12:36:17 +00001348 }
Hanno Becker55e2e3d2018-11-12 12:36:17 +00001349
1350 /* In the following, we can immediately return on an error,
1351 * because the PSA Crypto API guarantees that cipher operations
1352 * are terminated by unsuccessful calls to psa_cipher_update(),
1353 * and by any call to psa_cipher_finish(). */
Gilles Peskine449bd832023-01-11 14:50:10 +01001354 if (status != PSA_SUCCESS) {
1355 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
Przemyslaw Stekiel80c6a8e2021-09-29 12:13:11 +02001356 }
Hanno Becker55e2e3d2018-11-12 12:36:17 +00001357
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001358 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) != MBEDTLS_MODE_ECB) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001359 status = psa_cipher_set_iv(&cipher_op, iv, iv_len);
1360 if (status != PSA_SUCCESS) {
1361 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
1362 }
1363 }
Hanno Becker55e2e3d2018-11-12 12:36:17 +00001364
Gilles Peskine449bd832023-01-11 14:50:10 +01001365 status = psa_cipher_update(&cipher_op,
1366 input, ilen,
1367 output, ilen, olen);
1368 if (status != PSA_SUCCESS) {
1369 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
1370 }
1371
1372 status = psa_cipher_finish(&cipher_op,
1373 output + *olen, ilen - *olen,
1374 &part_len);
1375 if (status != PSA_SUCCESS) {
1376 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
1377 }
Hanno Becker55e2e3d2018-11-12 12:36:17 +00001378
1379 *olen += part_len;
Gilles Peskine449bd832023-01-11 14:50:10 +01001380 return 0;
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001381 }
1382#endif /* MBEDTLS_USE_PSA_CRYPTO */
1383
Gilles Peskine449bd832023-01-11 14:50:10 +01001384 if ((ret = mbedtls_cipher_set_iv(ctx, iv, iv_len)) != 0) {
1385 return ret;
1386 }
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001387
Gilles Peskine449bd832023-01-11 14:50:10 +01001388 if ((ret = mbedtls_cipher_reset(ctx)) != 0) {
1389 return ret;
1390 }
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001391
Gilles Peskine449bd832023-01-11 14:50:10 +01001392 if ((ret = mbedtls_cipher_update(ctx, input, ilen,
1393 output, olen)) != 0) {
1394 return ret;
1395 }
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001396
Gilles Peskine449bd832023-01-11 14:50:10 +01001397 if ((ret = mbedtls_cipher_finish(ctx, output + *olen,
1398 &finish_olen)) != 0) {
1399 return ret;
1400 }
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001401
1402 *olen += finish_olen;
1403
Gilles Peskine449bd832023-01-11 14:50:10 +01001404 return 0;
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001405}
1406
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001407#if defined(MBEDTLS_CIPHER_MODE_AEAD)
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001408/*
TRodziewicz18efb732021-04-29 23:12:19 +02001409 * Packet-oriented encryption for AEAD modes: internal function used by
1410 * mbedtls_cipher_auth_encrypt_ext().
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001411 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001412static int mbedtls_cipher_aead_encrypt(mbedtls_cipher_context_t *ctx,
1413 const unsigned char *iv, size_t iv_len,
1414 const unsigned char *ad, size_t ad_len,
1415 const unsigned char *input, size_t ilen,
1416 unsigned char *output, size_t *olen,
1417 unsigned char *tag, size_t tag_len)
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001418{
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001419#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine449bd832023-01-11 14:50:10 +01001420 if (ctx->psa_enabled == 1) {
Hanno Beckerfe73ade2018-11-12 16:26:46 +00001421 /* As in the non-PSA case, we don't check that
1422 * a key has been set. If not, the key slot will
1423 * still be in its default state of 0, which is
1424 * guaranteed to be invalid, hence the PSA-call
1425 * below will gracefully fail. */
1426 mbedtls_cipher_context_psa * const cipher_psa =
1427 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
1428
1429 psa_status_t status;
1430
1431 /* PSA Crypto API always writes the authentication tag
1432 * at the end of the encrypted message. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001433 if (output == NULL || tag != output + ilen) {
1434 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
1435 }
Hanno Beckerfe73ade2018-11-12 16:26:46 +00001436
Gilles Peskine449bd832023-01-11 14:50:10 +01001437 status = psa_aead_encrypt(cipher_psa->slot,
1438 cipher_psa->alg,
1439 iv, iv_len,
1440 ad, ad_len,
1441 input, ilen,
1442 output, ilen + tag_len, olen);
1443 if (status != PSA_SUCCESS) {
1444 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
1445 }
Hanno Beckerfe73ade2018-11-12 16:26:46 +00001446
1447 *olen -= tag_len;
Gilles Peskine449bd832023-01-11 14:50:10 +01001448 return 0;
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001449 }
1450#endif /* MBEDTLS_USE_PSA_CRYPTO */
1451
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001452#if defined(MBEDTLS_GCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001453 if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001454 *olen = ilen;
Gilles Peskine449bd832023-01-11 14:50:10 +01001455 return mbedtls_gcm_crypt_and_tag(ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT,
1456 ilen, iv, iv_len, ad, ad_len,
1457 input, output, tag_len, tag);
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001458 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001459#endif /* MBEDTLS_GCM_C */
1460#if defined(MBEDTLS_CCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001461 if (MBEDTLS_MODE_CCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001462 *olen = ilen;
Gilles Peskine449bd832023-01-11 14:50:10 +01001463 return mbedtls_ccm_encrypt_and_tag(ctx->cipher_ctx, ilen,
1464 iv, iv_len, ad, ad_len, input, output,
1465 tag, tag_len);
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001466 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001467#endif /* MBEDTLS_CCM_C */
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001468#if defined(MBEDTLS_CHACHAPOLY_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001469 if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001470 /* ChachaPoly has fixed length nonce and MAC (tag) */
Dave Rodgmanbb521fd2023-06-24 11:21:25 +01001471 if ((iv_len != mbedtls_cipher_info_get_iv_size(ctx->cipher_info)) ||
Gilles Peskine449bd832023-01-11 14:50:10 +01001472 (tag_len != 16U)) {
1473 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Daniel King8fe47012016-05-17 20:33:28 -03001474 }
1475
1476 *olen = ilen;
Gilles Peskine449bd832023-01-11 14:50:10 +01001477 return mbedtls_chachapoly_encrypt_and_tag(ctx->cipher_ctx,
1478 ilen, iv, ad, ad_len, input, output, tag);
Daniel King8fe47012016-05-17 20:33:28 -03001479 }
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001480#endif /* MBEDTLS_CHACHAPOLY_C */
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001481
Gilles Peskine449bd832023-01-11 14:50:10 +01001482 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001483}
1484
1485/*
TRodziewicz18efb732021-04-29 23:12:19 +02001486 * Packet-oriented encryption for AEAD modes: internal function used by
1487 * mbedtls_cipher_auth_encrypt_ext().
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001488 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001489static int mbedtls_cipher_aead_decrypt(mbedtls_cipher_context_t *ctx,
1490 const unsigned char *iv, size_t iv_len,
1491 const unsigned char *ad, size_t ad_len,
1492 const unsigned char *input, size_t ilen,
1493 unsigned char *output, size_t *olen,
1494 const unsigned char *tag, size_t tag_len)
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001495{
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001496#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine449bd832023-01-11 14:50:10 +01001497 if (ctx->psa_enabled == 1) {
Hanno Beckerfe73ade2018-11-12 16:26:46 +00001498 /* As in the non-PSA case, we don't check that
1499 * a key has been set. If not, the key slot will
1500 * still be in its default state of 0, which is
1501 * guaranteed to be invalid, hence the PSA-call
1502 * below will gracefully fail. */
1503 mbedtls_cipher_context_psa * const cipher_psa =
1504 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
1505
1506 psa_status_t status;
1507
1508 /* PSA Crypto API always writes the authentication tag
1509 * at the end of the encrypted message. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001510 if (input == NULL || tag != input + ilen) {
1511 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
1512 }
Hanno Beckerfe73ade2018-11-12 16:26:46 +00001513
Gilles Peskine449bd832023-01-11 14:50:10 +01001514 status = psa_aead_decrypt(cipher_psa->slot,
1515 cipher_psa->alg,
1516 iv, iv_len,
1517 ad, ad_len,
1518 input, ilen + tag_len,
1519 output, ilen, olen);
1520 if (status == PSA_ERROR_INVALID_SIGNATURE) {
1521 return MBEDTLS_ERR_CIPHER_AUTH_FAILED;
1522 } else if (status != PSA_SUCCESS) {
1523 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
1524 }
Hanno Beckerfe73ade2018-11-12 16:26:46 +00001525
Gilles Peskine449bd832023-01-11 14:50:10 +01001526 return 0;
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001527 }
1528#endif /* MBEDTLS_USE_PSA_CRYPTO */
1529
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001530#if defined(MBEDTLS_GCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001531 if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Janos Follath24eed8d2019-11-22 13:21:35 +00001532 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001533
1534 *olen = ilen;
Gilles Peskine449bd832023-01-11 14:50:10 +01001535 ret = mbedtls_gcm_auth_decrypt(ctx->cipher_ctx, ilen,
1536 iv, iv_len, ad, ad_len,
1537 tag, tag_len, input, output);
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001538
Gilles Peskine449bd832023-01-11 14:50:10 +01001539 if (ret == MBEDTLS_ERR_GCM_AUTH_FAILED) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001540 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
Gilles Peskine449bd832023-01-11 14:50:10 +01001541 }
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001542
Gilles Peskine449bd832023-01-11 14:50:10 +01001543 return ret;
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001544 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001545#endif /* MBEDTLS_GCM_C */
1546#if defined(MBEDTLS_CCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001547 if (MBEDTLS_MODE_CCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Janos Follath24eed8d2019-11-22 13:21:35 +00001548 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001549
1550 *olen = ilen;
Gilles Peskine449bd832023-01-11 14:50:10 +01001551 ret = mbedtls_ccm_auth_decrypt(ctx->cipher_ctx, ilen,
1552 iv, iv_len, ad, ad_len,
1553 input, output, tag, tag_len);
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001554
Gilles Peskine449bd832023-01-11 14:50:10 +01001555 if (ret == MBEDTLS_ERR_CCM_AUTH_FAILED) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001556 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
Gilles Peskine449bd832023-01-11 14:50:10 +01001557 }
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001558
Gilles Peskine449bd832023-01-11 14:50:10 +01001559 return ret;
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001560 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001561#endif /* MBEDTLS_CCM_C */
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001562#if defined(MBEDTLS_CHACHAPOLY_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001563 if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
Janos Follath24eed8d2019-11-22 13:21:35 +00001564 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel King8fe47012016-05-17 20:33:28 -03001565
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001566 /* ChachaPoly has fixed length nonce and MAC (tag) */
Dave Rodgmanbb521fd2023-06-24 11:21:25 +01001567 if ((iv_len != mbedtls_cipher_info_get_iv_size(ctx->cipher_info)) ||
Gilles Peskine449bd832023-01-11 14:50:10 +01001568 (tag_len != 16U)) {
1569 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Daniel King8fe47012016-05-17 20:33:28 -03001570 }
1571
1572 *olen = ilen;
Gilles Peskine449bd832023-01-11 14:50:10 +01001573 ret = mbedtls_chachapoly_auth_decrypt(ctx->cipher_ctx, ilen,
1574 iv, ad, ad_len, tag, input, output);
Daniel King8fe47012016-05-17 20:33:28 -03001575
Gilles Peskine449bd832023-01-11 14:50:10 +01001576 if (ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED) {
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001577 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
Gilles Peskine449bd832023-01-11 14:50:10 +01001578 }
Daniel King8fe47012016-05-17 20:33:28 -03001579
Gilles Peskine449bd832023-01-11 14:50:10 +01001580 return ret;
Daniel King8fe47012016-05-17 20:33:28 -03001581 }
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001582#endif /* MBEDTLS_CHACHAPOLY_C */
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001583
Gilles Peskine449bd832023-01-11 14:50:10 +01001584 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001585}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001586#endif /* MBEDTLS_CIPHER_MODE_AEAD */
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001587
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001588#if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C)
1589/*
1590 * Packet-oriented encryption for AEAD/NIST_KW: public function.
1591 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001592int mbedtls_cipher_auth_encrypt_ext(mbedtls_cipher_context_t *ctx,
1593 const unsigned char *iv, size_t iv_len,
1594 const unsigned char *ad, size_t ad_len,
1595 const unsigned char *input, size_t ilen,
1596 unsigned char *output, size_t output_len,
1597 size_t *olen, size_t tag_len)
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001598{
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001599#if defined(MBEDTLS_NIST_KW_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001600 if (
Gilles Peskinea56d3d92020-12-04 00:47:07 +01001601#if defined(MBEDTLS_USE_PSA_CRYPTO)
1602 ctx->psa_enabled == 0 &&
1603#endif
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001604 (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
1605 MBEDTLS_MODE_KWP == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode))) {
1606 mbedtls_nist_kw_mode_t mode =
1607 (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) ?
1608 MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001609
1610 /* There is no iv, tag or ad associated with KW and KWP,
1611 * so these length should be 0 as documented. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001612 if (iv_len != 0 || tag_len != 0 || ad_len != 0) {
1613 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1614 }
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001615
Manuel Pégourié-Gonnard841b6fa2020-12-07 10:42:21 +01001616 (void) iv;
1617 (void) ad;
1618
Gilles Peskine449bd832023-01-11 14:50:10 +01001619 return mbedtls_nist_kw_wrap(ctx->cipher_ctx, mode, input, ilen,
1620 output, olen, output_len);
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001621 }
1622#endif /* MBEDTLS_NIST_KW_C */
1623
1624#if defined(MBEDTLS_CIPHER_MODE_AEAD)
1625 /* AEAD case: check length before passing on to shared function */
Gilles Peskine449bd832023-01-11 14:50:10 +01001626 if (output_len < ilen + tag_len) {
1627 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1628 }
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001629
Gilles Peskine449bd832023-01-11 14:50:10 +01001630 int ret = mbedtls_cipher_aead_encrypt(ctx, iv, iv_len, ad, ad_len,
1631 input, ilen, output, olen,
1632 output + ilen, tag_len);
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001633 *olen += tag_len;
Gilles Peskine449bd832023-01-11 14:50:10 +01001634 return ret;
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001635#else
Gilles Peskine449bd832023-01-11 14:50:10 +01001636 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001637#endif /* MBEDTLS_CIPHER_MODE_AEAD */
1638}
1639
1640/*
1641 * Packet-oriented decryption for AEAD/NIST_KW: public function.
1642 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001643int mbedtls_cipher_auth_decrypt_ext(mbedtls_cipher_context_t *ctx,
1644 const unsigned char *iv, size_t iv_len,
1645 const unsigned char *ad, size_t ad_len,
1646 const unsigned char *input, size_t ilen,
1647 unsigned char *output, size_t output_len,
1648 size_t *olen, size_t tag_len)
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001649{
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001650#if defined(MBEDTLS_NIST_KW_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001651 if (
Gilles Peskinea56d3d92020-12-04 00:47:07 +01001652#if defined(MBEDTLS_USE_PSA_CRYPTO)
1653 ctx->psa_enabled == 0 &&
1654#endif
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001655 (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
1656 MBEDTLS_MODE_KWP == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode))) {
1657 mbedtls_nist_kw_mode_t mode =
1658 (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) ?
1659 MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001660
1661 /* There is no iv, tag or ad associated with KW and KWP,
1662 * so these length should be 0 as documented. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001663 if (iv_len != 0 || tag_len != 0 || ad_len != 0) {
1664 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1665 }
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001666
Manuel Pégourié-Gonnard841b6fa2020-12-07 10:42:21 +01001667 (void) iv;
1668 (void) ad;
1669
Gilles Peskine449bd832023-01-11 14:50:10 +01001670 return mbedtls_nist_kw_unwrap(ctx->cipher_ctx, mode, input, ilen,
1671 output, olen, output_len);
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001672 }
1673#endif /* MBEDTLS_NIST_KW_C */
1674
1675#if defined(MBEDTLS_CIPHER_MODE_AEAD)
1676 /* AEAD case: check length before passing on to shared function */
Gilles Peskine449bd832023-01-11 14:50:10 +01001677 if (ilen < tag_len || output_len < ilen - tag_len) {
1678 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1679 }
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001680
Gilles Peskine449bd832023-01-11 14:50:10 +01001681 return mbedtls_cipher_aead_decrypt(ctx, iv, iv_len, ad, ad_len,
1682 input, ilen - tag_len, output, olen,
1683 input + ilen - tag_len, tag_len);
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001684#else
Gilles Peskine449bd832023-01-11 14:50:10 +01001685 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001686#endif /* MBEDTLS_CIPHER_MODE_AEAD */
1687}
1688#endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */
1689
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001690#endif /* MBEDTLS_CIPHER_C */