Coverage Report

Created: 2026-07-25 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mbedtls/library/psa_crypto_cipher.c
Line
Count
Source
1
/*
2
 *  PSA cipher driver entry points
3
 */
4
/*
5
 *  Copyright The Mbed TLS Contributors
6
 *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
7
 */
8
9
#include "common.h"
10
11
#if defined(MBEDTLS_PSA_CRYPTO_C)
12
13
#include "psa_crypto_cipher.h"
14
#include "psa_crypto_core.h"
15
#include "psa_crypto_random_impl.h"
16
#include "constant_time_internal.h"
17
18
#include "mbedtls/cipher.h"
19
#include "mbedtls/error.h"
20
21
#include <string.h>
22
23
/* mbedtls_cipher_values_from_psa() below only checks if the proper build symbols
24
 * are enabled, but it does not provide any compatibility check between them
25
 * (i.e. if the specified key works with the specified algorithm). This helper
26
 * function is meant to provide this support.
27
 * mbedtls_cipher_info_from_psa() might be used for the same purpose, but it
28
 * requires CIPHER_C to be enabled.
29
 */
30
static psa_status_t mbedtls_cipher_validate_values(
31
    psa_algorithm_t alg,
32
    psa_key_type_t key_type)
33
0
{
34
    /* Reduce code size - hinting to the compiler about what it can assume allows the compiler to
35
       eliminate bits of the logic below. */
36
#if !defined(PSA_WANT_KEY_TYPE_AES)
37
    MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_AES);
38
#endif
39
#if !defined(PSA_WANT_KEY_TYPE_ARIA)
40
    MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_ARIA);
41
#endif
42
#if !defined(PSA_WANT_KEY_TYPE_CAMELLIA)
43
    MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CAMELLIA);
44
#endif
45
#if !defined(PSA_WANT_KEY_TYPE_CHACHA20)
46
    MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CHACHA20);
47
#endif
48
#if !defined(PSA_WANT_KEY_TYPE_DES)
49
    MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_DES);
50
#endif
51
#if !defined(PSA_WANT_ALG_CCM)
52
    MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0));
53
#endif
54
#if !defined(PSA_WANT_ALG_GCM)
55
    MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0));
56
#endif
57
#if !defined(PSA_WANT_ALG_STREAM_CIPHER)
58
    MBEDTLS_ASSUME(alg != PSA_ALG_STREAM_CIPHER);
59
#endif
60
#if !defined(PSA_WANT_ALG_CHACHA20_POLY1305)
61
    MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0));
62
#endif
63
#if !defined(PSA_WANT_ALG_CCM_STAR_NO_TAG)
64
    MBEDTLS_ASSUME(alg != PSA_ALG_CCM_STAR_NO_TAG);
65
#endif
66
#if !defined(PSA_WANT_ALG_CTR)
67
    MBEDTLS_ASSUME(alg != PSA_ALG_CTR);
68
#endif
69
#if !defined(PSA_WANT_ALG_CFB)
70
    MBEDTLS_ASSUME(alg != PSA_ALG_CFB);
71
#endif
72
#if !defined(PSA_WANT_ALG_OFB)
73
    MBEDTLS_ASSUME(alg != PSA_ALG_OFB);
74
#endif
75
#if !defined(PSA_WANT_ALG_ECB_NO_PADDING)
76
    MBEDTLS_ASSUME(alg != PSA_ALG_ECB_NO_PADDING);
77
#endif
78
#if !defined(PSA_WANT_ALG_CBC_NO_PADDING)
79
    MBEDTLS_ASSUME(alg != PSA_ALG_CBC_NO_PADDING);
80
#endif
81
#if !defined(PSA_WANT_ALG_CBC_PKCS7)
82
    MBEDTLS_ASSUME(alg != PSA_ALG_CBC_PKCS7);
83
#endif
84
#if !defined(PSA_WANT_ALG_CMAC)
85
    MBEDTLS_ASSUME(alg != PSA_ALG_CMAC);
86
#endif
87
88
0
    if (alg == PSA_ALG_STREAM_CIPHER ||
89
0
        alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0)) {
90
0
        if (key_type == PSA_KEY_TYPE_CHACHA20) {
91
0
            return PSA_SUCCESS;
92
0
        }
93
0
    }
94
95
0
    if (alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0) ||
96
0
        alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0) ||
97
0
        alg == PSA_ALG_CCM_STAR_NO_TAG) {
98
0
        if (key_type == PSA_KEY_TYPE_AES ||
99
0
            key_type == PSA_KEY_TYPE_ARIA ||
100
0
            key_type == PSA_KEY_TYPE_CAMELLIA) {
101
0
            return PSA_SUCCESS;
102
0
        }
103
0
    }
104
105
0
    if (alg == PSA_ALG_CTR ||
106
0
        alg == PSA_ALG_CFB ||
107
0
        alg == PSA_ALG_OFB ||
108
0
        alg == PSA_ALG_XTS ||
109
0
        alg == PSA_ALG_ECB_NO_PADDING ||
110
0
        alg == PSA_ALG_CBC_NO_PADDING ||
111
0
        alg == PSA_ALG_CBC_PKCS7 ||
112
0
        alg == PSA_ALG_CMAC) {
113
0
        if (key_type == PSA_KEY_TYPE_AES ||
114
0
            key_type == PSA_KEY_TYPE_ARIA ||
115
0
            key_type == PSA_KEY_TYPE_DES ||
116
0
            key_type == PSA_KEY_TYPE_CAMELLIA) {
117
0
            return PSA_SUCCESS;
118
0
        }
119
0
    }
120
121
0
    return PSA_ERROR_NOT_SUPPORTED;
122
0
}
123
124
psa_status_t mbedtls_cipher_values_from_psa(
125
    psa_algorithm_t alg,
126
    psa_key_type_t key_type,
127
    size_t *key_bits,
128
    mbedtls_cipher_mode_t *mode,
129
    mbedtls_cipher_id_t *cipher_id)
130
0
{
131
0
    mbedtls_cipher_id_t cipher_id_tmp;
132
    /* Only DES modifies key_bits */
133
#if !defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
134
    (void) key_bits;
135
#endif
136
137
0
    if (PSA_ALG_IS_AEAD(alg)) {
138
0
        alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0);
139
0
    }
140
141
0
    if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg)) {
142
0
        switch (alg) {
143
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER)
144
0
            case PSA_ALG_STREAM_CIPHER:
145
0
                *mode = MBEDTLS_MODE_STREAM;
146
0
                break;
147
0
#endif
148
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CTR)
149
0
            case PSA_ALG_CTR:
150
0
                *mode = MBEDTLS_MODE_CTR;
151
0
                break;
152
0
#endif
153
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CFB)
154
0
            case PSA_ALG_CFB:
155
0
                *mode = MBEDTLS_MODE_CFB;
156
0
                break;
157
0
#endif
158
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_OFB)
159
0
            case PSA_ALG_OFB:
160
0
                *mode = MBEDTLS_MODE_OFB;
161
0
                break;
162
0
#endif
163
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
164
0
            case PSA_ALG_ECB_NO_PADDING:
165
0
                *mode = MBEDTLS_MODE_ECB;
166
0
                break;
167
0
#endif
168
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING)
169
0
            case PSA_ALG_CBC_NO_PADDING:
170
0
                *mode = MBEDTLS_MODE_CBC;
171
0
                break;
172
0
#endif
173
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
174
0
            case PSA_ALG_CBC_PKCS7:
175
0
                *mode = MBEDTLS_MODE_CBC;
176
0
                break;
177
0
#endif
178
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG)
179
0
            case PSA_ALG_CCM_STAR_NO_TAG:
180
0
                *mode = MBEDTLS_MODE_CCM_STAR_NO_TAG;
181
0
                break;
182
0
#endif
183
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
184
0
            case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
185
0
                *mode = MBEDTLS_MODE_CCM;
186
0
                break;
187
0
#endif
188
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
189
0
            case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
190
0
                *mode = MBEDTLS_MODE_GCM;
191
0
                break;
192
0
#endif
193
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
194
0
            case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
195
0
                *mode = MBEDTLS_MODE_CHACHAPOLY;
196
0
                break;
197
0
#endif
198
0
            default:
199
0
                return PSA_ERROR_NOT_SUPPORTED;
200
0
        }
201
0
    } else if (alg == PSA_ALG_CMAC) {
202
0
        *mode = MBEDTLS_MODE_ECB;
203
0
    } else {
204
0
        return PSA_ERROR_NOT_SUPPORTED;
205
0
    }
206
207
0
    switch (key_type) {
208
0
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
209
0
        case PSA_KEY_TYPE_AES:
210
0
            cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
211
0
            break;
212
0
#endif
213
0
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA)
214
0
        case PSA_KEY_TYPE_ARIA:
215
0
            cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
216
0
            break;
217
0
#endif
218
0
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
219
0
        case PSA_KEY_TYPE_DES:
220
            /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
221
             * and 192 for three-key Triple-DES. */
222
0
            if (*key_bits == 64) {
223
0
                cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
224
0
            } else {
225
0
                cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
226
0
            }
227
            /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
228
             * but two-key Triple-DES is functionally three-key Triple-DES
229
             * with K1=K3, so that's how we present it to mbedtls. */
230
0
            if (*key_bits == 128) {
231
0
                *key_bits = 192;
232
0
            }
233
0
            break;
234
0
#endif
235
0
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
236
0
        case PSA_KEY_TYPE_CAMELLIA:
237
0
            cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
238
0
            break;
239
0
#endif
240
0
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
241
0
        case PSA_KEY_TYPE_CHACHA20:
242
0
            cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
243
0
            break;
244
0
#endif
245
0
        default:
246
0
            return PSA_ERROR_NOT_SUPPORTED;
247
0
    }
248
0
    if (cipher_id != NULL) {
249
0
        *cipher_id = cipher_id_tmp;
250
0
    }
251
252
0
    return mbedtls_cipher_validate_values(alg, key_type);
253
0
}
254
255
#if defined(MBEDTLS_CIPHER_C)
256
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
257
    psa_algorithm_t alg,
258
    psa_key_type_t key_type,
259
    size_t key_bits,
260
    mbedtls_cipher_id_t *cipher_id)
261
0
{
262
0
    mbedtls_cipher_mode_t mode;
263
0
    psa_status_t status;
264
0
    mbedtls_cipher_id_t cipher_id_tmp = MBEDTLS_CIPHER_ID_NONE;
265
266
0
    status = mbedtls_cipher_values_from_psa(alg, key_type, &key_bits, &mode, &cipher_id_tmp);
267
0
    if (status != PSA_SUCCESS) {
268
0
        return NULL;
269
0
    }
270
0
    if (cipher_id != NULL) {
271
0
        *cipher_id = cipher_id_tmp;
272
0
    }
273
274
0
    return mbedtls_cipher_info_from_values(cipher_id_tmp, (int) key_bits, mode);
275
0
}
276
#endif /* MBEDTLS_CIPHER_C */
277
278
#if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
279
280
static psa_status_t psa_cipher_setup(
281
    mbedtls_psa_cipher_operation_t *operation,
282
    const psa_key_attributes_t *attributes,
283
    const uint8_t *key_buffer, size_t key_buffer_size,
284
    psa_algorithm_t alg,
285
    mbedtls_operation_t cipher_operation)
286
0
{
287
0
    int ret = 0;
288
0
    size_t key_bits;
289
0
    const mbedtls_cipher_info_t *cipher_info = NULL;
290
0
    psa_key_type_t key_type = attributes->type;
291
292
0
    (void) key_buffer_size;
293
294
0
    mbedtls_cipher_init(&operation->ctx.cipher);
295
296
0
    operation->alg = alg;
297
0
    key_bits = attributes->bits;
298
0
    cipher_info = mbedtls_cipher_info_from_psa(alg, key_type,
299
0
                                               key_bits, NULL);
300
0
    if (cipher_info == NULL) {
301
0
        return PSA_ERROR_NOT_SUPPORTED;
302
0
    }
303
304
0
    ret = mbedtls_cipher_setup(&operation->ctx.cipher, cipher_info);
305
0
    if (ret != 0) {
306
0
        goto exit;
307
0
    }
308
309
0
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
310
0
    if (key_type == PSA_KEY_TYPE_DES && key_bits == 128) {
311
        /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
312
0
        uint8_t keys[24];
313
0
        memcpy(keys, key_buffer, 16);
314
0
        memcpy(keys + 16, key_buffer, 8);
315
0
        ret = mbedtls_cipher_setkey(&operation->ctx.cipher,
316
0
                                    keys,
317
0
                                    192, cipher_operation);
318
0
    } else
319
0
#endif
320
0
    {
321
0
        ret = mbedtls_cipher_setkey(&operation->ctx.cipher, key_buffer,
322
0
                                    (int) key_bits, cipher_operation);
323
0
    }
324
0
    if (ret != 0) {
325
0
        goto exit;
326
0
    }
327
328
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
329
0
    defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
330
0
    switch (alg) {
331
0
        case PSA_ALG_CBC_NO_PADDING:
332
0
            ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
333
0
                                                  MBEDTLS_PADDING_NONE);
334
0
            break;
335
0
        case PSA_ALG_CBC_PKCS7:
336
0
            ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
337
0
                                                  MBEDTLS_PADDING_PKCS7);
338
0
            break;
339
0
        default:
340
            /* The algorithm doesn't involve padding. */
341
0
            ret = 0;
342
0
            break;
343
0
    }
344
0
    if (ret != 0) {
345
0
        goto exit;
346
0
    }
347
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING ||
348
          MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */
349
350
0
    operation->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 :
351
0
                               PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type));
352
0
    operation->iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
353
354
0
exit:
355
0
    return mbedtls_to_psa_error(ret);
356
0
}
357
358
psa_status_t mbedtls_psa_cipher_encrypt_setup(
359
    mbedtls_psa_cipher_operation_t *operation,
360
    const psa_key_attributes_t *attributes,
361
    const uint8_t *key_buffer, size_t key_buffer_size,
362
    psa_algorithm_t alg)
363
0
{
364
0
    return psa_cipher_setup(operation, attributes,
365
0
                            key_buffer, key_buffer_size,
366
0
                            alg, MBEDTLS_ENCRYPT);
367
0
}
368
369
psa_status_t mbedtls_psa_cipher_decrypt_setup(
370
    mbedtls_psa_cipher_operation_t *operation,
371
    const psa_key_attributes_t *attributes,
372
    const uint8_t *key_buffer, size_t key_buffer_size,
373
    psa_algorithm_t alg)
374
0
{
375
0
    return psa_cipher_setup(operation, attributes,
376
0
                            key_buffer, key_buffer_size,
377
0
                            alg, MBEDTLS_DECRYPT);
378
0
}
379
380
psa_status_t mbedtls_psa_cipher_set_iv(
381
    mbedtls_psa_cipher_operation_t *operation,
382
    const uint8_t *iv, size_t iv_length)
383
0
{
384
0
    if (iv_length != operation->iv_length) {
385
0
        return PSA_ERROR_INVALID_ARGUMENT;
386
0
    }
387
388
0
    return mbedtls_to_psa_error(
389
0
        mbedtls_cipher_set_iv(&operation->ctx.cipher,
390
0
                              iv, iv_length));
391
0
}
392
393
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
394
/** Process input for which the algorithm is set to ECB mode.
395
 *
396
 * This requires manual processing, since the PSA API is defined as being
397
 * able to process arbitrary-length calls to psa_cipher_update() with ECB mode,
398
 * but the underlying mbedtls_cipher_update only takes full blocks.
399
 *
400
 * \param ctx           The mbedtls cipher context to use. It must have been
401
 *                      set up for ECB.
402
 * \param[in] input     The input plaintext or ciphertext to process.
403
 * \param input_length  The number of bytes to process from \p input.
404
 *                      This does not need to be aligned to a block boundary.
405
 *                      If there is a partial block at the end of the input,
406
 *                      it is stored in \p ctx for future processing.
407
 * \param output        The buffer where the output is written. It must be
408
 *                      at least `BS * floor((p + input_length) / BS)` bytes
409
 *                      long, where `p` is the number of bytes in the
410
 *                      unprocessed partial block in \p ctx (with
411
 *                      `0 <= p <= BS - 1`) and `BS` is the block size.
412
 * \param output_length On success, the number of bytes written to \p output.
413
 *                      \c 0 on error.
414
 *
415
 * \return #PSA_SUCCESS or an error from a hardware accelerator
416
 */
417
static psa_status_t psa_cipher_update_ecb(
418
    mbedtls_cipher_context_t *ctx,
419
    const uint8_t *input,
420
    size_t input_length,
421
    uint8_t *output,
422
    size_t *output_length)
423
0
{
424
0
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
425
0
    size_t block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
426
0
    size_t internal_output_length = 0;
427
0
    *output_length = 0;
428
429
0
    if (input_length == 0) {
430
0
        status = PSA_SUCCESS;
431
0
        goto exit;
432
0
    }
433
434
0
    if (ctx->unprocessed_len > 0) {
435
        /* Fill up to block size, and run the block if there's a full one. */
436
0
        size_t bytes_to_copy = block_size - ctx->unprocessed_len;
437
438
0
        if (input_length < bytes_to_copy) {
439
0
            bytes_to_copy = input_length;
440
0
        }
441
442
0
        memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
443
0
               input, bytes_to_copy);
444
0
        input_length -= bytes_to_copy;
445
0
        input += bytes_to_copy;
446
0
        ctx->unprocessed_len += bytes_to_copy;
447
448
0
        if (ctx->unprocessed_len == block_size) {
449
0
            status = mbedtls_to_psa_error(
450
0
                mbedtls_cipher_update(ctx,
451
0
                                      ctx->unprocessed_data,
452
0
                                      block_size,
453
0
                                      output, &internal_output_length));
454
455
0
            if (status != PSA_SUCCESS) {
456
0
                goto exit;
457
0
            }
458
459
0
            output += internal_output_length;
460
0
            *output_length += internal_output_length;
461
0
            ctx->unprocessed_len = 0;
462
0
        }
463
0
    }
464
465
0
    while (input_length >= block_size) {
466
        /* Run all full blocks we have, one by one */
467
0
        status = mbedtls_to_psa_error(
468
0
            mbedtls_cipher_update(ctx, input,
469
0
                                  block_size,
470
0
                                  output, &internal_output_length));
471
472
0
        if (status != PSA_SUCCESS) {
473
0
            goto exit;
474
0
        }
475
476
0
        input_length -= block_size;
477
0
        input += block_size;
478
479
0
        output += internal_output_length;
480
0
        *output_length += internal_output_length;
481
0
    }
482
483
0
    if (input_length > 0) {
484
        /* Save unprocessed bytes for later processing */
485
0
        memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
486
0
               input, input_length);
487
0
        ctx->unprocessed_len += input_length;
488
0
    }
489
490
0
    status = PSA_SUCCESS;
491
492
0
exit:
493
0
    return status;
494
0
}
495
#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
496
497
psa_status_t mbedtls_psa_cipher_update(
498
    mbedtls_psa_cipher_operation_t *operation,
499
    const uint8_t *input, size_t input_length,
500
    uint8_t *output, size_t output_size, size_t *output_length)
501
0
{
502
0
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
503
0
    size_t expected_output_size;
504
505
0
    if (!PSA_ALG_IS_STREAM_CIPHER(operation->alg)) {
506
        /* Take the unprocessed partial block left over from previous
507
         * update calls, if any, plus the input to this call. Remove
508
         * the last partial block, if any. You get the data that will be
509
         * output in this call. */
510
0
        expected_output_size =
511
0
            (operation->ctx.cipher.unprocessed_len + input_length)
512
0
            / operation->block_length * operation->block_length;
513
0
    } else {
514
0
        expected_output_size = input_length;
515
0
    }
516
517
0
    if (output_size < expected_output_size) {
518
0
        return PSA_ERROR_BUFFER_TOO_SMALL;
519
0
    }
520
521
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
522
0
    if (operation->alg == PSA_ALG_ECB_NO_PADDING) {
523
        /* mbedtls_cipher_update has an API inconsistency: it will only
524
         * process a single block at a time in ECB mode. Abstract away that
525
         * inconsistency here to match the PSA API behaviour. */
526
0
        status = psa_cipher_update_ecb(&operation->ctx.cipher,
527
0
                                       input,
528
0
                                       input_length,
529
0
                                       output,
530
0
                                       output_length);
531
0
    } else
532
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
533
0
    if (input_length == 0) {
534
        /* There is no input, nothing to be done */
535
0
        *output_length = 0;
536
0
        status = PSA_SUCCESS;
537
0
    } else {
538
0
        status = mbedtls_to_psa_error(
539
0
            mbedtls_cipher_update(&operation->ctx.cipher, input,
540
0
                                  input_length, output, output_length));
541
542
0
        if (*output_length > output_size) {
543
0
            return PSA_ERROR_CORRUPTION_DETECTED;
544
0
        }
545
0
    }
546
547
0
    return status;
548
0
}
549
550
psa_status_t mbedtls_psa_cipher_finish(
551
    mbedtls_psa_cipher_operation_t *operation,
552
    uint8_t *output, size_t output_size, size_t *output_length)
553
0
{
554
0
    psa_status_t status = PSA_ERROR_GENERIC_ERROR;
555
0
    size_t invalid_padding = 0;
556
557
    /* We will copy output_size bytes from temp_output_buffer to the
558
     * output buffer. We can't use *output_length to determine how
559
     * much to copy because we must not leak that value through timing
560
     * when doing decryption with unpadding. But the underlying function
561
     * is not guaranteed to write beyond *output_length. To ensure we don't
562
     * leak the former content of the stack to the caller, wipe that
563
     * former content. */
564
0
    uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH] = { 0 };
565
0
    if (output_size > sizeof(temp_output_buffer)) {
566
0
        output_size = sizeof(temp_output_buffer);
567
0
    }
568
569
0
    if (operation->ctx.cipher.unprocessed_len != 0) {
570
0
        if (operation->alg == PSA_ALG_ECB_NO_PADDING ||
571
0
            operation->alg == PSA_ALG_CBC_NO_PADDING) {
572
0
            status = PSA_ERROR_INVALID_ARGUMENT;
573
0
            goto exit;
574
0
        }
575
0
    }
576
577
0
    status = mbedtls_to_psa_error(
578
0
        mbedtls_cipher_finish_padded(&operation->ctx.cipher,
579
0
                                     temp_output_buffer,
580
0
                                     output_length,
581
0
                                     &invalid_padding));
582
0
    if (status != PSA_SUCCESS) {
583
0
        goto exit;
584
0
    }
585
586
0
    if (output_size == 0) {
587
0
        ; /* Nothing to copy. Note that output may be NULL in this case. */
588
0
    } else {
589
        /* Do not use the value of *output_length to determine how much
590
         * to copy. When decrypting a padded cipher, the output length is
591
         * sensitive, and leaking it could allow a padding oracle attack. */
592
0
        memcpy(output, temp_output_buffer, output_size);
593
0
    }
594
595
0
    status = mbedtls_ct_error_if_else_0(invalid_padding,
596
0
                                        PSA_ERROR_INVALID_PADDING);
597
0
    mbedtls_ct_condition_t buffer_too_small =
598
0
        mbedtls_ct_uint_lt(output_size, *output_length);
599
0
    status = mbedtls_ct_error_if(buffer_too_small,
600
0
                                 PSA_ERROR_BUFFER_TOO_SMALL,
601
0
                                 status);
602
603
0
exit:
604
0
    mbedtls_platform_zeroize(temp_output_buffer,
605
0
                             sizeof(temp_output_buffer));
606
0
    return status;
607
0
}
608
609
psa_status_t mbedtls_psa_cipher_abort(
610
    mbedtls_psa_cipher_operation_t *operation)
611
0
{
612
    /* Sanity check (shouldn't happen: operation->alg should
613
     * always have been initialized to a valid value). */
614
0
    if (!PSA_ALG_IS_CIPHER(operation->alg)) {
615
0
        return PSA_ERROR_BAD_STATE;
616
0
    }
617
618
0
    mbedtls_cipher_free(&operation->ctx.cipher);
619
620
0
    return PSA_SUCCESS;
621
0
}
622
623
psa_status_t mbedtls_psa_cipher_encrypt(
624
    const psa_key_attributes_t *attributes,
625
    const uint8_t *key_buffer,
626
    size_t key_buffer_size,
627
    psa_algorithm_t alg,
628
    const uint8_t *iv,
629
    size_t iv_length,
630
    const uint8_t *input,
631
    size_t input_length,
632
    uint8_t *output,
633
    size_t output_size,
634
    size_t *output_length)
635
0
{
636
0
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
637
0
    mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
638
0
    size_t update_output_length, finish_output_length;
639
640
0
    status = mbedtls_psa_cipher_encrypt_setup(&operation, attributes,
641
0
                                              key_buffer, key_buffer_size,
642
0
                                              alg);
643
0
    if (status != PSA_SUCCESS) {
644
0
        goto exit;
645
0
    }
646
647
0
    if (iv_length > 0) {
648
0
        status = mbedtls_psa_cipher_set_iv(&operation, iv, iv_length);
649
0
        if (status != PSA_SUCCESS) {
650
0
            goto exit;
651
0
        }
652
0
    }
653
654
0
    status = mbedtls_psa_cipher_update(&operation, input, input_length,
655
0
                                       output, output_size,
656
0
                                       &update_output_length);
657
0
    if (status != PSA_SUCCESS) {
658
0
        goto exit;
659
0
    }
660
661
0
    status = mbedtls_psa_cipher_finish(
662
0
        &operation,
663
0
        mbedtls_buffer_offset(output, update_output_length),
664
0
        output_size - update_output_length, &finish_output_length);
665
0
    if (status != PSA_SUCCESS) {
666
0
        goto exit;
667
0
    }
668
669
0
    *output_length = update_output_length + finish_output_length;
670
671
0
exit:
672
0
    if (status == PSA_SUCCESS) {
673
0
        status = mbedtls_psa_cipher_abort(&operation);
674
0
    } else {
675
0
        mbedtls_psa_cipher_abort(&operation);
676
0
    }
677
678
0
    return status;
679
0
}
680
681
psa_status_t mbedtls_psa_cipher_decrypt(
682
    const psa_key_attributes_t *attributes,
683
    const uint8_t *key_buffer,
684
    size_t key_buffer_size,
685
    psa_algorithm_t alg,
686
    const uint8_t *input,
687
    size_t input_length,
688
    uint8_t *output,
689
    size_t output_size,
690
    size_t *output_length)
691
0
{
692
0
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
693
0
    mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
694
0
    size_t olength, accumulated_length;
695
696
0
    status = mbedtls_psa_cipher_decrypt_setup(&operation, attributes,
697
0
                                              key_buffer, key_buffer_size,
698
0
                                              alg);
699
0
    if (status != PSA_SUCCESS) {
700
0
        goto exit;
701
0
    }
702
703
0
    if (operation.iv_length > 0) {
704
0
        status = mbedtls_psa_cipher_set_iv(&operation,
705
0
                                           input, operation.iv_length);
706
0
        if (status != PSA_SUCCESS) {
707
0
            goto exit;
708
0
        }
709
0
    }
710
711
0
    status = mbedtls_psa_cipher_update(
712
0
        &operation,
713
0
        mbedtls_buffer_offset_const(input, operation.iv_length),
714
0
        input_length - operation.iv_length,
715
0
        output, output_size, &olength);
716
0
    if (status != PSA_SUCCESS) {
717
0
        goto exit;
718
0
    }
719
720
0
    accumulated_length = olength;
721
722
0
    status = mbedtls_psa_cipher_finish(
723
0
        &operation,
724
0
        mbedtls_buffer_offset(output, accumulated_length),
725
0
        output_size - accumulated_length, &olength);
726
727
0
    *output_length = accumulated_length + olength;
728
729
0
exit:
730
0
    /* C99 doesn't allow a declaration to follow a label */;
731
0
    psa_status_t abort_status = mbedtls_psa_cipher_abort(&operation);
732
    /* Normally abort shouldn't fail unless the operation is in a bad
733
     * state, in which case we'd expect finish to fail with the same error.
734
     * So it doesn't matter much which call's error code we pick when both
735
     * fail. However, in unauthenticated decryption specifically, the
736
     * distinction between PSA_SUCCESS and PSA_ERROR_INVALID_PADDING is
737
     * security-sensitive (risk of a padding oracle attack), so here we
738
     * must not have a code path that depends on the value of status. */
739
0
    if (abort_status != PSA_SUCCESS) {
740
0
        status = abort_status;
741
0
    }
742
743
0
    return status;
744
0
}
745
#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
746
747
#endif /* MBEDTLS_PSA_CRYPTO_C */