| Manuel Pégourié-Gonnard | 2171876 | 2023-11-10 11:21:17 +0100 | [diff] [blame] | 1 | /** | 
|  | 2 | * \file block_cipher.c | 
|  | 3 | * | 
|  | 4 | * \brief Lightweight abstraction layer for block ciphers with 128 bit blocks, | 
|  | 5 | * for use by the GCM and CCM modules. | 
|  | 6 | */ | 
|  | 7 | /* | 
|  | 8 | *  Copyright The Mbed TLS Contributors | 
|  | 9 | *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later | 
|  | 10 | */ | 
|  | 11 |  | 
|  | 12 | #include "common.h" | 
|  | 13 |  | 
| Valerio Setti | c1db99d | 2023-12-12 11:19:17 +0100 | [diff] [blame] | 14 | #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) | 
| Valerio Setti | c1db99d | 2023-12-12 11:19:17 +0100 | [diff] [blame] | 15 | #include "psa/crypto.h" | 
| Valerio Setti | 849a1ab | 2023-12-13 16:34:07 +0100 | [diff] [blame] | 16 | #include "psa_crypto_core.h" | 
| Valerio Setti | c1db99d | 2023-12-12 11:19:17 +0100 | [diff] [blame] | 17 | #include "psa_util_internal.h" | 
|  | 18 | #endif | 
|  | 19 |  | 
| Manuel Pégourié-Gonnard | 2171876 | 2023-11-10 11:21:17 +0100 | [diff] [blame] | 20 | #include "block_cipher_internal.h" | 
|  | 21 |  | 
|  | 22 | #if defined(MBEDTLS_BLOCK_CIPHER_C) | 
|  | 23 |  | 
| Valerio Setti | c1db99d | 2023-12-12 11:19:17 +0100 | [diff] [blame] | 24 | #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) | 
| Valerio Setti | 4ff405c | 2023-12-15 16:10:52 +0100 | [diff] [blame] | 25 | static psa_key_type_t psa_key_type_from_block_cipher_id(mbedtls_block_cipher_id_t cipher_id) | 
| Valerio Setti | c1db99d | 2023-12-12 11:19:17 +0100 | [diff] [blame] | 26 | { | 
|  | 27 | switch (cipher_id) { | 
|  | 28 | #if defined(MBEDTLS_BLOCK_CIPHER_AES_VIA_PSA) | 
| Valerio Setti | 4ff405c | 2023-12-15 16:10:52 +0100 | [diff] [blame] | 29 | case MBEDTLS_BLOCK_CIPHER_ID_AES: | 
| Valerio Setti | c1db99d | 2023-12-12 11:19:17 +0100 | [diff] [blame] | 30 | return PSA_KEY_TYPE_AES; | 
|  | 31 | #endif | 
|  | 32 | #if defined(MBEDTLS_BLOCK_CIPHER_ARIA_VIA_PSA) | 
| Valerio Setti | 4ff405c | 2023-12-15 16:10:52 +0100 | [diff] [blame] | 33 | case MBEDTLS_BLOCK_CIPHER_ID_ARIA: | 
| Valerio Setti | c1db99d | 2023-12-12 11:19:17 +0100 | [diff] [blame] | 34 | return PSA_KEY_TYPE_ARIA; | 
|  | 35 | #endif | 
|  | 36 | #if defined(MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_PSA) | 
| Valerio Setti | 4ff405c | 2023-12-15 16:10:52 +0100 | [diff] [blame] | 37 | case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: | 
| Valerio Setti | c1db99d | 2023-12-12 11:19:17 +0100 | [diff] [blame] | 38 | return PSA_KEY_TYPE_CAMELLIA; | 
|  | 39 | #endif | 
|  | 40 | default: | 
|  | 41 | return PSA_KEY_TYPE_NONE; | 
|  | 42 | } | 
|  | 43 | } | 
|  | 44 |  | 
| Valerio Setti | 1994e72 | 2023-12-28 14:01:22 +0100 | [diff] [blame] | 45 | static int mbedtls_cipher_error_from_psa(psa_status_t status) | 
| Valerio Setti | c1db99d | 2023-12-12 11:19:17 +0100 | [diff] [blame] | 46 | { | 
|  | 47 | return PSA_TO_MBEDTLS_ERR_LIST(status, psa_to_cipher_errors, | 
|  | 48 | psa_generic_status_to_mbedtls); | 
|  | 49 | } | 
|  | 50 | #endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */ | 
|  | 51 |  | 
| Manuel Pégourié-Gonnard | 2171876 | 2023-11-10 11:21:17 +0100 | [diff] [blame] | 52 | void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx) | 
|  | 53 | { | 
| Valerio Setti | c1db99d | 2023-12-12 11:19:17 +0100 | [diff] [blame] | 54 | #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) | 
|  | 55 | if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) { | 
| Valerio Setti | c1db99d | 2023-12-12 11:19:17 +0100 | [diff] [blame] | 56 | psa_destroy_key(ctx->psa_key_id); | 
|  | 57 | return; | 
|  | 58 | } | 
|  | 59 | #endif | 
| Manuel Pégourié-Gonnard | 2171876 | 2023-11-10 11:21:17 +0100 | [diff] [blame] | 60 | switch (ctx->id) { | 
|  | 61 | #if defined(MBEDTLS_AES_C) | 
|  | 62 | case MBEDTLS_BLOCK_CIPHER_ID_AES: | 
|  | 63 | mbedtls_aes_free(&ctx->ctx.aes); | 
|  | 64 | break; | 
|  | 65 | #endif | 
|  | 66 | #if defined(MBEDTLS_ARIA_C) | 
|  | 67 | case MBEDTLS_BLOCK_CIPHER_ID_ARIA: | 
|  | 68 | mbedtls_aria_free(&ctx->ctx.aria); | 
|  | 69 | break; | 
|  | 70 | #endif | 
|  | 71 | #if defined(MBEDTLS_CAMELLIA_C) | 
|  | 72 | case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: | 
|  | 73 | mbedtls_camellia_free(&ctx->ctx.camellia); | 
|  | 74 | break; | 
|  | 75 | #endif | 
|  | 76 | default: | 
|  | 77 | break; | 
|  | 78 | } | 
|  | 79 | ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE; | 
|  | 80 | } | 
|  | 81 |  | 
|  | 82 | int mbedtls_block_cipher_setup(mbedtls_block_cipher_context_t *ctx, | 
|  | 83 | mbedtls_cipher_id_t cipher_id) | 
|  | 84 | { | 
| Valerio Setti | 4ff405c | 2023-12-15 16:10:52 +0100 | [diff] [blame] | 85 | ctx->id = (cipher_id == MBEDTLS_CIPHER_ID_AES) ? MBEDTLS_BLOCK_CIPHER_ID_AES : | 
|  | 86 | (cipher_id == MBEDTLS_CIPHER_ID_ARIA) ? MBEDTLS_BLOCK_CIPHER_ID_ARIA : | 
|  | 87 | (cipher_id == MBEDTLS_CIPHER_ID_CAMELLIA) ? MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA : | 
|  | 88 | MBEDTLS_BLOCK_CIPHER_ID_NONE; | 
|  | 89 |  | 
| Valerio Setti | c1db99d | 2023-12-12 11:19:17 +0100 | [diff] [blame] | 90 | #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) | 
| Valerio Setti | 1fff4f2 | 2023-12-28 14:19:34 +0100 | [diff] [blame] | 91 | psa_key_type_t psa_key_type = psa_key_type_from_block_cipher_id(ctx->id); | 
|  | 92 | if (psa_key_type != PSA_KEY_TYPE_NONE && | 
|  | 93 | psa_can_do_cipher(psa_key_type, PSA_ALG_ECB_NO_PADDING)) { | 
| Valerio Setti | 4ff405c | 2023-12-15 16:10:52 +0100 | [diff] [blame] | 94 | ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_PSA; | 
|  | 95 | return 0; | 
| Valerio Setti | c1db99d | 2023-12-12 11:19:17 +0100 | [diff] [blame] | 96 | } | 
|  | 97 | ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_LEGACY; | 
|  | 98 | #endif | 
|  | 99 |  | 
| Valerio Setti | 4ff405c | 2023-12-15 16:10:52 +0100 | [diff] [blame] | 100 | switch (ctx->id) { | 
| Manuel Pégourié-Gonnard | 2171876 | 2023-11-10 11:21:17 +0100 | [diff] [blame] | 101 | #if defined(MBEDTLS_AES_C) | 
| Valerio Setti | 4ff405c | 2023-12-15 16:10:52 +0100 | [diff] [blame] | 102 | case MBEDTLS_BLOCK_CIPHER_ID_AES: | 
| Manuel Pégourié-Gonnard | 2171876 | 2023-11-10 11:21:17 +0100 | [diff] [blame] | 103 | mbedtls_aes_init(&ctx->ctx.aes); | 
|  | 104 | return 0; | 
|  | 105 | #endif | 
|  | 106 | #if defined(MBEDTLS_ARIA_C) | 
| Valerio Setti | 4ff405c | 2023-12-15 16:10:52 +0100 | [diff] [blame] | 107 | case MBEDTLS_BLOCK_CIPHER_ID_ARIA: | 
| Manuel Pégourié-Gonnard | 2171876 | 2023-11-10 11:21:17 +0100 | [diff] [blame] | 108 | mbedtls_aria_init(&ctx->ctx.aria); | 
|  | 109 | return 0; | 
|  | 110 | #endif | 
|  | 111 | #if defined(MBEDTLS_CAMELLIA_C) | 
| Valerio Setti | 4ff405c | 2023-12-15 16:10:52 +0100 | [diff] [blame] | 112 | case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: | 
| Manuel Pégourié-Gonnard | 2171876 | 2023-11-10 11:21:17 +0100 | [diff] [blame] | 113 | mbedtls_camellia_init(&ctx->ctx.camellia); | 
|  | 114 | return 0; | 
|  | 115 | #endif | 
|  | 116 | default: | 
| Valerio Setti | 4ff405c | 2023-12-15 16:10:52 +0100 | [diff] [blame] | 117 | ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE; | 
| Manuel Pégourié-Gonnard | 2171876 | 2023-11-10 11:21:17 +0100 | [diff] [blame] | 118 | return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; | 
|  | 119 | } | 
|  | 120 | } | 
|  | 121 |  | 
| Manuel Pégourié-Gonnard | 3e0884f | 2023-11-10 11:52:10 +0100 | [diff] [blame] | 122 | int mbedtls_block_cipher_setkey(mbedtls_block_cipher_context_t *ctx, | 
|  | 123 | const unsigned char *key, | 
|  | 124 | unsigned key_bitlen) | 
|  | 125 | { | 
| Valerio Setti | c1db99d | 2023-12-12 11:19:17 +0100 | [diff] [blame] | 126 | #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) | 
|  | 127 | if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) { | 
|  | 128 | psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; | 
|  | 129 | psa_status_t status; | 
|  | 130 |  | 
| Valerio Setti | 4ff405c | 2023-12-15 16:10:52 +0100 | [diff] [blame] | 131 | psa_set_key_type(&key_attr, psa_key_type_from_block_cipher_id(ctx->id)); | 
| Valerio Setti | c1db99d | 2023-12-12 11:19:17 +0100 | [diff] [blame] | 132 | psa_set_key_bits(&key_attr, key_bitlen); | 
|  | 133 | psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING); | 
|  | 134 | psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT); | 
|  | 135 |  | 
| Valerio Setti | 785ec17 | 2023-12-13 16:49:05 +0100 | [diff] [blame] | 136 | status = psa_import_key(&key_attr, key, PSA_BITS_TO_BYTES(key_bitlen), &ctx->psa_key_id); | 
| Valerio Setti | c1db99d | 2023-12-12 11:19:17 +0100 | [diff] [blame] | 137 | if (status != PSA_SUCCESS) { | 
|  | 138 | return mbedtls_cipher_error_from_psa(status); | 
|  | 139 | } | 
|  | 140 | psa_reset_key_attributes(&key_attr); | 
|  | 141 |  | 
| Valerio Setti | c1db99d | 2023-12-12 11:19:17 +0100 | [diff] [blame] | 142 | return 0; | 
|  | 143 | } | 
|  | 144 | #endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */ | 
|  | 145 |  | 
| Manuel Pégourié-Gonnard | 3e0884f | 2023-11-10 11:52:10 +0100 | [diff] [blame] | 146 | switch (ctx->id) { | 
|  | 147 | #if defined(MBEDTLS_AES_C) | 
|  | 148 | case MBEDTLS_BLOCK_CIPHER_ID_AES: | 
|  | 149 | return mbedtls_aes_setkey_enc(&ctx->ctx.aes, key, key_bitlen); | 
|  | 150 | #endif | 
|  | 151 | #if defined(MBEDTLS_ARIA_C) | 
|  | 152 | case MBEDTLS_BLOCK_CIPHER_ID_ARIA: | 
|  | 153 | return mbedtls_aria_setkey_enc(&ctx->ctx.aria, key, key_bitlen); | 
|  | 154 | #endif | 
|  | 155 | #if defined(MBEDTLS_CAMELLIA_C) | 
|  | 156 | case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: | 
|  | 157 | return mbedtls_camellia_setkey_enc(&ctx->ctx.camellia, key, key_bitlen); | 
|  | 158 | #endif | 
|  | 159 | default: | 
|  | 160 | return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; | 
|  | 161 | } | 
|  | 162 | } | 
| Manuel Pégourié-Gonnard | 76fa16c | 2023-11-10 12:02:53 +0100 | [diff] [blame] | 163 |  | 
|  | 164 | int mbedtls_block_cipher_encrypt(mbedtls_block_cipher_context_t *ctx, | 
|  | 165 | const unsigned char input[16], | 
|  | 166 | unsigned char output[16]) | 
|  | 167 | { | 
| Valerio Setti | c1db99d | 2023-12-12 11:19:17 +0100 | [diff] [blame] | 168 | #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) | 
|  | 169 | if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) { | 
|  | 170 | psa_status_t status; | 
|  | 171 | size_t olen; | 
|  | 172 |  | 
|  | 173 | status = psa_cipher_encrypt(ctx->psa_key_id, PSA_ALG_ECB_NO_PADDING, | 
|  | 174 | input, 16, output, 16, &olen); | 
|  | 175 | if (status != PSA_SUCCESS) { | 
|  | 176 | return mbedtls_cipher_error_from_psa(status); | 
|  | 177 | } | 
|  | 178 | return 0; | 
|  | 179 | } | 
|  | 180 | #endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */ | 
|  | 181 |  | 
| Manuel Pégourié-Gonnard | 76fa16c | 2023-11-10 12:02:53 +0100 | [diff] [blame] | 182 | switch (ctx->id) { | 
|  | 183 | #if defined(MBEDTLS_AES_C) | 
|  | 184 | case MBEDTLS_BLOCK_CIPHER_ID_AES: | 
|  | 185 | return mbedtls_aes_crypt_ecb(&ctx->ctx.aes, MBEDTLS_AES_ENCRYPT, | 
|  | 186 | input, output); | 
|  | 187 | #endif | 
|  | 188 | #if defined(MBEDTLS_ARIA_C) | 
|  | 189 | case MBEDTLS_BLOCK_CIPHER_ID_ARIA: | 
|  | 190 | return mbedtls_aria_crypt_ecb(&ctx->ctx.aria, input, output); | 
|  | 191 | #endif | 
|  | 192 | #if defined(MBEDTLS_CAMELLIA_C) | 
|  | 193 | case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: | 
|  | 194 | return mbedtls_camellia_crypt_ecb(&ctx->ctx.camellia, | 
|  | 195 | MBEDTLS_CAMELLIA_ENCRYPT, | 
|  | 196 | input, output); | 
|  | 197 | #endif | 
|  | 198 | default: | 
|  | 199 | return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; | 
|  | 200 | } | 
|  | 201 | } | 
|  | 202 |  | 
| Manuel Pégourié-Gonnard | 2171876 | 2023-11-10 11:21:17 +0100 | [diff] [blame] | 203 | #endif /* MBEDTLS_BLOCK_CIPHER_C */ |