blob: c8217b9de1a98ff0bde7e113c65d041af4681abe [file] [log] [blame]
Paul Bakker8123e9d2011-01-06 15:37:30 +00001/**
2 * \file cipher.c
Paul Bakker7dc4c442014-02-01 22:50:26 +01003 *
Gilles Peskinee820c0a2023-08-03 17:45:20 +02004 * \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
Dave Rodgman16799db2023-11-02 19:47:20 +00009 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Paul Bakker8123e9d2011-01-06 15:37:30 +000010 */
11
Gilles Peskinedb09ef62020-06-03 01:43:33 +020012#include "common.h"
Paul Bakker8123e9d2011-01-06 15:37:30 +000013
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020014#if defined(MBEDTLS_CIPHER_C)
Paul Bakker8123e9d2011-01-06 15:37:30 +000015
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000016#include "mbedtls/cipher.h"
Chris Jonesdaacb592021-03-09 17:03:29 +000017#include "cipher_wrap.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050018#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000019#include "mbedtls/error.h"
Gabor Mezei765862c2021-10-19 12:22:25 +020020#include "mbedtls/constant_time.h"
Dave Rodgman6b7e2a52023-09-18 19:00:44 +010021#include "constant_time_internal.h"
Paul Bakker8123e9d2011-01-06 15:37:30 +000022
Rich Evans00ab4702015-02-06 13:43:58 +000023#include <stdlib.h>
24#include <string.h>
25
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +020026#if defined(MBEDTLS_CHACHAPOLY_C)
27#include "mbedtls/chachapoly.h"
Daniel King8fe47012016-05-17 20:33:28 -030028#endif
29
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020030#if defined(MBEDTLS_GCM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000031#include "mbedtls/gcm.h"
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +020032#endif
33
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_CCM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000035#include "mbedtls/ccm.h"
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +020036#endif
37
Daniel Kingbd920622016-05-15 19:56:20 -030038#if defined(MBEDTLS_CHACHA20_C)
39#include "mbedtls/chacha20.h"
40#endif
41
Simon Butcher327398a2016-10-05 14:09:11 +010042#if defined(MBEDTLS_CMAC_C)
43#include "mbedtls/cmac.h"
44#endif
45
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +020046#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
Hanno Becker4ccfc402018-11-09 16:10:57 +000047#include "psa/crypto.h"
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +020048#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
Hanno Becker4ccfc402018-11-09 16:10:57 +000049
Jack Lloydffdf2882019-03-07 17:00:32 -050050#if defined(MBEDTLS_NIST_KW_C)
51#include "mbedtls/nist_kw.h"
52#endif
53
Simon Butcher327398a2016-10-05 14:09:11 +010054#include "mbedtls/platform.h"
Simon Butcher327398a2016-10-05 14:09:11 +010055
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +020056static int supported_init = 0;
Paul Bakker72f62662011-01-16 21:27:44 +000057
Dave Rodgman3b46b772023-06-24 13:25:06 +010058static inline const mbedtls_cipher_base_t *mbedtls_cipher_get_base(
59 const mbedtls_cipher_info_t *info)
60{
Dave Rodgmande3de772023-06-24 12:51:06 +010061 return mbedtls_cipher_base_lookup_table[info->base_idx];
62}
63
Gilles Peskine449bd832023-01-11 14:50:10 +010064const int *mbedtls_cipher_list(void)
Paul Bakker72f62662011-01-16 21:27:44 +000065{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066 const mbedtls_cipher_definition_t *def;
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +020067 int *type;
68
Gilles Peskine449bd832023-01-11 14:50:10 +010069 if (!supported_init) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070 def = mbedtls_cipher_definitions;
71 type = mbedtls_cipher_supported;
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +020072
Gilles Peskine449bd832023-01-11 14:50:10 +010073 while (def->type != 0) {
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +020074 *type++ = (*def++).type;
Gilles Peskine449bd832023-01-11 14:50:10 +010075 }
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +020076
77 *type = 0;
78
79 supported_init = 1;
80 }
81
Gilles Peskine449bd832023-01-11 14:50:10 +010082 return mbedtls_cipher_supported;
Paul Bakker72f62662011-01-16 21:27:44 +000083}
84
Hanno Becker18597cd2018-11-09 16:36:33 +000085const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type(
Gilles Peskine449bd832023-01-11 14:50:10 +010086 const mbedtls_cipher_type_t cipher_type)
Paul Bakker8123e9d2011-01-06 15:37:30 +000087{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020088 const mbedtls_cipher_definition_t *def;
Paul Bakker5e0efa72013-09-08 23:04:04 +020089
Gilles Peskine449bd832023-01-11 14:50:10 +010090 for (def = mbedtls_cipher_definitions; def->info != NULL; def++) {
91 if (def->type == cipher_type) {
92 return def->info;
93 }
94 }
Paul Bakker343a8702011-06-09 14:27:58 +000095
Gilles Peskine449bd832023-01-11 14:50:10 +010096 return NULL;
Paul Bakker8123e9d2011-01-06 15:37:30 +000097}
98
Hanno Becker18597cd2018-11-09 16:36:33 +000099const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string(
Gilles Peskine449bd832023-01-11 14:50:10 +0100100 const char *cipher_name)
Paul Bakker8123e9d2011-01-06 15:37:30 +0000101{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200102 const mbedtls_cipher_definition_t *def;
Manuel Pégourié-Gonnarddace82f2013-09-18 15:12:07 +0200103
Gilles Peskine449bd832023-01-11 14:50:10 +0100104 if (NULL == cipher_name) {
105 return NULL;
106 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000107
Gilles Peskine449bd832023-01-11 14:50:10 +0100108 for (def = mbedtls_cipher_definitions; def->info != NULL; def++) {
109 if (!strcmp(def->info->name, cipher_name)) {
110 return def->info;
111 }
112 }
Paul Bakkerfab5c822012-02-06 16:45:10 +0000113
Gilles Peskine449bd832023-01-11 14:50:10 +0100114 return NULL;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000115}
116
Hanno Becker18597cd2018-11-09 16:36:33 +0000117const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values(
118 const mbedtls_cipher_id_t cipher_id,
119 int key_bitlen,
Gilles Peskine449bd832023-01-11 14:50:10 +0100120 const mbedtls_cipher_mode_t mode)
Paul Bakkerf46b6952013-09-09 00:08:26 +0200121{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200122 const mbedtls_cipher_definition_t *def;
Paul Bakkerf46b6952013-09-09 00:08:26 +0200123
Gilles Peskine449bd832023-01-11 14:50:10 +0100124 for (def = mbedtls_cipher_definitions; def->info != NULL; def++) {
Dave Rodgmande3de772023-06-24 12:51:06 +0100125 if (mbedtls_cipher_get_base(def->info)->cipher == cipher_id &&
Dave Rodgman9282d4f2023-06-24 11:03:04 +0100126 mbedtls_cipher_info_get_key_bitlen(def->info) == (unsigned) key_bitlen &&
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 def->info->mode == mode) {
128 return def->info;
129 }
130 }
Paul Bakkerf46b6952013-09-09 00:08:26 +0200131
Gilles Peskine449bd832023-01-11 14:50:10 +0100132 return NULL;
Paul Bakkerf46b6952013-09-09 00:08:26 +0200133}
134
Manuel Pégourié-Gonnardefcc1f22023-06-07 13:20:24 +0200135#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
136static inline psa_key_type_t mbedtls_psa_translate_cipher_type(
137 mbedtls_cipher_type_t cipher)
138{
139 switch (cipher) {
140 case MBEDTLS_CIPHER_AES_128_CCM:
141 case MBEDTLS_CIPHER_AES_192_CCM:
142 case MBEDTLS_CIPHER_AES_256_CCM:
143 case MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:
144 case MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:
145 case MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:
146 case MBEDTLS_CIPHER_AES_128_GCM:
147 case MBEDTLS_CIPHER_AES_192_GCM:
148 case MBEDTLS_CIPHER_AES_256_GCM:
149 case MBEDTLS_CIPHER_AES_128_CBC:
150 case MBEDTLS_CIPHER_AES_192_CBC:
151 case MBEDTLS_CIPHER_AES_256_CBC:
152 case MBEDTLS_CIPHER_AES_128_ECB:
153 case MBEDTLS_CIPHER_AES_192_ECB:
154 case MBEDTLS_CIPHER_AES_256_ECB:
155 return PSA_KEY_TYPE_AES;
156
157 /* ARIA not yet supported in PSA. */
158 /* case MBEDTLS_CIPHER_ARIA_128_CCM:
159 case MBEDTLS_CIPHER_ARIA_192_CCM:
160 case MBEDTLS_CIPHER_ARIA_256_CCM:
161 case MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:
162 case MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:
163 case MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:
164 case MBEDTLS_CIPHER_ARIA_128_GCM:
165 case MBEDTLS_CIPHER_ARIA_192_GCM:
166 case MBEDTLS_CIPHER_ARIA_256_GCM:
167 case MBEDTLS_CIPHER_ARIA_128_CBC:
168 case MBEDTLS_CIPHER_ARIA_192_CBC:
169 case MBEDTLS_CIPHER_ARIA_256_CBC:
170 return( PSA_KEY_TYPE_ARIA ); */
171
172 default:
173 return 0;
174 }
175}
176
177static inline psa_algorithm_t mbedtls_psa_translate_cipher_mode(
178 mbedtls_cipher_mode_t mode, size_t taglen)
179{
180 switch (mode) {
181 case MBEDTLS_MODE_ECB:
182 return PSA_ALG_ECB_NO_PADDING;
183 case MBEDTLS_MODE_GCM:
184 return PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, taglen);
185 case MBEDTLS_MODE_CCM:
186 return PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen);
187 case MBEDTLS_MODE_CCM_STAR_NO_TAG:
188 return PSA_ALG_CCM_STAR_NO_TAG;
189 case MBEDTLS_MODE_CBC:
190 if (taglen == 0) {
191 return PSA_ALG_CBC_NO_PADDING;
192 } else {
193 return 0;
194 }
195 default:
196 return 0;
197 }
198}
Manuel Pégourié-Gonnardefcc1f22023-06-07 13:20:24 +0200199#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
200
Gilles Peskine449bd832023-01-11 14:50:10 +0100201void mbedtls_cipher_init(mbedtls_cipher_context_t *ctx)
Paul Bakker84bbeb52014-07-01 14:53:22 +0200202{
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 memset(ctx, 0, sizeof(mbedtls_cipher_context_t));
Paul Bakker84bbeb52014-07-01 14:53:22 +0200204}
205
Gilles Peskine449bd832023-01-11 14:50:10 +0100206void mbedtls_cipher_free(mbedtls_cipher_context_t *ctx)
Paul Bakker84bbeb52014-07-01 14:53:22 +0200207{
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 if (ctx == NULL) {
Paul Bakker84bbeb52014-07-01 14:53:22 +0200209 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 }
Paul Bakker84bbeb52014-07-01 14:53:22 +0200211
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +0200212#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +0100213 if (ctx->psa_enabled == 1) {
214 if (ctx->cipher_ctx != NULL) {
Hanno Becker6118e432018-11-09 16:47:20 +0000215 mbedtls_cipher_context_psa * const cipher_psa =
216 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
217
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 if (cipher_psa->slot_state == MBEDTLS_CIPHER_PSA_KEY_OWNED) {
Hanno Beckeredda8b82018-11-12 11:59:30 +0000219 /* xxx_free() doesn't allow to return failures. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100220 (void) psa_destroy_key(cipher_psa->slot);
Hanno Becker6118e432018-11-09 16:47:20 +0000221 }
222
Tom Cosgroveca8c61b2023-07-17 15:17:40 +0100223 mbedtls_zeroize_and_free(cipher_psa, sizeof(*cipher_psa));
Hanno Becker6118e432018-11-09 16:47:20 +0000224 }
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000225
Gilles Peskine449bd832023-01-11 14:50:10 +0100226 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t));
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000227 return;
228 }
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +0200229#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000230
Simon Butcher327398a2016-10-05 14:09:11 +0100231#if defined(MBEDTLS_CMAC_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 if (ctx->cmac_ctx) {
Tom Cosgroveca8c61b2023-07-17 15:17:40 +0100233 mbedtls_zeroize_and_free(ctx->cmac_ctx,
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 sizeof(mbedtls_cmac_context_t));
Simon Butcher327398a2016-10-05 14:09:11 +0100235 }
236#endif
237
Gilles Peskine449bd832023-01-11 14:50:10 +0100238 if (ctx->cipher_ctx) {
Dave Rodgmande3de772023-06-24 12:51:06 +0100239 mbedtls_cipher_get_base(ctx->cipher_info)->ctx_free_func(ctx->cipher_ctx);
Gilles Peskine449bd832023-01-11 14:50:10 +0100240 }
Paul Bakker84bbeb52014-07-01 14:53:22 +0200241
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t));
Paul Bakker84bbeb52014-07-01 14:53:22 +0200243}
244
Gilles Peskine449bd832023-01-11 14:50:10 +0100245int mbedtls_cipher_setup(mbedtls_cipher_context_t *ctx,
246 const mbedtls_cipher_info_t *cipher_info)
Paul Bakker8123e9d2011-01-06 15:37:30 +0000247{
Gilles Peskine449bd832023-01-11 14:50:10 +0100248 if (cipher_info == NULL) {
249 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
250 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000251
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 memset(ctx, 0, sizeof(mbedtls_cipher_context_t));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000253
Valerio Settibbc46b42023-10-26 09:00:21 +0200254 if (mbedtls_cipher_get_base(cipher_info)->ctx_alloc_func != NULL) {
255 ctx->cipher_ctx = mbedtls_cipher_get_base(cipher_info)->ctx_alloc_func();
256 if (ctx->cipher_ctx == NULL) {
257 return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
258 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000260
261 ctx->cipher_info = cipher_info;
262
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 return 0;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000264}
265
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +0200266#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +0100267int mbedtls_cipher_setup_psa(mbedtls_cipher_context_t *ctx,
268 const mbedtls_cipher_info_t *cipher_info,
269 size_t taglen)
Hanno Becker4ccfc402018-11-09 16:10:57 +0000270{
Hanno Beckeredda8b82018-11-12 11:59:30 +0000271 psa_algorithm_t alg;
272 mbedtls_cipher_context_psa *cipher_psa;
273
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 if (NULL == cipher_info || NULL == ctx) {
275 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
276 }
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000277
Hanno Becker4ee7e762018-11-17 22:00:38 +0000278 /* Check that the underlying cipher mode and cipher type are
279 * supported by the underlying PSA Crypto implementation. */
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100280 alg = mbedtls_psa_translate_cipher_mode(((mbedtls_cipher_mode_t) cipher_info->mode), taglen);
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 if (alg == 0) {
282 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
283 }
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100284 if (mbedtls_psa_translate_cipher_type(((mbedtls_cipher_type_t) cipher_info->type)) == 0) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
286 }
Hanno Becker6118e432018-11-09 16:47:20 +0000287
Gilles Peskine449bd832023-01-11 14:50:10 +0100288 memset(ctx, 0, sizeof(mbedtls_cipher_context_t));
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000289
Gilles Peskine449bd832023-01-11 14:50:10 +0100290 cipher_psa = mbedtls_calloc(1, sizeof(mbedtls_cipher_context_psa));
291 if (cipher_psa == NULL) {
292 return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
293 }
Hanno Beckeredda8b82018-11-12 11:59:30 +0000294 cipher_psa->alg = alg;
295 ctx->cipher_ctx = cipher_psa;
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000296 ctx->cipher_info = cipher_info;
297 ctx->psa_enabled = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 return 0;
Hanno Becker4ccfc402018-11-09 16:10:57 +0000299}
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +0200300#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
Hanno Becker4ccfc402018-11-09 16:10:57 +0000301
Gilles Peskine449bd832023-01-11 14:50:10 +0100302int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx,
303 const unsigned char *key,
304 int key_bitlen,
305 const mbedtls_operation_t operation)
Paul Bakker8123e9d2011-01-06 15:37:30 +0000306{
Gilles Peskine449bd832023-01-11 14:50:10 +0100307 if (operation != MBEDTLS_ENCRYPT && operation != MBEDTLS_DECRYPT) {
Tuvshinzaya Erdenekhuu80a6af62022-08-05 15:31:57 +0100308 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100309 }
310 if (ctx->cipher_info == NULL) {
311 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
312 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000313
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +0200314#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +0100315 if (ctx->psa_enabled == 1) {
Hanno Beckeredda8b82018-11-12 11:59:30 +0000316 mbedtls_cipher_context_psa * const cipher_psa =
317 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
318
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 size_t const key_bytelen = ((size_t) key_bitlen + 7) / 8;
Hanno Beckeredda8b82018-11-12 11:59:30 +0000320
321 psa_status_t status;
322 psa_key_type_t key_type;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200323 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Hanno Beckeredda8b82018-11-12 11:59:30 +0000324
325 /* PSA Crypto API only accepts byte-aligned keys. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 if (key_bitlen % 8 != 0) {
327 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
328 }
Hanno Beckeredda8b82018-11-12 11:59:30 +0000329
330 /* Don't allow keys to be set multiple times. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100331 if (cipher_psa->slot_state != MBEDTLS_CIPHER_PSA_KEY_UNSET) {
332 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
333 }
Hanno Beckeredda8b82018-11-12 11:59:30 +0000334
Andrzej Kurekc7509322019-01-08 09:36:01 -0500335 key_type = mbedtls_psa_translate_cipher_type(
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100336 ((mbedtls_cipher_type_t) ctx->cipher_info->type));
Gilles Peskine449bd832023-01-11 14:50:10 +0100337 if (key_type == 0) {
338 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
339 }
340 psa_set_key_type(&attributes, key_type);
Hanno Beckera395d8f2018-11-12 13:33:16 +0000341
342 /* Mbed TLS' cipher layer doesn't enforce the mode of operation
Andrzej Kurekf410a5c2019-01-15 03:33:35 -0500343 * (encrypt vs. decrypt): it is possible to setup a key for encryption
344 * and use it for AEAD decryption. Until tests relying on this
345 * are changed, allow any usage in PSA. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 psa_set_key_usage_flags(&attributes,
Gilles Peskine449bd832023-01-11 14:50:10 +0100347 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
348 psa_set_key_algorithm(&attributes, cipher_psa->alg);
Hanno Beckeredda8b82018-11-12 11:59:30 +0000349
Gilles Peskine449bd832023-01-11 14:50:10 +0100350 status = psa_import_key(&attributes, key, key_bytelen,
351 &cipher_psa->slot);
352 switch (status) {
Gilles Peskined2d45c12019-05-27 14:53:13 +0200353 case PSA_SUCCESS:
354 break;
355 case PSA_ERROR_INSUFFICIENT_MEMORY:
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200357 case PSA_ERROR_NOT_SUPPORTED:
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200359 default:
Gilles Peskine449bd832023-01-11 14:50:10 +0100360 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200361 }
362 /* Indicate that we own the key slot and need to
363 * destroy it in mbedtls_cipher_free(). */
364 cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED;
Hanno Beckeredda8b82018-11-12 11:59:30 +0000365
366 ctx->key_bitlen = key_bitlen;
367 ctx->operation = operation;
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 return 0;
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000369 }
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +0200370#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000371
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 if ((ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN) == 0 &&
Dave Rodgman9282d4f2023-06-24 11:03:04 +0100373 (int) mbedtls_cipher_info_get_key_bitlen(ctx->cipher_info) != key_bitlen) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard398c57b2014-06-23 12:10:59 +0200375 }
Manuel Pégourié-Gonnarddd0f57f2013-09-16 11:47:43 +0200376
Manuel Pégourié-Gonnard898e0aa2015-06-18 15:28:12 +0200377 ctx->key_bitlen = key_bitlen;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000378 ctx->operation = operation;
379
Paul Bakker343a8702011-06-09 14:27:58 +0000380 /*
Simon Butcher8c0fd1e2018-04-22 22:58:07 +0100381 * For OFB, CFB and CTR mode always use the encryption key schedule
Paul Bakker343a8702011-06-09 14:27:58 +0000382 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 if (MBEDTLS_ENCRYPT == operation ||
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100384 MBEDTLS_MODE_CFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
385 MBEDTLS_MODE_OFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
386 MBEDTLS_MODE_CTR == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Dave Rodgmande3de772023-06-24 12:51:06 +0100387 return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_enc_func(ctx->cipher_ctx, key,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100388 ctx->key_bitlen);
Paul Bakker343a8702011-06-09 14:27:58 +0000389 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000390
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 if (MBEDTLS_DECRYPT == operation) {
Dave Rodgmande3de772023-06-24 12:51:06 +0100392 return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_dec_func(ctx->cipher_ctx, key,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100393 ctx->key_bitlen);
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000395
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000397}
398
Gilles Peskine449bd832023-01-11 14:50:10 +0100399int mbedtls_cipher_set_iv(mbedtls_cipher_context_t *ctx,
400 const unsigned char *iv,
401 size_t iv_len)
Paul Bakker8123e9d2011-01-06 15:37:30 +0000402{
Manuel Pégourié-Gonnarda235b5b2013-09-03 13:25:52 +0200403 size_t actual_iv_size;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000404
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 if (ctx->cipher_info == NULL) {
406 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
407 }
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +0200408#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +0100409 if (ctx->psa_enabled == 1) {
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000410 /* While PSA Crypto has an API for multipart
411 * operations, we currently don't make it
412 * accessible through the cipher layer. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000414 }
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +0200415#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000416
Manuel Pégourié-Gonnarde0dca4a2013-10-24 16:54:25 +0200417 /* avoid buffer overflow in ctx->iv */
Gilles Peskine449bd832023-01-11 14:50:10 +0100418 if (iv_len > MBEDTLS_MAX_IV_LENGTH) {
419 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
420 }
Manuel Pégourié-Gonnarde0dca4a2013-10-24 16:54:25 +0200421
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 if ((ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN) != 0) {
Manuel Pégourié-Gonnarda235b5b2013-09-03 13:25:52 +0200423 actual_iv_size = iv_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 } else {
Dave Rodgmanbb521fd2023-06-24 11:21:25 +0100425 actual_iv_size = mbedtls_cipher_info_get_iv_size(ctx->cipher_info);
Manuel Pégourié-Gonnard9c853b92013-09-03 13:04:44 +0200426
Manuel Pégourié-Gonnarde0dca4a2013-10-24 16:54:25 +0200427 /* avoid reading past the end of input buffer */
Gilles Peskine449bd832023-01-11 14:50:10 +0100428 if (actual_iv_size > iv_len) {
429 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
430 }
Manuel Pégourié-Gonnarde0dca4a2013-10-24 16:54:25 +0200431 }
432
Daniel Kingbd920622016-05-15 19:56:20 -0300433#if defined(MBEDTLS_CHACHA20_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100434 if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20) {
Andrzej Kurek33ca6af2021-12-01 21:58:05 +0100435 /* Even though the actual_iv_size is overwritten with a correct value
436 * of 12 from the cipher info, return an error to indicate that
437 * the input iv_len is wrong. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 if (iv_len != 12) {
439 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
440 }
Andrzej Kurek33ca6af2021-12-01 21:58:05 +0100441
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 if (0 != mbedtls_chacha20_starts((mbedtls_chacha20_context *) ctx->cipher_ctx,
443 iv,
444 0U)) { /* Initial counter value */
445 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Daniel Kingbd920622016-05-15 19:56:20 -0300446 }
447 }
Andrzej Kurek63439ed2021-12-01 22:19:33 +0100448#if defined(MBEDTLS_CHACHAPOLY_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100449 if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20_POLY1305 &&
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 iv_len != 12) {
451 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
452 }
Andrzej Kurek63439ed2021-12-01 22:19:33 +0100453#endif
Daniel Kingbd920622016-05-15 19:56:20 -0300454#endif
455
Gilles Peskine295fc132021-04-15 18:32:23 +0200456#if defined(MBEDTLS_GCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100457 if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 return mbedtls_gcm_starts((mbedtls_gcm_context *) ctx->cipher_ctx,
459 ctx->operation,
460 iv, iv_len);
Gilles Peskine295fc132021-04-15 18:32:23 +0200461 }
462#endif
463
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200464#if defined(MBEDTLS_CCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100465 if (MBEDTLS_MODE_CCM_STAR_NO_TAG == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200466 int set_lengths_result;
467 int ccm_star_mode;
468
469 set_lengths_result = mbedtls_ccm_set_lengths(
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 (mbedtls_ccm_context *) ctx->cipher_ctx,
471 0, 0, 0);
472 if (set_lengths_result != 0) {
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200473 return set_lengths_result;
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 }
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 if (ctx->operation == MBEDTLS_DECRYPT) {
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200477 ccm_star_mode = MBEDTLS_CCM_STAR_DECRYPT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 } else if (ctx->operation == MBEDTLS_ENCRYPT) {
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200479 ccm_star_mode = MBEDTLS_CCM_STAR_ENCRYPT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 } else {
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200481 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 }
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200483
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 return mbedtls_ccm_starts((mbedtls_ccm_context *) ctx->cipher_ctx,
485 ccm_star_mode,
486 iv, iv_len);
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200487 }
488#endif
489
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 if (actual_iv_size != 0) {
491 memcpy(ctx->iv, iv, actual_iv_size);
Ron Eldor4e64e0b2017-09-25 18:22:32 +0300492 ctx->iv_size = actual_iv_size;
493 }
Manuel Pégourié-Gonnard9c853b92013-09-03 13:04:44 +0200494
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 return 0;
Manuel Pégourié-Gonnard9c853b92013-09-03 13:04:44 +0200496}
497
Gilles Peskine449bd832023-01-11 14:50:10 +0100498int mbedtls_cipher_reset(mbedtls_cipher_context_t *ctx)
Manuel Pégourié-Gonnard9c853b92013-09-03 13:04:44 +0200499{
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 if (ctx->cipher_info == NULL) {
501 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
502 }
Manuel Pégourié-Gonnard2adc40c2013-09-03 13:54:12 +0200503
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +0200504#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 if (ctx->psa_enabled == 1) {
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000506 /* We don't support resetting PSA-based
507 * cipher contexts, yet. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000509 }
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +0200510#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000511
Paul Bakker8123e9d2011-01-06 15:37:30 +0000512 ctx->unprocessed_len = 0;
513
Gilles Peskine449bd832023-01-11 14:50:10 +0100514 return 0;
Manuel Pégourié-Gonnard2adc40c2013-09-03 13:54:12 +0200515}
516
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200517#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100518int mbedtls_cipher_update_ad(mbedtls_cipher_context_t *ctx,
519 const unsigned char *ad, size_t ad_len)
Manuel Pégourié-Gonnard2adc40c2013-09-03 13:54:12 +0200520{
Gilles Peskine449bd832023-01-11 14:50:10 +0100521 if (ctx->cipher_info == NULL) {
522 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
523 }
Manuel Pégourié-Gonnard2adc40c2013-09-03 13:54:12 +0200524
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +0200525#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 if (ctx->psa_enabled == 1) {
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000527 /* While PSA Crypto has an API for multipart
528 * operations, we currently don't make it
529 * accessible through the cipher layer. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000531 }
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +0200532#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000533
Daniel King8fe47012016-05-17 20:33:28 -0300534#if defined(MBEDTLS_GCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100535 if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100536 return mbedtls_gcm_update_ad((mbedtls_gcm_context *) ctx->cipher_ctx,
537 ad, ad_len);
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200538 }
Daniel King8fe47012016-05-17 20:33:28 -0300539#endif
540
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200541#if defined(MBEDTLS_CHACHAPOLY_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100542 if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
Daniel King8fe47012016-05-17 20:33:28 -0300543 int result;
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200544 mbedtls_chachapoly_mode_t mode;
Daniel King8fe47012016-05-17 20:33:28 -0300545
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 mode = (ctx->operation == MBEDTLS_ENCRYPT)
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200547 ? MBEDTLS_CHACHAPOLY_ENCRYPT
548 : MBEDTLS_CHACHAPOLY_DECRYPT;
Daniel King8fe47012016-05-17 20:33:28 -0300549
Gilles Peskine449bd832023-01-11 14:50:10 +0100550 result = mbedtls_chachapoly_starts((mbedtls_chachapoly_context *) ctx->cipher_ctx,
551 ctx->iv,
552 mode);
553 if (result != 0) {
554 return result;
555 }
Daniel King8fe47012016-05-17 20:33:28 -0300556
Gilles Peskine449bd832023-01-11 14:50:10 +0100557 return mbedtls_chachapoly_update_aad((mbedtls_chachapoly_context *) ctx->cipher_ctx,
558 ad, ad_len);
Daniel King8fe47012016-05-17 20:33:28 -0300559 }
560#endif
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200561
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000563}
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200564#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
Paul Bakker8123e9d2011-01-06 15:37:30 +0000565
Gilles Peskine449bd832023-01-11 14:50:10 +0100566int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *input,
567 size_t ilen, unsigned char *output, size_t *olen)
Paul Bakker8123e9d2011-01-06 15:37:30 +0000568{
Janos Follath24eed8d2019-11-22 13:21:35 +0000569 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500570 size_t block_size;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000571
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 if (ctx->cipher_info == NULL) {
573 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
574 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000575
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +0200576#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +0100577 if (ctx->psa_enabled == 1) {
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000578 /* While PSA Crypto has an API for multipart
579 * operations, we currently don't make it
580 * accessible through the cipher layer. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100581 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000582 }
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +0200583#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerce1ddee2018-11-09 16:20:29 +0000584
Paul Bakker6c212762013-12-16 15:24:50 +0100585 *olen = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 block_size = mbedtls_cipher_get_block_size(ctx);
587 if (0 == block_size) {
588 return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
Gilles Peskinea2bdcb92020-01-21 15:02:14 +0100589 }
Paul Bakker6c212762013-12-16 15:24:50 +0100590
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100591 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_ECB) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100592 if (ilen != block_size) {
593 return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
594 }
Paul Bakker5e0efa72013-09-08 23:04:04 +0200595
596 *olen = ilen;
597
Dave Rodgmande3de772023-06-24 12:51:06 +0100598 if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ecb_func(ctx->cipher_ctx,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100599 ctx->operation, input,
600 output))) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 return ret;
Paul Bakker5e0efa72013-09-08 23:04:04 +0200602 }
603
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 return 0;
Paul Bakker5e0efa72013-09-08 23:04:04 +0200605 }
606
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200607#if defined(MBEDTLS_GCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100608 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_GCM) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100609 return mbedtls_gcm_update((mbedtls_gcm_context *) ctx->cipher_ctx,
610 input, ilen,
611 output, ilen, olen);
Manuel Pégourié-Gonnardb8bd5932013-09-05 13:38:15 +0200612 }
613#endif
614
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200615#if defined(MBEDTLS_CCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100616 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CCM_STAR_NO_TAG) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 return mbedtls_ccm_update((mbedtls_ccm_context *) ctx->cipher_ctx,
618 input, ilen,
619 output, ilen, olen);
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200620 }
621#endif
622
Manuel Pégourié-Gonnard32902e62018-05-10 12:30:19 +0200623#if defined(MBEDTLS_CHACHAPOLY_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100624 if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20_POLY1305) {
Manuel Pégourié-Gonnard32902e62018-05-10 12:30:19 +0200625 *olen = ilen;
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 return mbedtls_chachapoly_update((mbedtls_chachapoly_context *) ctx->cipher_ctx,
627 ilen, input, output);
Manuel Pégourié-Gonnard32902e62018-05-10 12:30:19 +0200628 }
629#endif
630
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 if (input == output &&
632 (ctx->unprocessed_len != 0 || ilen % block_size)) {
633 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Paul Bakker68884e32013-01-07 18:20:04 +0100634 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000635
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200636#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100637 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CBC) {
Manuel Pégourié-Gonnard989ed382013-09-13 14:41:45 +0200638 size_t copy_len = 0;
639
Paul Bakker8123e9d2011-01-06 15:37:30 +0000640 /*
641 * If there is not enough data for a full block, cache it.
642 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 if ((ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding &&
644 ilen <= block_size - ctx->unprocessed_len) ||
645 (ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding &&
646 ilen < block_size - ctx->unprocessed_len) ||
647 (ctx->operation == MBEDTLS_ENCRYPT &&
648 ilen < block_size - ctx->unprocessed_len)) {
649 memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input,
650 ilen);
Paul Bakker8123e9d2011-01-06 15:37:30 +0000651
652 ctx->unprocessed_len += ilen;
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 return 0;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000654 }
655
656 /*
657 * Process cached data first
658 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 if (0 != ctx->unprocessed_len) {
Janos Follath98e28a72016-05-31 14:03:54 +0100660 copy_len = block_size - ctx->unprocessed_len;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000661
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input,
663 copy_len);
Paul Bakker8123e9d2011-01-06 15:37:30 +0000664
Dave Rodgmande3de772023-06-24 12:51:06 +0100665 if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100666 ctx->operation,
667 block_size, ctx->iv,
668 ctx->
669 unprocessed_data,
670 output))) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 return ret;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000672 }
673
Janos Follath98e28a72016-05-31 14:03:54 +0100674 *olen += block_size;
675 output += block_size;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000676 ctx->unprocessed_len = 0;
677
678 input += copy_len;
679 ilen -= copy_len;
680 }
681
682 /*
683 * Cache final, incomplete block
684 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 if (0 != ilen) {
Andy Leiserson79e77892017-04-28 20:01:49 -0700686 /* Encryption: only cache partial blocks
687 * Decryption w/ padding: always keep at least one whole block
688 * Decryption w/o padding: only cache partial blocks
689 */
Janos Follath98e28a72016-05-31 14:03:54 +0100690 copy_len = ilen % block_size;
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 if (copy_len == 0 &&
Andy Leiserson79e77892017-04-28 20:01:49 -0700692 ctx->operation == MBEDTLS_DECRYPT &&
Gilles Peskine449bd832023-01-11 14:50:10 +0100693 NULL != ctx->add_padding) {
Janos Follath98e28a72016-05-31 14:03:54 +0100694 copy_len = block_size;
Andy Leiserson79e77892017-04-28 20:01:49 -0700695 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000696
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 memcpy(ctx->unprocessed_data, &(input[ilen - copy_len]),
698 copy_len);
Paul Bakker8123e9d2011-01-06 15:37:30 +0000699
700 ctx->unprocessed_len += copy_len;
701 ilen -= copy_len;
702 }
703
704 /*
705 * Process remaining full blocks
706 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 if (ilen) {
Dave Rodgmande3de772023-06-24 12:51:06 +0100708 if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100709 ctx->operation,
710 ilen, ctx->iv,
711 input,
712 output))) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 return ret;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000714 }
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200715
Paul Bakker8123e9d2011-01-06 15:37:30 +0000716 *olen += ilen;
717 }
718
Gilles Peskine449bd832023-01-11 14:50:10 +0100719 return 0;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000720 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200721#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker8123e9d2011-01-06 15:37:30 +0000722
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200723#if defined(MBEDTLS_CIPHER_MODE_CFB)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100724 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CFB) {
Dave Rodgmande3de772023-06-24 12:51:06 +0100725 if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cfb_func(ctx->cipher_ctx,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100726 ctx->operation, ilen,
727 &ctx->unprocessed_len,
728 ctx->iv,
729 input, output))) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 return ret;
Paul Bakker343a8702011-06-09 14:27:58 +0000731 }
732
733 *olen = ilen;
734
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 return 0;
Paul Bakker343a8702011-06-09 14:27:58 +0000736 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200737#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakker343a8702011-06-09 14:27:58 +0000738
Simon Butcher8c0fd1e2018-04-22 22:58:07 +0100739#if defined(MBEDTLS_CIPHER_MODE_OFB)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100740 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_OFB) {
Dave Rodgmande3de772023-06-24 12:51:06 +0100741 if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ofb_func(ctx->cipher_ctx,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100742 ilen,
743 &ctx->unprocessed_len,
744 ctx->iv,
745 input, output))) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 return ret;
Simon Butcher8c0fd1e2018-04-22 22:58:07 +0100747 }
748
749 *olen = ilen;
750
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 return 0;
Simon Butcher8c0fd1e2018-04-22 22:58:07 +0100752 }
753#endif /* MBEDTLS_CIPHER_MODE_OFB */
754
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200755#if defined(MBEDTLS_CIPHER_MODE_CTR)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100756 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CTR) {
Dave Rodgmande3de772023-06-24 12:51:06 +0100757 if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ctr_func(ctx->cipher_ctx,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100758 ilen,
759 &ctx->unprocessed_len,
760 ctx->iv,
761 ctx->unprocessed_data,
762 input, output))) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100763 return ret;
Paul Bakker343a8702011-06-09 14:27:58 +0000764 }
765
766 *olen = ilen;
767
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 return 0;
Paul Bakker343a8702011-06-09 14:27:58 +0000769 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200770#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker343a8702011-06-09 14:27:58 +0000771
Jaeden Ameroc6539902018-04-30 17:17:41 +0100772#if defined(MBEDTLS_CIPHER_MODE_XTS)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100773 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_XTS) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 if (ctx->unprocessed_len > 0) {
Jaeden Ameroc6539902018-04-30 17:17:41 +0100775 /* We can only process an entire data unit at a time. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Jaeden Ameroc6539902018-04-30 17:17:41 +0100777 }
778
Dave Rodgmande3de772023-06-24 12:51:06 +0100779 ret = mbedtls_cipher_get_base(ctx->cipher_info)->xts_func(ctx->cipher_ctx,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100780 ctx->operation,
781 ilen,
782 ctx->iv,
783 input,
784 output);
Gilles Peskine449bd832023-01-11 14:50:10 +0100785 if (ret != 0) {
786 return ret;
Jaeden Ameroc6539902018-04-30 17:17:41 +0100787 }
788
789 *olen = ilen;
790
Gilles Peskine449bd832023-01-11 14:50:10 +0100791 return 0;
Jaeden Ameroc6539902018-04-30 17:17:41 +0100792 }
793#endif /* MBEDTLS_CIPHER_MODE_XTS */
794
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200795#if defined(MBEDTLS_CIPHER_MODE_STREAM)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +0100796 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_STREAM) {
Dave Rodgmande3de772023-06-24 12:51:06 +0100797 if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->stream_func(ctx->cipher_ctx,
Dave Rodgman3b46b772023-06-24 13:25:06 +0100798 ilen, input,
799 output))) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100800 return ret;
Manuel Pégourié-Gonnard37e230c2013-08-28 13:50:42 +0200801 }
802
803 *olen = ilen;
804
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 return 0;
Manuel Pégourié-Gonnard37e230c2013-08-28 13:50:42 +0200806 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200807#endif /* MBEDTLS_CIPHER_MODE_STREAM */
Manuel Pégourié-Gonnard37e230c2013-08-28 13:50:42 +0200808
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000810}
811
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200812#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
813#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200814/*
815 * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len
816 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100817static void add_pkcs_padding(unsigned char *output, size_t output_len,
818 size_t data_len)
Paul Bakker8123e9d2011-01-06 15:37:30 +0000819{
Paul Bakker23986e52011-04-24 08:57:21 +0000820 size_t padding_len = output_len - data_len;
Manuel Pégourié-Gonnardf8ab0692013-10-27 17:21:14 +0100821 unsigned char i;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000822
Gilles Peskine449bd832023-01-11 14:50:10 +0100823 for (i = 0; i < padding_len; i++) {
Paul Bakker23986e52011-04-24 08:57:21 +0000824 output[data_len + i] = (unsigned char) padding_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100825 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000826}
827
Gilles Peskine449bd832023-01-11 14:50:10 +0100828static int get_pkcs_padding(unsigned char *input, size_t input_len,
829 size_t *data_len)
Paul Bakker8123e9d2011-01-06 15:37:30 +0000830{
Manuel Pégourié-Gonnardf8ab0692013-10-27 17:21:14 +0100831 size_t i, pad_idx;
Dave Rodgman6b7e2a52023-09-18 19:00:44 +0100832 unsigned char padding_len;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000833
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 if (NULL == input || NULL == data_len) {
835 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
836 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000837
838 padding_len = input[input_len - 1];
Paul Bakker8123e9d2011-01-06 15:37:30 +0000839 *data_len = input_len - padding_len;
840
Dave Rodgmane834d6c2023-09-20 19:06:53 +0100841 mbedtls_ct_condition_t bad = mbedtls_ct_uint_gt(padding_len, input_len);
Dave Rodgman6b7e2a52023-09-18 19:00:44 +0100842 bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0));
Manuel Pégourié-Gonnardf8ab0692013-10-27 17:21:14 +0100843
844 /* The number of bytes checked must be independent of padding_len,
845 * so pick input_len, which is usually 8 or 16 (one block) */
846 pad_idx = input_len - padding_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 for (i = 0; i < input_len; i++) {
Dave Rodgmanc43a0a42023-09-20 19:07:22 +0100848 mbedtls_ct_condition_t in_padding = mbedtls_ct_uint_ge(i, pad_idx);
849 mbedtls_ct_condition_t different = mbedtls_ct_uint_ne(input[i], padding_len);
850 bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_and(in_padding, different));
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 }
Manuel Pégourié-Gonnardf8ab0692013-10-27 17:21:14 +0100852
Dave Rodgmand03f4832023-09-22 09:52:15 +0100853 return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING);
Paul Bakker8123e9d2011-01-06 15:37:30 +0000854}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200855#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
Paul Bakker8123e9d2011-01-06 15:37:30 +0000856
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200857#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200858/*
859 * One and zeros padding: fill with 80 00 ... 00
860 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100861static void add_one_and_zeros_padding(unsigned char *output,
862 size_t output_len, size_t data_len)
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200863{
864 size_t padding_len = output_len - data_len;
865 unsigned char i = 0;
866
867 output[data_len] = 0x80;
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 for (i = 1; i < padding_len; i++) {
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200869 output[data_len + i] = 0x00;
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 }
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200871}
872
Gilles Peskine449bd832023-01-11 14:50:10 +0100873static int get_one_and_zeros_padding(unsigned char *input, size_t input_len,
874 size_t *data_len)
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200875{
Gilles Peskine449bd832023-01-11 14:50:10 +0100876 if (NULL == input || NULL == data_len) {
877 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
878 }
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200879
Dave Rodgman89a9bd52023-09-19 14:37:50 +0100880 mbedtls_ct_condition_t in_padding = MBEDTLS_CT_TRUE;
881 mbedtls_ct_condition_t bad = MBEDTLS_CT_TRUE;
882
Manuel Pégourié-Gonnard6c329902013-10-27 18:25:03 +0100883 *data_len = 0;
Dave Rodgman89a9bd52023-09-19 14:37:50 +0100884
Dave Rodgman437500c2023-09-19 21:36:43 +0100885 for (ptrdiff_t i = (ptrdiff_t) (input_len) - 1; i >= 0; i--) {
Dave Rodgman89a9bd52023-09-19 14:37:50 +0100886 mbedtls_ct_condition_t is_nonzero = mbedtls_ct_bool(input[i]);
887
888 mbedtls_ct_condition_t hit_first_nonzero = mbedtls_ct_bool_and(is_nonzero, in_padding);
889
890 *data_len = mbedtls_ct_size_if(hit_first_nonzero, i, *data_len);
891
Dave Rodgmanfd965792023-09-19 21:51:50 +0100892 bad = mbedtls_ct_bool_if(hit_first_nonzero, mbedtls_ct_uint_ne(input[i], 0x80), bad);
Dave Rodgman89a9bd52023-09-19 14:37:50 +0100893
894 in_padding = mbedtls_ct_bool_and(in_padding, mbedtls_ct_bool_not(is_nonzero));
Manuel Pégourié-Gonnard6c329902013-10-27 18:25:03 +0100895 }
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200896
Dave Rodgmand03f4832023-09-22 09:52:15 +0100897 return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING);
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200898}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200899#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
Manuel Pégourié-Gonnard679f9e92013-07-26 12:46:02 +0200900
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200901#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200902/*
903 * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length
904 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100905static void add_zeros_and_len_padding(unsigned char *output,
906 size_t output_len, size_t data_len)
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200907{
908 size_t padding_len = output_len - data_len;
909 unsigned char i = 0;
910
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 for (i = 1; i < padding_len; i++) {
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200912 output[data_len + i - 1] = 0x00;
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 }
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200914 output[output_len - 1] = (unsigned char) padding_len;
915}
916
Gilles Peskine449bd832023-01-11 14:50:10 +0100917static int get_zeros_and_len_padding(unsigned char *input, size_t input_len,
918 size_t *data_len)
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200919{
Manuel Pégourié-Gonnardd17df512013-10-27 17:32:43 +0100920 size_t i, pad_idx;
Dave Rodgman6cec41c2023-09-18 21:51:55 +0100921 unsigned char padding_len;
922 mbedtls_ct_condition_t bad;
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200923
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 if (NULL == input || NULL == data_len) {
925 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
926 }
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200927
928 padding_len = input[input_len - 1];
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200929 *data_len = input_len - padding_len;
930
Manuel Pégourié-Gonnardd17df512013-10-27 17:32:43 +0100931 /* Avoid logical || since it results in a branch */
Dave Rodgman6cec41c2023-09-18 21:51:55 +0100932 bad = mbedtls_ct_uint_gt(padding_len, input_len);
933 bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0));
Manuel Pégourié-Gonnardd17df512013-10-27 17:32:43 +0100934
935 /* The number of bytes checked must be independent of padding_len */
936 pad_idx = input_len - padding_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 for (i = 0; i < input_len - 1; i++) {
Dave Rodgman6cec41c2023-09-18 21:51:55 +0100938 mbedtls_ct_condition_t is_padding = mbedtls_ct_uint_ge(i, pad_idx);
Dave Rodgman6be4bcf2023-09-19 19:47:51 +0100939 mbedtls_ct_condition_t nonzero_pad_byte;
Dave Rodgmanfd965792023-09-19 21:51:50 +0100940 nonzero_pad_byte = mbedtls_ct_bool_if_else_0(is_padding, mbedtls_ct_bool(input[i]));
Dave Rodgman6cec41c2023-09-18 21:51:55 +0100941 bad = mbedtls_ct_bool_or(bad, nonzero_pad_byte);
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 }
Manuel Pégourié-Gonnardd17df512013-10-27 17:32:43 +0100943
Dave Rodgmand03f4832023-09-22 09:52:15 +0100944 return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING);
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200945}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200946#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
Manuel Pégourié-Gonnard8d4291b2013-07-26 14:55:18 +0200947
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200948#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200949/*
950 * Zero padding: fill with 00 ... 00
951 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100952static void add_zeros_padding(unsigned char *output,
953 size_t output_len, size_t data_len)
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200954{
Dave Rodgmanf8182d92023-09-19 16:25:17 +0100955 memset(output + data_len, 0, output_len - data_len);
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200956}
957
Gilles Peskine449bd832023-01-11 14:50:10 +0100958static int get_zeros_padding(unsigned char *input, size_t input_len,
959 size_t *data_len)
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200960{
Manuel Pégourié-Gonnarde68bf172013-10-27 18:26:39 +0100961 size_t i;
Dave Rodgmand8c68a92023-09-19 16:19:38 +0100962 mbedtls_ct_condition_t done = MBEDTLS_CT_FALSE, prev_done;
Manuel Pégourié-Gonnarde68bf172013-10-27 18:26:39 +0100963
Gilles Peskine449bd832023-01-11 14:50:10 +0100964 if (NULL == input || NULL == data_len) {
965 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Manuel Pégourié-Gonnarde68bf172013-10-27 18:26:39 +0100966 }
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200967
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 *data_len = 0;
969 for (i = input_len; i > 0; i--) {
970 prev_done = done;
Dave Rodgmand8c68a92023-09-19 16:19:38 +0100971 done = mbedtls_ct_bool_or(done, mbedtls_ct_uint_ne(input[i-1], 0));
972 *data_len = mbedtls_ct_size_if(mbedtls_ct_bool_ne(done, prev_done), i, *data_len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 }
974
975 return 0;
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200976}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200977#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
Manuel Pégourié-Gonnard0e7d2c02013-07-26 16:05:14 +0200978
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200979/*
980 * No padding: don't pad :)
981 *
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200982 * There is no add_padding function (check for NULL in mbedtls_cipher_finish)
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200983 * but a trivial get_padding function
984 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100985static int get_no_padding(unsigned char *input, size_t input_len,
986 size_t *data_len)
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200987{
Gilles Peskine449bd832023-01-11 14:50:10 +0100988 if (NULL == input || NULL == data_len) {
989 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
990 }
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200991
992 *data_len = input_len;
993
Gilles Peskine449bd832023-01-11 14:50:10 +0100994 return 0;
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200995}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200996#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +0200997
Gilles Peskine449bd832023-01-11 14:50:10 +0100998int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx,
999 unsigned char *output, size_t *olen)
Paul Bakker8123e9d2011-01-06 15:37:30 +00001000{
Gilles Peskine449bd832023-01-11 14:50:10 +01001001 if (ctx->cipher_info == NULL) {
1002 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1003 }
Paul Bakker8123e9d2011-01-06 15:37:30 +00001004
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +02001005#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 if (ctx->psa_enabled == 1) {
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001007 /* While PSA Crypto has an API for multipart
1008 * operations, we currently don't make it
1009 * accessible through the cipher layer. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001011 }
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +02001012#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001013
Paul Bakker8123e9d2011-01-06 15:37:30 +00001014 *olen = 0;
1015
Waleed Elmelegya7d206f2023-09-07 17:54:46 +01001016#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
1017 /* CBC mode requires padding so we make sure a call to
1018 * mbedtls_cipher_set_padding_mode has been done successfully. */
1019 if (MBEDTLS_MODE_CBC == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
1020 if (ctx->get_padding == NULL) {
1021 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1022 }
1023 }
1024#endif
1025
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001026 if (MBEDTLS_MODE_CFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
1027 MBEDTLS_MODE_OFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
1028 MBEDTLS_MODE_CTR == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
1029 MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
1030 MBEDTLS_MODE_CCM_STAR_NO_TAG == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
1031 MBEDTLS_MODE_XTS == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
1032 MBEDTLS_MODE_STREAM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001033 return 0;
Paul Bakker343a8702011-06-09 14:27:58 +00001034 }
1035
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001036 if ((MBEDTLS_CIPHER_CHACHA20 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) ||
1037 (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type))) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 return 0;
Daniel Kingbd920622016-05-15 19:56:20 -03001039 }
1040
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001041 if (MBEDTLS_MODE_ECB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001042 if (ctx->unprocessed_len != 0) {
1043 return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
1044 }
Paul Bakker5e0efa72013-09-08 23:04:04 +02001045
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 return 0;
Paul Bakker5e0efa72013-09-08 23:04:04 +02001047 }
1048
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001049#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001050 if (MBEDTLS_MODE_CBC == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Manuel Pégourié-Gonnard989ed382013-09-13 14:41:45 +02001051 int ret = 0;
1052
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 if (MBEDTLS_ENCRYPT == ctx->operation) {
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001054 /* check for 'no padding' mode */
Gilles Peskine449bd832023-01-11 14:50:10 +01001055 if (NULL == ctx->add_padding) {
1056 if (0 != ctx->unprocessed_len) {
1057 return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
1058 }
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001059
Gilles Peskine449bd832023-01-11 14:50:10 +01001060 return 0;
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001061 }
1062
Gilles Peskine449bd832023-01-11 14:50:10 +01001063 ctx->add_padding(ctx->unprocessed_data, mbedtls_cipher_get_iv_size(ctx),
1064 ctx->unprocessed_len);
1065 } else if (mbedtls_cipher_get_block_size(ctx) != ctx->unprocessed_len) {
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001066 /*
1067 * For decrypt operations, expect a full block,
1068 * or an empty block if no padding
1069 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001070 if (NULL == ctx->add_padding && 0 == ctx->unprocessed_len) {
1071 return 0;
1072 }
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001073
Gilles Peskine449bd832023-01-11 14:50:10 +01001074 return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
Paul Bakker8123e9d2011-01-06 15:37:30 +00001075 }
1076
1077 /* cipher block */
Dave Rodgmande3de772023-06-24 12:51:06 +01001078 if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx,
Dave Rodgman3b46b772023-06-24 13:25:06 +01001079 ctx->operation,
1080 mbedtls_cipher_get_block_size(
1081 ctx),
1082 ctx->iv,
1083 ctx->unprocessed_data,
1084 output))) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001085 return ret;
Paul Bakker8123e9d2011-01-06 15:37:30 +00001086 }
1087
1088 /* Set output size for decryption */
Gilles Peskine449bd832023-01-11 14:50:10 +01001089 if (MBEDTLS_DECRYPT == ctx->operation) {
1090 return ctx->get_padding(output, mbedtls_cipher_get_block_size(ctx),
1091 olen);
1092 }
Paul Bakker8123e9d2011-01-06 15:37:30 +00001093
1094 /* Set output size for encryption */
Gilles Peskine449bd832023-01-11 14:50:10 +01001095 *olen = mbedtls_cipher_get_block_size(ctx);
1096 return 0;
Paul Bakker8123e9d2011-01-06 15:37:30 +00001097 }
Manuel Pégourié-Gonnard989ed382013-09-13 14:41:45 +02001098#else
1099 ((void) output);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001100#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker8123e9d2011-01-06 15:37:30 +00001101
Gilles Peskine449bd832023-01-11 14:50:10 +01001102 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Paul Bakker8123e9d2011-01-06 15:37:30 +00001103}
1104
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001105#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Gilles Peskine449bd832023-01-11 14:50:10 +01001106int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx,
1107 mbedtls_cipher_padding_t mode)
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001108{
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001109 if (NULL == ctx->cipher_info ||
1110 MBEDTLS_MODE_CBC != ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001111 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001112 }
1113
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +02001114#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +01001115 if (ctx->psa_enabled == 1) {
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001116 /* While PSA Crypto knows about CBC padding
1117 * schemes, we currently don't make them
1118 * accessible through the cipher layer. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001119 if (mode != MBEDTLS_PADDING_NONE) {
1120 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
1121 }
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001122
Gilles Peskine449bd832023-01-11 14:50:10 +01001123 return 0;
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001124 }
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +02001125#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001126
Gilles Peskine449bd832023-01-11 14:50:10 +01001127 switch (mode) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001128#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
Gilles Peskine449bd832023-01-11 14:50:10 +01001129 case MBEDTLS_PADDING_PKCS7:
1130 ctx->add_padding = add_pkcs_padding;
1131 ctx->get_padding = get_pkcs_padding;
1132 break;
Paul Bakker48e93c82013-08-14 12:21:18 +02001133#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001134#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
Gilles Peskine449bd832023-01-11 14:50:10 +01001135 case MBEDTLS_PADDING_ONE_AND_ZEROS:
1136 ctx->add_padding = add_one_and_zeros_padding;
1137 ctx->get_padding = get_one_and_zeros_padding;
1138 break;
Paul Bakker48e93c82013-08-14 12:21:18 +02001139#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001140#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
Gilles Peskine449bd832023-01-11 14:50:10 +01001141 case MBEDTLS_PADDING_ZEROS_AND_LEN:
1142 ctx->add_padding = add_zeros_and_len_padding;
1143 ctx->get_padding = get_zeros_and_len_padding;
1144 break;
Paul Bakker48e93c82013-08-14 12:21:18 +02001145#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001146#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
Gilles Peskine449bd832023-01-11 14:50:10 +01001147 case MBEDTLS_PADDING_ZEROS:
1148 ctx->add_padding = add_zeros_padding;
1149 ctx->get_padding = get_zeros_padding;
1150 break;
Paul Bakker48e93c82013-08-14 12:21:18 +02001151#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001152 case MBEDTLS_PADDING_NONE:
1153 ctx->add_padding = NULL;
1154 ctx->get_padding = get_no_padding;
1155 break;
Paul Bakker1a45d912013-08-14 12:04:26 +02001156
Gilles Peskine449bd832023-01-11 14:50:10 +01001157 default:
1158 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnardebdc4132013-07-26 16:50:44 +02001159 }
1160
Gilles Peskine449bd832023-01-11 14:50:10 +01001161 return 0;
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001162}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001163#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
Manuel Pégourié-Gonnardac56a1a2013-07-25 12:31:10 +02001164
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001165#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001166int mbedtls_cipher_write_tag(mbedtls_cipher_context_t *ctx,
1167 unsigned char *tag, size_t tag_len)
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001168{
Gilles Peskine449bd832023-01-11 14:50:10 +01001169 if (ctx->cipher_info == NULL) {
1170 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1171 }
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001172
Gilles Peskine449bd832023-01-11 14:50:10 +01001173 if (MBEDTLS_ENCRYPT != ctx->operation) {
1174 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1175 }
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001176
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +02001177#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +01001178 if (ctx->psa_enabled == 1) {
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001179 /* While PSA Crypto has an API for multipart
1180 * operations, we currently don't make it
1181 * accessible through the cipher layer. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001182 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001183 }
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +02001184#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001185
Daniel King8fe47012016-05-17 20:33:28 -03001186#if defined(MBEDTLS_GCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001187 if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Gilles Peskine5a7be102021-06-23 21:51:32 +02001188 size_t output_length;
1189 /* The code here doesn't yet support alternative implementations
1190 * that can delay up to a block of output. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001191 return mbedtls_gcm_finish((mbedtls_gcm_context *) ctx->cipher_ctx,
1192 NULL, 0, &output_length,
1193 tag, tag_len);
Gilles Peskine5a7be102021-06-23 21:51:32 +02001194 }
Daniel King8fe47012016-05-17 20:33:28 -03001195#endif
1196
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001197#if defined(MBEDTLS_CHACHAPOLY_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001198 if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
Daniel King8fe47012016-05-17 20:33:28 -03001199 /* Don't allow truncated MAC for Poly1305 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001200 if (tag_len != 16U) {
1201 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1202 }
Daniel King8fe47012016-05-17 20:33:28 -03001203
Gilles Peskine449bd832023-01-11 14:50:10 +01001204 return mbedtls_chachapoly_finish(
1205 (mbedtls_chachapoly_context *) ctx->cipher_ctx, tag);
Daniel King8fe47012016-05-17 20:33:28 -03001206 }
1207#endif
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001208
Gilles Peskine449bd832023-01-11 14:50:10 +01001209 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001210}
Paul Bakker9af723c2014-05-01 13:03:14 +02001211
Gilles Peskine449bd832023-01-11 14:50:10 +01001212int mbedtls_cipher_check_tag(mbedtls_cipher_context_t *ctx,
1213 const unsigned char *tag, size_t tag_len)
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001214{
Daniel King8fe47012016-05-17 20:33:28 -03001215 unsigned char check_tag[16];
Janos Follath24eed8d2019-11-22 13:21:35 +00001216 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001217
Gilles Peskine449bd832023-01-11 14:50:10 +01001218 if (ctx->cipher_info == NULL) {
1219 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1220 }
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001221
Gilles Peskine449bd832023-01-11 14:50:10 +01001222 if (MBEDTLS_DECRYPT != ctx->operation) {
1223 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001224 }
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001225
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +02001226#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +01001227 if (ctx->psa_enabled == 1) {
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001228 /* While PSA Crypto has an API for multipart
1229 * operations, we currently don't make it
1230 * accessible through the cipher layer. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001231 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001232 }
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +02001233#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001234
Denis V. Lunev2df73ae2018-11-01 12:22:27 +03001235 /* Status to return on a non-authenticated algorithm. */
1236 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee7835d92021-12-13 12:32:43 +01001237
Daniel King8fe47012016-05-17 20:33:28 -03001238#if defined(MBEDTLS_GCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001239 if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Gilles Peskine5a7be102021-06-23 21:51:32 +02001240 size_t output_length;
1241 /* The code here doesn't yet support alternative implementations
1242 * that can delay up to a block of output. */
1243
Gilles Peskine449bd832023-01-11 14:50:10 +01001244 if (tag_len > sizeof(check_tag)) {
1245 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1246 }
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001247
Gilles Peskine449bd832023-01-11 14:50:10 +01001248 if (0 != (ret = mbedtls_gcm_finish(
1249 (mbedtls_gcm_context *) ctx->cipher_ctx,
1250 NULL, 0, &output_length,
1251 check_tag, tag_len))) {
1252 return ret;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001253 }
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001254
1255 /* Check the tag in "constant-time" */
Gilles Peskine449bd832023-01-11 14:50:10 +01001256 if (mbedtls_ct_memcmp(tag, check_tag, tag_len) != 0) {
Gilles Peskinee7835d92021-12-13 12:32:43 +01001257 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
Gilles Peskinecd742982021-12-13 16:57:47 +01001258 goto exit;
1259 }
Manuel Pégourié-Gonnard43a47802013-09-03 16:35:53 +02001260 }
Daniel King8fe47012016-05-17 20:33:28 -03001261#endif /* MBEDTLS_GCM_C */
1262
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001263#if defined(MBEDTLS_CHACHAPOLY_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001264 if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
Daniel King8fe47012016-05-17 20:33:28 -03001265 /* Don't allow truncated MAC for Poly1305 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001266 if (tag_len != sizeof(check_tag)) {
1267 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1268 }
Daniel King8fe47012016-05-17 20:33:28 -03001269
Hanno Becker18597cd2018-11-09 16:36:33 +00001270 ret = mbedtls_chachapoly_finish(
Gilles Peskine449bd832023-01-11 14:50:10 +01001271 (mbedtls_chachapoly_context *) ctx->cipher_ctx, check_tag);
1272 if (ret != 0) {
1273 return ret;
Daniel King8fe47012016-05-17 20:33:28 -03001274 }
1275
1276 /* Check the tag in "constant-time" */
Gilles Peskine449bd832023-01-11 14:50:10 +01001277 if (mbedtls_ct_memcmp(tag, check_tag, tag_len) != 0) {
Gilles Peskinee7835d92021-12-13 12:32:43 +01001278 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
Gilles Peskinecd742982021-12-13 16:57:47 +01001279 goto exit;
1280 }
Daniel King8fe47012016-05-17 20:33:28 -03001281 }
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001282#endif /* MBEDTLS_CHACHAPOLY_C */
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001283
Gilles Peskinecd742982021-12-13 16:57:47 +01001284exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001285 mbedtls_platform_zeroize(check_tag, tag_len);
1286 return ret;
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001287}
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001288#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
Manuel Pégourié-Gonnardaa9ffc52013-09-03 16:19:22 +02001289
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001290/*
1291 * Packet-oriented wrapper for non-AEAD modes
1292 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001293int mbedtls_cipher_crypt(mbedtls_cipher_context_t *ctx,
1294 const unsigned char *iv, size_t iv_len,
1295 const unsigned char *input, size_t ilen,
1296 unsigned char *output, size_t *olen)
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001297{
Janos Follath24eed8d2019-11-22 13:21:35 +00001298 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001299 size_t finish_olen;
1300
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +02001301#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +01001302 if (ctx->psa_enabled == 1) {
Hanno Becker55e2e3d2018-11-12 12:36:17 +00001303 /* As in the non-PSA case, we don't check that
1304 * a key has been set. If not, the key slot will
1305 * still be in its default state of 0, which is
1306 * guaranteed to be invalid, hence the PSA-call
1307 * below will gracefully fail. */
1308 mbedtls_cipher_context_psa * const cipher_psa =
1309 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
1310
1311 psa_status_t status;
Jaeden Amerofe96fbe2019-02-20 10:32:28 +00001312 psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT;
Hanno Becker55e2e3d2018-11-12 12:36:17 +00001313 size_t part_len;
1314
Gilles Peskine449bd832023-01-11 14:50:10 +01001315 if (ctx->operation == MBEDTLS_DECRYPT) {
1316 status = psa_cipher_decrypt_setup(&cipher_op,
1317 cipher_psa->slot,
1318 cipher_psa->alg);
1319 } else if (ctx->operation == MBEDTLS_ENCRYPT) {
1320 status = psa_cipher_encrypt_setup(&cipher_op,
1321 cipher_psa->slot,
1322 cipher_psa->alg);
1323 } else {
1324 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Hanno Becker55e2e3d2018-11-12 12:36:17 +00001325 }
Hanno Becker55e2e3d2018-11-12 12:36:17 +00001326
1327 /* In the following, we can immediately return on an error,
1328 * because the PSA Crypto API guarantees that cipher operations
1329 * are terminated by unsuccessful calls to psa_cipher_update(),
1330 * and by any call to psa_cipher_finish(). */
Gilles Peskine449bd832023-01-11 14:50:10 +01001331 if (status != PSA_SUCCESS) {
1332 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
Przemyslaw Stekiel80c6a8e2021-09-29 12:13:11 +02001333 }
Hanno Becker55e2e3d2018-11-12 12:36:17 +00001334
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001335 if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) != MBEDTLS_MODE_ECB) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001336 status = psa_cipher_set_iv(&cipher_op, iv, iv_len);
1337 if (status != PSA_SUCCESS) {
1338 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
1339 }
1340 }
Hanno Becker55e2e3d2018-11-12 12:36:17 +00001341
Gilles Peskine449bd832023-01-11 14:50:10 +01001342 status = psa_cipher_update(&cipher_op,
1343 input, ilen,
1344 output, ilen, olen);
1345 if (status != PSA_SUCCESS) {
1346 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
1347 }
1348
1349 status = psa_cipher_finish(&cipher_op,
1350 output + *olen, ilen - *olen,
1351 &part_len);
1352 if (status != PSA_SUCCESS) {
1353 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
1354 }
Hanno Becker55e2e3d2018-11-12 12:36:17 +00001355
1356 *olen += part_len;
Gilles Peskine449bd832023-01-11 14:50:10 +01001357 return 0;
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001358 }
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +02001359#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001360
Gilles Peskine449bd832023-01-11 14:50:10 +01001361 if ((ret = mbedtls_cipher_set_iv(ctx, iv, iv_len)) != 0) {
1362 return ret;
1363 }
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001364
Gilles Peskine449bd832023-01-11 14:50:10 +01001365 if ((ret = mbedtls_cipher_reset(ctx)) != 0) {
1366 return ret;
1367 }
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001368
Gilles Peskine449bd832023-01-11 14:50:10 +01001369 if ((ret = mbedtls_cipher_update(ctx, input, ilen,
1370 output, olen)) != 0) {
1371 return ret;
1372 }
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001373
Gilles Peskine449bd832023-01-11 14:50:10 +01001374 if ((ret = mbedtls_cipher_finish(ctx, output + *olen,
1375 &finish_olen)) != 0) {
1376 return ret;
1377 }
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001378
1379 *olen += finish_olen;
1380
Gilles Peskine449bd832023-01-11 14:50:10 +01001381 return 0;
Manuel Pégourié-Gonnard3c1d1502014-05-12 13:46:08 +02001382}
1383
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001384#if defined(MBEDTLS_CIPHER_MODE_AEAD)
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001385/*
TRodziewicz18efb732021-04-29 23:12:19 +02001386 * Packet-oriented encryption for AEAD modes: internal function used by
1387 * mbedtls_cipher_auth_encrypt_ext().
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001388 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001389static int mbedtls_cipher_aead_encrypt(mbedtls_cipher_context_t *ctx,
1390 const unsigned char *iv, size_t iv_len,
1391 const unsigned char *ad, size_t ad_len,
1392 const unsigned char *input, size_t ilen,
1393 unsigned char *output, size_t *olen,
1394 unsigned char *tag, size_t tag_len)
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001395{
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +02001396#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +01001397 if (ctx->psa_enabled == 1) {
Hanno Beckerfe73ade2018-11-12 16:26:46 +00001398 /* As in the non-PSA case, we don't check that
1399 * a key has been set. If not, the key slot will
1400 * still be in its default state of 0, which is
1401 * guaranteed to be invalid, hence the PSA-call
1402 * below will gracefully fail. */
1403 mbedtls_cipher_context_psa * const cipher_psa =
1404 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
1405
1406 psa_status_t status;
1407
1408 /* PSA Crypto API always writes the authentication tag
1409 * at the end of the encrypted message. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001410 if (output == NULL || tag != output + ilen) {
1411 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
1412 }
Hanno Beckerfe73ade2018-11-12 16:26:46 +00001413
Gilles Peskine449bd832023-01-11 14:50:10 +01001414 status = psa_aead_encrypt(cipher_psa->slot,
1415 cipher_psa->alg,
1416 iv, iv_len,
1417 ad, ad_len,
1418 input, ilen,
1419 output, ilen + tag_len, olen);
1420 if (status != PSA_SUCCESS) {
1421 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
1422 }
Hanno Beckerfe73ade2018-11-12 16:26:46 +00001423
1424 *olen -= tag_len;
Gilles Peskine449bd832023-01-11 14:50:10 +01001425 return 0;
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001426 }
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +02001427#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001428
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001429#if defined(MBEDTLS_GCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001430 if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001431 *olen = ilen;
Gilles Peskine449bd832023-01-11 14:50:10 +01001432 return mbedtls_gcm_crypt_and_tag(ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT,
1433 ilen, iv, iv_len, ad, ad_len,
1434 input, output, tag_len, tag);
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001435 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001436#endif /* MBEDTLS_GCM_C */
1437#if defined(MBEDTLS_CCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001438 if (MBEDTLS_MODE_CCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001439 *olen = ilen;
Gilles Peskine449bd832023-01-11 14:50:10 +01001440 return mbedtls_ccm_encrypt_and_tag(ctx->cipher_ctx, ilen,
1441 iv, iv_len, ad, ad_len, input, output,
1442 tag, tag_len);
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001443 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001444#endif /* MBEDTLS_CCM_C */
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001445#if defined(MBEDTLS_CHACHAPOLY_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001446 if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001447 /* ChachaPoly has fixed length nonce and MAC (tag) */
Dave Rodgmanbb521fd2023-06-24 11:21:25 +01001448 if ((iv_len != mbedtls_cipher_info_get_iv_size(ctx->cipher_info)) ||
Gilles Peskine449bd832023-01-11 14:50:10 +01001449 (tag_len != 16U)) {
1450 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Daniel King8fe47012016-05-17 20:33:28 -03001451 }
1452
1453 *olen = ilen;
Gilles Peskine449bd832023-01-11 14:50:10 +01001454 return mbedtls_chachapoly_encrypt_and_tag(ctx->cipher_ctx,
1455 ilen, iv, ad, ad_len, input, output, tag);
Daniel King8fe47012016-05-17 20:33:28 -03001456 }
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001457#endif /* MBEDTLS_CHACHAPOLY_C */
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001458
Gilles Peskine449bd832023-01-11 14:50:10 +01001459 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001460}
1461
1462/*
TRodziewicz18efb732021-04-29 23:12:19 +02001463 * Packet-oriented encryption for AEAD modes: internal function used by
1464 * mbedtls_cipher_auth_encrypt_ext().
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001465 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001466static int mbedtls_cipher_aead_decrypt(mbedtls_cipher_context_t *ctx,
1467 const unsigned char *iv, size_t iv_len,
1468 const unsigned char *ad, size_t ad_len,
1469 const unsigned char *input, size_t ilen,
1470 unsigned char *output, size_t *olen,
1471 const unsigned char *tag, size_t tag_len)
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001472{
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +02001473#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +01001474 if (ctx->psa_enabled == 1) {
Hanno Beckerfe73ade2018-11-12 16:26:46 +00001475 /* As in the non-PSA case, we don't check that
1476 * a key has been set. If not, the key slot will
1477 * still be in its default state of 0, which is
1478 * guaranteed to be invalid, hence the PSA-call
1479 * below will gracefully fail. */
1480 mbedtls_cipher_context_psa * const cipher_psa =
1481 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
1482
1483 psa_status_t status;
1484
1485 /* PSA Crypto API always writes the authentication tag
1486 * at the end of the encrypted message. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001487 if (input == NULL || tag != input + ilen) {
1488 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
1489 }
Hanno Beckerfe73ade2018-11-12 16:26:46 +00001490
Gilles Peskine449bd832023-01-11 14:50:10 +01001491 status = psa_aead_decrypt(cipher_psa->slot,
1492 cipher_psa->alg,
1493 iv, iv_len,
1494 ad, ad_len,
1495 input, ilen + tag_len,
1496 output, ilen, olen);
1497 if (status == PSA_ERROR_INVALID_SIGNATURE) {
1498 return MBEDTLS_ERR_CIPHER_AUTH_FAILED;
1499 } else if (status != PSA_SUCCESS) {
1500 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
1501 }
Hanno Beckerfe73ade2018-11-12 16:26:46 +00001502
Gilles Peskine449bd832023-01-11 14:50:10 +01001503 return 0;
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001504 }
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +02001505#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerce1ddee2018-11-09 16:20:29 +00001506
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001507#if defined(MBEDTLS_GCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001508 if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Janos Follath24eed8d2019-11-22 13:21:35 +00001509 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001510
1511 *olen = ilen;
Gilles Peskine449bd832023-01-11 14:50:10 +01001512 ret = mbedtls_gcm_auth_decrypt(ctx->cipher_ctx, ilen,
1513 iv, iv_len, ad, ad_len,
1514 tag, tag_len, input, output);
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001515
Gilles Peskine449bd832023-01-11 14:50:10 +01001516 if (ret == MBEDTLS_ERR_GCM_AUTH_FAILED) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001517 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
Gilles Peskine449bd832023-01-11 14:50:10 +01001518 }
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001519
Gilles Peskine449bd832023-01-11 14:50:10 +01001520 return ret;
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001521 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001522#endif /* MBEDTLS_GCM_C */
1523#if defined(MBEDTLS_CCM_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001524 if (MBEDTLS_MODE_CCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
Janos Follath24eed8d2019-11-22 13:21:35 +00001525 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001526
1527 *olen = ilen;
Gilles Peskine449bd832023-01-11 14:50:10 +01001528 ret = mbedtls_ccm_auth_decrypt(ctx->cipher_ctx, ilen,
1529 iv, iv_len, ad, ad_len,
1530 input, output, tag, tag_len);
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001531
Gilles Peskine449bd832023-01-11 14:50:10 +01001532 if (ret == MBEDTLS_ERR_CCM_AUTH_FAILED) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001533 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
Gilles Peskine449bd832023-01-11 14:50:10 +01001534 }
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001535
Gilles Peskine449bd832023-01-11 14:50:10 +01001536 return ret;
Manuel Pégourié-Gonnard41936952014-05-13 13:18:17 +02001537 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001538#endif /* MBEDTLS_CCM_C */
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001539#if defined(MBEDTLS_CHACHAPOLY_C)
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001540 if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
Janos Follath24eed8d2019-11-22 13:21:35 +00001541 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel King8fe47012016-05-17 20:33:28 -03001542
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001543 /* ChachaPoly has fixed length nonce and MAC (tag) */
Dave Rodgmanbb521fd2023-06-24 11:21:25 +01001544 if ((iv_len != mbedtls_cipher_info_get_iv_size(ctx->cipher_info)) ||
Gilles Peskine449bd832023-01-11 14:50:10 +01001545 (tag_len != 16U)) {
1546 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Daniel King8fe47012016-05-17 20:33:28 -03001547 }
1548
1549 *olen = ilen;
Gilles Peskine449bd832023-01-11 14:50:10 +01001550 ret = mbedtls_chachapoly_auth_decrypt(ctx->cipher_ctx, ilen,
1551 iv, ad, ad_len, tag, input, output);
Daniel King8fe47012016-05-17 20:33:28 -03001552
Gilles Peskine449bd832023-01-11 14:50:10 +01001553 if (ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED) {
Manuel Pégourié-Gonnardfe725de2018-05-08 09:38:09 +02001554 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
Gilles Peskine449bd832023-01-11 14:50:10 +01001555 }
Daniel King8fe47012016-05-17 20:33:28 -03001556
Gilles Peskine449bd832023-01-11 14:50:10 +01001557 return ret;
Daniel King8fe47012016-05-17 20:33:28 -03001558 }
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02001559#endif /* MBEDTLS_CHACHAPOLY_C */
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001560
Gilles Peskine449bd832023-01-11 14:50:10 +01001561 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001562}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001563#endif /* MBEDTLS_CIPHER_MODE_AEAD */
Manuel Pégourié-Gonnard4562ffe2014-05-13 12:19:29 +02001564
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001565#if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C)
1566/*
1567 * Packet-oriented encryption for AEAD/NIST_KW: public function.
1568 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001569int mbedtls_cipher_auth_encrypt_ext(mbedtls_cipher_context_t *ctx,
1570 const unsigned char *iv, size_t iv_len,
1571 const unsigned char *ad, size_t ad_len,
1572 const unsigned char *input, size_t ilen,
1573 unsigned char *output, size_t output_len,
1574 size_t *olen, size_t tag_len)
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001575{
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001576#if defined(MBEDTLS_NIST_KW_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001577 if (
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +02001578#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskinea56d3d92020-12-04 00:47:07 +01001579 ctx->psa_enabled == 0 &&
1580#endif
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001581 (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
1582 MBEDTLS_MODE_KWP == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode))) {
1583 mbedtls_nist_kw_mode_t mode =
1584 (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) ?
1585 MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001586
1587 /* There is no iv, tag or ad associated with KW and KWP,
1588 * so these length should be 0 as documented. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001589 if (iv_len != 0 || tag_len != 0 || ad_len != 0) {
1590 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1591 }
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001592
Manuel Pégourié-Gonnard841b6fa2020-12-07 10:42:21 +01001593 (void) iv;
1594 (void) ad;
1595
Gilles Peskine449bd832023-01-11 14:50:10 +01001596 return mbedtls_nist_kw_wrap(ctx->cipher_ctx, mode, input, ilen,
1597 output, olen, output_len);
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001598 }
1599#endif /* MBEDTLS_NIST_KW_C */
1600
1601#if defined(MBEDTLS_CIPHER_MODE_AEAD)
1602 /* AEAD case: check length before passing on to shared function */
Gilles Peskine449bd832023-01-11 14:50:10 +01001603 if (output_len < ilen + tag_len) {
1604 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1605 }
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001606
Gilles Peskine449bd832023-01-11 14:50:10 +01001607 int ret = mbedtls_cipher_aead_encrypt(ctx, iv, iv_len, ad, ad_len,
1608 input, ilen, output, olen,
1609 output + ilen, tag_len);
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001610 *olen += tag_len;
Gilles Peskine449bd832023-01-11 14:50:10 +01001611 return ret;
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001612#else
Gilles Peskine449bd832023-01-11 14:50:10 +01001613 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001614#endif /* MBEDTLS_CIPHER_MODE_AEAD */
1615}
1616
1617/*
1618 * Packet-oriented decryption for AEAD/NIST_KW: public function.
1619 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001620int mbedtls_cipher_auth_decrypt_ext(mbedtls_cipher_context_t *ctx,
1621 const unsigned char *iv, size_t iv_len,
1622 const unsigned char *ad, size_t ad_len,
1623 const unsigned char *input, size_t ilen,
1624 unsigned char *output, size_t output_len,
1625 size_t *olen, size_t tag_len)
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001626{
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001627#if defined(MBEDTLS_NIST_KW_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001628 if (
Manuel Pégourié-Gonnard5c731b02023-06-21 10:37:30 +02001629#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskinea56d3d92020-12-04 00:47:07 +01001630 ctx->psa_enabled == 0 &&
1631#endif
Dave Rodgman1b8a3b12023-06-24 17:32:43 +01001632 (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
1633 MBEDTLS_MODE_KWP == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode))) {
1634 mbedtls_nist_kw_mode_t mode =
1635 (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) ?
1636 MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001637
1638 /* There is no iv, tag or ad associated with KW and KWP,
1639 * so these length should be 0 as documented. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001640 if (iv_len != 0 || tag_len != 0 || ad_len != 0) {
1641 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1642 }
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001643
Manuel Pégourié-Gonnard841b6fa2020-12-07 10:42:21 +01001644 (void) iv;
1645 (void) ad;
1646
Gilles Peskine449bd832023-01-11 14:50:10 +01001647 return mbedtls_nist_kw_unwrap(ctx->cipher_ctx, mode, input, ilen,
1648 output, olen, output_len);
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001649 }
1650#endif /* MBEDTLS_NIST_KW_C */
1651
1652#if defined(MBEDTLS_CIPHER_MODE_AEAD)
1653 /* AEAD case: check length before passing on to shared function */
Gilles Peskine449bd832023-01-11 14:50:10 +01001654 if (ilen < tag_len || output_len < ilen - tag_len) {
1655 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
1656 }
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001657
Gilles Peskine449bd832023-01-11 14:50:10 +01001658 return mbedtls_cipher_aead_decrypt(ctx, iv, iv_len, ad, ad_len,
1659 input, ilen - tag_len, output, olen,
1660 input + ilen - tag_len, tag_len);
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001661#else
Gilles Peskine449bd832023-01-11 14:50:10 +01001662 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnardfaddf982020-11-25 13:39:47 +01001663#endif /* MBEDTLS_CIPHER_MODE_AEAD */
1664}
1665#endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */
1666
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001667#endif /* MBEDTLS_CIPHER_C */