/**
 * \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 (ctx == NULL) {
        return;
    }

#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 */
