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