LCOV - code coverage report
Current view: top level - externals/mbedtls/library - psa_crypto_cipher.c (source / functions) Coverage Total Hit
Test: lcov.info Lines: 16.0 % 213 34
Test Date: 2026-03-12 12:01:18 Functions: 15.4 % 13 2
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 14.5 % 138 20

             Branch data     Line data    Source code
       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                 :          34 : static psa_status_t mbedtls_cipher_validate_values(
      31                 :             :     psa_algorithm_t alg,
      32                 :             :     psa_key_type_t key_type)
      33                 :             : {
      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         [ -  + ]:          34 :     MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_ARIA);
      41                 :             : #endif
      42                 :             : #if !defined(PSA_WANT_KEY_TYPE_CAMELLIA)
      43         [ -  + ]:          34 :     MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CAMELLIA);
      44                 :             : #endif
      45                 :             : #if !defined(PSA_WANT_KEY_TYPE_CHACHA20)
      46         [ -  + ]:          34 :     MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CHACHA20);
      47                 :             : #endif
      48                 :             : #if !defined(PSA_WANT_KEY_TYPE_DES)
      49         [ -  + ]:          34 :     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         [ -  + ]:          34 :     MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0));
      56                 :             : #endif
      57                 :             : #if !defined(PSA_WANT_ALG_STREAM_CIPHER)
      58         [ -  + ]:          34 :     MBEDTLS_ASSUME(alg != PSA_ALG_STREAM_CIPHER);
      59                 :             : #endif
      60                 :             : #if !defined(PSA_WANT_ALG_CHACHA20_POLY1305)
      61         [ -  + ]:          34 :     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         [ -  + ]:          34 :     MBEDTLS_ASSUME(alg != PSA_ALG_CTR);
      68                 :             : #endif
      69                 :             : #if !defined(PSA_WANT_ALG_CFB)
      70         [ -  + ]:          34 :     MBEDTLS_ASSUME(alg != PSA_ALG_CFB);
      71                 :             : #endif
      72                 :             : #if !defined(PSA_WANT_ALG_OFB)
      73         [ -  + ]:          34 :     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         [ -  + ]:          34 :     MBEDTLS_ASSUME(alg != PSA_ALG_CBC_NO_PADDING);
      80                 :             : #endif
      81                 :             : #if !defined(PSA_WANT_ALG_CBC_PKCS7)
      82         [ -  + ]:          34 :     MBEDTLS_ASSUME(alg != PSA_ALG_CBC_PKCS7);
      83                 :             : #endif
      84                 :             : #if !defined(PSA_WANT_ALG_CMAC)
      85         [ -  + ]:          34 :     MBEDTLS_ASSUME(alg != PSA_ALG_CMAC);
      86                 :             : #endif
      87                 :             : 
      88                 :          34 :     if (alg == PSA_ALG_STREAM_CIPHER ||
      89                 :             :         alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0)) {
      90                 :             :         if (key_type == PSA_KEY_TYPE_CHACHA20) {
      91                 :             :             return PSA_SUCCESS;
      92                 :             :         }
      93                 :             :     }
      94                 :             : 
      95         [ -  + ]:          34 :     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                 :             :         alg == PSA_ALG_CCM_STAR_NO_TAG) {
      98         [ -  + ]:          34 :         if (key_type == PSA_KEY_TYPE_AES ||
      99                 :             :             key_type == PSA_KEY_TYPE_ARIA ||
     100                 :             :             key_type == PSA_KEY_TYPE_CAMELLIA) {
     101                 :             :             return PSA_SUCCESS;
     102                 :             :         }
     103                 :             :     }
     104                 :             : 
     105                 :           0 :     if (alg == PSA_ALG_CTR ||
     106                 :             :         alg == PSA_ALG_CFB ||
     107         [ #  # ]:           0 :         alg == PSA_ALG_OFB ||
     108                 :             :         alg == PSA_ALG_XTS ||
     109         [ #  # ]:           0 :         alg == PSA_ALG_ECB_NO_PADDING ||
     110                 :             :         alg == PSA_ALG_CBC_NO_PADDING ||
     111                 :             :         alg == PSA_ALG_CBC_PKCS7 ||
     112                 :             :         alg == PSA_ALG_CMAC) {
     113         [ #  # ]:           0 :         if (key_type == PSA_KEY_TYPE_AES ||
     114                 :             :             key_type == PSA_KEY_TYPE_ARIA ||
     115                 :             :             key_type == PSA_KEY_TYPE_DES ||
     116                 :             :             key_type == PSA_KEY_TYPE_CAMELLIA) {
     117                 :           0 :             return PSA_SUCCESS;
     118                 :             :         }
     119                 :             :     }
     120                 :             : 
     121                 :             :     return PSA_ERROR_NOT_SUPPORTED;
     122                 :             : }
     123                 :             : 
     124                 :          34 : 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                 :             : {
     131                 :          34 :     mbedtls_cipher_id_t cipher_id_tmp;
     132                 :             :     /* Only DES modifies key_bits */
     133                 :             : #if !defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
     134                 :          34 :     (void) key_bits;
     135                 :             : #endif
     136                 :             : 
     137         [ +  - ]:          34 :     if (PSA_ALG_IS_AEAD(alg)) {
     138                 :          34 :         alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0);
     139                 :             :     }
     140                 :             : 
     141         [ +  - ]:          34 :     if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg)) {
     142   [ -  -  +  - ]:          34 :         switch (alg) {
     143                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER)
     144                 :             :             case PSA_ALG_STREAM_CIPHER:
     145                 :             :                 *mode = MBEDTLS_MODE_STREAM;
     146                 :             :                 break;
     147                 :             : #endif
     148                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CTR)
     149                 :             :             case PSA_ALG_CTR:
     150                 :             :                 *mode = MBEDTLS_MODE_CTR;
     151                 :             :                 break;
     152                 :             : #endif
     153                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CFB)
     154                 :             :             case PSA_ALG_CFB:
     155                 :             :                 *mode = MBEDTLS_MODE_CFB;
     156                 :             :                 break;
     157                 :             : #endif
     158                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_OFB)
     159                 :             :             case PSA_ALG_OFB:
     160                 :             :                 *mode = MBEDTLS_MODE_OFB;
     161                 :             :                 break;
     162                 :             : #endif
     163                 :             : #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                 :             : #endif
     168                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING)
     169                 :             :             case PSA_ALG_CBC_NO_PADDING:
     170                 :             :                 *mode = MBEDTLS_MODE_CBC;
     171                 :             :                 break;
     172                 :             : #endif
     173                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
     174                 :             :             case PSA_ALG_CBC_PKCS7:
     175                 :             :                 *mode = MBEDTLS_MODE_CBC;
     176                 :             :                 break;
     177                 :             : #endif
     178                 :             : #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                 :             : #endif
     183                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
     184                 :          34 :             case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
     185                 :          34 :                 *mode = MBEDTLS_MODE_CCM;
     186                 :          34 :                 break;
     187                 :             : #endif
     188                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
     189                 :             :             case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
     190                 :             :                 *mode = MBEDTLS_MODE_GCM;
     191                 :             :                 break;
     192                 :             : #endif
     193                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
     194                 :             :             case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
     195                 :             :                 *mode = MBEDTLS_MODE_CHACHAPOLY;
     196                 :             :                 break;
     197                 :             : #endif
     198                 :             :             default:
     199                 :             :                 return PSA_ERROR_NOT_SUPPORTED;
     200                 :             :         }
     201         [ #  # ]:           0 :     } else if (alg == PSA_ALG_CMAC) {
     202                 :           0 :         *mode = MBEDTLS_MODE_ECB;
     203                 :             :     } else {
     204                 :             :         return PSA_ERROR_NOT_SUPPORTED;
     205                 :             :     }
     206                 :             : 
     207         [ -  + ]:          34 :     switch (key_type) {
     208                 :             : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
     209                 :          34 :         case PSA_KEY_TYPE_AES:
     210                 :          34 :             cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
     211                 :          34 :             break;
     212                 :             : #endif
     213                 :             : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA)
     214                 :             :         case PSA_KEY_TYPE_ARIA:
     215                 :             :             cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
     216                 :             :             break;
     217                 :             : #endif
     218                 :             : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
     219                 :             :         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                 :             :             if (*key_bits == 64) {
     223                 :             :                 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
     224                 :             :             } else {
     225                 :             :                 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
     226                 :             :             }
     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                 :             :             if (*key_bits == 128) {
     231                 :             :                 *key_bits = 192;
     232                 :             :             }
     233                 :             :             break;
     234                 :             : #endif
     235                 :             : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
     236                 :             :         case PSA_KEY_TYPE_CAMELLIA:
     237                 :             :             cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
     238                 :             :             break;
     239                 :             : #endif
     240                 :             : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
     241                 :             :         case PSA_KEY_TYPE_CHACHA20:
     242                 :             :             cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
     243                 :             :             break;
     244                 :             : #endif
     245                 :             :         default:
     246                 :             :             return PSA_ERROR_NOT_SUPPORTED;
     247                 :             :     }
     248         [ +  - ]:          34 :     if (cipher_id != NULL) {
     249                 :          34 :         *cipher_id = cipher_id_tmp;
     250                 :             :     }
     251                 :             : 
     252                 :          34 :     return mbedtls_cipher_validate_values(alg, key_type);
     253                 :             : }
     254                 :             : 
     255                 :             : #if defined(MBEDTLS_CIPHER_C)
     256                 :           0 : 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                 :             : {
     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                 :             :         return NULL;
     269                 :             :     }
     270         [ #  # ]:           0 :     if (cipher_id != NULL) {
     271                 :           0 :         *cipher_id = cipher_id_tmp;
     272                 :             :     }
     273                 :             : 
     274                 :           0 :     return mbedtls_cipher_info_from_values(cipher_id_tmp, (int) key_bits, mode);
     275                 :             : }
     276                 :             : #endif /* MBEDTLS_CIPHER_C */
     277                 :             : 
     278                 :             : #if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
     279                 :             : 
     280                 :           0 : 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                 :             : {
     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                 :             :                                                key_bits, NULL);
     300         [ #  # ]:           0 :     if (cipher_info == NULL) {
     301                 :             :         return PSA_ERROR_NOT_SUPPORTED;
     302                 :             :     }
     303                 :             : 
     304                 :           0 :     ret = mbedtls_cipher_setup(&operation->ctx.cipher, cipher_info);
     305         [ #  # ]:           0 :     if (ret != 0) {
     306                 :           0 :         goto exit;
     307                 :             :     }
     308                 :             : 
     309                 :             : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
     310                 :             :     if (key_type == PSA_KEY_TYPE_DES && key_bits == 128) {
     311                 :             :         /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
     312                 :             :         uint8_t keys[24];
     313                 :             :         memcpy(keys, key_buffer, 16);
     314                 :             :         memcpy(keys + 16, key_buffer, 8);
     315                 :             :         ret = mbedtls_cipher_setkey(&operation->ctx.cipher,
     316                 :             :                                     keys,
     317                 :             :                                     192, cipher_operation);
     318                 :             :     } else
     319                 :             : #endif
     320                 :             :     {
     321                 :           0 :         ret = mbedtls_cipher_setkey(&operation->ctx.cipher, key_buffer,
     322                 :             :                                     (int) key_bits, cipher_operation);
     323                 :             :     }
     324         [ #  # ]:           0 :     if (ret != 0) {
     325                 :           0 :         goto exit;
     326                 :             :     }
     327                 :             : 
     328                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
     329                 :             :     defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
     330                 :             :     switch (alg) {
     331                 :             :         case PSA_ALG_CBC_NO_PADDING:
     332                 :             :             ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
     333                 :             :                                                   MBEDTLS_PADDING_NONE);
     334                 :             :             break;
     335                 :             :         case PSA_ALG_CBC_PKCS7:
     336                 :             :             ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
     337                 :             :                                                   MBEDTLS_PADDING_PKCS7);
     338                 :             :             break;
     339                 :             :         default:
     340                 :             :             /* The algorithm doesn't involve padding. */
     341                 :             :             ret = 0;
     342                 :             :             break;
     343                 :             :     }
     344                 :             :     if (ret != 0) {
     345                 :             :         goto exit;
     346                 :             :     }
     347                 :             : #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                 :             : }
     357                 :             : 
     358                 :           0 : 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                 :             : {
     364                 :           0 :     return psa_cipher_setup(operation, attributes,
     365                 :             :                             key_buffer, key_buffer_size,
     366                 :             :                             alg, MBEDTLS_ENCRYPT);
     367                 :             : }
     368                 :             : 
     369                 :           0 : 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                 :             : {
     375                 :           0 :     return psa_cipher_setup(operation, attributes,
     376                 :             :                             key_buffer, key_buffer_size,
     377                 :             :                             alg, MBEDTLS_DECRYPT);
     378                 :             : }
     379                 :             : 
     380                 :           0 : 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                 :             : {
     384         [ #  # ]:           0 :     if (iv_length != operation->iv_length) {
     385                 :             :         return PSA_ERROR_INVALID_ARGUMENT;
     386                 :             :     }
     387                 :             : 
     388                 :           0 :     return mbedtls_to_psa_error(
     389                 :             :         mbedtls_cipher_set_iv(&operation->ctx.cipher,
     390                 :             :                               iv, iv_length));
     391                 :             : }
     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                 :           0 : 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                 :             : {
     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                 :             :     }
     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                 :             :             bytes_to_copy = input_length;
     440                 :             :         }
     441                 :             : 
     442         [ #  # ]:           0 :         memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
     443                 :             :                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                 :             :                 mbedtls_cipher_update(ctx,
     451                 :           0 :                                       ctx->unprocessed_data,
     452                 :             :                                       block_size,
     453                 :             :                                       output, &internal_output_length));
     454                 :             : 
     455         [ #  # ]:           0 :             if (status != PSA_SUCCESS) {
     456                 :           0 :                 goto exit;
     457                 :             :             }
     458                 :             : 
     459                 :           0 :             output += internal_output_length;
     460                 :           0 :             *output_length += internal_output_length;
     461                 :           0 :             ctx->unprocessed_len = 0;
     462                 :             :         }
     463                 :             :     }
     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                 :             :             mbedtls_cipher_update(ctx, input,
     469                 :             :                                   block_size,
     470                 :             :                                   output, &internal_output_length));
     471                 :             : 
     472         [ #  # ]:           0 :         if (status != PSA_SUCCESS) {
     473                 :           0 :             goto exit;
     474                 :             :         }
     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                 :             :     }
     482                 :             : 
     483         [ #  # ]:           0 :     if (input_length > 0) {
     484                 :             :         /* Save unprocessed bytes for later processing */
     485                 :           0 :         memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
     486                 :             :                input, input_length);
     487                 :           0 :         ctx->unprocessed_len += input_length;
     488                 :             :     }
     489                 :             : 
     490                 :             :     status = PSA_SUCCESS;
     491                 :             : 
     492                 :           0 : exit:
     493                 :           0 :     return status;
     494                 :             : }
     495                 :             : #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
     496                 :             : 
     497                 :           0 : 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                 :             : {
     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                 :             :     } else {
     514                 :             :         expected_output_size = input_length;
     515                 :             :     }
     516                 :             : 
     517         [ #  # ]:           0 :     if (output_size < expected_output_size) {
     518                 :             :         return PSA_ERROR_BUFFER_TOO_SMALL;
     519                 :             :     }
     520                 :             : 
     521                 :             : #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                 :             :                                        input,
     528                 :             :                                        input_length,
     529                 :             :                                        output,
     530                 :             :                                        output_length);
     531                 :             :     } else
     532                 :             : #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                 :             :     } else {
     538                 :           0 :         status = mbedtls_to_psa_error(
     539                 :             :             mbedtls_cipher_update(&operation->ctx.cipher, input,
     540                 :             :                                   input_length, output, output_length));
     541                 :             : 
     542         [ #  # ]:           0 :         if (*output_length > output_size) {
     543                 :           0 :             return PSA_ERROR_CORRUPTION_DETECTED;
     544                 :             :         }
     545                 :             :     }
     546                 :             : 
     547                 :             :     return status;
     548                 :             : }
     549                 :             : 
     550                 :           0 : 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                 :             : {
     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                 :             :         output_size = sizeof(temp_output_buffer);
     567                 :             :     }
     568                 :             : 
     569         [ #  # ]:           0 :     if (operation->ctx.cipher.unprocessed_len != 0) {
     570         [ #  # ]:           0 :         if (operation->alg == PSA_ALG_ECB_NO_PADDING ||
     571                 :             :             operation->alg == PSA_ALG_CBC_NO_PADDING) {
     572                 :           0 :             status = PSA_ERROR_INVALID_ARGUMENT;
     573                 :           0 :             goto exit;
     574                 :             :         }
     575                 :             :     }
     576                 :             : 
     577                 :           0 :     status = mbedtls_to_psa_error(
     578                 :             :         mbedtls_cipher_finish_padded(&operation->ctx.cipher,
     579                 :             :                                      temp_output_buffer,
     580                 :             :                                      output_length,
     581                 :             :                                      &invalid_padding));
     582         [ #  # ]:           0 :     if (status != PSA_SUCCESS) {
     583                 :           0 :         goto exit;
     584                 :             :     }
     585                 :             : 
     586         [ #  # ]:           0 :     if (output_size == 0) {
     587                 :             :         ; /* Nothing to copy. Note that output may be NULL in this case. */
     588                 :             :     } 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                 :             :     }
     594                 :             : 
     595                 :           0 :     status = mbedtls_ct_error_if_else_0(invalid_padding,
     596                 :             :                                         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                 :             :                                  PSA_ERROR_BUFFER_TOO_SMALL,
     601                 :             :                                  status);
     602                 :             : 
     603                 :           0 : exit:
     604                 :           0 :     mbedtls_platform_zeroize(temp_output_buffer,
     605                 :             :                              sizeof(temp_output_buffer));
     606                 :           0 :     return status;
     607                 :             : }
     608                 :             : 
     609                 :           0 : psa_status_t mbedtls_psa_cipher_abort(
     610                 :             :     mbedtls_psa_cipher_operation_t *operation)
     611                 :             : {
     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                 :             :         return PSA_ERROR_BAD_STATE;
     616                 :             :     }
     617                 :             : 
     618                 :           0 :     mbedtls_cipher_free(&operation->ctx.cipher);
     619                 :             : 
     620                 :           0 :     return PSA_SUCCESS;
     621                 :             : }
     622                 :             : 
     623                 :           0 : 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                 :             : {
     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                 :             :                                               key_buffer, key_buffer_size,
     642                 :             :                                               alg);
     643         [ #  # ]:           0 :     if (status != PSA_SUCCESS) {
     644                 :           0 :         goto exit;
     645                 :             :     }
     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                 :             :         }
     652                 :             :     }
     653                 :             : 
     654                 :           0 :     status = mbedtls_psa_cipher_update(&operation, input, input_length,
     655                 :             :                                        output, output_size,
     656                 :             :                                        &update_output_length);
     657         [ #  # ]:           0 :     if (status != PSA_SUCCESS) {
     658                 :           0 :         goto exit;
     659                 :             :     }
     660                 :             : 
     661                 :           0 :     status = mbedtls_psa_cipher_finish(
     662                 :             :         &operation,
     663                 :           0 :         mbedtls_buffer_offset(output, update_output_length),
     664                 :             :         output_size - update_output_length, &finish_output_length);
     665         [ #  # ]:           0 :     if (status != PSA_SUCCESS) {
     666                 :           0 :         goto exit;
     667                 :             :     }
     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                 :             :     } else {
     675                 :           0 :         mbedtls_psa_cipher_abort(&operation);
     676                 :             :     }
     677                 :             : 
     678                 :           0 :     return status;
     679                 :             : }
     680                 :             : 
     681                 :           0 : 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                 :             : {
     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                 :             :                                               key_buffer, key_buffer_size,
     698                 :             :                                               alg);
     699         [ #  # ]:           0 :     if (status != PSA_SUCCESS) {
     700                 :           0 :         goto exit;
     701                 :             :     }
     702                 :             : 
     703         [ #  # ]:           0 :     if (operation.iv_length > 0) {
     704                 :           0 :         status = mbedtls_psa_cipher_set_iv(&operation,
     705                 :             :                                            input, operation.iv_length);
     706         [ #  # ]:           0 :         if (status != PSA_SUCCESS) {
     707                 :           0 :             goto exit;
     708                 :             :         }
     709                 :             :     }
     710                 :             : 
     711                 :           0 :     status = mbedtls_psa_cipher_update(
     712                 :             :         &operation,
     713                 :           0 :         mbedtls_buffer_offset_const(input, operation.iv_length),
     714                 :           0 :         input_length - operation.iv_length,
     715                 :             :         output, output_size, &olength);
     716         [ #  # ]:           0 :     if (status != PSA_SUCCESS) {
     717                 :           0 :         goto exit;
     718                 :             :     }
     719                 :             : 
     720                 :           0 :     accumulated_length = olength;
     721                 :             : 
     722                 :           0 :     status = mbedtls_psa_cipher_finish(
     723                 :             :         &operation,
     724                 :           0 :         mbedtls_buffer_offset(output, accumulated_length),
     725                 :             :         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                 :             :     }
     742                 :             : 
     743                 :           0 :     return status;
     744                 :             : }
     745                 :             : #endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
     746                 :             : 
     747                 :             : #endif /* MBEDTLS_PSA_CRYPTO_C */
        

Generated by: LCOV version 2.0-1