/**
 * \file block_cipher.c
 *
 * \brief Lightweight abstraction layer for block ciphers with 128 bit blocks,
 * for use by the GCM and CCM modules.
 */
/*
 *  Copyright The Mbed TLS Contributors
 *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
 */

#include "common.h"

#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
#include "psa/crypto.h"
#include "psa_crypto_core.h"
#include "psa_util_internal.h"
#endif

#include "block_cipher_internal.h"

#if defined(MBEDTLS_BLOCK_CIPHER_C)

#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
static psa_key_type_t psa_key_type_from_block_cipher_id(mbedtls_block_cipher_id_t cipher_id)
{
    switch (cipher_id) {
#if defined(MBEDTLS_BLOCK_CIPHER_AES_VIA_PSA)
        case MBEDTLS_BLOCK_CIPHER_ID_AES:
            return PSA_KEY_TYPE_AES;
#endif
#if defined(MBEDTLS_BLOCK_CIPHER_ARIA_VIA_PSA)
        case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
            return PSA_KEY_TYPE_ARIA;
#endif
#if defined(MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_PSA)
        case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
            return PSA_KEY_TYPE_CAMELLIA;
#endif
        default:
            return PSA_KEY_TYPE_NONE;
    }
}

static int mbedtls_cipher_error_from_psa(psa_status_t status)
{
    return PSA_TO_MBEDTLS_ERR_LIST(status, psa_to_cipher_errors,
                                   psa_generic_status_to_mbedtls);
}
#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */

void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx)
{
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
    if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) {
        psa_destroy_key(ctx->psa_key_id);
        return;
    }
#endif
    switch (ctx->id) {
#if defined(MBEDTLS_AES_C)
        case MBEDTLS_BLOCK_CIPHER_ID_AES:
            mbedtls_aes_free(&ctx->ctx.aes);
            break;
#endif
#if defined(MBEDTLS_ARIA_C)
        case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
            mbedtls_aria_free(&ctx->ctx.aria);
            break;
#endif
#if defined(MBEDTLS_CAMELLIA_C)
        case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
            mbedtls_camellia_free(&ctx->ctx.camellia);
            break;
#endif
        default:
            break;
    }
    ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE;
}

int mbedtls_block_cipher_setup(mbedtls_block_cipher_context_t *ctx,
                               mbedtls_cipher_id_t cipher_id)
{
    ctx->id = (cipher_id == MBEDTLS_CIPHER_ID_AES) ? MBEDTLS_BLOCK_CIPHER_ID_AES :
              (cipher_id == MBEDTLS_CIPHER_ID_ARIA) ? MBEDTLS_BLOCK_CIPHER_ID_ARIA :
              (cipher_id == MBEDTLS_CIPHER_ID_CAMELLIA) ? MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA :
              MBEDTLS_BLOCK_CIPHER_ID_NONE;

#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
    psa_key_type_t psa_key_type = psa_key_type_from_block_cipher_id(ctx->id);
    if (psa_key_type != PSA_KEY_TYPE_NONE &&
        psa_can_do_cipher(psa_key_type, PSA_ALG_ECB_NO_PADDING)) {
        ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_PSA;
        return 0;
    }
    ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_LEGACY;
#endif

    switch (ctx->id) {
#if defined(MBEDTLS_AES_C)
        case MBEDTLS_BLOCK_CIPHER_ID_AES:
            mbedtls_aes_init(&ctx->ctx.aes);
            return 0;
#endif
#if defined(MBEDTLS_ARIA_C)
        case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
            mbedtls_aria_init(&ctx->ctx.aria);
            return 0;
#endif
#if defined(MBEDTLS_CAMELLIA_C)
        case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
            mbedtls_camellia_init(&ctx->ctx.camellia);
            return 0;
#endif
        default:
            ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE;
            return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    }
}

int mbedtls_block_cipher_setkey(mbedtls_block_cipher_context_t *ctx,
                                const unsigned char *key,
                                unsigned key_bitlen)
{
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
    if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) {
        psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
        psa_status_t status;

        psa_set_key_type(&key_attr, psa_key_type_from_block_cipher_id(ctx->id));
        psa_set_key_bits(&key_attr, key_bitlen);
        psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING);
        psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT);

        status = psa_import_key(&key_attr, key, PSA_BITS_TO_BYTES(key_bitlen), &ctx->psa_key_id);
        if (status != PSA_SUCCESS) {
            return mbedtls_cipher_error_from_psa(status);
        }
        psa_reset_key_attributes(&key_attr);

        return 0;
    }
#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */

    switch (ctx->id) {
#if defined(MBEDTLS_AES_C)
        case MBEDTLS_BLOCK_CIPHER_ID_AES:
            return mbedtls_aes_setkey_enc(&ctx->ctx.aes, key, key_bitlen);
#endif
#if defined(MBEDTLS_ARIA_C)
        case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
            return mbedtls_aria_setkey_enc(&ctx->ctx.aria, key, key_bitlen);
#endif
#if defined(MBEDTLS_CAMELLIA_C)
        case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
            return mbedtls_camellia_setkey_enc(&ctx->ctx.camellia, key, key_bitlen);
#endif
        default:
            return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
    }
}

int mbedtls_block_cipher_encrypt(mbedtls_block_cipher_context_t *ctx,
                                 const unsigned char input[16],
                                 unsigned char output[16])
{
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
    if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) {
        psa_status_t status;
        size_t olen;

        status = psa_cipher_encrypt(ctx->psa_key_id, PSA_ALG_ECB_NO_PADDING,
                                    input, 16, output, 16, &olen);
        if (status != PSA_SUCCESS) {
            return mbedtls_cipher_error_from_psa(status);
        }
        return 0;
    }
#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */

    switch (ctx->id) {
#if defined(MBEDTLS_AES_C)
        case MBEDTLS_BLOCK_CIPHER_ID_AES:
            return mbedtls_aes_crypt_ecb(&ctx->ctx.aes, MBEDTLS_AES_ENCRYPT,
                                         input, output);
#endif
#if defined(MBEDTLS_ARIA_C)
        case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
            return mbedtls_aria_crypt_ecb(&ctx->ctx.aria, input, output);
#endif
#if defined(MBEDTLS_CAMELLIA_C)
        case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
            return mbedtls_camellia_crypt_ecb(&ctx->ctx.camellia,
                                              MBEDTLS_CAMELLIA_ENCRYPT,
                                              input, output);
#endif
        default:
            return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
    }
}

#endif /* MBEDTLS_BLOCK_CIPHER_C */
