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 14 #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) 15 #include "psa/crypto.h" 16 #include "psa_crypto_core.h" 17 #include "psa_util_internal.h" 18 #endif 19 20 #include "block_cipher_internal.h" 21 22 #if defined(MBEDTLS_BLOCK_CIPHER_C) 23 24 #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) 25 static psa_key_type_t psa_key_type_from_block_cipher_id(mbedtls_block_cipher_id_t cipher_id) 26 { 27 switch (cipher_id) { 28 #if defined(MBEDTLS_BLOCK_CIPHER_AES_VIA_PSA) 29 case MBEDTLS_BLOCK_CIPHER_ID_AES: 30 return PSA_KEY_TYPE_AES; 31 #endif 32 #if defined(MBEDTLS_BLOCK_CIPHER_ARIA_VIA_PSA) 33 case MBEDTLS_BLOCK_CIPHER_ID_ARIA: 34 return PSA_KEY_TYPE_ARIA; 35 #endif 36 #if defined(MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_PSA) 37 case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: 38 return PSA_KEY_TYPE_CAMELLIA; 39 #endif 40 default: 41 return PSA_KEY_TYPE_NONE; 42 } 43 } 44 45 static int mbedtls_cipher_error_from_psa(psa_status_t status) 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 52 void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx) 53 { 54 if (ctx == NULL) { 55 return; 56 } 57 58 #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) 59 if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) { 60 psa_destroy_key(ctx->psa_key_id); 61 return; 62 } 63 #endif 64 switch (ctx->id) { 65 #if defined(MBEDTLS_AES_C) 66 case MBEDTLS_BLOCK_CIPHER_ID_AES: 67 mbedtls_aes_free(&ctx->ctx.aes); 68 break; 69 #endif 70 #if defined(MBEDTLS_ARIA_C) 71 case MBEDTLS_BLOCK_CIPHER_ID_ARIA: 72 mbedtls_aria_free(&ctx->ctx.aria); 73 break; 74 #endif 75 #if defined(MBEDTLS_CAMELLIA_C) 76 case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: 77 mbedtls_camellia_free(&ctx->ctx.camellia); 78 break; 79 #endif 80 default: 81 break; 82 } 83 ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE; 84 } 85 86 int mbedtls_block_cipher_setup(mbedtls_block_cipher_context_t *ctx, 87 mbedtls_cipher_id_t cipher_id) 88 { 89 ctx->id = (cipher_id == MBEDTLS_CIPHER_ID_AES) ? MBEDTLS_BLOCK_CIPHER_ID_AES : 90 (cipher_id == MBEDTLS_CIPHER_ID_ARIA) ? MBEDTLS_BLOCK_CIPHER_ID_ARIA : 91 (cipher_id == MBEDTLS_CIPHER_ID_CAMELLIA) ? MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA : 92 MBEDTLS_BLOCK_CIPHER_ID_NONE; 93 94 #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) 95 psa_key_type_t psa_key_type = psa_key_type_from_block_cipher_id(ctx->id); 96 if (psa_key_type != PSA_KEY_TYPE_NONE && 97 psa_can_do_cipher(psa_key_type, PSA_ALG_ECB_NO_PADDING)) { 98 ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_PSA; 99 return 0; 100 } 101 ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_LEGACY; 102 #endif 103 104 switch (ctx->id) { 105 #if defined(MBEDTLS_AES_C) 106 case MBEDTLS_BLOCK_CIPHER_ID_AES: 107 mbedtls_aes_init(&ctx->ctx.aes); 108 return 0; 109 #endif 110 #if defined(MBEDTLS_ARIA_C) 111 case MBEDTLS_BLOCK_CIPHER_ID_ARIA: 112 mbedtls_aria_init(&ctx->ctx.aria); 113 return 0; 114 #endif 115 #if defined(MBEDTLS_CAMELLIA_C) 116 case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: 117 mbedtls_camellia_init(&ctx->ctx.camellia); 118 return 0; 119 #endif 120 default: 121 ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE; 122 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; 123 } 124 } 125 126 int mbedtls_block_cipher_setkey(mbedtls_block_cipher_context_t *ctx, 127 const unsigned char *key, 128 unsigned key_bitlen) 129 { 130 #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) 131 if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) { 132 psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; 133 psa_status_t status; 134 135 psa_set_key_type(&key_attr, psa_key_type_from_block_cipher_id(ctx->id)); 136 psa_set_key_bits(&key_attr, key_bitlen); 137 psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING); 138 psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT); 139 140 status = psa_import_key(&key_attr, key, PSA_BITS_TO_BYTES(key_bitlen), &ctx->psa_key_id); 141 if (status != PSA_SUCCESS) { 142 return mbedtls_cipher_error_from_psa(status); 143 } 144 psa_reset_key_attributes(&key_attr); 145 146 return 0; 147 } 148 #endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */ 149 150 switch (ctx->id) { 151 #if defined(MBEDTLS_AES_C) 152 case MBEDTLS_BLOCK_CIPHER_ID_AES: 153 return mbedtls_aes_setkey_enc(&ctx->ctx.aes, key, key_bitlen); 154 #endif 155 #if defined(MBEDTLS_ARIA_C) 156 case MBEDTLS_BLOCK_CIPHER_ID_ARIA: 157 return mbedtls_aria_setkey_enc(&ctx->ctx.aria, key, key_bitlen); 158 #endif 159 #if defined(MBEDTLS_CAMELLIA_C) 160 case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: 161 return mbedtls_camellia_setkey_enc(&ctx->ctx.camellia, key, key_bitlen); 162 #endif 163 default: 164 return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; 165 } 166 } 167 168 int mbedtls_block_cipher_encrypt(mbedtls_block_cipher_context_t *ctx, 169 const unsigned char input[16], 170 unsigned char output[16]) 171 { 172 #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) 173 if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) { 174 psa_status_t status; 175 size_t olen; 176 177 status = psa_cipher_encrypt(ctx->psa_key_id, PSA_ALG_ECB_NO_PADDING, 178 input, 16, output, 16, &olen); 179 if (status != PSA_SUCCESS) { 180 return mbedtls_cipher_error_from_psa(status); 181 } 182 return 0; 183 } 184 #endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */ 185 186 switch (ctx->id) { 187 #if defined(MBEDTLS_AES_C) 188 case MBEDTLS_BLOCK_CIPHER_ID_AES: 189 return mbedtls_aes_crypt_ecb(&ctx->ctx.aes, MBEDTLS_AES_ENCRYPT, 190 input, output); 191 #endif 192 #if defined(MBEDTLS_ARIA_C) 193 case MBEDTLS_BLOCK_CIPHER_ID_ARIA: 194 return mbedtls_aria_crypt_ecb(&ctx->ctx.aria, input, output); 195 #endif 196 #if defined(MBEDTLS_CAMELLIA_C) 197 case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: 198 return mbedtls_camellia_crypt_ecb(&ctx->ctx.camellia, 199 MBEDTLS_CAMELLIA_ENCRYPT, 200 input, output); 201 #endif 202 default: 203 return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; 204 } 205 } 206 207 #endif /* MBEDTLS_BLOCK_CIPHER_C */ 208