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) 25static 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 45static 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 52void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx) 53{ 54#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) 55 if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) { 56 psa_destroy_key(ctx->psa_key_id); 57 return; 58 } 59#endif 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 82int mbedtls_block_cipher_setup(mbedtls_block_cipher_context_t *ctx, 83 mbedtls_cipher_id_t cipher_id) 84{ 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 90#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) 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)) { 94 ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_PSA; 95 return 0; 96 } 97 ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_LEGACY; 98#endif 99 100 switch (ctx->id) { 101#if defined(MBEDTLS_AES_C) 102 case MBEDTLS_BLOCK_CIPHER_ID_AES: 103 mbedtls_aes_init(&ctx->ctx.aes); 104 return 0; 105#endif 106#if defined(MBEDTLS_ARIA_C) 107 case MBEDTLS_BLOCK_CIPHER_ID_ARIA: 108 mbedtls_aria_init(&ctx->ctx.aria); 109 return 0; 110#endif 111#if defined(MBEDTLS_CAMELLIA_C) 112 case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: 113 mbedtls_camellia_init(&ctx->ctx.camellia); 114 return 0; 115#endif 116 default: 117 ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE; 118 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; 119 } 120} 121 122int mbedtls_block_cipher_setkey(mbedtls_block_cipher_context_t *ctx, 123 const unsigned char *key, 124 unsigned key_bitlen) 125{ 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 131 psa_set_key_type(&key_attr, psa_key_type_from_block_cipher_id(ctx->id)); 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 136 status = psa_import_key(&key_attr, key, PSA_BITS_TO_BYTES(key_bitlen), &ctx->psa_key_id); 137 if (status != PSA_SUCCESS) { 138 return mbedtls_cipher_error_from_psa(status); 139 } 140 psa_reset_key_attributes(&key_attr); 141 142 return 0; 143 } 144#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */ 145 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} 163 164int mbedtls_block_cipher_encrypt(mbedtls_block_cipher_context_t *ctx, 165 const unsigned char input[16], 166 unsigned char output[16]) 167{ 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 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 203#endif /* MBEDTLS_BLOCK_CIPHER_C */ 204