diff --git a/include/mbedtls/block_cipher.h b/include/mbedtls/block_cipher.h new file mode 100644 index 0000000000..154ae26e2d --- /dev/null +++ b/include/mbedtls/block_cipher.h @@ -0,0 +1,58 @@ +/** + * \file block_cipher.h + * + * \brief Internal abstraction layer. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_BLOCK_CIPHER_H +#define MBEDTLS_BLOCK_CIPHER_H + +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" + +#if defined(MBEDTLS_AES_C) +#include "mbedtls/aes.h" +#endif +#if defined(MBEDTLS_ARIA_C) +#include "mbedtls/aria.h" +#endif +#if defined(MBEDTLS_CAMELLIA_C) +#include "mbedtls/camellia.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + MBEDTLS_BLOCK_CIPHER_ID_NONE = 0, /**< Unset. */ + MBEDTLS_BLOCK_CIPHER_ID_AES, /**< The AES cipher. */ + MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */ + MBEDTLS_BLOCK_CIPHER_ID_ARIA, /**< The Aria cipher. */ +} mbedtls_block_cipher_id_t; + +typedef struct { + mbedtls_block_cipher_id_t MBEDTLS_PRIVATE(id); + union { + unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ +#if defined(MBEDTLS_AES_C) + mbedtls_aes_context MBEDTLS_PRIVATE(aes); +#endif +#if defined(MBEDTLS_ARIA_C) + mbedtls_aria_context MBEDTLS_PRIVATE(aria); +#endif +#if defined(MBEDTLS_CAMELLIA_C) + mbedtls_camellia_context MBEDTLS_PRIVATE(camellia); +#endif + } MBEDTLS_PRIVATE(ctx); +} mbedtls_block_cipher_context_t; + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_BLOCK_CIPHER_H */ diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index eeda06aeeb..5c297e0a1f 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -22,6 +22,7 @@ set(src_crypto bignum_core.c bignum_mod.c bignum_mod_raw.c + block_cipher.c camellia.c ccm.c chacha20.c diff --git a/library/Makefile b/library/Makefile index 9e2d723107..d11a98df01 100644 --- a/library/Makefile +++ b/library/Makefile @@ -91,6 +91,7 @@ OBJS_CRYPTO= \ bignum_core.o \ bignum_mod.o \ bignum_mod_raw.o \ + block_cipher.o \ camellia.o \ ccm.o \ chacha20.o \ diff --git a/library/block_cipher.c b/library/block_cipher.c new file mode 100644 index 0000000000..08364d745c --- /dev/null +++ b/library/block_cipher.c @@ -0,0 +1,69 @@ +/** + * \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" + +#include "block_cipher_internal.h" + +#if defined(MBEDTLS_BLOCK_CIPHER_C) + +void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx) +{ + 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) +{ + switch (cipher_id) { +#if defined(MBEDTLS_AES_C) + case MBEDTLS_CIPHER_ID_AES: + ctx->id = MBEDTLS_BLOCK_CIPHER_ID_AES; + mbedtls_aes_init(&ctx->ctx.aes); + return 0; +#endif +#if defined(MBEDTLS_ARIA_C) + case MBEDTLS_CIPHER_ID_ARIA: + ctx->id = MBEDTLS_BLOCK_CIPHER_ID_ARIA; + mbedtls_aria_init(&ctx->ctx.aria); + return 0; +#endif +#if defined(MBEDTLS_CAMELLIA_C) + case MBEDTLS_CIPHER_ID_CAMELLIA: + ctx->id = MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA; + mbedtls_camellia_init(&ctx->ctx.camellia); + return 0; +#endif + default: + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } +} + +#endif /* MBEDTLS_BLOCK_CIPHER_C */ diff --git a/library/block_cipher_internal.h b/library/block_cipher_internal.h new file mode 100644 index 0000000000..4f25e26ca8 --- /dev/null +++ b/library/block_cipher_internal.h @@ -0,0 +1,63 @@ +/** + * \file block_cipher_internal.h + * + * \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 + */ +#ifndef MBEDTLS_BLOCK_CIPHER_INTERNAL_H +#define MBEDTLS_BLOCK_CIPHER_INTERNAL_H + +#include "mbedtls/build_info.h" + +#include "mbedtls/cipher.h" + +#include "mbedtls/block_cipher.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Initialize the context. + * This must be the first API call before using the context. + * + * \param ctx The context to initialize. + */ +static inline void mbedtls_block_cipher_init(mbedtls_block_cipher_context_t *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); +} + +/** + * \brief Set the block cipher to use with this context. + * This must be called after mbedtls_block_cipher_init(). + * + * \param ctx The context to set up. + * \param cipher_id The identifier of the cipher to use. + * This must be either AES, ARIA or Camellia. + * Warning: this is a ::mbedtls_cipher_id_t, + * not a ::mbedtls_block_cipher_id_t! + * + * \retval \c 0 on success. + * \retval #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if \p cipher_id was + * invalid. + */ +int mbedtls_block_cipher_setup(mbedtls_block_cipher_context_t *ctx, + mbedtls_cipher_id_t cipher_id); + +/** + * \brief Clear the context. + * + * \param ctx The context to clear. + */ +void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_BLOCK_CIPHER_INTERNAL_H */ diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 086677a600..b1d6c19c18 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -1498,7 +1498,7 @@ component_test_full_no_cipher () { scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO scripts/config.py unset MBEDTLS_LMS_C scripts/config.py unset MBEDTLS_LMS_PRIVATE - make + make CFLAGS='-DMBEDTLS_BLOCK_CIPHER_C' msg "test: full no CIPHER no PSA_CRYPTO_C" make test diff --git a/tests/suites/test_suite_block_cipher.data b/tests/suites/test_suite_block_cipher.data new file mode 100644 index 0000000000..f0529a92e3 --- /dev/null +++ b/tests/suites/test_suite_block_cipher.data @@ -0,0 +1,2 @@ +Invalid input +invalid: diff --git a/tests/suites/test_suite_block_cipher.function b/tests/suites/test_suite_block_cipher.function new file mode 100644 index 0000000000..7133653e50 --- /dev/null +++ b/tests/suites/test_suite_block_cipher.function @@ -0,0 +1,28 @@ +/* BEGIN_HEADER */ +#include "block_cipher_internal.h" + +#define BLOCK_SIZE 16 +/* END_HEADER */ + +/* BEGIN_DEPENDENCIES + * depends_on:MBEDTLS_BLOCK_CIPHER_C + * END_DEPENDENCIES + */ + +/* BEGIN_CASE */ +void invalid() +{ + mbedtls_block_cipher_context_t ctx; + + mbedtls_block_cipher_init(&ctx); + + TEST_EQUAL(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, + mbedtls_block_cipher_setup(&ctx, MBEDTLS_CIPHER_ID_NONE)); + + TEST_EQUAL(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, + mbedtls_block_cipher_setup(&ctx, MBEDTLS_CIPHER_ID_DES)); + +exit: + mbedtls_block_cipher_free(&ctx); +} +/* END_CASE */