xref: /optee_os/lib/libmbedtls/mbedtls/library/psa_crypto_cipher.c (revision c3deb3d6f3b13d0e17fc9efe5880aec039e47594)
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  */
mbedtls_cipher_validate_values(psa_algorithm_t alg,psa_key_type_t key_type)29 static psa_status_t mbedtls_cipher_validate_values(
30     psa_algorithm_t alg,
31     psa_key_type_t key_type)
32 {
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     if (alg == PSA_ALG_STREAM_CIPHER ||
88         alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0)) {
89         if (key_type == PSA_KEY_TYPE_CHACHA20) {
90             return PSA_SUCCESS;
91         }
92     }
93 
94     if (alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0) ||
95         alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0) ||
96         alg == PSA_ALG_CCM_STAR_NO_TAG) {
97         if (key_type == PSA_KEY_TYPE_AES ||
98             key_type == PSA_KEY_TYPE_ARIA ||
99             key_type == PSA_KEY_TYPE_CAMELLIA) {
100             return PSA_SUCCESS;
101         }
102     }
103 
104     if (alg == PSA_ALG_CTR ||
105         alg == PSA_ALG_CFB ||
106         alg == PSA_ALG_OFB ||
107         alg == PSA_ALG_XTS ||
108         alg == PSA_ALG_ECB_NO_PADDING ||
109         alg == PSA_ALG_CBC_NO_PADDING ||
110         alg == PSA_ALG_CBC_PKCS7 ||
111         alg == PSA_ALG_CMAC) {
112         if (key_type == PSA_KEY_TYPE_AES ||
113             key_type == PSA_KEY_TYPE_ARIA ||
114             key_type == PSA_KEY_TYPE_DES ||
115             key_type == PSA_KEY_TYPE_CAMELLIA) {
116             return PSA_SUCCESS;
117         }
118     }
119 
120     return PSA_ERROR_NOT_SUPPORTED;
121 }
122 
mbedtls_cipher_values_from_psa(psa_algorithm_t alg,psa_key_type_t key_type,size_t * key_bits,mbedtls_cipher_mode_t * mode,mbedtls_cipher_id_t * cipher_id)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 {
130     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     if (PSA_ALG_IS_AEAD(alg)) {
137         alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0);
138     }
139 
140     if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg)) {
141         switch (alg) {
142 #if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER)
143             case PSA_ALG_STREAM_CIPHER:
144                 *mode = MBEDTLS_MODE_STREAM;
145                 break;
146 #endif
147 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CTR)
148             case PSA_ALG_CTR:
149                 *mode = MBEDTLS_MODE_CTR;
150                 break;
151 #endif
152 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CFB)
153             case PSA_ALG_CFB:
154                 *mode = MBEDTLS_MODE_CFB;
155                 break;
156 #endif
157 #if defined(MBEDTLS_PSA_BUILTIN_ALG_OFB)
158             case PSA_ALG_OFB:
159                 *mode = MBEDTLS_MODE_OFB;
160                 break;
161 #endif
162 #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
163             case PSA_ALG_ECB_NO_PADDING:
164                 *mode = MBEDTLS_MODE_ECB;
165                 break;
166 #endif
167 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING)
168             case PSA_ALG_CBC_NO_PADDING:
169                 *mode = MBEDTLS_MODE_CBC;
170                 break;
171 #endif
172 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
173             case PSA_ALG_CBC_PKCS7:
174                 *mode = MBEDTLS_MODE_CBC;
175                 break;
176 #endif
177 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG)
178             case PSA_ALG_CCM_STAR_NO_TAG:
179                 *mode = MBEDTLS_MODE_CCM_STAR_NO_TAG;
180                 break;
181 #endif
182 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
183             case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
184                 *mode = MBEDTLS_MODE_CCM;
185                 break;
186 #endif
187 #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
188             case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
189                 *mode = MBEDTLS_MODE_GCM;
190                 break;
191 #endif
192 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
193             case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
194                 *mode = MBEDTLS_MODE_CHACHAPOLY;
195                 break;
196 #endif
197             default:
198                 return PSA_ERROR_NOT_SUPPORTED;
199         }
200     } else if (alg == PSA_ALG_CMAC) {
201         *mode = MBEDTLS_MODE_ECB;
202     } else {
203         return PSA_ERROR_NOT_SUPPORTED;
204     }
205 
206     switch (key_type) {
207 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
208         case PSA_KEY_TYPE_AES:
209             cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
210             break;
211 #endif
212 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA)
213         case PSA_KEY_TYPE_ARIA:
214             cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
215             break;
216 #endif
217 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
218         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             if (*key_bits == 64) {
222                 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
223             } else {
224                 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
225             }
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             if (*key_bits == 128) {
230                 *key_bits = 192;
231             }
232             break;
233 #endif
234 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
235         case PSA_KEY_TYPE_CAMELLIA:
236             cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
237             break;
238 #endif
239 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
240         case PSA_KEY_TYPE_CHACHA20:
241             cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
242             break;
243 #endif
244         default:
245             return PSA_ERROR_NOT_SUPPORTED;
246     }
247     if (cipher_id != NULL) {
248         *cipher_id = cipher_id_tmp;
249     }
250 
251     return mbedtls_cipher_validate_values(alg, key_type);
252 }
253 
254 #if defined(MBEDTLS_CIPHER_C)
mbedtls_cipher_info_from_psa(psa_algorithm_t alg,psa_key_type_t key_type,size_t key_bits,mbedtls_cipher_id_t * cipher_id)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 {
261     mbedtls_cipher_mode_t mode;
262     psa_status_t status;
263     mbedtls_cipher_id_t cipher_id_tmp = MBEDTLS_CIPHER_ID_NONE;
264 
265     status = mbedtls_cipher_values_from_psa(alg, key_type, &key_bits, &mode, &cipher_id_tmp);
266     if (status != PSA_SUCCESS) {
267         return NULL;
268     }
269     if (cipher_id != NULL) {
270         *cipher_id = cipher_id_tmp;
271     }
272 
273     return mbedtls_cipher_info_from_values(cipher_id_tmp, (int) key_bits, mode);
274 }
275 #endif /* MBEDTLS_CIPHER_C */
276 
277 #if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
278 
psa_cipher_setup(mbedtls_psa_cipher_operation_t * operation,const psa_key_attributes_t * attributes,const uint8_t * key_buffer,size_t key_buffer_size,psa_algorithm_t alg,mbedtls_operation_t cipher_operation)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 {
286     int ret = 0;
287     size_t key_bits;
288     const mbedtls_cipher_info_t *cipher_info = NULL;
289     psa_key_type_t key_type = attributes->type;
290 
291     (void) key_buffer_size;
292 
293     mbedtls_cipher_init(&operation->ctx.cipher);
294 
295     operation->alg = alg;
296     key_bits = attributes->bits;
297     cipher_info = mbedtls_cipher_info_from_psa(alg, key_type,
298                                                key_bits, NULL);
299     if (cipher_info == NULL) {
300         return PSA_ERROR_NOT_SUPPORTED;
301     }
302 
303     ret = mbedtls_cipher_setup(&operation->ctx.cipher, cipher_info);
304     if (ret != 0) {
305         goto exit;
306     }
307 
308 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
309     if (key_type == PSA_KEY_TYPE_DES && key_bits == 128) {
310         /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
311         uint8_t keys[24];
312         memcpy(keys, key_buffer, 16);
313         memcpy(keys + 16, key_buffer, 8);
314         ret = mbedtls_cipher_setkey(&operation->ctx.cipher,
315                                     keys,
316                                     192, cipher_operation);
317     } else
318 #endif
319     {
320         ret = mbedtls_cipher_setkey(&operation->ctx.cipher, key_buffer,
321                                     (int) key_bits, cipher_operation);
322     }
323     if (ret != 0) {
324         goto exit;
325     }
326 
327 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
328     defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
329     switch (alg) {
330         case PSA_ALG_CBC_NO_PADDING:
331             ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
332                                                   MBEDTLS_PADDING_NONE);
333             break;
334         case PSA_ALG_CBC_PKCS7:
335             ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
336                                                   MBEDTLS_PADDING_PKCS7);
337             break;
338         default:
339             /* The algorithm doesn't involve padding. */
340             ret = 0;
341             break;
342     }
343     if (ret != 0) {
344         goto exit;
345     }
346 #endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING ||
347           MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */
348 
349     operation->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 :
350                                PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type));
351     operation->iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
352 
353 exit:
354     return mbedtls_to_psa_error(ret);
355 }
356 
mbedtls_psa_cipher_encrypt_setup(mbedtls_psa_cipher_operation_t * operation,const psa_key_attributes_t * attributes,const uint8_t * key_buffer,size_t key_buffer_size,psa_algorithm_t alg)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 {
363     return psa_cipher_setup(operation, attributes,
364                             key_buffer, key_buffer_size,
365                             alg, MBEDTLS_ENCRYPT);
366 }
367 
mbedtls_psa_cipher_decrypt_setup(mbedtls_psa_cipher_operation_t * operation,const psa_key_attributes_t * attributes,const uint8_t * key_buffer,size_t key_buffer_size,psa_algorithm_t alg)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 {
374     return psa_cipher_setup(operation, attributes,
375                             key_buffer, key_buffer_size,
376                             alg, MBEDTLS_DECRYPT);
377 }
378 
mbedtls_psa_cipher_set_iv(mbedtls_psa_cipher_operation_t * operation,const uint8_t * iv,size_t iv_length)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 {
383     if (iv_length != operation->iv_length) {
384         return PSA_ERROR_INVALID_ARGUMENT;
385     }
386 
387     return mbedtls_to_psa_error(
388         mbedtls_cipher_set_iv(&operation->ctx.cipher,
389                               iv, iv_length));
390 }
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  */
psa_cipher_update_ecb(mbedtls_cipher_context_t * ctx,const uint8_t * input,size_t input_length,uint8_t * output,size_t * output_length)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 {
423     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
424     size_t block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
425     size_t internal_output_length = 0;
426     *output_length = 0;
427 
428     if (input_length == 0) {
429         status = PSA_SUCCESS;
430         goto exit;
431     }
432 
433     if (ctx->unprocessed_len > 0) {
434         /* Fill up to block size, and run the block if there's a full one. */
435         size_t bytes_to_copy = block_size - ctx->unprocessed_len;
436 
437         if (input_length < bytes_to_copy) {
438             bytes_to_copy = input_length;
439         }
440 
441         memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
442                input, bytes_to_copy);
443         input_length -= bytes_to_copy;
444         input += bytes_to_copy;
445         ctx->unprocessed_len += bytes_to_copy;
446 
447         if (ctx->unprocessed_len == block_size) {
448             status = mbedtls_to_psa_error(
449                 mbedtls_cipher_update(ctx,
450                                       ctx->unprocessed_data,
451                                       block_size,
452                                       output, &internal_output_length));
453 
454             if (status != PSA_SUCCESS) {
455                 goto exit;
456             }
457 
458             output += internal_output_length;
459             *output_length += internal_output_length;
460             ctx->unprocessed_len = 0;
461         }
462     }
463 
464     while (input_length >= block_size) {
465         /* Run all full blocks we have, one by one */
466         status = mbedtls_to_psa_error(
467             mbedtls_cipher_update(ctx, input,
468                                   block_size,
469                                   output, &internal_output_length));
470 
471         if (status != PSA_SUCCESS) {
472             goto exit;
473         }
474 
475         input_length -= block_size;
476         input += block_size;
477 
478         output += internal_output_length;
479         *output_length += internal_output_length;
480     }
481 
482     if (input_length > 0) {
483         /* Save unprocessed bytes for later processing */
484         memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
485                input, input_length);
486         ctx->unprocessed_len += input_length;
487     }
488 
489     status = PSA_SUCCESS;
490 
491 exit:
492     return status;
493 }
494 #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
495 
mbedtls_psa_cipher_update(mbedtls_psa_cipher_operation_t * operation,const uint8_t * input,size_t input_length,uint8_t * output,size_t output_size,size_t * output_length)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 {
501     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
502     size_t expected_output_size;
503 
504     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         expected_output_size =
510             (operation->ctx.cipher.unprocessed_len + input_length)
511             / operation->block_length * operation->block_length;
512     } else {
513         expected_output_size = input_length;
514     }
515 
516     if (output_size < expected_output_size) {
517         return PSA_ERROR_BUFFER_TOO_SMALL;
518     }
519 
520 #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
521     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         status = psa_cipher_update_ecb(&operation->ctx.cipher,
526                                        input,
527                                        input_length,
528                                        output,
529                                        output_length);
530     } else
531 #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
532     if (input_length == 0) {
533         /* There is no input, nothing to be done */
534         *output_length = 0;
535         status = PSA_SUCCESS;
536     } else {
537         status = mbedtls_to_psa_error(
538             mbedtls_cipher_update(&operation->ctx.cipher, input,
539                                   input_length, output, output_length));
540 
541         if (*output_length > output_size) {
542             return PSA_ERROR_CORRUPTION_DETECTED;
543         }
544     }
545 
546     return status;
547 }
548 
mbedtls_psa_cipher_finish(mbedtls_psa_cipher_operation_t * operation,uint8_t * output,size_t output_size,size_t * output_length)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 {
553     psa_status_t status = PSA_ERROR_GENERIC_ERROR;
554     uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
555 
556     if (operation->ctx.cipher.unprocessed_len != 0) {
557         if (operation->alg == PSA_ALG_ECB_NO_PADDING ||
558             operation->alg == PSA_ALG_CBC_NO_PADDING) {
559             status = PSA_ERROR_INVALID_ARGUMENT;
560             goto exit;
561         }
562     }
563 
564     status = mbedtls_to_psa_error(
565         mbedtls_cipher_finish(&operation->ctx.cipher,
566                               temp_output_buffer,
567                               output_length));
568     if (status != PSA_SUCCESS) {
569         goto exit;
570     }
571 
572     if (*output_length == 0) {
573         ; /* Nothing to copy. Note that output may be NULL in this case. */
574     } else if (output_size >= *output_length) {
575         memcpy(output, temp_output_buffer, *output_length);
576     } else {
577         status = PSA_ERROR_BUFFER_TOO_SMALL;
578     }
579 
580 exit:
581     mbedtls_platform_zeroize(temp_output_buffer,
582                              sizeof(temp_output_buffer));
583 
584     return status;
585 }
586 
mbedtls_psa_cipher_abort(mbedtls_psa_cipher_operation_t * operation)587 psa_status_t mbedtls_psa_cipher_abort(
588     mbedtls_psa_cipher_operation_t *operation)
589 {
590     /* Sanity check (shouldn't happen: operation->alg should
591      * always have been initialized to a valid value). */
592     if (!PSA_ALG_IS_CIPHER(operation->alg)) {
593         return PSA_ERROR_BAD_STATE;
594     }
595 
596     mbedtls_cipher_free(&operation->ctx.cipher);
597 
598     return PSA_SUCCESS;
599 }
600 
mbedtls_psa_cipher_encrypt(const psa_key_attributes_t * attributes,const uint8_t * key_buffer,size_t key_buffer_size,psa_algorithm_t alg,const uint8_t * iv,size_t iv_length,const uint8_t * input,size_t input_length,uint8_t * output,size_t output_size,size_t * output_length)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 {
614     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
615     mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
616     size_t update_output_length, finish_output_length;
617 
618     status = mbedtls_psa_cipher_encrypt_setup(&operation, attributes,
619                                               key_buffer, key_buffer_size,
620                                               alg);
621     if (status != PSA_SUCCESS) {
622         goto exit;
623     }
624 
625     if (iv_length > 0) {
626         status = mbedtls_psa_cipher_set_iv(&operation, iv, iv_length);
627         if (status != PSA_SUCCESS) {
628             goto exit;
629         }
630     }
631 
632     status = mbedtls_psa_cipher_update(&operation, input, input_length,
633                                        output, output_size,
634                                        &update_output_length);
635     if (status != PSA_SUCCESS) {
636         goto exit;
637     }
638 
639     status = mbedtls_psa_cipher_finish(
640         &operation,
641         mbedtls_buffer_offset(output, update_output_length),
642         output_size - update_output_length, &finish_output_length);
643     if (status != PSA_SUCCESS) {
644         goto exit;
645     }
646 
647     *output_length = update_output_length + finish_output_length;
648 
649 exit:
650     if (status == PSA_SUCCESS) {
651         status = mbedtls_psa_cipher_abort(&operation);
652     } else {
653         mbedtls_psa_cipher_abort(&operation);
654     }
655 
656     return status;
657 }
658 
mbedtls_psa_cipher_decrypt(const psa_key_attributes_t * attributes,const uint8_t * key_buffer,size_t key_buffer_size,psa_algorithm_t alg,const uint8_t * input,size_t input_length,uint8_t * output,size_t output_size,size_t * output_length)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 {
670     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
671     mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
672     size_t olength, accumulated_length;
673 
674     status = mbedtls_psa_cipher_decrypt_setup(&operation, attributes,
675                                               key_buffer, key_buffer_size,
676                                               alg);
677     if (status != PSA_SUCCESS) {
678         goto exit;
679     }
680 
681     if (operation.iv_length > 0) {
682         status = mbedtls_psa_cipher_set_iv(&operation,
683                                            input, operation.iv_length);
684         if (status != PSA_SUCCESS) {
685             goto exit;
686         }
687     }
688 
689     status = mbedtls_psa_cipher_update(
690         &operation,
691         mbedtls_buffer_offset_const(input, operation.iv_length),
692         input_length - operation.iv_length,
693         output, output_size, &olength);
694     if (status != PSA_SUCCESS) {
695         goto exit;
696     }
697 
698     accumulated_length = olength;
699 
700     status = mbedtls_psa_cipher_finish(
701         &operation,
702         mbedtls_buffer_offset(output, accumulated_length),
703         output_size - accumulated_length, &olength);
704     if (status != PSA_SUCCESS) {
705         goto exit;
706     }
707 
708     *output_length = accumulated_length + olength;
709 
710 exit:
711     if (status == PSA_SUCCESS) {
712         status = mbedtls_psa_cipher_abort(&operation);
713     } else {
714         mbedtls_psa_cipher_abort(&operation);
715     }
716 
717     return status;
718 }
719 #endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
720 
721 #endif /* MBEDTLS_PSA_CRYPTO_C */
722