Coverage Report

Created: 2025-03-01 06:26

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