Start adding internal module block_cipher.c

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
diff --git a/include/mbedtls/block_cipher.h b/include/mbedtls/block_cipher.h
new file mode 100644
index 0000000..154ae26
--- /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 eeda06a..5c297e0 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -22,6 +22,7 @@
     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 9e2d723..d11a98d 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -91,6 +91,7 @@
 	     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 0000000..08364d7
--- /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 0000000..4f25e26
--- /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 086677a..b1d6c19 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1498,7 +1498,7 @@
     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 0000000..f0529a9
--- /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 0000000..7133653
--- /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 */