From fbf918785fe413a13fd631e775cc19ec06317bc8 Mon Sep 17 00:00:00 2001 From: Sebastian Renner Date: Tue, 16 Jul 2019 12:45:13 +0200 Subject: [PATCH] NIST enc/dec wrapper functions for AES GCM --- mbed_aes_gcm/.gitignore | 3 +++ mbed_aes_gcm/Makefile | 18 ++++++++++++++++++ mbed_aes_gcm/aes.c | 2209 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/aes.h | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/api.h | 5 +++++ mbed_aes_gcm/cipher.c | 1540 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/cipher.h | 926 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/cipher_internal.h | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/cipher_wrap.c | 2411 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/config.h | 5 +++++ mbed_aes_gcm/crypto_aead.h | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/example_decryption.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/example_encryption.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/gcm | Bin 0 -> 45824 bytes mbed_aes_gcm/gcm.c | 1067 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/gcm.h | 326 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/main. | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/main.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/platform.c | 391 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/platform.h | 419 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/platform_time.h | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/platform_util.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/platform_util.h | 196 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/threading.c | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/threading.h | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/utils.c | 36 ++++++++++++++++++++++++++++++++++++ mbed_aes_gcm/utils.h | 7 +++++++ templates/blackpill/Src/Makefile | 18 ------------------ templates/blackpill/Src/aes.c | 2209 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- templates/blackpill/Src/aes.h | 674 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- templates/blackpill/Src/cipher.c | 1540 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- templates/blackpill/Src/cipher.h | 926 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- templates/blackpill/Src/cipher_internal.h | 153 --------------------------------------------------------------------------------------------------------------------------------------------------------- templates/blackpill/Src/cipher_wrap.c | 2411 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- templates/blackpill/Src/gcm.c | 1020 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ templates/blackpill/Src/gcm.h | 326 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- templates/blackpill/Src/mygcmmain.c | 54 ------------------------------------------------------ templates/blackpill/Src/platform.c | 391 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- templates/blackpill/Src/platform.h | 419 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- templates/blackpill/Src/platform_time.h | 82 ---------------------------------------------------------------------------------- templates/blackpill/Src/platform_util.c | 136 ---------------------------------------------------------------------------------------------------------------------------------------- templates/blackpill/Src/platform_util.h | 196 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- templates/blackpill/Src/threading.c | 187 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- templates/blackpill/Src/threading.h | 122 -------------------------------------------------------------------------------------------------------------------------- templates/blackpill/Src/utils.c | 36 ------------------------------------ templates/blackpill/Src/utils.h | 7 ------- 46 files changed, 11192 insertions(+), 10907 deletions(-) create mode 100644 mbed_aes_gcm/.gitignore create mode 100644 mbed_aes_gcm/Makefile create mode 100644 mbed_aes_gcm/aes.c create mode 100644 mbed_aes_gcm/aes.h create mode 100644 mbed_aes_gcm/api.h create mode 100644 mbed_aes_gcm/cipher.c create mode 100644 mbed_aes_gcm/cipher.h create mode 100644 mbed_aes_gcm/cipher_internal.h create mode 100644 mbed_aes_gcm/cipher_wrap.c create mode 100644 mbed_aes_gcm/config.h create mode 100644 mbed_aes_gcm/crypto_aead.h create mode 100644 mbed_aes_gcm/example_decryption.c create mode 100644 mbed_aes_gcm/example_encryption.c create mode 100755 mbed_aes_gcm/gcm create mode 100644 mbed_aes_gcm/gcm.c create mode 100644 mbed_aes_gcm/gcm.h create mode 100644 mbed_aes_gcm/main. create mode 100644 mbed_aes_gcm/main.c create mode 100644 mbed_aes_gcm/platform.c create mode 100644 mbed_aes_gcm/platform.h create mode 100644 mbed_aes_gcm/platform_time.h create mode 100644 mbed_aes_gcm/platform_util.c create mode 100644 mbed_aes_gcm/platform_util.h create mode 100644 mbed_aes_gcm/threading.c create mode 100644 mbed_aes_gcm/threading.h create mode 100644 mbed_aes_gcm/utils.c create mode 100644 mbed_aes_gcm/utils.h delete mode 100644 templates/blackpill/Src/Makefile delete mode 100644 templates/blackpill/Src/aes.c delete mode 100644 templates/blackpill/Src/aes.h delete mode 100644 templates/blackpill/Src/cipher.c delete mode 100644 templates/blackpill/Src/cipher.h delete mode 100644 templates/blackpill/Src/cipher_internal.h delete mode 100644 templates/blackpill/Src/cipher_wrap.c delete mode 100644 templates/blackpill/Src/gcm.c delete mode 100644 templates/blackpill/Src/gcm.h delete mode 100644 templates/blackpill/Src/mygcmmain.c delete mode 100644 templates/blackpill/Src/platform.c delete mode 100644 templates/blackpill/Src/platform.h delete mode 100644 templates/blackpill/Src/platform_time.h delete mode 100644 templates/blackpill/Src/platform_util.c delete mode 100644 templates/blackpill/Src/platform_util.h delete mode 100644 templates/blackpill/Src/threading.c delete mode 100644 templates/blackpill/Src/threading.h delete mode 100644 templates/blackpill/Src/utils.c delete mode 100644 templates/blackpill/Src/utils.h diff --git a/mbed_aes_gcm/.gitignore b/mbed_aes_gcm/.gitignore new file mode 100644 index 0000000..eb261ea --- /dev/null +++ b/mbed_aes_gcm/.gitignore @@ -0,0 +1,3 @@ +out.dSYM +out +*.o diff --git a/mbed_aes_gcm/Makefile b/mbed_aes_gcm/Makefile new file mode 100644 index 0000000..87853fe --- /dev/null +++ b/mbed_aes_gcm/Makefile @@ -0,0 +1,18 @@ +CC=gcc +CFLAGS=-c -Wall +LDFLAGS= +SOURCES=aes.c cipher.c cipher_wrap.c gcm.c main.c platform.c platform_util.c +OBJECTS=$(SOURCES:.c=.o) +EXECUTABLE=gcm + +all: $(SOURCES) $(EXECUTABLE) + +$(EXECUTABLE): $(OBJECTS) + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +.cpp.o: + $(CC) $(CFLAGS) $< -o $@ + +clean: + rm -rf *.o out + diff --git a/mbed_aes_gcm/aes.c b/mbed_aes_gcm/aes.c new file mode 100644 index 0000000..560624c --- /dev/null +++ b/mbed_aes_gcm/aes.c @@ -0,0 +1,2209 @@ +/* + * FIPS-197 compliant AES implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. + * + * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf + * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_AES_C) + +#include + +#include "aes.h" +#include "platform.h" +#include "platform_util.h" +#if defined(MBEDTLS_PADLOCK_C) +#include "mbedtls/padlock.h" +#endif +#if defined(MBEDTLS_AESNI_C) +#include "mbedtls/aesni.h" +#endif + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_AES_ALT) + +/* Parameter validation macros based on platform_util.h */ +#define AES_VALIDATE_RET( cond ) \ + MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA ) +#define AES_VALIDATE( cond ) \ + MBEDTLS_INTERNAL_VALIDATE( cond ) + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT32_LE +#define GET_UINT32_LE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] ) \ + | ( (uint32_t) (b)[(i) + 1] << 8 ) \ + | ( (uint32_t) (b)[(i) + 2] << 16 ) \ + | ( (uint32_t) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_UINT32_LE +#define PUT_UINT32_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ + (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ + (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ + (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ +} +#endif + +#if defined(MBEDTLS_PADLOCK_C) && \ + ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) ) +static int aes_padlock_ace = -1; +#endif + +#if defined(MBEDTLS_AES_ROM_TABLES) +/* + * Forward S-box + */ +static const unsigned char FSb[256] = +{ + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, + 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, + 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, + 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, + 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, + 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, + 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, + 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, + 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, + 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, + 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, + 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, + 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, + 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, + 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, + 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, + 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 +}; + +/* + * Forward tables + */ +#define FT \ +\ + V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \ + V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \ + V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \ + V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \ + V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \ + V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \ + V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \ + V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \ + V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \ + V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \ + V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \ + V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \ + V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \ + V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \ + V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \ + V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \ + V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \ + V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \ + V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \ + V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \ + V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \ + V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \ + V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \ + V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \ + V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \ + V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \ + V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \ + V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \ + V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \ + V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \ + V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \ + V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \ + V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \ + V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \ + V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \ + V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \ + V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \ + V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \ + V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \ + V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \ + V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \ + V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \ + V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \ + V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \ + V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \ + V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \ + V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \ + V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \ + V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \ + V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \ + V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \ + V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \ + V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \ + V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \ + V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \ + V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \ + V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \ + V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \ + V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \ + V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \ + V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \ + V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \ + V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \ + V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C) + +#define V(a,b,c,d) 0x##a##b##c##d +static const uint32_t FT0[256] = { FT }; +#undef V + +#if !defined(MBEDTLS_AES_FEWER_TABLES) + +#define V(a,b,c,d) 0x##b##c##d##a +static const uint32_t FT1[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##c##d##a##b +static const uint32_t FT2[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##d##a##b##c +static const uint32_t FT3[256] = { FT }; +#undef V + +#endif /* !MBEDTLS_AES_FEWER_TABLES */ + +#undef FT + +/* + * Reverse S-box + */ +static const unsigned char RSb[256] = +{ + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, + 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, + 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, + 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, + 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, + 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, + 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, + 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, + 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, + 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, + 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, + 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, + 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, + 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, + 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, + 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D +}; + +/* + * Reverse tables + */ +#define RT \ +\ + V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \ + V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \ + V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \ + V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \ + V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \ + V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \ + V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \ + V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \ + V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \ + V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \ + V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \ + V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \ + V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \ + V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \ + V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \ + V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \ + V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \ + V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \ + V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \ + V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \ + V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \ + V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \ + V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \ + V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \ + V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \ + V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \ + V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \ + V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \ + V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \ + V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \ + V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \ + V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \ + V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \ + V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \ + V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \ + V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \ + V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \ + V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \ + V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \ + V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \ + V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \ + V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \ + V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \ + V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \ + V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \ + V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \ + V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \ + V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \ + V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \ + V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \ + V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \ + V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \ + V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \ + V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \ + V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \ + V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \ + V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \ + V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \ + V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \ + V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \ + V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \ + V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \ + V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \ + V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0) + +#define V(a,b,c,d) 0x##a##b##c##d +static const uint32_t RT0[256] = { RT }; +#undef V + +#if !defined(MBEDTLS_AES_FEWER_TABLES) + +#define V(a,b,c,d) 0x##b##c##d##a +static const uint32_t RT1[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##c##d##a##b +static const uint32_t RT2[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##d##a##b##c +static const uint32_t RT3[256] = { RT }; +#undef V + +#endif /* !MBEDTLS_AES_FEWER_TABLES */ + +#undef RT + +/* + * Round constants + */ +static const uint32_t RCON[10] = +{ + 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080, + 0x0000001B, 0x00000036 +}; + +#else /* MBEDTLS_AES_ROM_TABLES */ + +/* + * Forward S-box & tables + */ +static unsigned char FSb[256]; +static uint32_t FT0[256]; +#if !defined(MBEDTLS_AES_FEWER_TABLES) +static uint32_t FT1[256]; +static uint32_t FT2[256]; +static uint32_t FT3[256]; +#endif /* !MBEDTLS_AES_FEWER_TABLES */ + +/* + * Reverse S-box & tables + */ +static unsigned char RSb[256]; +static uint32_t RT0[256]; +#if !defined(MBEDTLS_AES_FEWER_TABLES) +static uint32_t RT1[256]; +static uint32_t RT2[256]; +static uint32_t RT3[256]; +#endif /* !MBEDTLS_AES_FEWER_TABLES */ + +/* + * Round constants + */ +static uint32_t RCON[10]; + +/* + * Tables generation code + */ +#define ROTL8(x) ( ( (x) << 8 ) & 0xFFFFFFFF ) | ( (x) >> 24 ) +#define XTIME(x) ( ( (x) << 1 ) ^ ( ( (x) & 0x80 ) ? 0x1B : 0x00 ) ) +#define MUL(x,y) ( ( (x) && (y) ) ? pow[(log[(x)]+log[(y)]) % 255] : 0 ) + +static int aes_init_done = 0; + +static void aes_gen_tables( void ) +{ + int i, x, y, z; + int pow[256]; + int log[256]; + + /* + * compute pow and log tables over GF(2^8) + */ + for( i = 0, x = 1; i < 256; i++ ) + { + pow[i] = x; + log[x] = i; + x = ( x ^ XTIME( x ) ) & 0xFF; + } + + /* + * calculate the round constants + */ + for( i = 0, x = 1; i < 10; i++ ) + { + RCON[i] = (uint32_t) x; + x = XTIME( x ) & 0xFF; + } + + /* + * generate the forward and reverse S-boxes + */ + FSb[0x00] = 0x63; + RSb[0x63] = 0x00; + + for( i = 1; i < 256; i++ ) + { + x = pow[255 - log[i]]; + + y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y ^ 0x63; + + FSb[i] = (unsigned char) x; + RSb[x] = (unsigned char) i; + } + + /* + * generate the forward and reverse tables + */ + for( i = 0; i < 256; i++ ) + { + x = FSb[i]; + y = XTIME( x ) & 0xFF; + z = ( y ^ x ) & 0xFF; + + FT0[i] = ( (uint32_t) y ) ^ + ( (uint32_t) x << 8 ) ^ + ( (uint32_t) x << 16 ) ^ + ( (uint32_t) z << 24 ); + +#if !defined(MBEDTLS_AES_FEWER_TABLES) + FT1[i] = ROTL8( FT0[i] ); + FT2[i] = ROTL8( FT1[i] ); + FT3[i] = ROTL8( FT2[i] ); +#endif /* !MBEDTLS_AES_FEWER_TABLES */ + + x = RSb[i]; + + RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^ + ( (uint32_t) MUL( 0x09, x ) << 8 ) ^ + ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^ + ( (uint32_t) MUL( 0x0B, x ) << 24 ); + +#if !defined(MBEDTLS_AES_FEWER_TABLES) + RT1[i] = ROTL8( RT0[i] ); + RT2[i] = ROTL8( RT1[i] ); + RT3[i] = ROTL8( RT2[i] ); +#endif /* !MBEDTLS_AES_FEWER_TABLES */ + } +} + +#undef ROTL8 + +#endif /* MBEDTLS_AES_ROM_TABLES */ + +#if defined(MBEDTLS_AES_FEWER_TABLES) + +#define ROTL8(x) ( (uint32_t)( ( x ) << 8 ) + (uint32_t)( ( x ) >> 24 ) ) +#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) ) +#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >> 8 ) ) + +#define AES_RT0(idx) RT0[idx] +#define AES_RT1(idx) ROTL8( RT0[idx] ) +#define AES_RT2(idx) ROTL16( RT0[idx] ) +#define AES_RT3(idx) ROTL24( RT0[idx] ) + +#define AES_FT0(idx) FT0[idx] +#define AES_FT1(idx) ROTL8( FT0[idx] ) +#define AES_FT2(idx) ROTL16( FT0[idx] ) +#define AES_FT3(idx) ROTL24( FT0[idx] ) + +#else /* MBEDTLS_AES_FEWER_TABLES */ + +#define AES_RT0(idx) RT0[idx] +#define AES_RT1(idx) RT1[idx] +#define AES_RT2(idx) RT2[idx] +#define AES_RT3(idx) RT3[idx] + +#define AES_FT0(idx) FT0[idx] +#define AES_FT1(idx) FT1[idx] +#define AES_FT2(idx) FT2[idx] +#define AES_FT3(idx) FT3[idx] + +#endif /* MBEDTLS_AES_FEWER_TABLES */ + +void mbedtls_aes_init( mbedtls_aes_context *ctx ) +{ + AES_VALIDATE( ctx != NULL ); + + memset( ctx, 0, sizeof( mbedtls_aes_context ) ); +} + +void mbedtls_aes_free( mbedtls_aes_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) ); +} + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx ) +{ + AES_VALIDATE( ctx != NULL ); + + mbedtls_aes_init( &ctx->crypt ); + mbedtls_aes_init( &ctx->tweak ); +} + +void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_aes_free( &ctx->crypt ); + mbedtls_aes_free( &ctx->tweak ); +} +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +/* + * AES key schedule (encryption) + */ +#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT) +int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ) +{ + unsigned int i; + uint32_t *RK; + + AES_VALIDATE_RET( ctx != NULL ); + AES_VALIDATE_RET( key != NULL ); + + switch( keybits ) + { + case 128: ctx->nr = 10; break; + case 192: ctx->nr = 12; break; + case 256: ctx->nr = 14; break; + default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); + } + +#if !defined(MBEDTLS_AES_ROM_TABLES) + if( aes_init_done == 0 ) + { + aes_gen_tables(); + aes_init_done = 1; + } +#endif + +#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) + if( aes_padlock_ace == -1 ) + aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); + + if( aes_padlock_ace ) + ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); + else +#endif + ctx->rk = RK = ctx->buf; + +#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) + if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) + return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) ); +#endif + + for( i = 0; i < ( keybits >> 5 ); i++ ) + { + GET_UINT32_LE( RK[i], key, i << 2 ); + } + + switch( ctx->nr ) + { + case 10: + + for( i = 0; i < 10; i++, RK += 4 ) + { + RK[4] = RK[0] ^ RCON[i] ^ + ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 ); + + RK[5] = RK[1] ^ RK[4]; + RK[6] = RK[2] ^ RK[5]; + RK[7] = RK[3] ^ RK[6]; + } + break; + + case 12: + + for( i = 0; i < 8; i++, RK += 6 ) + { + RK[6] = RK[0] ^ RCON[i] ^ + ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 ); + + RK[7] = RK[1] ^ RK[6]; + RK[8] = RK[2] ^ RK[7]; + RK[9] = RK[3] ^ RK[8]; + RK[10] = RK[4] ^ RK[9]; + RK[11] = RK[5] ^ RK[10]; + } + break; + + case 14: + + for( i = 0; i < 7; i++, RK += 8 ) + { + RK[8] = RK[0] ^ RCON[i] ^ + ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 ); + + RK[9] = RK[1] ^ RK[8]; + RK[10] = RK[2] ^ RK[9]; + RK[11] = RK[3] ^ RK[10]; + + RK[12] = RK[4] ^ + ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 ); + + RK[13] = RK[5] ^ RK[12]; + RK[14] = RK[6] ^ RK[13]; + RK[15] = RK[7] ^ RK[14]; + } + break; + } + + return( 0 ); +} +#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */ + +/* + * AES key schedule (decryption) + */ +#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) +int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ) +{ + int i, j, ret; + mbedtls_aes_context cty; + uint32_t *RK; + uint32_t *SK; + + AES_VALIDATE_RET( ctx != NULL ); + AES_VALIDATE_RET( key != NULL ); + + mbedtls_aes_init( &cty ); + +#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) + if( aes_padlock_ace == -1 ) + aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); + + if( aes_padlock_ace ) + ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); + else +#endif + ctx->rk = RK = ctx->buf; + + /* Also checks keybits */ + if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 ) + goto exit; + + ctx->nr = cty.nr; + +#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) + if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) + { + mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk, + (const unsigned char *) cty.rk, ctx->nr ); + goto exit; + } +#endif + + SK = cty.rk + cty.nr * 4; + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + + for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 ) + { + for( j = 0; j < 4; j++, SK++ ) + { + *RK++ = AES_RT0( FSb[ ( *SK ) & 0xFF ] ) ^ + AES_RT1( FSb[ ( *SK >> 8 ) & 0xFF ] ) ^ + AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^ + AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] ); + } + } + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + +exit: + mbedtls_aes_free( &cty ); + + return( ret ); +} + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +static int mbedtls_aes_xts_decode_keys( const unsigned char *key, + unsigned int keybits, + const unsigned char **key1, + unsigned int *key1bits, + const unsigned char **key2, + unsigned int *key2bits ) +{ + const unsigned int half_keybits = keybits / 2; + const unsigned int half_keybytes = half_keybits / 8; + + switch( keybits ) + { + case 256: break; + case 512: break; + default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); + } + + *key1bits = half_keybits; + *key2bits = half_keybits; + *key1 = &key[0]; + *key2 = &key[half_keybytes]; + + return 0; +} + +int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx, + const unsigned char *key, + unsigned int keybits) +{ + int ret; + const unsigned char *key1, *key2; + unsigned int key1bits, key2bits; + + AES_VALIDATE_RET( ctx != NULL ); + AES_VALIDATE_RET( key != NULL ); + + ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits, + &key2, &key2bits ); + if( ret != 0 ) + return( ret ); + + /* Set the tweak key. Always set tweak key for the encryption mode. */ + ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits ); + if( ret != 0 ) + return( ret ); + + /* Set crypt key for encryption. */ + return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits ); +} + +int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx, + const unsigned char *key, + unsigned int keybits) +{ + int ret; + const unsigned char *key1, *key2; + unsigned int key1bits, key2bits; + + AES_VALIDATE_RET( ctx != NULL ); + AES_VALIDATE_RET( key != NULL ); + + ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits, + &key2, &key2bits ); + if( ret != 0 ) + return( ret ); + + /* Set the tweak key. Always set tweak key for encryption. */ + ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits ); + if( ret != 0 ) + return( ret ); + + /* Set crypt key for decryption. */ + return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits ); +} +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */ + +#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ + do \ + { \ + (X0) = *RK++ ^ AES_FT0( ( (Y0) ) & 0xFF ) ^ \ + AES_FT1( ( (Y1) >> 8 ) & 0xFF ) ^ \ + AES_FT2( ( (Y2) >> 16 ) & 0xFF ) ^ \ + AES_FT3( ( (Y3) >> 24 ) & 0xFF ); \ + \ + (X1) = *RK++ ^ AES_FT0( ( (Y1) ) & 0xFF ) ^ \ + AES_FT1( ( (Y2) >> 8 ) & 0xFF ) ^ \ + AES_FT2( ( (Y3) >> 16 ) & 0xFF ) ^ \ + AES_FT3( ( (Y0) >> 24 ) & 0xFF ); \ + \ + (X2) = *RK++ ^ AES_FT0( ( (Y2) ) & 0xFF ) ^ \ + AES_FT1( ( (Y3) >> 8 ) & 0xFF ) ^ \ + AES_FT2( ( (Y0) >> 16 ) & 0xFF ) ^ \ + AES_FT3( ( (Y1) >> 24 ) & 0xFF ); \ + \ + (X3) = *RK++ ^ AES_FT0( ( (Y3) ) & 0xFF ) ^ \ + AES_FT1( ( (Y0) >> 8 ) & 0xFF ) ^ \ + AES_FT2( ( (Y1) >> 16 ) & 0xFF ) ^ \ + AES_FT3( ( (Y2) >> 24 ) & 0xFF ); \ + } while( 0 ) + +#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ + do \ + { \ + (X0) = *RK++ ^ AES_RT0( ( (Y0) ) & 0xFF ) ^ \ + AES_RT1( ( (Y3) >> 8 ) & 0xFF ) ^ \ + AES_RT2( ( (Y2) >> 16 ) & 0xFF ) ^ \ + AES_RT3( ( (Y1) >> 24 ) & 0xFF ); \ + \ + (X1) = *RK++ ^ AES_RT0( ( (Y1) ) & 0xFF ) ^ \ + AES_RT1( ( (Y0) >> 8 ) & 0xFF ) ^ \ + AES_RT2( ( (Y3) >> 16 ) & 0xFF ) ^ \ + AES_RT3( ( (Y2) >> 24 ) & 0xFF ); \ + \ + (X2) = *RK++ ^ AES_RT0( ( (Y2) ) & 0xFF ) ^ \ + AES_RT1( ( (Y1) >> 8 ) & 0xFF ) ^ \ + AES_RT2( ( (Y0) >> 16 ) & 0xFF ) ^ \ + AES_RT3( ( (Y3) >> 24 ) & 0xFF ); \ + \ + (X3) = *RK++ ^ AES_RT0( ( (Y3) ) & 0xFF ) ^ \ + AES_RT1( ( (Y2) >> 8 ) & 0xFF ) ^ \ + AES_RT2( ( (Y1) >> 16 ) & 0xFF ) ^ \ + AES_RT3( ( (Y0) >> 24 ) & 0xFF ); \ + } while( 0 ) + +/* + * AES-ECB block encryption + */ +#if !defined(MBEDTLS_AES_ENCRYPT_ALT) +int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ) +{ + int i; + uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; + + RK = ctx->rk; + + GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; + GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; + GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; + GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; + + for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) + { + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); + } + + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + + X0 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); + + X1 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); + + X2 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); + + X3 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); + + PUT_UINT32_LE( X0, output, 0 ); + PUT_UINT32_LE( X1, output, 4 ); + PUT_UINT32_LE( X2, output, 8 ); + PUT_UINT32_LE( X3, output, 12 ); + + return( 0 ); +} +#endif /* !MBEDTLS_AES_ENCRYPT_ALT */ + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ) +{ + mbedtls_internal_aes_encrypt( ctx, input, output ); +} +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ + +/* + * AES-ECB block decryption + */ +#if !defined(MBEDTLS_AES_DECRYPT_ALT) +int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ) +{ + int i; + uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; + + RK = ctx->rk; + + GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; + GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; + GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; + GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; + + for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) + { + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); + } + + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + + X0 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); + + X1 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); + + X2 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); + + X3 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); + + PUT_UINT32_LE( X0, output, 0 ); + PUT_UINT32_LE( X1, output, 4 ); + PUT_UINT32_LE( X2, output, 8 ); + PUT_UINT32_LE( X3, output, 12 ); + + return( 0 ); +} +#endif /* !MBEDTLS_AES_DECRYPT_ALT */ + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ) +{ + mbedtls_internal_aes_decrypt( ctx, input, output ); +} +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ + +/* + * AES-ECB block encryption/decryption + */ +int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ + AES_VALIDATE_RET( ctx != NULL ); + AES_VALIDATE_RET( input != NULL ); + AES_VALIDATE_RET( output != NULL ); + AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || + mode == MBEDTLS_AES_DECRYPT ); + +#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) + if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) + return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) ); +#endif + +#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) + if( aes_padlock_ace ) + { + if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 ) + return( 0 ); + + // If padlock data misaligned, we just fall back to + // unaccelerated mode + // + } +#endif + + if( mode == MBEDTLS_AES_ENCRYPT ) + return( mbedtls_internal_aes_encrypt( ctx, input, output ) ); + else + return( mbedtls_internal_aes_decrypt( ctx, input, output ) ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/* + * AES-CBC buffer encryption/decryption + */ +int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int i; + unsigned char temp[16]; + + AES_VALIDATE_RET( ctx != NULL ); + AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || + mode == MBEDTLS_AES_DECRYPT ); + AES_VALIDATE_RET( iv != NULL ); + AES_VALIDATE_RET( input != NULL ); + AES_VALIDATE_RET( output != NULL ); + + if( length % 16 ) + return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH ); + +#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) + if( aes_padlock_ace ) + { + if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 ) + return( 0 ); + + // If padlock data misaligned, we just fall back to + // unaccelerated mode + // + } +#endif + + if( mode == MBEDTLS_AES_DECRYPT ) + { + while( length > 0 ) + { + memcpy( temp, input, 16 ); + mbedtls_aes_crypt_ecb( ctx, mode, input, output ); + + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + else + { + while( length > 0 ) + { + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + mbedtls_aes_crypt_ecb( ctx, mode, output, output ); + memcpy( iv, output, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_XTS) + +/* Endianess with 64 bits values */ +#ifndef GET_UINT64_LE +#define GET_UINT64_LE(n,b,i) \ +{ \ + (n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \ + | ( (uint64_t) (b)[(i) + 6] << 48 ) \ + | ( (uint64_t) (b)[(i) + 5] << 40 ) \ + | ( (uint64_t) (b)[(i) + 4] << 32 ) \ + | ( (uint64_t) (b)[(i) + 3] << 24 ) \ + | ( (uint64_t) (b)[(i) + 2] << 16 ) \ + | ( (uint64_t) (b)[(i) + 1] << 8 ) \ + | ( (uint64_t) (b)[(i) ] ); \ +} +#endif + +#ifndef PUT_UINT64_LE +#define PUT_UINT64_LE(n,b,i) \ +{ \ + (b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \ + (b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \ + (b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \ + (b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) ] = (unsigned char) ( (n) ); \ +} +#endif + +typedef unsigned char mbedtls_be128[16]; + +/* + * GF(2^128) multiplication function + * + * This function multiplies a field element by x in the polynomial field + * representation. It uses 64-bit word operations to gain speed but compensates + * for machine endianess and hence works correctly on both big and little + * endian machines. + */ +static void mbedtls_gf128mul_x_ble( unsigned char r[16], + const unsigned char x[16] ) +{ + uint64_t a, b, ra, rb; + + GET_UINT64_LE( a, x, 0 ); + GET_UINT64_LE( b, x, 8 ); + + ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) ); + rb = ( a >> 63 ) | ( b << 1 ); + + PUT_UINT64_LE( ra, r, 0 ); + PUT_UINT64_LE( rb, r, 8 ); +} + +/* + * AES-XTS buffer encryption/decryption + */ +int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, + int mode, + size_t length, + const unsigned char data_unit[16], + const unsigned char *input, + unsigned char *output ) +{ + int ret; + size_t blocks = length / 16; + size_t leftover = length % 16; + unsigned char tweak[16]; + unsigned char prev_tweak[16]; + unsigned char tmp[16]; + + AES_VALIDATE_RET( ctx != NULL ); + AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || + mode == MBEDTLS_AES_DECRYPT ); + AES_VALIDATE_RET( data_unit != NULL ); + AES_VALIDATE_RET( input != NULL ); + AES_VALIDATE_RET( output != NULL ); + + /* Data units must be at least 16 bytes long. */ + if( length < 16 ) + return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; + + /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */ + if( length > ( 1 << 20 ) * 16 ) + return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; + + /* Compute the tweak. */ + ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT, + data_unit, tweak ); + if( ret != 0 ) + return( ret ); + + while( blocks-- ) + { + size_t i; + + if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 ) + { + /* We are on the last block in a decrypt operation that has + * leftover bytes, so we need to use the next tweak for this block, + * and this tweak for the lefover bytes. Save the current tweak for + * the leftovers and then update the current tweak for use on this, + * the last full block. */ + memcpy( prev_tweak, tweak, sizeof( tweak ) ); + mbedtls_gf128mul_x_ble( tweak, tweak ); + } + + for( i = 0; i < 16; i++ ) + tmp[i] = input[i] ^ tweak[i]; + + ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp ); + if( ret != 0 ) + return( ret ); + + for( i = 0; i < 16; i++ ) + output[i] = tmp[i] ^ tweak[i]; + + /* Update the tweak for the next block. */ + mbedtls_gf128mul_x_ble( tweak, tweak ); + + output += 16; + input += 16; + } + + if( leftover ) + { + /* If we are on the leftover bytes in a decrypt operation, we need to + * use the previous tweak for these bytes (as saved in prev_tweak). */ + unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak; + + /* We are now on the final part of the data unit, which doesn't divide + * evenly by 16. It's time for ciphertext stealing. */ + size_t i; + unsigned char *prev_output = output - 16; + + /* Copy ciphertext bytes from the previous block to our output for each + * byte of cyphertext we won't steal. At the same time, copy the + * remainder of the input for this final round (since the loop bounds + * are the same). */ + for( i = 0; i < leftover; i++ ) + { + output[i] = prev_output[i]; + tmp[i] = input[i] ^ t[i]; + } + + /* Copy ciphertext bytes from the previous block for input in this + * round. */ + for( ; i < 16; i++ ) + tmp[i] = prev_output[i] ^ t[i]; + + ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp ); + if( ret != 0 ) + return ret; + + /* Write the result back to the previous block, overriding the previous + * output we copied. */ + for( i = 0; i < 16; i++ ) + prev_output[i] = tmp[i] ^ t[i]; + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/* + * AES-CFB128 buffer encryption/decryption + */ +int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int c; + size_t n; + + AES_VALIDATE_RET( ctx != NULL ); + AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || + mode == MBEDTLS_AES_DECRYPT ); + AES_VALIDATE_RET( iv_off != NULL ); + AES_VALIDATE_RET( iv != NULL ); + AES_VALIDATE_RET( input != NULL ); + AES_VALIDATE_RET( output != NULL ); + + n = *iv_off; + + if( n > 15 ) + return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); + + if( mode == MBEDTLS_AES_DECRYPT ) + { + while( length-- ) + { + if( n == 0 ) + mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); + + c = *input++; + *output++ = (unsigned char)( c ^ iv[n] ); + iv[n] = (unsigned char) c; + + n = ( n + 1 ) & 0x0F; + } + } + else + { + while( length-- ) + { + if( n == 0 ) + mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); + + iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); + + n = ( n + 1 ) & 0x0F; + } + } + + *iv_off = n; + + return( 0 ); +} + +/* + * AES-CFB8 buffer encryption/decryption + */ +int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + unsigned char c; + unsigned char ov[17]; + + AES_VALIDATE_RET( ctx != NULL ); + AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || + mode == MBEDTLS_AES_DECRYPT ); + AES_VALIDATE_RET( iv != NULL ); + AES_VALIDATE_RET( input != NULL ); + AES_VALIDATE_RET( output != NULL ); + while( length-- ) + { + memcpy( ov, iv, 16 ); + mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); + + if( mode == MBEDTLS_AES_DECRYPT ) + ov[16] = *input; + + c = *output++ = (unsigned char)( iv[0] ^ *input++ ); + + if( mode == MBEDTLS_AES_ENCRYPT ) + ov[16] = c; + + memcpy( iv, ov + 1, 16 ); + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_OFB) +/* + * AES-OFB (Output Feedback Mode) buffer encryption/decryption + */ +int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int ret = 0; + size_t n; + + AES_VALIDATE_RET( ctx != NULL ); + AES_VALIDATE_RET( iv_off != NULL ); + AES_VALIDATE_RET( iv != NULL ); + AES_VALIDATE_RET( input != NULL ); + AES_VALIDATE_RET( output != NULL ); + + n = *iv_off; + + if( n > 15 ) + return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); + + while( length-- ) + { + if( n == 0 ) + { + ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); + if( ret != 0 ) + goto exit; + } + *output++ = *input++ ^ iv[n]; + + n = ( n + 1 ) & 0x0F; + } + + *iv_off = n; + +exit: + return( ret ); +} +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/* + * AES-CTR buffer encryption/decryption + */ +int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ) +{ + int c, i; + size_t n; + + AES_VALIDATE_RET( ctx != NULL ); + AES_VALIDATE_RET( nc_off != NULL ); + AES_VALIDATE_RET( nonce_counter != NULL ); + AES_VALIDATE_RET( stream_block != NULL ); + AES_VALIDATE_RET( input != NULL ); + AES_VALIDATE_RET( output != NULL ); + + n = *nc_off; + + if ( n > 0x0F ) + return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); + + while( length-- ) + { + if( n == 0 ) { + mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block ); + + for( i = 16; i > 0; i-- ) + if( ++nonce_counter[i - 1] != 0 ) + break; + } + c = *input++; + *output++ = (unsigned char)( c ^ stream_block[n] ); + + n = ( n + 1 ) & 0x0F; + } + + *nc_off = n; + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#endif /* !MBEDTLS_AES_ALT */ + +#if defined(MBEDTLS_SELF_TEST) +/* + * AES test vectors from: + * + * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip + */ +static const unsigned char aes_test_ecb_dec[3][16] = +{ + { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58, + 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 }, + { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, + 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 }, + { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, + 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE } +}; + +static const unsigned char aes_test_ecb_enc[3][16] = +{ + { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73, + 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F }, + { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11, + 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 }, + { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D, + 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 } +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const unsigned char aes_test_cbc_dec[3][16] = +{ + { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73, + 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 }, + { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75, + 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B }, + { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75, + 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 } +}; + +static const unsigned char aes_test_cbc_enc[3][16] = +{ + { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84, + 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D }, + { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB, + 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 }, + { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5, + 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 } +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/* + * AES-CFB128 test vectors from: + * + * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + */ +static const unsigned char aes_test_cfb128_key[3][32] = +{ + { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, + { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, + 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, + 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, + { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } +}; + +static const unsigned char aes_test_cfb128_iv[16] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; + +static const unsigned char aes_test_cfb128_pt[64] = +{ + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const unsigned char aes_test_cfb128_ct[3][64] = +{ + { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, + 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, + 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F, + 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B, + 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40, + 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF, + 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E, + 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 }, + { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, + 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, + 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21, + 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A, + 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1, + 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9, + 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0, + 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF }, + { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, + 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, + 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8, + 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B, + 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92, + 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9, + 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8, + 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 } +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_OFB) +/* + * AES-OFB test vectors from: + * + * https://csrc.nist.gov/publications/detail/sp/800-38a/final + */ +static const unsigned char aes_test_ofb_key[3][32] = +{ + { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, + { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, + 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, + 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, + { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } +}; + +static const unsigned char aes_test_ofb_iv[16] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; + +static const unsigned char aes_test_ofb_pt[64] = +{ + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const unsigned char aes_test_ofb_ct[3][64] = +{ + { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, + 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, + 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03, + 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25, + 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6, + 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc, + 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78, + 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e }, + { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, + 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, + 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c, + 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01, + 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f, + 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2, + 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e, + 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a }, + { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, + 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, + 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a, + 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d, + 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed, + 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08, + 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8, + 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 } +}; +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/* + * AES-CTR test vectors from: + * + * http://www.faqs.org/rfcs/rfc3686.html + */ + +static const unsigned char aes_test_ctr_key[3][16] = +{ + { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, + 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, + { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, + 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, + { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } +}; + +static const unsigned char aes_test_ctr_nonce_counter[3][16] = +{ + { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, + 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, + 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } +}; + +static const unsigned char aes_test_ctr_pt[3][48] = +{ + { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, + 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23 } +}; + +static const unsigned char aes_test_ctr_ct[3][48] = +{ + { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, + 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 }, + { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9, + 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88, + 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8, + 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 }, + { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, + 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, + 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, + 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, + 0x25, 0xB2, 0x07, 0x2F } +}; + +static const int aes_test_ctr_len[3] = + { 16, 32, 36 }; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/* + * AES-XTS test vectors from: + * + * IEEE P1619/D16 Annex B + * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf + * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf) + */ +static const unsigned char aes_test_xts_key[][32] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, + { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, + 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, +}; + +static const unsigned char aes_test_xts_pt32[][32] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }, + { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }, +}; + +static const unsigned char aes_test_xts_ct32[][32] = +{ + { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec, + 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92, + 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85, + 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e }, + { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e, + 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b, + 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4, + 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 }, + { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a, + 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2, + 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53, + 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 }, +}; + +static const unsigned char aes_test_xts_data_unit[][16] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, +}; + +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +/* + * Checkup routine + */ +int mbedtls_aes_self_test( int verbose ) +{ + int ret = 0, i, j, u, mode; + unsigned int keybits; + unsigned char key[32]; + unsigned char buf[64]; + const unsigned char *aes_tests; +#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) + unsigned char iv[16]; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CBC) + unsigned char prv[16]; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \ + defined(MBEDTLS_CIPHER_MODE_OFB) + size_t offset; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS) + int len; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + unsigned char nonce_counter[16]; + unsigned char stream_block[16]; +#endif + mbedtls_aes_context ctx; + + memset( key, 0, 32 ); + mbedtls_aes_init( &ctx ); + + /* + * ECB mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + keybits = 128 + u * 64; + mode = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-ECB-%3d (%s): ", keybits, + ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memset( buf, 0, 16 ); + + if( mode == MBEDTLS_AES_DECRYPT ) + { + ret = mbedtls_aes_setkey_dec( &ctx, key, keybits ); + aes_tests = aes_test_ecb_dec[u]; + } + else + { + ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); + aes_tests = aes_test_ecb_enc[u]; + } + + /* + * AES-192 is an optional feature that may be unavailable when + * there is an alternative underlying implementation i.e. when + * MBEDTLS_AES_ALT is defined. + */ + if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) + { + mbedtls_printf( "skipped\n" ); + continue; + } + else if( ret != 0 ) + { + goto exit; + } + + for( j = 0; j < 10000; j++ ) + { + ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf ); + if( ret != 0 ) + goto exit; + } + + if( memcmp( buf, aes_tests, 16 ) != 0 ) + { + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + /* + * CBC mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + keybits = 128 + u * 64; + mode = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-CBC-%3d (%s): ", keybits, + ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memset( iv , 0, 16 ); + memset( prv, 0, 16 ); + memset( buf, 0, 16 ); + + if( mode == MBEDTLS_AES_DECRYPT ) + { + ret = mbedtls_aes_setkey_dec( &ctx, key, keybits ); + aes_tests = aes_test_cbc_dec[u]; + } + else + { + ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); + aes_tests = aes_test_cbc_enc[u]; + } + + /* + * AES-192 is an optional feature that may be unavailable when + * there is an alternative underlying implementation i.e. when + * MBEDTLS_AES_ALT is defined. + */ + if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) + { + mbedtls_printf( "skipped\n" ); + continue; + } + else if( ret != 0 ) + { + goto exit; + } + + for( j = 0; j < 10000; j++ ) + { + if( mode == MBEDTLS_AES_ENCRYPT ) + { + unsigned char tmp[16]; + + memcpy( tmp, prv, 16 ); + memcpy( prv, buf, 16 ); + memcpy( buf, tmp, 16 ); + } + + ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf ); + if( ret != 0 ) + goto exit; + + } + + if( memcmp( buf, aes_tests, 16 ) != 0 ) + { + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) + /* + * CFB128 mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + keybits = 128 + u * 64; + mode = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-CFB128-%3d (%s): ", keybits, + ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( iv, aes_test_cfb128_iv, 16 ); + memcpy( key, aes_test_cfb128_key[u], keybits / 8 ); + + offset = 0; + ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); + /* + * AES-192 is an optional feature that may be unavailable when + * there is an alternative underlying implementation i.e. when + * MBEDTLS_AES_ALT is defined. + */ + if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) + { + mbedtls_printf( "skipped\n" ); + continue; + } + else if( ret != 0 ) + { + goto exit; + } + + if( mode == MBEDTLS_AES_DECRYPT ) + { + memcpy( buf, aes_test_cfb128_ct[u], 64 ); + aes_tests = aes_test_cfb128_pt; + } + else + { + memcpy( buf, aes_test_cfb128_pt, 64 ); + aes_tests = aes_test_cfb128_ct[u]; + } + + ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf ); + if( ret != 0 ) + goto exit; + + if( memcmp( buf, aes_tests, 64 ) != 0 ) + { + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_OFB) + /* + * OFB mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + keybits = 128 + u * 64; + mode = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-OFB-%3d (%s): ", keybits, + ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( iv, aes_test_ofb_iv, 16 ); + memcpy( key, aes_test_ofb_key[u], keybits / 8 ); + + offset = 0; + ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); + /* + * AES-192 is an optional feature that may be unavailable when + * there is an alternative underlying implementation i.e. when + * MBEDTLS_AES_ALT is defined. + */ + if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) + { + mbedtls_printf( "skipped\n" ); + continue; + } + else if( ret != 0 ) + { + goto exit; + } + + if( mode == MBEDTLS_AES_DECRYPT ) + { + memcpy( buf, aes_test_ofb_ct[u], 64 ); + aes_tests = aes_test_ofb_pt; + } + else + { + memcpy( buf, aes_test_ofb_pt, 64 ); + aes_tests = aes_test_ofb_ct[u]; + } + + ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf ); + if( ret != 0 ) + goto exit; + + if( memcmp( buf, aes_tests, 64 ) != 0 ) + { + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) + /* + * CTR mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + mode = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-CTR-128 (%s): ", + ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); + memcpy( key, aes_test_ctr_key[u], 16 ); + + offset = 0; + if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 ) + goto exit; + + len = aes_test_ctr_len[u]; + + if( mode == MBEDTLS_AES_DECRYPT ) + { + memcpy( buf, aes_test_ctr_ct[u], len ); + aes_tests = aes_test_ctr_pt[u]; + } + else + { + memcpy( buf, aes_test_ctr_pt[u], len ); + aes_tests = aes_test_ctr_ct[u]; + } + + ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, + stream_block, buf, buf ); + if( ret != 0 ) + goto exit; + + if( memcmp( buf, aes_tests, len ) != 0 ) + { + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_CIPHER_MODE_XTS) + { + static const int num_tests = + sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key); + mbedtls_aes_xts_context ctx_xts; + + /* + * XTS mode + */ + mbedtls_aes_xts_init( &ctx_xts ); + + for( i = 0; i < num_tests << 1; i++ ) + { + const unsigned char *data_unit; + u = i >> 1; + mode = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-XTS-128 (%s): ", + ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memset( key, 0, sizeof( key ) ); + memcpy( key, aes_test_xts_key[u], 32 ); + data_unit = aes_test_xts_data_unit[u]; + + len = sizeof( *aes_test_xts_ct32 ); + + if( mode == MBEDTLS_AES_DECRYPT ) + { + ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 ); + if( ret != 0) + goto exit; + memcpy( buf, aes_test_xts_ct32[u], len ); + aes_tests = aes_test_xts_pt32[u]; + } + else + { + ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 ); + if( ret != 0) + goto exit; + memcpy( buf, aes_test_xts_pt32[u], len ); + aes_tests = aes_test_xts_ct32[u]; + } + + + ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit, + buf, buf ); + if( ret != 0 ) + goto exit; + + if( memcmp( buf, aes_tests, len ) != 0 ) + { + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + mbedtls_aes_xts_free( &ctx_xts ); + } +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + + ret = 0; + +exit: + if( ret != 0 && verbose != 0 ) + mbedtls_printf( "failed\n" ); + + mbedtls_aes_free( &ctx ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_AES_C */ diff --git a/mbed_aes_gcm/aes.h b/mbed_aes_gcm/aes.h new file mode 100644 index 0000000..94e7282 --- /dev/null +++ b/mbed_aes_gcm/aes.h @@ -0,0 +1,674 @@ +/** + * \file aes.h + * + * \brief This file contains AES definitions and functions. + * + * The Advanced Encryption Standard (AES) specifies a FIPS-approved + * cryptographic algorithm that can be used to protect electronic + * data. + * + * The AES algorithm is a symmetric block cipher that can + * encrypt and decrypt information. For more information, see + * FIPS Publication 197: Advanced Encryption Standard and + * ISO/IEC 18033-2:2006: Information technology -- Security + * techniques -- Encryption algorithms -- Part 2: Asymmetric + * ciphers. + * + * The AES-XTS block mode is standardized by NIST SP 800-38E + * + * and described in detail by IEEE P1619 + * . + */ + +/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of Mbed TLS (https://tls.mbed.org) + */ + +#ifndef MBEDTLS_AES_H +#define MBEDTLS_AES_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include +#include + +/* padlock.c and aesni.c rely on these values! */ +#define MBEDTLS_AES_ENCRYPT 1 /**< AES encryption. */ +#define MBEDTLS_AES_DECRYPT 0 /**< AES decryption. */ + +/* Error codes in range 0x0020-0x0022 */ +#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */ +#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */ + +/* Error codes in range 0x0021-0x0025 */ +#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021 /**< Invalid input data. */ + +/* MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE is deprecated and should not be used. */ +#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE -0x0023 /**< Feature not available. For example, an unsupported AES key size. */ + +/* MBEDTLS_ERR_AES_HW_ACCEL_FAILED is deprecated and should not be used. */ +#define MBEDTLS_ERR_AES_HW_ACCEL_FAILED -0x0025 /**< AES hardware accelerator failed. */ + +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(MBEDTLS_AES_ALT) +// Regular implementation +// + +/** + * \brief The AES context-type definition. + */ +typedef struct mbedtls_aes_context +{ + int nr; /*!< The number of rounds. */ + uint32_t *rk; /*!< AES round keys. */ + uint32_t buf[68]; /*!< Unaligned data buffer. This buffer can + hold 32 extra Bytes, which can be used for + one of the following purposes: +
  • Alignment if VIA padlock is + used.
  • +
  • Simplifying key expansion in the 256-bit + case by generating an extra round key. +
*/ +} +mbedtls_aes_context; + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/** + * \brief The AES XTS context-type definition. + */ +typedef struct mbedtls_aes_xts_context +{ + mbedtls_aes_context crypt; /*!< The AES context to use for AES block + encryption or decryption. */ + mbedtls_aes_context tweak; /*!< The AES context used for tweak + computation. */ +} mbedtls_aes_xts_context; +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +#else /* MBEDTLS_AES_ALT */ +#include "aes_alt.h" +#endif /* MBEDTLS_AES_ALT */ + +/** + * \brief This function initializes the specified AES context. + * + * It must be the first API called before using + * the context. + * + * \param ctx The AES context to initialize. This must not be \c NULL. + */ +void mbedtls_aes_init( mbedtls_aes_context *ctx ); + +/** + * \brief This function releases and clears the specified AES context. + * + * \param ctx The AES context to clear. + * If this is \c NULL, this function does nothing. + * Otherwise, the context must have been at least initialized. + */ +void mbedtls_aes_free( mbedtls_aes_context *ctx ); + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/** + * \brief This function initializes the specified AES XTS context. + * + * It must be the first API called before using + * the context. + * + * \param ctx The AES XTS context to initialize. This must not be \c NULL. + */ +void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx ); + +/** + * \brief This function releases and clears the specified AES XTS context. + * + * \param ctx The AES XTS context to clear. + * If this is \c NULL, this function does nothing. + * Otherwise, the context must have been at least initialized. + */ +void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx ); +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +/** + * \brief This function sets the encryption key. + * + * \param ctx The AES context to which the key should be bound. + * It must be initialized. + * \param key The encryption key. + * This must be a readable buffer of size \p keybits bits. + * \param keybits The size of data passed in bits. Valid options are: + *
  • 128 bits
  • + *
  • 192 bits
  • + *
  • 256 bits
+ * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. + */ +int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ); + +/** + * \brief This function sets the decryption key. + * + * \param ctx The AES context to which the key should be bound. + * It must be initialized. + * \param key The decryption key. + * This must be a readable buffer of size \p keybits bits. + * \param keybits The size of data passed. Valid options are: + *
  • 128 bits
  • + *
  • 192 bits
  • + *
  • 256 bits
+ * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. + */ +int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ); + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/** + * \brief This function prepares an XTS context for encryption and + * sets the encryption key. + * + * \param ctx The AES XTS context to which the key should be bound. + * It must be initialized. + * \param key The encryption key. This is comprised of the XTS key1 + * concatenated with the XTS key2. + * This must be a readable buffer of size \p keybits bits. + * \param keybits The size of \p key passed in bits. Valid options are: + *
  • 256 bits (each of key1 and key2 is a 128-bit key)
  • + *
  • 512 bits (each of key1 and key2 is a 256-bit key)
+ * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. + */ +int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx, + const unsigned char *key, + unsigned int keybits ); + +/** + * \brief This function prepares an XTS context for decryption and + * sets the decryption key. + * + * \param ctx The AES XTS context to which the key should be bound. + * It must be initialized. + * \param key The decryption key. This is comprised of the XTS key1 + * concatenated with the XTS key2. + * This must be a readable buffer of size \p keybits bits. + * \param keybits The size of \p key passed in bits. Valid options are: + *
  • 256 bits (each of key1 and key2 is a 128-bit key)
  • + *
  • 512 bits (each of key1 and key2 is a 256-bit key)
+ * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. + */ +int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx, + const unsigned char *key, + unsigned int keybits ); +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +/** + * \brief This function performs an AES single-block encryption or + * decryption operation. + * + * It performs the operation defined in the \p mode parameter + * (encrypt or decrypt), on the input data buffer defined in + * the \p input parameter. + * + * mbedtls_aes_init(), and either mbedtls_aes_setkey_enc() or + * mbedtls_aes_setkey_dec() must be called before the first + * call to this API with the same context. + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or + * #MBEDTLS_AES_DECRYPT. + * \param input The buffer holding the input data. + * It must be readable and at least \c 16 Bytes long. + * \param output The buffer where the output data will be written. + * It must be writeable and at least \c 16 Bytes long. + + * \return \c 0 on success. + */ +int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/** + * \brief This function performs an AES-CBC encryption or decryption operation + * on full blocks. + * + * It performs the operation defined in the \p mode + * parameter (encrypt/decrypt), on the input data buffer defined in + * the \p input parameter. + * + * It can be called as many times as needed, until all the input + * data is processed. mbedtls_aes_init(), and either + * mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called + * before the first call to this API with the same context. + * + * \note This function operates on full blocks, that is, the input size + * must be a multiple of the AES block size of \c 16 Bytes. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the same function again on the next + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If you need to retain the contents of the IV, you should + * either save it manually or use the cipher module instead. + * + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or + * #MBEDTLS_AES_DECRYPT. + * \param length The length of the input data in Bytes. This must be a + * multiple of the block size (\c 16 Bytes). + * \param iv Initialization vector (updated after use). + * It must be a readable and writeable buffer of \c 16 Bytes. + * \param input The buffer holding the input data. + * It must be readable and of size \p length Bytes. + * \param output The buffer holding the output data. + * It must be writeable and of size \p length Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH + * on failure. + */ +int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/** + * \brief This function performs an AES-XTS encryption or decryption + * operation for an entire XTS data unit. + * + * AES-XTS encrypts or decrypts blocks based on their location as + * defined by a data unit number. The data unit number must be + * provided by \p data_unit. + * + * NIST SP 800-38E limits the maximum size of a data unit to 2^20 + * AES blocks. If the data unit is larger than this, this function + * returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH. + * + * \param ctx The AES XTS context to use for AES XTS operations. + * It must be initialized and bound to a key. + * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or + * #MBEDTLS_AES_DECRYPT. + * \param length The length of a data unit in Bytes. This can be any + * length between 16 bytes and 2^24 bytes inclusive + * (between 1 and 2^20 block cipher blocks). + * \param data_unit The address of the data unit encoded as an array of 16 + * bytes in little-endian format. For disk encryption, this + * is typically the index of the block device sector that + * contains the data. + * \param input The buffer holding the input data (which is an entire + * data unit). This function reads \p length Bytes from \p + * input. + * \param output The buffer holding the output data (which is an entire + * data unit). This function writes \p length Bytes to \p + * output. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is + * smaller than an AES block in size (16 Bytes) or if \p + * length is larger than 2^20 blocks (16 MiB). + */ +int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, + int mode, + size_t length, + const unsigned char data_unit[16], + const unsigned char *input, + unsigned char *output ); +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/** + * \brief This function performs an AES-CFB128 encryption or decryption + * operation. + * + * It performs the operation defined in the \p mode + * parameter (encrypt or decrypt), on the input data buffer + * defined in the \p input parameter. + * + * For CFB, you must set up the context with mbedtls_aes_setkey_enc(), + * regardless of whether you are performing an encryption or decryption + * operation, that is, regardless of the \p mode parameter. This is + * because CFB mode uses the same key schedule for encryption and + * decryption. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the same function again on the next + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If you need to retain the contents of the + * IV, you must either save it manually or use the cipher + * module instead. + * + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or + * #MBEDTLS_AES_DECRYPT. + * \param length The length of the input data in Bytes. + * \param iv_off The offset in IV (updated after use). + * It must point to a valid \c size_t. + * \param iv The initialization vector (updated after use). + * It must be a readable and writeable buffer of \c 16 Bytes. + * \param input The buffer holding the input data. + * It must be readable and of size \p length Bytes. + * \param output The buffer holding the output data. + * It must be writeable and of size \p length Bytes. + * + * \return \c 0 on success. + */ +int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +/** + * \brief This function performs an AES-CFB8 encryption or decryption + * operation. + * + * It performs the operation defined in the \p mode + * parameter (encrypt/decrypt), on the input data buffer defined + * in the \p input parameter. + * + * Due to the nature of CFB, you must use the same key schedule for + * both encryption and decryption operations. Therefore, you must + * use the context initialized with mbedtls_aes_setkey_enc() for + * both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the same function again on the next + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or + * #MBEDTLS_AES_DECRYPT + * \param length The length of the input data. + * \param iv The initialization vector (updated after use). + * It must be a readable and writeable buffer of \c 16 Bytes. + * \param input The buffer holding the input data. + * It must be readable and of size \p length Bytes. + * \param output The buffer holding the output data. + * It must be writeable and of size \p length Bytes. + * + * \return \c 0 on success. + */ +int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); +#endif /*MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_OFB) +/** + * \brief This function performs an AES-OFB (Output Feedback Mode) + * encryption or decryption operation. + * + * For OFB, you must set up the context with + * mbedtls_aes_setkey_enc(), regardless of whether you are + * performing an encryption or decryption operation. This is + * because OFB mode uses the same key schedule for encryption and + * decryption. + * + * The OFB operation is identical for encryption or decryption, + * therefore no operation mode needs to be specified. + * + * \note Upon exit, the content of iv, the Initialisation Vector, is + * updated so that you can call the same function again on the next + * block(s) of data and get the same result as if it was encrypted + * in one call. This allows a "streaming" usage, by initialising + * iv_off to 0 before the first call, and preserving its value + * between calls. + * + * For non-streaming use, the iv should be initialised on each call + * to a unique value, and iv_off set to 0 on each call. + * + * If you need to retain the contents of the initialisation vector, + * you must either save it manually or use the cipher module + * instead. + * + * \warning For the OFB mode, the initialisation vector must be unique + * every encryption operation. Reuse of an initialisation vector + * will compromise security. + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param length The length of the input data. + * \param iv_off The offset in IV (updated after use). + * It must point to a valid \c size_t. + * \param iv The initialization vector (updated after use). + * It must be a readable and writeable buffer of \c 16 Bytes. + * \param input The buffer holding the input data. + * It must be readable and of size \p length Bytes. + * \param output The buffer holding the output data. + * It must be writeable and of size \p length Bytes. + * + * \return \c 0 on success. + */ +int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/** + * \brief This function performs an AES-CTR encryption or decryption + * operation. + * + * This function performs the operation defined in the \p mode + * parameter (encrypt/decrypt), on the input data buffer + * defined in the \p input parameter. + * + * Due to the nature of CTR, you must use the same key schedule + * for both encryption and decryption operations. Therefore, you + * must use the context initialized with mbedtls_aes_setkey_enc() + * for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT. + * + * \warning You must never reuse a nonce value with the same key. Doing so + * would void the encryption for the two messages encrypted with + * the same nonce and key. + * + * There are two common strategies for managing nonces with CTR: + * + * 1. You can handle everything as a single message processed over + * successive calls to this function. In that case, you want to + * set \p nonce_counter and \p nc_off to 0 for the first call, and + * then preserve the values of \p nonce_counter, \p nc_off and \p + * stream_block across calls to this function as they will be + * updated by this function. + * + * With this strategy, you must not encrypt more than 2**128 + * blocks of data with the same key. + * + * 2. You can encrypt separate messages by dividing the \p + * nonce_counter buffer in two areas: the first one used for a + * per-message nonce, handled by yourself, and the second one + * updated by this function internally. + * + * For example, you might reserve the first 12 bytes for the + * per-message nonce, and the last 4 bytes for internal use. In that + * case, before calling this function on a new message you need to + * set the first 12 bytes of \p nonce_counter to your chosen nonce + * value, the last 4 to 0, and \p nc_off to 0 (which will cause \p + * stream_block to be ignored). That way, you can encrypt at most + * 2**96 messages of up to 2**32 blocks each with the same key. + * + * The per-message nonce (or information sufficient to reconstruct + * it) needs to be communicated with the ciphertext and must be unique. + * The recommended way to ensure uniqueness is to use a message + * counter. An alternative is to generate random nonces, but this + * limits the number of messages that can be securely encrypted: + * for example, with 96-bit random nonces, you should not encrypt + * more than 2**32 messages with the same key. + * + * Note that for both stategies, sizes are measured in blocks and + * that an AES block is 16 bytes. + * + * \warning Upon return, \p stream_block contains sensitive data. Its + * content must not be written to insecure storage and should be + * securely discarded as soon as it's no longer needed. + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param length The length of the input data. + * \param nc_off The offset in the current \p stream_block, for + * resuming within the current cipher stream. The + * offset pointer should be 0 at the start of a stream. + * It must point to a valid \c size_t. + * \param nonce_counter The 128-bit nonce and counter. + * It must be a readable-writeable buffer of \c 16 Bytes. + * \param stream_block The saved stream block for resuming. This is + * overwritten by the function. + * It must be a readable-writeable buffer of \c 16 Bytes. + * \param input The buffer holding the input data. + * It must be readable and of size \p length Bytes. + * \param output The buffer holding the output data. + * It must be writeable and of size \p length Bytes. + * + * \return \c 0 on success. + */ +int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ); +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +/** + * \brief Internal AES block encryption function. This is only + * exposed to allow overriding it using + * \c MBEDTLS_AES_ENCRYPT_ALT. + * + * \param ctx The AES context to use for encryption. + * \param input The plaintext block. + * \param output The output (ciphertext) block. + * + * \return \c 0 on success. + */ +int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +/** + * \brief Internal AES block decryption function. This is only + * exposed to allow overriding it using see + * \c MBEDTLS_AES_DECRYPT_ALT. + * + * \param ctx The AES context to use for decryption. + * \param input The ciphertext block. + * \param output The output (plaintext) block. + * + * \return \c 0 on success. + */ +int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief Deprecated internal AES block encryption function + * without return value. + * + * \deprecated Superseded by mbedtls_internal_aes_encrypt() + * + * \param ctx The AES context to use for encryption. + * \param input Plaintext block. + * \param output Output (ciphertext) block. + */ +MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +/** + * \brief Deprecated internal AES block decryption function + * without return value. + * + * \deprecated Superseded by mbedtls_internal_aes_decrypt() + * + * \param ctx The AES context to use for decryption. + * \param input Ciphertext block. + * \param output Output (plaintext) block. + */ +MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +#undef MBEDTLS_DEPRECATED +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ + + +#if defined(MBEDTLS_SELF_TEST) +/** + * \brief Checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_aes_self_test( int verbose ); + +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* aes.h */ diff --git a/mbed_aes_gcm/api.h b/mbed_aes_gcm/api.h new file mode 100644 index 0000000..c3c0a27 --- /dev/null +++ b/mbed_aes_gcm/api.h @@ -0,0 +1,5 @@ +#define CRYPTO_KEYBYTES 16 +#define CRYPTO_NSECBYTES 0 +#define CRYPTO_NPUBBYTES 12 +#define CRYPTO_ABYTES 16 +#define CRYPTO_NOOVERLAP 1 diff --git a/mbed_aes_gcm/cipher.c b/mbed_aes_gcm/cipher.c new file mode 100644 index 0000000..0a46dae --- /dev/null +++ b/mbed_aes_gcm/cipher.c @@ -0,0 +1,1540 @@ +/** + * \file cipher.c + * + * \brief Generic cipher wrapper for mbed TLS + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CIPHER_C) + +#include "cipher.h" +#include "cipher_internal.h" +#include "platform_util.h" + +#include +#include + +#if defined(MBEDTLS_CHACHAPOLY_C) +#include "mbedtls/chachapoly.h" +#endif + +#if defined(MBEDTLS_GCM_C) +#include "gcm.h" +#endif + +#if defined(MBEDTLS_CCM_C) +#include "mbedtls/ccm.h" +#endif + +#if defined(MBEDTLS_CHACHA20_C) +#include "mbedtls/chacha20.h" +#endif + +#if defined(MBEDTLS_CMAC_C) +#include "mbedtls/cmac.h" +#endif + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +#include "psa/crypto.h" +#include "mbedtls/psa_util.h" +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +#if defined(MBEDTLS_NIST_KW_C) +#include "mbedtls/nist_kw.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#define CIPHER_VALIDATE_RET( cond ) \ + MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ) +#define CIPHER_VALIDATE( cond ) \ + MBEDTLS_INTERNAL_VALIDATE( cond ) + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +/* Compare the contents of two buffers in constant time. + * Returns 0 if the contents are bitwise identical, otherwise returns + * a non-zero value. + * This is currently only used by GCM and ChaCha20+Poly1305. + */ +static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, + size_t len ) +{ + const unsigned char *p1 = (const unsigned char*) v1; + const unsigned char *p2 = (const unsigned char*) v2; + size_t i; + unsigned char diff; + + for( diff = 0, i = 0; i < len; i++ ) + diff |= p1[i] ^ p2[i]; + + return( (int)diff ); +} +#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ + +static int supported_init = 0; + +const int *mbedtls_cipher_list( void ) +{ + const mbedtls_cipher_definition_t *def; + int *type; + + if( ! supported_init ) + { + def = mbedtls_cipher_definitions; + type = mbedtls_cipher_supported; + + while( def->type != 0 ) + *type++ = (*def++).type; + + *type = 0; + + supported_init = 1; + } + + return( mbedtls_cipher_supported ); +} + +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( + const mbedtls_cipher_type_t cipher_type ) +{ + const mbedtls_cipher_definition_t *def; + + for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) + if( def->type == cipher_type ) + return( def->info ); + + return( NULL ); +} + +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( + const char *cipher_name ) +{ + const mbedtls_cipher_definition_t *def; + + if( NULL == cipher_name ) + return( NULL ); + + for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) + if( ! strcmp( def->info->name, cipher_name ) ) + return( def->info ); + + return( NULL ); +} + +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( + const mbedtls_cipher_id_t cipher_id, + int key_bitlen, + const mbedtls_cipher_mode_t mode ) +{ + const mbedtls_cipher_definition_t *def; + + for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) + if( def->info->base->cipher == cipher_id && + def->info->key_bitlen == (unsigned) key_bitlen && + def->info->mode == mode ) + return( def->info ); + + return( NULL ); +} + +void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ) +{ + CIPHER_VALIDATE( ctx != NULL ); + memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); +} + +void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ) +{ + if( ctx == NULL ) + return; + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if( ctx->psa_enabled == 1 ) + { + if( ctx->cipher_ctx != NULL ) + { + mbedtls_cipher_context_psa * const cipher_psa = + (mbedtls_cipher_context_psa *) ctx->cipher_ctx; + + if( cipher_psa->slot_state == MBEDTLS_CIPHER_PSA_KEY_OWNED ) + { + /* xxx_free() doesn't allow to return failures. */ + (void) psa_destroy_key( cipher_psa->slot ); + } + + mbedtls_platform_zeroize( cipher_psa, sizeof( *cipher_psa ) ); + mbedtls_free( cipher_psa ); + } + + mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) ); + return; + } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +#if defined(MBEDTLS_CMAC_C) + if( ctx->cmac_ctx ) + { + mbedtls_platform_zeroize( ctx->cmac_ctx, + sizeof( mbedtls_cmac_context_t ) ); + mbedtls_free( ctx->cmac_ctx ); + } +#endif + + if( ctx->cipher_ctx ) + ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx ); + + mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) ); +} + +int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, + const mbedtls_cipher_info_t *cipher_info ) +{ + CIPHER_VALIDATE_RET( ctx != NULL ); + if( cipher_info == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); + + if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) ) + return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); + + ctx->cipher_info = cipher_info; + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) + /* + * Ignore possible errors caused by a cipher mode that doesn't use padding + */ +#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) + (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 ); +#else + (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE ); +#endif +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + + return( 0 ); +} + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx, + const mbedtls_cipher_info_t *cipher_info, + size_t taglen ) +{ + psa_algorithm_t alg; + mbedtls_cipher_context_psa *cipher_psa; + + if( NULL == cipher_info || NULL == ctx ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + /* Check that the underlying cipher mode and cipher type are + * supported by the underlying PSA Crypto implementation. */ + alg = mbedtls_psa_translate_cipher_mode( cipher_info->mode, taglen ); + if( alg == 0 ) + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + if( mbedtls_psa_translate_cipher_type( cipher_info->type ) == 0 ) + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + + memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); + + cipher_psa = mbedtls_calloc( 1, sizeof(mbedtls_cipher_context_psa ) ); + if( cipher_psa == NULL ) + return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); + cipher_psa->alg = alg; + ctx->cipher_ctx = cipher_psa; + ctx->cipher_info = cipher_info; + ctx->psa_enabled = 1; + return( 0 ); +} +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, + const unsigned char *key, + int key_bitlen, + const mbedtls_operation_t operation ) +{ + CIPHER_VALIDATE_RET( ctx != NULL ); + CIPHER_VALIDATE_RET( key != NULL ); + CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT || + operation == MBEDTLS_DECRYPT ); + if( ctx->cipher_info == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if( ctx->psa_enabled == 1 ) + { + mbedtls_cipher_context_psa * const cipher_psa = + (mbedtls_cipher_context_psa *) ctx->cipher_ctx; + + size_t const key_bytelen = ( (size_t) key_bitlen + 7 ) / 8; + + psa_status_t status; + psa_key_type_t key_type; + psa_key_usage_t key_usage; + psa_key_policy_t key_policy; + + /* PSA Crypto API only accepts byte-aligned keys. */ + if( key_bitlen % 8 != 0 ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + /* Don't allow keys to be set multiple times. */ + if( cipher_psa->slot_state != MBEDTLS_CIPHER_PSA_KEY_UNSET ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + key_type = mbedtls_psa_translate_cipher_type( + ctx->cipher_info->type ); + if( key_type == 0 ) + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + + /* Allocate a key slot to use. */ + status = psa_allocate_key( &cipher_psa->slot ); + if( status != PSA_SUCCESS ) + return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); + + /* Indicate that we own the key slot and need to + * destroy it in mbedtls_cipher_free(). */ + cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED; + + /* From that point on, the responsibility for destroying the + * key slot is on mbedtls_cipher_free(). This includes the case + * where the policy setup or key import below fail, as + * mbedtls_cipher_free() needs to be called in any case. */ + + /* Setup policy for the new key slot. */ + key_policy = psa_key_policy_init(); + + /* Mbed TLS' cipher layer doesn't enforce the mode of operation + * (encrypt vs. decrypt): it is possible to setup a key for encryption + * and use it for AEAD decryption. Until tests relying on this + * are changed, allow any usage in PSA. */ + /* key_usage = mbedtls_psa_translate_cipher_operation( operation ); */ + key_usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT; + psa_key_policy_set_usage( &key_policy, key_usage, cipher_psa->alg ); + status = psa_set_key_policy( cipher_psa->slot, &key_policy ); + if( status != PSA_SUCCESS ) + return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); + + /* Populate new key slot. */ + status = psa_import_key( cipher_psa->slot, + key_type, key, key_bytelen ); + if( status != PSA_SUCCESS ) + return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); + + ctx->key_bitlen = key_bitlen; + ctx->operation = operation; + return( 0 ); + } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + + if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 && + (int) ctx->cipher_info->key_bitlen != key_bitlen ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + ctx->key_bitlen = key_bitlen; + ctx->operation = operation; + + /* + * For OFB, CFB and CTR mode always use the encryption key schedule + */ + if( MBEDTLS_ENCRYPT == operation || + MBEDTLS_MODE_CFB == ctx->cipher_info->mode || + MBEDTLS_MODE_OFB == ctx->cipher_info->mode || + MBEDTLS_MODE_CTR == ctx->cipher_info->mode ) + { + return( ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key, + ctx->key_bitlen ) ); + } + + if( MBEDTLS_DECRYPT == operation ) + return( ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key, + ctx->key_bitlen ) ); + + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); +} + +int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, + size_t iv_len ) +{ + size_t actual_iv_size; + + CIPHER_VALIDATE_RET( ctx != NULL ); + CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); + if( ctx->cipher_info == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if( ctx->psa_enabled == 1 ) + { + /* While PSA Crypto has an API for multipart + * operations, we currently don't make it + * accessible through the cipher layer. */ + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + + /* avoid buffer overflow in ctx->iv */ + if( iv_len > MBEDTLS_MAX_IV_LENGTH ) + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + + if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 ) + actual_iv_size = iv_len; + else + { + actual_iv_size = ctx->cipher_info->iv_size; + + /* avoid reading past the end of input buffer */ + if( actual_iv_size > iv_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + +#if defined(MBEDTLS_CHACHA20_C) + if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 ) + { + if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx, + iv, + 0U ) ) /* Initial counter value */ + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + } +#endif + + if ( actual_iv_size != 0 ) + { + memcpy( ctx->iv, iv, actual_iv_size ); + ctx->iv_size = actual_iv_size; + } + + return( 0 ); +} + +int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ) +{ + CIPHER_VALIDATE_RET( ctx != NULL ); + if( ctx->cipher_info == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if( ctx->psa_enabled == 1 ) + { + /* We don't support resetting PSA-based + * cipher contexts, yet. */ + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + + ctx->unprocessed_len = 0; + + return( 0 ); +} + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, + const unsigned char *ad, size_t ad_len ) +{ + CIPHER_VALIDATE_RET( ctx != NULL ); + CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); + if( ctx->cipher_info == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if( ctx->psa_enabled == 1 ) + { + /* While PSA Crypto has an API for multipart + * operations, we currently don't make it + * accessible through the cipher layer. */ + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +#if defined(MBEDTLS_GCM_C) + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + { + return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation, + ctx->iv, ctx->iv_size, ad, ad_len ) ); + } +#endif + +#if defined(MBEDTLS_CHACHAPOLY_C) + if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) + { + int result; + mbedtls_chachapoly_mode_t mode; + + mode = ( ctx->operation == MBEDTLS_ENCRYPT ) + ? MBEDTLS_CHACHAPOLY_ENCRYPT + : MBEDTLS_CHACHAPOLY_DECRYPT; + + result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx, + ctx->iv, + mode ); + if ( result != 0 ) + return( result ); + + return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx, + ad, ad_len ) ); + } +#endif + + return( 0 ); +} +#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ + +int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, + size_t ilen, unsigned char *output, size_t *olen ) +{ + int ret; + size_t block_size; + + CIPHER_VALIDATE_RET( ctx != NULL ); + CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); + CIPHER_VALIDATE_RET( output != NULL ); + CIPHER_VALIDATE_RET( olen != NULL ); + if( ctx->cipher_info == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if( ctx->psa_enabled == 1 ) + { + /* While PSA Crypto has an API for multipart + * operations, we currently don't make it + * accessible through the cipher layer. */ + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + + *olen = 0; + block_size = mbedtls_cipher_get_block_size( ctx ); + + if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB ) + { + if( ilen != block_size ) + return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + + *olen = ilen; + + if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx, + ctx->operation, input, output ) ) ) + { + return( ret ); + } + + return( 0 ); + } + +#if defined(MBEDTLS_GCM_C) + if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM ) + { + *olen = ilen; + return( mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input, + output ) ); + } +#endif + +#if defined(MBEDTLS_CHACHAPOLY_C) + if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) + { + *olen = ilen; + return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx, + ilen, input, output ) ); + } +#endif + + if ( 0 == block_size ) + { + return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT ); + } + + if( input == output && + ( ctx->unprocessed_len != 0 || ilen % block_size ) ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC ) + { + size_t copy_len = 0; + + /* + * If there is not enough data for a full block, cache it. + */ + if( ( ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding && + ilen <= block_size - ctx->unprocessed_len ) || + ( ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding && + ilen < block_size - ctx->unprocessed_len ) || + ( ctx->operation == MBEDTLS_ENCRYPT && + ilen < block_size - ctx->unprocessed_len ) ) + { + memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, + ilen ); + + ctx->unprocessed_len += ilen; + return( 0 ); + } + + /* + * Process cached data first + */ + if( 0 != ctx->unprocessed_len ) + { + copy_len = block_size - ctx->unprocessed_len; + + memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, + copy_len ); + + if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, + ctx->operation, block_size, ctx->iv, + ctx->unprocessed_data, output ) ) ) + { + return( ret ); + } + + *olen += block_size; + output += block_size; + ctx->unprocessed_len = 0; + + input += copy_len; + ilen -= copy_len; + } + + /* + * Cache final, incomplete block + */ + if( 0 != ilen ) + { + if( 0 == block_size ) + { + return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT ); + } + + /* Encryption: only cache partial blocks + * Decryption w/ padding: always keep at least one whole block + * Decryption w/o padding: only cache partial blocks + */ + copy_len = ilen % block_size; + if( copy_len == 0 && + ctx->operation == MBEDTLS_DECRYPT && + NULL != ctx->add_padding) + { + copy_len = block_size; + } + + memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), + copy_len ); + + ctx->unprocessed_len += copy_len; + ilen -= copy_len; + } + + /* + * Process remaining full blocks + */ + if( ilen ) + { + if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, + ctx->operation, ilen, ctx->iv, input, output ) ) ) + { + return( ret ); + } + + *olen += ilen; + } + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) + if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB ) + { + if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx, + ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv, + input, output ) ) ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_OFB) + if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB ) + { + if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx, + ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) + if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR ) + { + if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx, + ilen, &ctx->unprocessed_len, ctx->iv, + ctx->unprocessed_data, input, output ) ) ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_CIPHER_MODE_XTS) + if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS ) + { + if( ctx->unprocessed_len > 0 ) { + /* We can only process an entire data unit at a time. */ + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + } + + ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx, + ctx->operation, ilen, ctx->iv, input, output ); + if( ret != 0 ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM ) + { + if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx, + ilen, input, output ) ) ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_STREAM */ + + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) +#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) +/* + * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len + */ +static void add_pkcs_padding( unsigned char *output, size_t output_len, + size_t data_len ) +{ + size_t padding_len = output_len - data_len; + unsigned char i; + + for( i = 0; i < padding_len; i++ ) + output[data_len + i] = (unsigned char) padding_len; +} + +static int get_pkcs_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i, pad_idx; + unsigned char padding_len, bad = 0; + + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + padding_len = input[input_len - 1]; + *data_len = input_len - padding_len; + + /* Avoid logical || since it results in a branch */ + bad |= padding_len > input_len; + bad |= padding_len == 0; + + /* The number of bytes checked must be independent of padding_len, + * so pick input_len, which is usually 8 or 16 (one block) */ + pad_idx = input_len - padding_len; + for( i = 0; i < input_len; i++ ) + bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx ); + + return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); +} +#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ + +#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) +/* + * One and zeros padding: fill with 80 00 ... 00 + */ +static void add_one_and_zeros_padding( unsigned char *output, + size_t output_len, size_t data_len ) +{ + size_t padding_len = output_len - data_len; + unsigned char i = 0; + + output[data_len] = 0x80; + for( i = 1; i < padding_len; i++ ) + output[data_len + i] = 0x00; +} + +static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i; + unsigned char done = 0, prev_done, bad; + + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + bad = 0x80; + *data_len = 0; + for( i = input_len; i > 0; i-- ) + { + prev_done = done; + done |= ( input[i - 1] != 0 ); + *data_len |= ( i - 1 ) * ( done != prev_done ); + bad ^= input[i - 1] * ( done != prev_done ); + } + + return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); + +} +#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ + +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) +/* + * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length + */ +static void add_zeros_and_len_padding( unsigned char *output, + size_t output_len, size_t data_len ) +{ + size_t padding_len = output_len - data_len; + unsigned char i = 0; + + for( i = 1; i < padding_len; i++ ) + output[data_len + i - 1] = 0x00; + output[output_len - 1] = (unsigned char) padding_len; +} + +static int get_zeros_and_len_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i, pad_idx; + unsigned char padding_len, bad = 0; + + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + padding_len = input[input_len - 1]; + *data_len = input_len - padding_len; + + /* Avoid logical || since it results in a branch */ + bad |= padding_len > input_len; + bad |= padding_len == 0; + + /* The number of bytes checked must be independent of padding_len */ + pad_idx = input_len - padding_len; + for( i = 0; i < input_len - 1; i++ ) + bad |= input[i] * ( i >= pad_idx ); + + return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); +} +#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ + +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) +/* + * Zero padding: fill with 00 ... 00 + */ +static void add_zeros_padding( unsigned char *output, + size_t output_len, size_t data_len ) +{ + size_t i; + + for( i = data_len; i < output_len; i++ ) + output[i] = 0x00; +} + +static int get_zeros_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i; + unsigned char done = 0, prev_done; + + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + *data_len = 0; + for( i = input_len; i > 0; i-- ) + { + prev_done = done; + done |= ( input[i-1] != 0 ); + *data_len |= i * ( done != prev_done ); + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ + +/* + * No padding: don't pad :) + * + * There is no add_padding function (check for NULL in mbedtls_cipher_finish) + * but a trivial get_padding function + */ +static int get_no_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + *data_len = input_len; + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + +int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, + unsigned char *output, size_t *olen ) +{ + CIPHER_VALIDATE_RET( ctx != NULL ); + CIPHER_VALIDATE_RET( output != NULL ); + CIPHER_VALIDATE_RET( olen != NULL ); + if( ctx->cipher_info == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if( ctx->psa_enabled == 1 ) + { + /* While PSA Crypto has an API for multipart + * operations, we currently don't make it + * accessible through the cipher layer. */ + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + + *olen = 0; + + if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode || + MBEDTLS_MODE_OFB == ctx->cipher_info->mode || + MBEDTLS_MODE_CTR == ctx->cipher_info->mode || + MBEDTLS_MODE_GCM == ctx->cipher_info->mode || + MBEDTLS_MODE_XTS == ctx->cipher_info->mode || + MBEDTLS_MODE_STREAM == ctx->cipher_info->mode ) + { + return( 0 ); + } + + if ( ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) || + ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) ) + { + return( 0 ); + } + + if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode ) + { + if( ctx->unprocessed_len != 0 ) + return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + + return( 0 ); + } + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode ) + { + int ret = 0; + + if( MBEDTLS_ENCRYPT == ctx->operation ) + { + /* check for 'no padding' mode */ + if( NULL == ctx->add_padding ) + { + if( 0 != ctx->unprocessed_len ) + return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + + return( 0 ); + } + + ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ), + ctx->unprocessed_len ); + } + else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len ) + { + /* + * For decrypt operations, expect a full block, + * or an empty block if no padding + */ + if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len ) + return( 0 ); + + return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + } + + /* cipher block */ + if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, + ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv, + ctx->unprocessed_data, output ) ) ) + { + return( ret ); + } + + /* Set output size for decryption */ + if( MBEDTLS_DECRYPT == ctx->operation ) + return( ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ), + olen ) ); + + /* Set output size for encryption */ + *olen = mbedtls_cipher_get_block_size( ctx ); + return( 0 ); + } +#else + ((void) output); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) +int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, + mbedtls_cipher_padding_t mode ) +{ + CIPHER_VALIDATE_RET( ctx != NULL ); + + if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if( ctx->psa_enabled == 1 ) + { + /* While PSA Crypto knows about CBC padding + * schemes, we currently don't make them + * accessible through the cipher layer. */ + if( mode != MBEDTLS_PADDING_NONE ) + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + + return( 0 ); + } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + + switch( mode ) + { +#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) + case MBEDTLS_PADDING_PKCS7: + ctx->add_padding = add_pkcs_padding; + ctx->get_padding = get_pkcs_padding; + break; +#endif +#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) + case MBEDTLS_PADDING_ONE_AND_ZEROS: + ctx->add_padding = add_one_and_zeros_padding; + ctx->get_padding = get_one_and_zeros_padding; + break; +#endif +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) + case MBEDTLS_PADDING_ZEROS_AND_LEN: + ctx->add_padding = add_zeros_and_len_padding; + ctx->get_padding = get_zeros_and_len_padding; + break; +#endif +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) + case MBEDTLS_PADDING_ZEROS: + ctx->add_padding = add_zeros_padding; + ctx->get_padding = get_zeros_padding; + break; +#endif + case MBEDTLS_PADDING_NONE: + ctx->add_padding = NULL; + ctx->get_padding = get_no_padding; + break; + + default: + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, + unsigned char *tag, size_t tag_len ) +{ + CIPHER_VALIDATE_RET( ctx != NULL ); + CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); + if( ctx->cipher_info == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( MBEDTLS_ENCRYPT != ctx->operation ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if( ctx->psa_enabled == 1 ) + { + /* While PSA Crypto has an API for multipart + * operations, we currently don't make it + * accessible through the cipher layer. */ + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + + return( 0 ); + } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +#if defined(MBEDTLS_GCM_C) + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, + tag, tag_len ) ); +#endif + +#if defined(MBEDTLS_CHACHAPOLY_C) + if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) + { + /* Don't allow truncated MAC for Poly1305 */ + if ( tag_len != 16U ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + return( mbedtls_chachapoly_finish( + (mbedtls_chachapoly_context*) ctx->cipher_ctx, tag ) ); + } +#endif + + return( 0 ); +} + +int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, + const unsigned char *tag, size_t tag_len ) +{ + unsigned char check_tag[16]; + int ret; + + CIPHER_VALIDATE_RET( ctx != NULL ); + CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); + if( ctx->cipher_info == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( MBEDTLS_DECRYPT != ctx->operation ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if( ctx->psa_enabled == 1 ) + { + /* While PSA Crypto has an API for multipart + * operations, we currently don't make it + * accessible through the cipher layer. */ + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +#if defined(MBEDTLS_GCM_C) + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + { + if( tag_len > sizeof( check_tag ) ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( 0 != ( ret = mbedtls_gcm_finish( + (mbedtls_gcm_context *) ctx->cipher_ctx, + check_tag, tag_len ) ) ) + { + return( ret ); + } + + /* Check the tag in "constant-time" */ + if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) + return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); + + return( 0 ); + } +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CHACHAPOLY_C) + if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) + { + /* Don't allow truncated MAC for Poly1305 */ + if ( tag_len != sizeof( check_tag ) ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + ret = mbedtls_chachapoly_finish( + (mbedtls_chachapoly_context*) ctx->cipher_ctx, check_tag ); + if ( ret != 0 ) + { + return( ret ); + } + + /* Check the tag in "constant-time" */ + if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) + return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); + + return( 0 ); + } +#endif /* MBEDTLS_CHACHAPOLY_C */ + + return( 0 ); +} +#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ + +/* + * Packet-oriented wrapper for non-AEAD modes + */ +int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen ) +{ + int ret; + size_t finish_olen; + + CIPHER_VALIDATE_RET( ctx != NULL ); + CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); + CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); + CIPHER_VALIDATE_RET( output != NULL ); + CIPHER_VALIDATE_RET( olen != NULL ); + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if( ctx->psa_enabled == 1 ) + { + /* As in the non-PSA case, we don't check that + * a key has been set. If not, the key slot will + * still be in its default state of 0, which is + * guaranteed to be invalid, hence the PSA-call + * below will gracefully fail. */ + mbedtls_cipher_context_psa * const cipher_psa = + (mbedtls_cipher_context_psa *) ctx->cipher_ctx; + + psa_status_t status; + psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT; + size_t part_len; + + if( ctx->operation == MBEDTLS_DECRYPT ) + { + status = psa_cipher_decrypt_setup( &cipher_op, + cipher_psa->slot, + cipher_psa->alg ); + } + else if( ctx->operation == MBEDTLS_ENCRYPT ) + { + status = psa_cipher_encrypt_setup( &cipher_op, + cipher_psa->slot, + cipher_psa->alg ); + } + else + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + /* In the following, we can immediately return on an error, + * because the PSA Crypto API guarantees that cipher operations + * are terminated by unsuccessful calls to psa_cipher_update(), + * and by any call to psa_cipher_finish(). */ + if( status != PSA_SUCCESS ) + return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); + + status = psa_cipher_set_iv( &cipher_op, iv, iv_len ); + if( status != PSA_SUCCESS ) + return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); + + status = psa_cipher_update( &cipher_op, + input, ilen, + output, ilen, olen ); + if( status != PSA_SUCCESS ) + return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); + + status = psa_cipher_finish( &cipher_op, + output + *olen, ilen - *olen, + &part_len ); + if( status != PSA_SUCCESS ) + return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); + + *olen += part_len; + return( 0 ); + } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + + if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_update( ctx, input, ilen, + output, olen ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, + &finish_olen ) ) != 0 ) + return( ret ); + + *olen += finish_olen; + + return( 0 ); +} + +#if defined(MBEDTLS_CIPHER_MODE_AEAD) +/* + * Packet-oriented encryption for AEAD modes + */ +int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + unsigned char *tag, size_t tag_len ) +{ + CIPHER_VALIDATE_RET( ctx != NULL ); + CIPHER_VALIDATE_RET( iv != NULL ); + CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); + CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); + CIPHER_VALIDATE_RET( output != NULL ); + CIPHER_VALIDATE_RET( olen != NULL ); + CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if( ctx->psa_enabled == 1 ) + { + /* As in the non-PSA case, we don't check that + * a key has been set. If not, the key slot will + * still be in its default state of 0, which is + * guaranteed to be invalid, hence the PSA-call + * below will gracefully fail. */ + mbedtls_cipher_context_psa * const cipher_psa = + (mbedtls_cipher_context_psa *) ctx->cipher_ctx; + + psa_status_t status; + + /* PSA Crypto API always writes the authentication tag + * at the end of the encrypted message. */ + if( tag != output + ilen ) + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + + status = psa_aead_encrypt( cipher_psa->slot, + cipher_psa->alg, + iv, iv_len, + ad, ad_len, + input, ilen, + output, ilen + tag_len, olen ); + if( status != PSA_SUCCESS ) + return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); + + *olen -= tag_len; + return( 0 ); + } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +#if defined(MBEDTLS_GCM_C) + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + { + *olen = ilen; + return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, + ilen, iv, iv_len, ad, ad_len, + input, output, tag_len, tag ) ); + } +#endif /* MBEDTLS_GCM_C */ +#if defined(MBEDTLS_CCM_C) + if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) + { + *olen = ilen; + return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, input, output, + tag, tag_len ) ); + } +#endif /* MBEDTLS_CCM_C */ +#if defined(MBEDTLS_CHACHAPOLY_C) + if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) + { + /* ChachaPoly has fixed length nonce and MAC (tag) */ + if ( ( iv_len != ctx->cipher_info->iv_size ) || + ( tag_len != 16U ) ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + *olen = ilen; + return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx, + ilen, iv, ad, ad_len, input, output, tag ) ); + } +#endif /* MBEDTLS_CHACHAPOLY_C */ +#if defined(MBEDTLS_NIST_KW_C) + if( MBEDTLS_MODE_KW == ctx->cipher_info->mode || + MBEDTLS_MODE_KWP == ctx->cipher_info->mode ) + { + mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ? + MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP; + + /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */ + if( iv_len != 0 || tag_len != 0 || ad_len != 0 ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + return( mbedtls_nist_kw_wrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) ); + } +#endif /* MBEDTLS_NIST_KW_C */ + + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} + +/* + * Packet-oriented decryption for AEAD modes + */ +int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + const unsigned char *tag, size_t tag_len ) +{ + CIPHER_VALIDATE_RET( ctx != NULL ); + CIPHER_VALIDATE_RET( iv != NULL ); + CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); + CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); + CIPHER_VALIDATE_RET( output != NULL ); + CIPHER_VALIDATE_RET( olen != NULL ); + CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if( ctx->psa_enabled == 1 ) + { + /* As in the non-PSA case, we don't check that + * a key has been set. If not, the key slot will + * still be in its default state of 0, which is + * guaranteed to be invalid, hence the PSA-call + * below will gracefully fail. */ + mbedtls_cipher_context_psa * const cipher_psa = + (mbedtls_cipher_context_psa *) ctx->cipher_ctx; + + psa_status_t status; + + /* PSA Crypto API always writes the authentication tag + * at the end of the encrypted message. */ + if( tag != input + ilen ) + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + + status = psa_aead_decrypt( cipher_psa->slot, + cipher_psa->alg, + iv, iv_len, + ad, ad_len, + input, ilen + tag_len, + output, ilen, olen ); + if( status == PSA_ERROR_INVALID_SIGNATURE ) + return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); + else if( status != PSA_SUCCESS ) + return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); + + return( 0 ); + } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +#if defined(MBEDTLS_GCM_C) + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + { + int ret; + + *olen = ilen; + ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, + tag, tag_len, input, output ); + + if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED ) + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + + return( ret ); + } +#endif /* MBEDTLS_GCM_C */ +#if defined(MBEDTLS_CCM_C) + if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) + { + int ret; + + *olen = ilen; + ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, + input, output, tag, tag_len ); + + if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED ) + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + + return( ret ); + } +#endif /* MBEDTLS_CCM_C */ +#if defined(MBEDTLS_CHACHAPOLY_C) + if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) + { + int ret; + + /* ChachaPoly has fixed length nonce and MAC (tag) */ + if ( ( iv_len != ctx->cipher_info->iv_size ) || + ( tag_len != 16U ) ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + *olen = ilen; + ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen, + iv, ad, ad_len, tag, input, output ); + + if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ) + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + + return( ret ); + } +#endif /* MBEDTLS_CHACHAPOLY_C */ +#if defined(MBEDTLS_NIST_KW_C) + if( MBEDTLS_MODE_KW == ctx->cipher_info->mode || + MBEDTLS_MODE_KWP == ctx->cipher_info->mode ) + { + mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ? + MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP; + + /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */ + if( iv_len != 0 || tag_len != 0 || ad_len != 0 ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + return( mbedtls_nist_kw_unwrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) ); + } +#endif /* MBEDTLS_NIST_KW_C */ + + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} +#endif /* MBEDTLS_CIPHER_MODE_AEAD */ + +#endif /* MBEDTLS_CIPHER_C */ diff --git a/mbed_aes_gcm/cipher.h b/mbed_aes_gcm/cipher.h new file mode 100644 index 0000000..ea00703 --- /dev/null +++ b/mbed_aes_gcm/cipher.h @@ -0,0 +1,926 @@ +/** + * \file cipher.h + * + * \brief This file contains an abstraction interface for use with the cipher + * primitives provided by the library. It provides a common interface to all of + * the available cipher operations. + * + * \author Adriaan de Jong + */ +/* + * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of Mbed TLS (https://tls.mbed.org) + */ + +#ifndef MBEDTLS_CIPHER_H +#define MBEDTLS_CIPHER_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include +#include "platform_util.h" + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +#define MBEDTLS_CIPHER_MODE_AEAD +#endif + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#define MBEDTLS_CIPHER_MODE_WITH_PADDING +#endif + +#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \ + defined(MBEDTLS_CHACHA20_C) +#define MBEDTLS_CIPHER_MODE_STREAM +#endif + +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + +#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */ +#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters. */ +#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */ +#define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */ +#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */ +#define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */ +#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 /**< The context is invalid. For example, because it was freed. */ + +/* MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED is deprecated and should not be used. */ +#define MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED -0x6400 /**< Cipher hardware accelerator failed. */ + +#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length. */ +#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Supported cipher types. + * + * \warning RC4 and DES are considered weak ciphers and their use + * constitutes a security risk. Arm recommends considering stronger + * ciphers instead. + */ +typedef enum { + MBEDTLS_CIPHER_ID_NONE = 0, /**< Placeholder to mark the end of cipher ID lists. */ + MBEDTLS_CIPHER_ID_NULL, /**< The identity cipher, treated as a stream cipher. */ + MBEDTLS_CIPHER_ID_AES, /**< The AES cipher. */ + MBEDTLS_CIPHER_ID_DES, /**< The DES cipher. */ + MBEDTLS_CIPHER_ID_3DES, /**< The Triple DES cipher. */ + MBEDTLS_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */ + MBEDTLS_CIPHER_ID_BLOWFISH, /**< The Blowfish cipher. */ + MBEDTLS_CIPHER_ID_ARC4, /**< The RC4 cipher. */ + MBEDTLS_CIPHER_ID_ARIA, /**< The Aria cipher. */ + MBEDTLS_CIPHER_ID_CHACHA20, /**< The ChaCha20 cipher. */ +} mbedtls_cipher_id_t; + +/** + * \brief Supported {cipher type, cipher mode} pairs. + * + * \warning RC4 and DES are considered weak ciphers and their use + * constitutes a security risk. Arm recommends considering stronger + * ciphers instead. + */ +typedef enum { + MBEDTLS_CIPHER_NONE = 0, /**< Placeholder to mark the end of cipher-pair lists. */ + MBEDTLS_CIPHER_NULL, /**< The identity stream cipher. */ + MBEDTLS_CIPHER_AES_128_ECB, /**< AES cipher with 128-bit ECB mode. */ + MBEDTLS_CIPHER_AES_192_ECB, /**< AES cipher with 192-bit ECB mode. */ + MBEDTLS_CIPHER_AES_256_ECB, /**< AES cipher with 256-bit ECB mode. */ + MBEDTLS_CIPHER_AES_128_CBC, /**< AES cipher with 128-bit CBC mode. */ + MBEDTLS_CIPHER_AES_192_CBC, /**< AES cipher with 192-bit CBC mode. */ + MBEDTLS_CIPHER_AES_256_CBC, /**< AES cipher with 256-bit CBC mode. */ + MBEDTLS_CIPHER_AES_128_CFB128, /**< AES cipher with 128-bit CFB128 mode. */ + MBEDTLS_CIPHER_AES_192_CFB128, /**< AES cipher with 192-bit CFB128 mode. */ + MBEDTLS_CIPHER_AES_256_CFB128, /**< AES cipher with 256-bit CFB128 mode. */ + MBEDTLS_CIPHER_AES_128_CTR, /**< AES cipher with 128-bit CTR mode. */ + MBEDTLS_CIPHER_AES_192_CTR, /**< AES cipher with 192-bit CTR mode. */ + MBEDTLS_CIPHER_AES_256_CTR, /**< AES cipher with 256-bit CTR mode. */ + MBEDTLS_CIPHER_AES_128_GCM, /**< AES cipher with 128-bit GCM mode. */ + MBEDTLS_CIPHER_AES_192_GCM, /**< AES cipher with 192-bit GCM mode. */ + MBEDTLS_CIPHER_AES_256_GCM, /**< AES cipher with 256-bit GCM mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_ECB, /**< Camellia cipher with 128-bit ECB mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_ECB, /**< Camellia cipher with 192-bit ECB mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_ECB, /**< Camellia cipher with 256-bit ECB mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_CBC, /**< Camellia cipher with 128-bit CBC mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_CBC, /**< Camellia cipher with 192-bit CBC mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_CBC, /**< Camellia cipher with 256-bit CBC mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_CFB128, /**< Camellia cipher with 128-bit CFB128 mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_CFB128, /**< Camellia cipher with 192-bit CFB128 mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_CFB128, /**< Camellia cipher with 256-bit CFB128 mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_CTR, /**< Camellia cipher with 128-bit CTR mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_CTR, /**< Camellia cipher with 192-bit CTR mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_CTR, /**< Camellia cipher with 256-bit CTR mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_GCM, /**< Camellia cipher with 128-bit GCM mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_GCM, /**< Camellia cipher with 192-bit GCM mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_GCM, /**< Camellia cipher with 256-bit GCM mode. */ + MBEDTLS_CIPHER_DES_ECB, /**< DES cipher with ECB mode. */ + MBEDTLS_CIPHER_DES_CBC, /**< DES cipher with CBC mode. */ + MBEDTLS_CIPHER_DES_EDE_ECB, /**< DES cipher with EDE ECB mode. */ + MBEDTLS_CIPHER_DES_EDE_CBC, /**< DES cipher with EDE CBC mode. */ + MBEDTLS_CIPHER_DES_EDE3_ECB, /**< DES cipher with EDE3 ECB mode. */ + MBEDTLS_CIPHER_DES_EDE3_CBC, /**< DES cipher with EDE3 CBC mode. */ + MBEDTLS_CIPHER_BLOWFISH_ECB, /**< Blowfish cipher with ECB mode. */ + MBEDTLS_CIPHER_BLOWFISH_CBC, /**< Blowfish cipher with CBC mode. */ + MBEDTLS_CIPHER_BLOWFISH_CFB64, /**< Blowfish cipher with CFB64 mode. */ + MBEDTLS_CIPHER_BLOWFISH_CTR, /**< Blowfish cipher with CTR mode. */ + MBEDTLS_CIPHER_ARC4_128, /**< RC4 cipher with 128-bit mode. */ + MBEDTLS_CIPHER_AES_128_CCM, /**< AES cipher with 128-bit CCM mode. */ + MBEDTLS_CIPHER_AES_192_CCM, /**< AES cipher with 192-bit CCM mode. */ + MBEDTLS_CIPHER_AES_256_CCM, /**< AES cipher with 256-bit CCM mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_CCM, /**< Camellia cipher with 128-bit CCM mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_CCM, /**< Camellia cipher with 192-bit CCM mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_CCM, /**< Camellia cipher with 256-bit CCM mode. */ + MBEDTLS_CIPHER_ARIA_128_ECB, /**< Aria cipher with 128-bit key and ECB mode. */ + MBEDTLS_CIPHER_ARIA_192_ECB, /**< Aria cipher with 192-bit key and ECB mode. */ + MBEDTLS_CIPHER_ARIA_256_ECB, /**< Aria cipher with 256-bit key and ECB mode. */ + MBEDTLS_CIPHER_ARIA_128_CBC, /**< Aria cipher with 128-bit key and CBC mode. */ + MBEDTLS_CIPHER_ARIA_192_CBC, /**< Aria cipher with 192-bit key and CBC mode. */ + MBEDTLS_CIPHER_ARIA_256_CBC, /**< Aria cipher with 256-bit key and CBC mode. */ + MBEDTLS_CIPHER_ARIA_128_CFB128, /**< Aria cipher with 128-bit key and CFB-128 mode. */ + MBEDTLS_CIPHER_ARIA_192_CFB128, /**< Aria cipher with 192-bit key and CFB-128 mode. */ + MBEDTLS_CIPHER_ARIA_256_CFB128, /**< Aria cipher with 256-bit key and CFB-128 mode. */ + MBEDTLS_CIPHER_ARIA_128_CTR, /**< Aria cipher with 128-bit key and CTR mode. */ + MBEDTLS_CIPHER_ARIA_192_CTR, /**< Aria cipher with 192-bit key and CTR mode. */ + MBEDTLS_CIPHER_ARIA_256_CTR, /**< Aria cipher with 256-bit key and CTR mode. */ + MBEDTLS_CIPHER_ARIA_128_GCM, /**< Aria cipher with 128-bit key and GCM mode. */ + MBEDTLS_CIPHER_ARIA_192_GCM, /**< Aria cipher with 192-bit key and GCM mode. */ + MBEDTLS_CIPHER_ARIA_256_GCM, /**< Aria cipher with 256-bit key and GCM mode. */ + MBEDTLS_CIPHER_ARIA_128_CCM, /**< Aria cipher with 128-bit key and CCM mode. */ + MBEDTLS_CIPHER_ARIA_192_CCM, /**< Aria cipher with 192-bit key and CCM mode. */ + MBEDTLS_CIPHER_ARIA_256_CCM, /**< Aria cipher with 256-bit key and CCM mode. */ + MBEDTLS_CIPHER_AES_128_OFB, /**< AES 128-bit cipher in OFB mode. */ + MBEDTLS_CIPHER_AES_192_OFB, /**< AES 192-bit cipher in OFB mode. */ + MBEDTLS_CIPHER_AES_256_OFB, /**< AES 256-bit cipher in OFB mode. */ + MBEDTLS_CIPHER_AES_128_XTS, /**< AES 128-bit cipher in XTS block mode. */ + MBEDTLS_CIPHER_AES_256_XTS, /**< AES 256-bit cipher in XTS block mode. */ + MBEDTLS_CIPHER_CHACHA20, /**< ChaCha20 stream cipher. */ + MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< ChaCha20-Poly1305 AEAD cipher. */ + MBEDTLS_CIPHER_AES_128_KW, /**< AES cipher with 128-bit NIST KW mode. */ + MBEDTLS_CIPHER_AES_192_KW, /**< AES cipher with 192-bit NIST KW mode. */ + MBEDTLS_CIPHER_AES_256_KW, /**< AES cipher with 256-bit NIST KW mode. */ + MBEDTLS_CIPHER_AES_128_KWP, /**< AES cipher with 128-bit NIST KWP mode. */ + MBEDTLS_CIPHER_AES_192_KWP, /**< AES cipher with 192-bit NIST KWP mode. */ + MBEDTLS_CIPHER_AES_256_KWP, /**< AES cipher with 256-bit NIST KWP mode. */ +} mbedtls_cipher_type_t; + +/** Supported cipher modes. */ +typedef enum { + MBEDTLS_MODE_NONE = 0, /**< None. */ + MBEDTLS_MODE_ECB, /**< The ECB cipher mode. */ + MBEDTLS_MODE_CBC, /**< The CBC cipher mode. */ + MBEDTLS_MODE_CFB, /**< The CFB cipher mode. */ + MBEDTLS_MODE_OFB, /**< The OFB cipher mode. */ + MBEDTLS_MODE_CTR, /**< The CTR cipher mode. */ + MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */ + MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */ + MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */ + MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */ + MBEDTLS_MODE_CHACHAPOLY, /**< The ChaCha-Poly cipher mode. */ + MBEDTLS_MODE_KW, /**< The SP800-38F KW mode */ + MBEDTLS_MODE_KWP, /**< The SP800-38F KWP mode */ +} mbedtls_cipher_mode_t; + +/** Supported cipher padding types. */ +typedef enum { + MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default). */ + MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding. */ + MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding. */ + MBEDTLS_PADDING_ZEROS, /**< Zero padding (not reversible). */ + MBEDTLS_PADDING_NONE, /**< Never pad (full blocks only). */ +} mbedtls_cipher_padding_t; + +/** Type of operation. */ +typedef enum { + MBEDTLS_OPERATION_NONE = -1, + MBEDTLS_DECRYPT = 0, + MBEDTLS_ENCRYPT, +} mbedtls_operation_t; + +enum { + /** Undefined key length. */ + MBEDTLS_KEY_LENGTH_NONE = 0, + /** Key length, in bits (including parity), for DES keys. */ + MBEDTLS_KEY_LENGTH_DES = 64, + /** Key length in bits, including parity, for DES in two-key EDE. */ + MBEDTLS_KEY_LENGTH_DES_EDE = 128, + /** Key length in bits, including parity, for DES in three-key EDE. */ + MBEDTLS_KEY_LENGTH_DES_EDE3 = 192, +}; + +/** Maximum length of any IV, in Bytes. */ +#define MBEDTLS_MAX_IV_LENGTH 16 +/** Maximum block size of any cipher, in Bytes. */ +#define MBEDTLS_MAX_BLOCK_LENGTH 16 + +/** + * Base cipher information (opaque struct). + */ +typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t; + +/** + * CMAC context (opaque struct). + */ +typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t; + +/** + * Cipher information. Allows calling cipher functions + * in a generic way. + */ +typedef struct mbedtls_cipher_info_t +{ + /** Full cipher identifier. For example, + * MBEDTLS_CIPHER_AES_256_CBC. + */ + mbedtls_cipher_type_t type; + + /** The cipher mode. For example, MBEDTLS_MODE_CBC. */ + mbedtls_cipher_mode_t mode; + + /** The cipher key length, in bits. This is the + * default length for variable sized ciphers. + * Includes parity bits for ciphers like DES. + */ + unsigned int key_bitlen; + + /** Name of the cipher. */ + const char * name; + + /** IV or nonce size, in Bytes. + * For ciphers that accept variable IV sizes, + * this is the recommended size. + */ + unsigned int iv_size; + + /** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and + * MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the + * cipher supports variable IV or variable key sizes, respectively. + */ + int flags; + + /** The block size, in Bytes. */ + unsigned int block_size; + + /** Struct for base cipher information and functions. */ + const mbedtls_cipher_base_t *base; + +} mbedtls_cipher_info_t; + +/** + * Generic cipher context. + */ +typedef struct mbedtls_cipher_context_t +{ + /** Information about the associated cipher. */ + const mbedtls_cipher_info_t *cipher_info; + + /** Key length to use. */ + int key_bitlen; + + /** Operation that the key of the context has been + * initialized for. + */ + mbedtls_operation_t operation; + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) + /** Padding functions to use, if relevant for + * the specific cipher mode. + */ + void (*add_padding)( unsigned char *output, size_t olen, size_t data_len ); + int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len ); +#endif + + /** Buffer for input that has not been processed yet. */ + unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH]; + + /** Number of Bytes that have not been processed yet. */ + size_t unprocessed_len; + + /** Current IV or NONCE_COUNTER for CTR-mode, data unit (or sector) number + * for XTS-mode. */ + unsigned char iv[MBEDTLS_MAX_IV_LENGTH]; + + /** IV size in Bytes, for ciphers with variable-length IVs. */ + size_t iv_size; + + /** The cipher-specific context. */ + void *cipher_ctx; + +#if defined(MBEDTLS_CMAC_C) + /** CMAC-specific context. */ + mbedtls_cmac_context_t *cmac_ctx; +#endif + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + /** Indicates whether the cipher operations should be performed + * by Mbed TLS' own crypto library or an external implementation + * of the PSA Crypto API. + * This is unset if the cipher context was established through + * mbedtls_cipher_setup(), and set if it was established through + * mbedtls_cipher_setup_psa(). + */ + unsigned char psa_enabled; +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +} mbedtls_cipher_context_t; + +/** + * \brief This function retrieves the list of ciphers supported + * by the generic cipher module. + * + * For any cipher identifier in the returned list, you can + * obtain the corresponding generic cipher information structure + * via mbedtls_cipher_info_from_type(), which can then be used + * to prepare a cipher context via mbedtls_cipher_setup(). + * + * + * \return A statically-allocated array of cipher identifiers + * of type cipher_type_t. The last entry is zero. + */ +const int *mbedtls_cipher_list( void ); + +/** + * \brief This function retrieves the cipher-information + * structure associated with the given cipher name. + * + * \param cipher_name Name of the cipher to search for. This must not be + * \c NULL. + * + * \return The cipher information structure associated with the + * given \p cipher_name. + * \return \c NULL if the associated cipher information is not found. + */ +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name ); + +/** + * \brief This function retrieves the cipher-information + * structure associated with the given cipher type. + * + * \param cipher_type Type of the cipher to search for. + * + * \return The cipher information structure associated with the + * given \p cipher_type. + * \return \c NULL if the associated cipher information is not found. + */ +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type ); + +/** + * \brief This function retrieves the cipher-information + * structure associated with the given cipher ID, + * key size and mode. + * + * \param cipher_id The ID of the cipher to search for. For example, + * #MBEDTLS_CIPHER_ID_AES. + * \param key_bitlen The length of the key in bits. + * \param mode The cipher mode. For example, #MBEDTLS_MODE_CBC. + * + * \return The cipher information structure associated with the + * given \p cipher_id. + * \return \c NULL if the associated cipher information is not found. + */ +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id, + int key_bitlen, + const mbedtls_cipher_mode_t mode ); + +/** + * \brief This function initializes a \p cipher_context as NONE. + * + * \param ctx The context to be initialized. This must not be \c NULL. + */ +void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ); + +/** + * \brief This function frees and clears the cipher-specific + * context of \p ctx. Freeing \p ctx itself remains the + * responsibility of the caller. + * + * \param ctx The context to be freed. If this is \c NULL, the + * function has no effect, otherwise this must point to an + * initialized context. + */ +void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ); + + +/** + * \brief This function initializes a cipher context for + * use with the given cipher primitive. + * + * \param ctx The context to initialize. This must be initialized. + * \param cipher_info The cipher to use. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the + * cipher-specific context fails. + * + * \internal Currently, the function also clears the structure. + * In future versions, the caller will be required to call + * mbedtls_cipher_init() on the structure first. + */ +int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, + const mbedtls_cipher_info_t *cipher_info ); + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +/** + * \brief This function initializes a cipher context for + * PSA-based use with the given cipher primitive. + * + * \note See #MBEDTLS_USE_PSA_CRYPTO for information on PSA. + * + * \param ctx The context to initialize. May not be \c NULL. + * \param cipher_info The cipher to use. + * \param taglen For AEAD ciphers, the length in bytes of the + * authentication tag to use. Subsequent uses of + * mbedtls_cipher_auth_encrypt() or + * mbedtls_cipher_auth_decrypt() must provide + * the same tag length. + * For non-AEAD ciphers, the value must be \c 0. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the + * cipher-specific context fails. + */ +int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx, + const mbedtls_cipher_info_t *cipher_info, + size_t taglen ); +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +/** + * \brief This function returns the block size of the given cipher. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The block size of the underlying cipher. + * \return \c 0 if \p ctx has not been initialized. + */ +static inline unsigned int mbedtls_cipher_get_block_size( + const mbedtls_cipher_context_t *ctx ) +{ + MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 ); + if( ctx->cipher_info == NULL ) + return 0; + + return ctx->cipher_info->block_size; +} + +/** + * \brief This function returns the mode of operation for + * the cipher. For example, MBEDTLS_MODE_CBC. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The mode of operation. + * \return #MBEDTLS_MODE_NONE if \p ctx has not been initialized. + */ +static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( + const mbedtls_cipher_context_t *ctx ) +{ + MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, MBEDTLS_MODE_NONE ); + if( ctx->cipher_info == NULL ) + return MBEDTLS_MODE_NONE; + + return ctx->cipher_info->mode; +} + +/** + * \brief This function returns the size of the IV or nonce + * of the cipher, in Bytes. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The recommended IV size if no IV has been set. + * \return \c 0 for ciphers not using an IV or a nonce. + * \return The actual size if an IV has been set. + */ +static inline int mbedtls_cipher_get_iv_size( + const mbedtls_cipher_context_t *ctx ) +{ + MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 ); + if( ctx->cipher_info == NULL ) + return 0; + + if( ctx->iv_size != 0 ) + return (int) ctx->iv_size; + + return (int) ctx->cipher_info->iv_size; +} + +/** + * \brief This function returns the type of the given cipher. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The type of the cipher. + * \return #MBEDTLS_CIPHER_NONE if \p ctx has not been initialized. + */ +static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( + const mbedtls_cipher_context_t *ctx ) +{ + MBEDTLS_INTERNAL_VALIDATE_RET( + ctx != NULL, MBEDTLS_CIPHER_NONE ); + if( ctx->cipher_info == NULL ) + return MBEDTLS_CIPHER_NONE; + + return ctx->cipher_info->type; +} + +/** + * \brief This function returns the name of the given cipher + * as a string. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The name of the cipher. + * \return NULL if \p ctx has not been not initialized. + */ +static inline const char *mbedtls_cipher_get_name( + const mbedtls_cipher_context_t *ctx ) +{ + MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 ); + if( ctx->cipher_info == NULL ) + return 0; + + return ctx->cipher_info->name; +} + +/** + * \brief This function returns the key length of the cipher. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The key length of the cipher in bits. + * \return #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been + * initialized. + */ +static inline int mbedtls_cipher_get_key_bitlen( + const mbedtls_cipher_context_t *ctx ) +{ + MBEDTLS_INTERNAL_VALIDATE_RET( + ctx != NULL, MBEDTLS_KEY_LENGTH_NONE ); + if( ctx->cipher_info == NULL ) + return MBEDTLS_KEY_LENGTH_NONE; + + return (int) ctx->cipher_info->key_bitlen; +} + +/** + * \brief This function returns the operation of the given cipher. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The type of operation: #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT. + * \return #MBEDTLS_OPERATION_NONE if \p ctx has not been initialized. + */ +static inline mbedtls_operation_t mbedtls_cipher_get_operation( + const mbedtls_cipher_context_t *ctx ) +{ + MBEDTLS_INTERNAL_VALIDATE_RET( + ctx != NULL, MBEDTLS_OPERATION_NONE ); + if( ctx->cipher_info == NULL ) + return MBEDTLS_OPERATION_NONE; + + return ctx->operation; +} + +/** + * \brief This function sets the key to use with the given context. + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a cipher information structure. + * \param key The key to use. This must be a readable buffer of at + * least \p key_bitlen Bits. + * \param key_bitlen The key length to use, in Bits. + * \param operation The operation that the key will be used for: + * #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, + const unsigned char *key, + int key_bitlen, + const mbedtls_operation_t operation ); + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) +/** + * \brief This function sets the padding mode, for cipher modes + * that use padding. + * + * The default passing mode is PKCS7 padding. + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a cipher information structure. + * \param mode The padding mode. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE + * if the selected padding mode is not supported. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode + * does not support padding. + */ +int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, + mbedtls_cipher_padding_t mode ); +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + +/** + * \brief This function sets the initialization vector (IV) + * or nonce. + * + * \note Some ciphers do not use IVs nor nonce. For these + * ciphers, this function has no effect. + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a cipher information structure. + * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. This + * must be a readable buffer of at least \p iv_len Bytes. + * \param iv_len The IV length for ciphers with variable-size IV. + * This parameter is discarded by ciphers with fixed-size IV. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + */ +int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, + size_t iv_len ); + +/** + * \brief This function resets the cipher state. + * + * \param ctx The generic cipher context. This must be initialized. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + */ +int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ); + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +/** + * \brief This function adds additional data for AEAD ciphers. + * Currently supported with GCM and ChaCha20+Poly1305. + * This must be called exactly once, after + * mbedtls_cipher_reset(). + * + * \param ctx The generic cipher context. This must be initialized. + * \param ad The additional data to use. This must be a readable + * buffer of at least \p ad_len Bytes. + * \param ad_len The length of \p ad in Bytes. + * + * \return \c 0 on success. + * \return A specific error code on failure. + */ +int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, + const unsigned char *ad, size_t ad_len ); +#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ + +/** + * \brief The generic cipher update function. It encrypts or + * decrypts using the given cipher context. Writes as + * many block-sized blocks of data as possible to output. + * Any data that cannot be written immediately is either + * added to the next block, or flushed when + * mbedtls_cipher_finish() is called. + * Exception: For MBEDTLS_MODE_ECB, expects a single block + * in size. For example, 16 Bytes for AES. + * + * \note If the underlying cipher is used in GCM mode, all calls + * to this function, except for the last one before + * mbedtls_cipher_finish(), must have \p ilen as a + * multiple of the block size of the cipher. + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a key. + * \param input The buffer holding the input data. This must be a + * readable buffer of at least \p ilen Bytes. + * \param ilen The length of the input data. + * \param output The buffer for the output data. This must be able to + * hold at least `ilen + block_size`. This must not be the + * same buffer as \p input. + * \param olen The length of the output data, to be updated with the + * actual number of Bytes written. This must not be + * \c NULL. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an + * unsupported mode for a cipher. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, + const unsigned char *input, + size_t ilen, unsigned char *output, + size_t *olen ); + +/** + * \brief The generic cipher finalization function. If data still + * needs to be flushed from an incomplete block, the data + * contained in it is padded to the size of + * the last block, and written to the \p output buffer. + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a key. + * \param output The buffer to write data to. This needs to be a writable + * buffer of at least \p block_size Bytes. + * \param olen The length of the data written to the \p output buffer. + * This may not be \c NULL. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption + * expecting a full block but not receiving one. + * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding + * while decrypting. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, + unsigned char *output, size_t *olen ); + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +/** + * \brief This function writes a tag for AEAD ciphers. + * Currently supported with GCM and ChaCha20+Poly1305. + * This must be called after mbedtls_cipher_finish(). + * + * \param ctx The generic cipher context. This must be initialized, + * bound to a key, and have just completed a cipher + * operation through mbedtls_cipher_finish() the tag for + * which should be written. + * \param tag The buffer to write the tag to. This must be a writable + * buffer of at least \p tag_len Bytes. + * \param tag_len The length of the tag to write. + * + * \return \c 0 on success. + * \return A specific error code on failure. + */ +int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, + unsigned char *tag, size_t tag_len ); + +/** + * \brief This function checks the tag for AEAD ciphers. + * Currently supported with GCM and ChaCha20+Poly1305. + * This must be called after mbedtls_cipher_finish(). + * + * \param ctx The generic cipher context. This must be initialized. + * \param tag The buffer holding the tag. This must be a readable + * buffer of at least \p tag_len Bytes. + * \param tag_len The length of the tag to check. + * + * \return \c 0 on success. + * \return A specific error code on failure. + */ +int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, + const unsigned char *tag, size_t tag_len ); +#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ + +/** + * \brief The generic all-in-one encryption/decryption function, + * for all ciphers except AEAD constructs. + * + * \param ctx The generic cipher context. This must be initialized. + * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. + * This must be a readable buffer of at least \p iv_len + * Bytes. + * \param iv_len The IV length for ciphers with variable-size IV. + * This parameter is discarded by ciphers with fixed-size + * IV. + * \param input The buffer holding the input data. This must be a + * readable buffer of at least \p ilen Bytes. + * \param ilen The length of the input data in Bytes. + * \param output The buffer for the output data. This must be able to + * hold at least `ilen + block_size`. This must not be the + * same buffer as \p input. + * \param olen The length of the output data, to be updated with the + * actual number of Bytes written. This must not be + * \c NULL. + * + * \note Some ciphers do not use IVs nor nonce. For these + * ciphers, use \p iv = NULL and \p iv_len = 0. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption + * expecting a full block but not receiving one. + * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding + * while decrypting. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen ); + +#if defined(MBEDTLS_CIPHER_MODE_AEAD) +/** + * \brief The generic autenticated encryption (AEAD) function. + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a key. + * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. + * This must be a readable buffer of at least \p iv_len + * Bytes. + * \param iv_len The IV length for ciphers with variable-size IV. + * This parameter is discarded by ciphers with fixed-size IV. + * \param ad The additional data to authenticate. This must be a + * readable buffer of at least \p ad_len Bytes. + * \param ad_len The length of \p ad. + * \param input The buffer holding the input data. This must be a + * readable buffer of at least \p ilen Bytes. + * \param ilen The length of the input data. + * \param output The buffer for the output data. This must be able to + * hold at least \p ilen Bytes. + * \param olen The length of the output data, to be updated with the + * actual number of Bytes written. This must not be + * \c NULL. + * \param tag The buffer for the authentication tag. This must be a + * writable buffer of at least \p tag_len Bytes. + * \param tag_len The desired length of the authentication tag. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + unsigned char *tag, size_t tag_len ); + +/** + * \brief The generic autenticated decryption (AEAD) function. + * + * \note If the data is not authentic, then the output buffer + * is zeroed out to prevent the unauthentic plaintext being + * used, making this interface safer. + * + * \param ctx The generic cipher context. This must be initialized and + * and bound to a key. + * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. + * This must be a readable buffer of at least \p iv_len + * Bytes. + * \param iv_len The IV length for ciphers with variable-size IV. + * This parameter is discarded by ciphers with fixed-size IV. + * \param ad The additional data to be authenticated. This must be a + * readable buffer of at least \p ad_len Bytes. + * \param ad_len The length of \p ad. + * \param input The buffer holding the input data. This must be a + * readable buffer of at least \p ilen Bytes. + * \param ilen The length of the input data. + * \param output The buffer for the output data. + * This must be able to hold at least \p ilen Bytes. + * \param olen The length of the output data, to be updated with the + * actual number of Bytes written. This must not be + * \c NULL. + * \param tag The buffer holding the authentication tag. This must be + * a readable buffer of at least \p tag_len Bytes. + * \param tag_len The length of the authentication tag. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + const unsigned char *tag, size_t tag_len ); +#endif /* MBEDTLS_CIPHER_MODE_AEAD */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CIPHER_H */ diff --git a/mbed_aes_gcm/cipher_internal.h b/mbed_aes_gcm/cipher_internal.h new file mode 100644 index 0000000..d711339 --- /dev/null +++ b/mbed_aes_gcm/cipher_internal.h @@ -0,0 +1,153 @@ +/** + * \file cipher_internal.h + * + * \brief Cipher wrappers. + * + * \author Adriaan de Jong + */ +/* + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_CIPHER_WRAP_H +#define MBEDTLS_CIPHER_WRAP_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "cipher.h" + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +#include "psa/crypto.h" +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Base cipher information. The non-mode specific functions and values. + */ +struct mbedtls_cipher_base_t +{ + /** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */ + mbedtls_cipher_id_t cipher; + + /** Encrypt using ECB */ + int (*ecb_func)( void *ctx, mbedtls_operation_t mode, + const unsigned char *input, unsigned char *output ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + /** Encrypt using CBC */ + int (*cbc_func)( void *ctx, mbedtls_operation_t mode, size_t length, + unsigned char *iv, const unsigned char *input, + unsigned char *output ); +#endif + +#if defined(MBEDTLS_CIPHER_MODE_CFB) + /** Encrypt using CFB (Full length) */ + int (*cfb_func)( void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off, + unsigned char *iv, const unsigned char *input, + unsigned char *output ); +#endif + +#if defined(MBEDTLS_CIPHER_MODE_OFB) + /** Encrypt using OFB (Full length) */ + int (*ofb_func)( void *ctx, size_t length, size_t *iv_off, + unsigned char *iv, + const unsigned char *input, + unsigned char *output ); +#endif + +#if defined(MBEDTLS_CIPHER_MODE_CTR) + /** Encrypt using CTR */ + int (*ctr_func)( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ); +#endif + +#if defined(MBEDTLS_CIPHER_MODE_XTS) + /** Encrypt or decrypt using XTS. */ + int (*xts_func)( void *ctx, mbedtls_operation_t mode, size_t length, + const unsigned char data_unit[16], + const unsigned char *input, unsigned char *output ); +#endif + +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + /** Encrypt using STREAM */ + int (*stream_func)( void *ctx, size_t length, + const unsigned char *input, unsigned char *output ); +#endif + + /** Set key for encryption purposes */ + int (*setkey_enc_func)( void *ctx, const unsigned char *key, + unsigned int key_bitlen ); + + /** Set key for decryption purposes */ + int (*setkey_dec_func)( void *ctx, const unsigned char *key, + unsigned int key_bitlen); + + /** Allocate a new context */ + void * (*ctx_alloc_func)( void ); + + /** Free the given context */ + void (*ctx_free_func)( void *ctx ); + +}; + +typedef struct +{ + mbedtls_cipher_type_t type; + const mbedtls_cipher_info_t *info; +} mbedtls_cipher_definition_t; + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +typedef enum +{ + MBEDTLS_CIPHER_PSA_KEY_UNSET = 0, + MBEDTLS_CIPHER_PSA_KEY_OWNED, /* Used for PSA-based cipher contexts which */ + /* use raw key material internally imported */ + /* into a allocated key slot, and which */ + /* hence need to destroy that key slot */ + /* when they are no longer needed. */ + MBEDTLS_CIPHER_PSA_KEY_NOT_OWNED, /* Used for PSA-based cipher contexts */ + /* which use a key from a key slot */ + /* provided by the user, and which */ + /* hence should not be destroyed when */ + /* the context is no longer needed. */ +} mbedtls_cipher_psa_key_ownership; + +typedef struct +{ + psa_algorithm_t alg; + psa_key_handle_t slot; + mbedtls_cipher_psa_key_ownership slot_state; +} mbedtls_cipher_context_psa; +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[]; + +extern int mbedtls_cipher_supported[]; + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CIPHER_WRAP_H */ diff --git a/mbed_aes_gcm/cipher_wrap.c b/mbed_aes_gcm/cipher_wrap.c new file mode 100644 index 0000000..fcbc92d --- /dev/null +++ b/mbed_aes_gcm/cipher_wrap.c @@ -0,0 +1,2411 @@ +/** + * \file cipher_wrap.c + * + * \brief Generic cipher wrapper for mbed TLS + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CIPHER_C) + +#include "cipher_internal.h" + +#if defined(MBEDTLS_CHACHAPOLY_C) +#include "mbedtls/chachapoly.h" +#endif + +#if defined(MBEDTLS_AES_C) +#include "aes.h" +#endif + +#if defined(MBEDTLS_ARC4_C) +#include "mbedtls/arc4.h" +#endif + +#if defined(MBEDTLS_CAMELLIA_C) +#include "mbedtls/camellia.h" +#endif + +#if defined(MBEDTLS_ARIA_C) +#include "mbedtls/aria.h" +#endif + +#if defined(MBEDTLS_DES_C) +#include "mbedtls/des.h" +#endif + +#if defined(MBEDTLS_BLOWFISH_C) +#include "mbedtls/blowfish.h" +#endif + +#if defined(MBEDTLS_CHACHA20_C) +#include "mbedtls/chacha20.h" +#endif + +#if defined(MBEDTLS_GCM_C) +#include "gcm.h" +#endif + +#if defined(MBEDTLS_CCM_C) +#include "mbedtls/ccm.h" +#endif + +#if defined(MBEDTLS_NIST_KW_C) +#include "mbedtls/nist_kw.h" +#endif + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +#include +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#if defined(MBEDTLS_GCM_C) +/* shared by all GCM ciphers */ +static void *gcm_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_gcm_context ) ); + + if( ctx != NULL ) + mbedtls_gcm_init( (mbedtls_gcm_context *) ctx ); + + return( ctx ); +} + +static void gcm_ctx_free( void *ctx ) +{ + mbedtls_gcm_free( ctx ); + mbedtls_free( ctx ); +} +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +/* shared by all CCM ciphers */ +static void *ccm_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ccm_context ) ); + + if( ctx != NULL ) + mbedtls_ccm_init( (mbedtls_ccm_context *) ctx ); + + return( ctx ); +} + +static void ccm_ctx_free( void *ctx ) +{ + mbedtls_ccm_free( ctx ); + mbedtls_free( ctx ); +} +#endif /* MBEDTLS_CCM_C */ + +#if defined(MBEDTLS_AES_C) + +static int aes_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_ecb( (mbedtls_aes_context *) ctx, operation, input, output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int aes_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_cbc( (mbedtls_aes_context *) ctx, operation, length, iv, input, + output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int aes_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_cfb128( (mbedtls_aes_context *) ctx, operation, length, iv_off, iv, + input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_OFB) +static int aes_crypt_ofb_wrap( void *ctx, size_t length, size_t *iv_off, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_ofb( (mbedtls_aes_context *) ctx, length, iv_off, + iv, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_ctr( (mbedtls_aes_context *) ctx, length, nc_off, nonce_counter, + stream_block, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +static int aes_crypt_xts_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, + const unsigned char data_unit[16], + const unsigned char *input, + unsigned char *output ) +{ + mbedtls_aes_xts_context *xts_ctx = ctx; + int mode; + + switch( operation ) + { + case MBEDTLS_ENCRYPT: + mode = MBEDTLS_AES_ENCRYPT; + break; + case MBEDTLS_DECRYPT: + mode = MBEDTLS_AES_DECRYPT; + break; + default: + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + return mbedtls_aes_crypt_xts( xts_ctx, mode, length, + data_unit, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_aes_setkey_dec( (mbedtls_aes_context *) ctx, key, key_bitlen ); +} + +static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_aes_setkey_enc( (mbedtls_aes_context *) ctx, key, key_bitlen ); +} + +static void * aes_ctx_alloc( void ) +{ + mbedtls_aes_context *aes = mbedtls_calloc( 1, sizeof( mbedtls_aes_context ) ); + + if( aes == NULL ) + return( NULL ); + + mbedtls_aes_init( aes ); + + return( aes ); +} + +static void aes_ctx_free( void *ctx ) +{ + mbedtls_aes_free( (mbedtls_aes_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t aes_info = { + MBEDTLS_CIPHER_ID_AES, + aes_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + aes_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + aes_crypt_cfb128_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + aes_crypt_ofb_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + aes_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + aes_setkey_enc_wrap, + aes_setkey_dec_wrap, + aes_ctx_alloc, + aes_ctx_free +}; + +static const mbedtls_cipher_info_t aes_128_ecb_info = { + MBEDTLS_CIPHER_AES_128_ECB, + MBEDTLS_MODE_ECB, + 128, + "AES-128-ECB", + 0, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_ecb_info = { + MBEDTLS_CIPHER_AES_192_ECB, + MBEDTLS_MODE_ECB, + 192, + "AES-192-ECB", + 0, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_ecb_info = { + MBEDTLS_CIPHER_AES_256_ECB, + MBEDTLS_MODE_ECB, + 256, + "AES-256-ECB", + 0, + 0, + 16, + &aes_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t aes_128_cbc_info = { + MBEDTLS_CIPHER_AES_128_CBC, + MBEDTLS_MODE_CBC, + 128, + "AES-128-CBC", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_cbc_info = { + MBEDTLS_CIPHER_AES_192_CBC, + MBEDTLS_MODE_CBC, + 192, + "AES-192-CBC", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_cbc_info = { + MBEDTLS_CIPHER_AES_256_CBC, + MBEDTLS_MODE_CBC, + 256, + "AES-256-CBC", + 16, + 0, + 16, + &aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t aes_128_cfb128_info = { + MBEDTLS_CIPHER_AES_128_CFB128, + MBEDTLS_MODE_CFB, + 128, + "AES-128-CFB128", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_cfb128_info = { + MBEDTLS_CIPHER_AES_192_CFB128, + MBEDTLS_MODE_CFB, + 192, + "AES-192-CFB128", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_cfb128_info = { + MBEDTLS_CIPHER_AES_256_CFB128, + MBEDTLS_MODE_CFB, + 256, + "AES-256-CFB128", + 16, + 0, + 16, + &aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_OFB) +static const mbedtls_cipher_info_t aes_128_ofb_info = { + MBEDTLS_CIPHER_AES_128_OFB, + MBEDTLS_MODE_OFB, + 128, + "AES-128-OFB", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_ofb_info = { + MBEDTLS_CIPHER_AES_192_OFB, + MBEDTLS_MODE_OFB, + 192, + "AES-192-OFB", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_ofb_info = { + MBEDTLS_CIPHER_AES_256_OFB, + MBEDTLS_MODE_OFB, + 256, + "AES-256-OFB", + 16, + 0, + 16, + &aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t aes_128_ctr_info = { + MBEDTLS_CIPHER_AES_128_CTR, + MBEDTLS_MODE_CTR, + 128, + "AES-128-CTR", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_ctr_info = { + MBEDTLS_CIPHER_AES_192_CTR, + MBEDTLS_MODE_CTR, + 192, + "AES-192-CTR", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_ctr_info = { + MBEDTLS_CIPHER_AES_256_CTR, + MBEDTLS_MODE_CTR, + 256, + "AES-256-CTR", + 16, + 0, + 16, + &aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +static int xts_aes_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + mbedtls_aes_xts_context *xts_ctx = ctx; + return( mbedtls_aes_xts_setkey_enc( xts_ctx, key, key_bitlen ) ); +} + +static int xts_aes_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + mbedtls_aes_xts_context *xts_ctx = ctx; + return( mbedtls_aes_xts_setkey_dec( xts_ctx, key, key_bitlen ) ); +} + +static void *xts_aes_ctx_alloc( void ) +{ + mbedtls_aes_xts_context *xts_ctx = mbedtls_calloc( 1, sizeof( *xts_ctx ) ); + + if( xts_ctx != NULL ) + mbedtls_aes_xts_init( xts_ctx ); + + return( xts_ctx ); +} + +static void xts_aes_ctx_free( void *ctx ) +{ + mbedtls_aes_xts_context *xts_ctx = ctx; + + if( xts_ctx == NULL ) + return; + + mbedtls_aes_xts_free( xts_ctx ); + mbedtls_free( xts_ctx ); +} + +static const mbedtls_cipher_base_t xts_aes_info = { + MBEDTLS_CIPHER_ID_AES, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + aes_crypt_xts_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + xts_aes_setkey_enc_wrap, + xts_aes_setkey_dec_wrap, + xts_aes_ctx_alloc, + xts_aes_ctx_free +}; + +static const mbedtls_cipher_info_t aes_128_xts_info = { + MBEDTLS_CIPHER_AES_128_XTS, + MBEDTLS_MODE_XTS, + 256, + "AES-128-XTS", + 16, + 0, + 16, + &xts_aes_info +}; + +static const mbedtls_cipher_info_t aes_256_xts_info = { + MBEDTLS_CIPHER_AES_256_XTS, + MBEDTLS_MODE_XTS, + 512, + "AES-256-XTS", + 16, + 0, + 16, + &xts_aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +#if defined(MBEDTLS_GCM_C) +static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_AES, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t gcm_aes_info = { + MBEDTLS_CIPHER_ID_AES, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + gcm_aes_setkey_wrap, + gcm_aes_setkey_wrap, + gcm_ctx_alloc, + gcm_ctx_free, +}; + +static const mbedtls_cipher_info_t aes_128_gcm_info = { + MBEDTLS_CIPHER_AES_128_GCM, + MBEDTLS_MODE_GCM, + 128, + "AES-128-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aes_info +}; + +static const mbedtls_cipher_info_t aes_192_gcm_info = { + MBEDTLS_CIPHER_AES_192_GCM, + MBEDTLS_MODE_GCM, + 192, + "AES-192-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aes_info +}; + +static const mbedtls_cipher_info_t aes_256_gcm_info = { + MBEDTLS_CIPHER_AES_256_GCM, + MBEDTLS_MODE_GCM, + 256, + "AES-256-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aes_info +}; +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +static int ccm_aes_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_AES, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t ccm_aes_info = { + MBEDTLS_CIPHER_ID_AES, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + ccm_aes_setkey_wrap, + ccm_aes_setkey_wrap, + ccm_ctx_alloc, + ccm_ctx_free, +}; + +static const mbedtls_cipher_info_t aes_128_ccm_info = { + MBEDTLS_CIPHER_AES_128_CCM, + MBEDTLS_MODE_CCM, + 128, + "AES-128-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; + +static const mbedtls_cipher_info_t aes_192_ccm_info = { + MBEDTLS_CIPHER_AES_192_CCM, + MBEDTLS_MODE_CCM, + 192, + "AES-192-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; + +static const mbedtls_cipher_info_t aes_256_ccm_info = { + MBEDTLS_CIPHER_AES_256_CCM, + MBEDTLS_MODE_CCM, + 256, + "AES-256-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; +#endif /* MBEDTLS_CCM_C */ + +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) + +static int camellia_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_ecb( (mbedtls_camellia_context *) ctx, operation, input, + output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int camellia_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_cbc( (mbedtls_camellia_context *) ctx, operation, length, iv, + input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int camellia_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_cfb128( (mbedtls_camellia_context *) ctx, operation, length, + iv_off, iv, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int camellia_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_ctr( (mbedtls_camellia_context *) ctx, length, nc_off, + nonce_counter, stream_block, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_camellia_setkey_dec( (mbedtls_camellia_context *) ctx, key, key_bitlen ); +} + +static int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_camellia_setkey_enc( (mbedtls_camellia_context *) ctx, key, key_bitlen ); +} + +static void * camellia_ctx_alloc( void ) +{ + mbedtls_camellia_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_camellia_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_camellia_init( ctx ); + + return( ctx ); +} + +static void camellia_ctx_free( void *ctx ) +{ + mbedtls_camellia_free( (mbedtls_camellia_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t camellia_info = { + MBEDTLS_CIPHER_ID_CAMELLIA, + camellia_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + camellia_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + camellia_crypt_cfb128_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + camellia_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + camellia_setkey_enc_wrap, + camellia_setkey_dec_wrap, + camellia_ctx_alloc, + camellia_ctx_free +}; + +static const mbedtls_cipher_info_t camellia_128_ecb_info = { + MBEDTLS_CIPHER_CAMELLIA_128_ECB, + MBEDTLS_MODE_ECB, + 128, + "CAMELLIA-128-ECB", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_ecb_info = { + MBEDTLS_CIPHER_CAMELLIA_192_ECB, + MBEDTLS_MODE_ECB, + 192, + "CAMELLIA-192-ECB", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_ecb_info = { + MBEDTLS_CIPHER_CAMELLIA_256_ECB, + MBEDTLS_MODE_ECB, + 256, + "CAMELLIA-256-ECB", + 16, + 0, + 16, + &camellia_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t camellia_128_cbc_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CBC, + MBEDTLS_MODE_CBC, + 128, + "CAMELLIA-128-CBC", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_cbc_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CBC, + MBEDTLS_MODE_CBC, + 192, + "CAMELLIA-192-CBC", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_cbc_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CBC, + MBEDTLS_MODE_CBC, + 256, + "CAMELLIA-256-CBC", + 16, + 0, + 16, + &camellia_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t camellia_128_cfb128_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CFB128, + MBEDTLS_MODE_CFB, + 128, + "CAMELLIA-128-CFB128", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_cfb128_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CFB128, + MBEDTLS_MODE_CFB, + 192, + "CAMELLIA-192-CFB128", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_cfb128_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CFB128, + MBEDTLS_MODE_CFB, + 256, + "CAMELLIA-256-CFB128", + 16, + 0, + 16, + &camellia_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t camellia_128_ctr_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CTR, + MBEDTLS_MODE_CTR, + 128, + "CAMELLIA-128-CTR", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_ctr_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CTR, + MBEDTLS_MODE_CTR, + 192, + "CAMELLIA-192-CTR", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_ctr_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CTR, + MBEDTLS_MODE_CTR, + 256, + "CAMELLIA-256-CTR", + 16, + 0, + 16, + &camellia_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_GCM_C) +static int gcm_camellia_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t gcm_camellia_info = { + MBEDTLS_CIPHER_ID_CAMELLIA, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + gcm_camellia_setkey_wrap, + gcm_camellia_setkey_wrap, + gcm_ctx_alloc, + gcm_ctx_free, +}; + +static const mbedtls_cipher_info_t camellia_128_gcm_info = { + MBEDTLS_CIPHER_CAMELLIA_128_GCM, + MBEDTLS_MODE_GCM, + 128, + "CAMELLIA-128-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_gcm_info = { + MBEDTLS_CIPHER_CAMELLIA_192_GCM, + MBEDTLS_MODE_GCM, + 192, + "CAMELLIA-192-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_gcm_info = { + MBEDTLS_CIPHER_CAMELLIA_256_GCM, + MBEDTLS_MODE_GCM, + 256, + "CAMELLIA-256-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_camellia_info +}; +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +static int ccm_camellia_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t ccm_camellia_info = { + MBEDTLS_CIPHER_ID_CAMELLIA, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + ccm_camellia_setkey_wrap, + ccm_camellia_setkey_wrap, + ccm_ctx_alloc, + ccm_ctx_free, +}; + +static const mbedtls_cipher_info_t camellia_128_ccm_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CCM, + MBEDTLS_MODE_CCM, + 128, + "CAMELLIA-128-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_ccm_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CCM, + MBEDTLS_MODE_CCM, + 192, + "CAMELLIA-192-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_ccm_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CCM, + MBEDTLS_MODE_CCM, + 256, + "CAMELLIA-256-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; +#endif /* MBEDTLS_CCM_C */ + +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_ARIA_C) + +static int aria_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + (void) operation; + return mbedtls_aria_crypt_ecb( (mbedtls_aria_context *) ctx, input, + output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int aria_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aria_crypt_cbc( (mbedtls_aria_context *) ctx, operation, length, iv, + input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int aria_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aria_crypt_cfb128( (mbedtls_aria_context *) ctx, operation, length, + iv_off, iv, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int aria_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aria_crypt_ctr( (mbedtls_aria_context *) ctx, length, nc_off, + nonce_counter, stream_block, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static int aria_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_aria_setkey_dec( (mbedtls_aria_context *) ctx, key, key_bitlen ); +} + +static int aria_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_aria_setkey_enc( (mbedtls_aria_context *) ctx, key, key_bitlen ); +} + +static void * aria_ctx_alloc( void ) +{ + mbedtls_aria_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_aria_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_aria_init( ctx ); + + return( ctx ); +} + +static void aria_ctx_free( void *ctx ) +{ + mbedtls_aria_free( (mbedtls_aria_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t aria_info = { + MBEDTLS_CIPHER_ID_ARIA, + aria_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + aria_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + aria_crypt_cfb128_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + aria_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + aria_setkey_enc_wrap, + aria_setkey_dec_wrap, + aria_ctx_alloc, + aria_ctx_free +}; + +static const mbedtls_cipher_info_t aria_128_ecb_info = { + MBEDTLS_CIPHER_ARIA_128_ECB, + MBEDTLS_MODE_ECB, + 128, + "ARIA-128-ECB", + 16, + 0, + 16, + &aria_info +}; + +static const mbedtls_cipher_info_t aria_192_ecb_info = { + MBEDTLS_CIPHER_ARIA_192_ECB, + MBEDTLS_MODE_ECB, + 192, + "ARIA-192-ECB", + 16, + 0, + 16, + &aria_info +}; + +static const mbedtls_cipher_info_t aria_256_ecb_info = { + MBEDTLS_CIPHER_ARIA_256_ECB, + MBEDTLS_MODE_ECB, + 256, + "ARIA-256-ECB", + 16, + 0, + 16, + &aria_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t aria_128_cbc_info = { + MBEDTLS_CIPHER_ARIA_128_CBC, + MBEDTLS_MODE_CBC, + 128, + "ARIA-128-CBC", + 16, + 0, + 16, + &aria_info +}; + +static const mbedtls_cipher_info_t aria_192_cbc_info = { + MBEDTLS_CIPHER_ARIA_192_CBC, + MBEDTLS_MODE_CBC, + 192, + "ARIA-192-CBC", + 16, + 0, + 16, + &aria_info +}; + +static const mbedtls_cipher_info_t aria_256_cbc_info = { + MBEDTLS_CIPHER_ARIA_256_CBC, + MBEDTLS_MODE_CBC, + 256, + "ARIA-256-CBC", + 16, + 0, + 16, + &aria_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t aria_128_cfb128_info = { + MBEDTLS_CIPHER_ARIA_128_CFB128, + MBEDTLS_MODE_CFB, + 128, + "ARIA-128-CFB128", + 16, + 0, + 16, + &aria_info +}; + +static const mbedtls_cipher_info_t aria_192_cfb128_info = { + MBEDTLS_CIPHER_ARIA_192_CFB128, + MBEDTLS_MODE_CFB, + 192, + "ARIA-192-CFB128", + 16, + 0, + 16, + &aria_info +}; + +static const mbedtls_cipher_info_t aria_256_cfb128_info = { + MBEDTLS_CIPHER_ARIA_256_CFB128, + MBEDTLS_MODE_CFB, + 256, + "ARIA-256-CFB128", + 16, + 0, + 16, + &aria_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t aria_128_ctr_info = { + MBEDTLS_CIPHER_ARIA_128_CTR, + MBEDTLS_MODE_CTR, + 128, + "ARIA-128-CTR", + 16, + 0, + 16, + &aria_info +}; + +static const mbedtls_cipher_info_t aria_192_ctr_info = { + MBEDTLS_CIPHER_ARIA_192_CTR, + MBEDTLS_MODE_CTR, + 192, + "ARIA-192-CTR", + 16, + 0, + 16, + &aria_info +}; + +static const mbedtls_cipher_info_t aria_256_ctr_info = { + MBEDTLS_CIPHER_ARIA_256_CTR, + MBEDTLS_MODE_CTR, + 256, + "ARIA-256-CTR", + 16, + 0, + 16, + &aria_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_GCM_C) +static int gcm_aria_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t gcm_aria_info = { + MBEDTLS_CIPHER_ID_ARIA, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + gcm_aria_setkey_wrap, + gcm_aria_setkey_wrap, + gcm_ctx_alloc, + gcm_ctx_free, +}; + +static const mbedtls_cipher_info_t aria_128_gcm_info = { + MBEDTLS_CIPHER_ARIA_128_GCM, + MBEDTLS_MODE_GCM, + 128, + "ARIA-128-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aria_info +}; + +static const mbedtls_cipher_info_t aria_192_gcm_info = { + MBEDTLS_CIPHER_ARIA_192_GCM, + MBEDTLS_MODE_GCM, + 192, + "ARIA-192-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aria_info +}; + +static const mbedtls_cipher_info_t aria_256_gcm_info = { + MBEDTLS_CIPHER_ARIA_256_GCM, + MBEDTLS_MODE_GCM, + 256, + "ARIA-256-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aria_info +}; +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +static int ccm_aria_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t ccm_aria_info = { + MBEDTLS_CIPHER_ID_ARIA, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + ccm_aria_setkey_wrap, + ccm_aria_setkey_wrap, + ccm_ctx_alloc, + ccm_ctx_free, +}; + +static const mbedtls_cipher_info_t aria_128_ccm_info = { + MBEDTLS_CIPHER_ARIA_128_CCM, + MBEDTLS_MODE_CCM, + 128, + "ARIA-128-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aria_info +}; + +static const mbedtls_cipher_info_t aria_192_ccm_info = { + MBEDTLS_CIPHER_ARIA_192_CCM, + MBEDTLS_MODE_CCM, + 192, + "ARIA-192-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aria_info +}; + +static const mbedtls_cipher_info_t aria_256_ccm_info = { + MBEDTLS_CIPHER_ARIA_256_CCM, + MBEDTLS_MODE_CCM, + 256, + "ARIA-256-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aria_info +}; +#endif /* MBEDTLS_CCM_C */ + +#endif /* MBEDTLS_ARIA_C */ + +#if defined(MBEDTLS_DES_C) + +static int des_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + ((void) operation); + return mbedtls_des_crypt_ecb( (mbedtls_des_context *) ctx, input, output ); +} + +static int des3_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + ((void) operation); + return mbedtls_des3_crypt_ecb( (mbedtls_des3_context *) ctx, input, output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int des_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ + return mbedtls_des_crypt_cbc( (mbedtls_des_context *) ctx, operation, length, iv, input, + output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int des3_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ + return mbedtls_des3_crypt_cbc( (mbedtls_des3_context *) ctx, operation, length, iv, input, + output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static int des_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des_setkey_dec( (mbedtls_des_context *) ctx, key ); +} + +static int des_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des_setkey_enc( (mbedtls_des_context *) ctx, key ); +} + +static int des3_set2key_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set2key_dec( (mbedtls_des3_context *) ctx, key ); +} + +static int des3_set2key_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set2key_enc( (mbedtls_des3_context *) ctx, key ); +} + +static int des3_set3key_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set3key_dec( (mbedtls_des3_context *) ctx, key ); +} + +static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set3key_enc( (mbedtls_des3_context *) ctx, key ); +} + +static void * des_ctx_alloc( void ) +{ + mbedtls_des_context *des = mbedtls_calloc( 1, sizeof( mbedtls_des_context ) ); + + if( des == NULL ) + return( NULL ); + + mbedtls_des_init( des ); + + return( des ); +} + +static void des_ctx_free( void *ctx ) +{ + mbedtls_des_free( (mbedtls_des_context *) ctx ); + mbedtls_free( ctx ); +} + +static void * des3_ctx_alloc( void ) +{ + mbedtls_des3_context *des3; + des3 = mbedtls_calloc( 1, sizeof( mbedtls_des3_context ) ); + + if( des3 == NULL ) + return( NULL ); + + mbedtls_des3_init( des3 ); + + return( des3 ); +} + +static void des3_ctx_free( void *ctx ) +{ + mbedtls_des3_free( (mbedtls_des3_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t des_info = { + MBEDTLS_CIPHER_ID_DES, + des_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + des_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + des_setkey_enc_wrap, + des_setkey_dec_wrap, + des_ctx_alloc, + des_ctx_free +}; + +static const mbedtls_cipher_info_t des_ecb_info = { + MBEDTLS_CIPHER_DES_ECB, + MBEDTLS_MODE_ECB, + MBEDTLS_KEY_LENGTH_DES, + "DES-ECB", + 8, + 0, + 8, + &des_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t des_cbc_info = { + MBEDTLS_CIPHER_DES_CBC, + MBEDTLS_MODE_CBC, + MBEDTLS_KEY_LENGTH_DES, + "DES-CBC", + 8, + 0, + 8, + &des_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static const mbedtls_cipher_base_t des_ede_info = { + MBEDTLS_CIPHER_ID_DES, + des3_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + des3_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + des3_set2key_enc_wrap, + des3_set2key_dec_wrap, + des3_ctx_alloc, + des3_ctx_free +}; + +static const mbedtls_cipher_info_t des_ede_ecb_info = { + MBEDTLS_CIPHER_DES_EDE_ECB, + MBEDTLS_MODE_ECB, + MBEDTLS_KEY_LENGTH_DES_EDE, + "DES-EDE-ECB", + 8, + 0, + 8, + &des_ede_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t des_ede_cbc_info = { + MBEDTLS_CIPHER_DES_EDE_CBC, + MBEDTLS_MODE_CBC, + MBEDTLS_KEY_LENGTH_DES_EDE, + "DES-EDE-CBC", + 8, + 0, + 8, + &des_ede_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static const mbedtls_cipher_base_t des_ede3_info = { + MBEDTLS_CIPHER_ID_3DES, + des3_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + des3_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + des3_set3key_enc_wrap, + des3_set3key_dec_wrap, + des3_ctx_alloc, + des3_ctx_free +}; + +static const mbedtls_cipher_info_t des_ede3_ecb_info = { + MBEDTLS_CIPHER_DES_EDE3_ECB, + MBEDTLS_MODE_ECB, + MBEDTLS_KEY_LENGTH_DES_EDE3, + "DES-EDE3-ECB", + 8, + 0, + 8, + &des_ede3_info +}; +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t des_ede3_cbc_info = { + MBEDTLS_CIPHER_DES_EDE3_CBC, + MBEDTLS_MODE_CBC, + MBEDTLS_KEY_LENGTH_DES_EDE3, + "DES-EDE3-CBC", + 8, + 0, + 8, + &des_ede3_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_BLOWFISH_C) + +static int blowfish_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_blowfish_crypt_ecb( (mbedtls_blowfish_context *) ctx, operation, input, + output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int blowfish_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, unsigned char *iv, const unsigned char *input, + unsigned char *output ) +{ + return mbedtls_blowfish_crypt_cbc( (mbedtls_blowfish_context *) ctx, operation, length, iv, + input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int blowfish_crypt_cfb64_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_blowfish_crypt_cfb64( (mbedtls_blowfish_context *) ctx, operation, length, + iv_off, iv, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_blowfish_crypt_ctr( (mbedtls_blowfish_context *) ctx, length, nc_off, + nonce_counter, stream_block, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static int blowfish_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_blowfish_setkey( (mbedtls_blowfish_context *) ctx, key, key_bitlen ); +} + +static void * blowfish_ctx_alloc( void ) +{ + mbedtls_blowfish_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_blowfish_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_blowfish_init( ctx ); + + return( ctx ); +} + +static void blowfish_ctx_free( void *ctx ) +{ + mbedtls_blowfish_free( (mbedtls_blowfish_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t blowfish_info = { + MBEDTLS_CIPHER_ID_BLOWFISH, + blowfish_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + blowfish_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + blowfish_crypt_cfb64_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + blowfish_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + blowfish_setkey_wrap, + blowfish_setkey_wrap, + blowfish_ctx_alloc, + blowfish_ctx_free +}; + +static const mbedtls_cipher_info_t blowfish_ecb_info = { + MBEDTLS_CIPHER_BLOWFISH_ECB, + MBEDTLS_MODE_ECB, + 128, + "BLOWFISH-ECB", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t blowfish_cbc_info = { + MBEDTLS_CIPHER_BLOWFISH_CBC, + MBEDTLS_MODE_CBC, + 128, + "BLOWFISH-CBC", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t blowfish_cfb64_info = { + MBEDTLS_CIPHER_BLOWFISH_CFB64, + MBEDTLS_MODE_CFB, + 128, + "BLOWFISH-CFB64", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t blowfish_ctr_info = { + MBEDTLS_CIPHER_BLOWFISH_CTR, + MBEDTLS_MODE_CTR, + 128, + "BLOWFISH-CTR", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ +#endif /* MBEDTLS_BLOWFISH_C */ + +#if defined(MBEDTLS_ARC4_C) +static int arc4_crypt_stream_wrap( void *ctx, size_t length, + const unsigned char *input, + unsigned char *output ) +{ + return( mbedtls_arc4_crypt( (mbedtls_arc4_context *) ctx, length, input, output ) ); +} + +static int arc4_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + /* we get key_bitlen in bits, arc4 expects it in bytes */ + if( key_bitlen % 8 != 0 ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + mbedtls_arc4_setup( (mbedtls_arc4_context *) ctx, key, key_bitlen / 8 ); + return( 0 ); +} + +static void * arc4_ctx_alloc( void ) +{ + mbedtls_arc4_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_arc4_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_arc4_init( ctx ); + + return( ctx ); +} + +static void arc4_ctx_free( void *ctx ) +{ + mbedtls_arc4_free( (mbedtls_arc4_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t arc4_base_info = { + MBEDTLS_CIPHER_ID_ARC4, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + arc4_crypt_stream_wrap, +#endif + arc4_setkey_wrap, + arc4_setkey_wrap, + arc4_ctx_alloc, + arc4_ctx_free +}; + +static const mbedtls_cipher_info_t arc4_128_info = { + MBEDTLS_CIPHER_ARC4_128, + MBEDTLS_MODE_STREAM, + 128, + "ARC4-128", + 0, + 0, + 1, + &arc4_base_info +}; +#endif /* MBEDTLS_ARC4_C */ + +#if defined(MBEDTLS_CHACHA20_C) + +static int chacha20_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + if( key_bitlen != 256U ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if ( 0 != mbedtls_chacha20_setkey( (mbedtls_chacha20_context*)ctx, key ) ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + return( 0 ); +} + +static int chacha20_stream_wrap( void *ctx, size_t length, + const unsigned char *input, + unsigned char *output ) +{ + int ret; + + ret = mbedtls_chacha20_update( ctx, length, input, output ); + if( ret == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + return( ret ); +} + +static void * chacha20_ctx_alloc( void ) +{ + mbedtls_chacha20_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_chacha20_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_chacha20_init( ctx ); + + return( ctx ); +} + +static void chacha20_ctx_free( void *ctx ) +{ + mbedtls_chacha20_free( (mbedtls_chacha20_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t chacha20_base_info = { + MBEDTLS_CIPHER_ID_CHACHA20, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + chacha20_stream_wrap, +#endif + chacha20_setkey_wrap, + chacha20_setkey_wrap, + chacha20_ctx_alloc, + chacha20_ctx_free +}; +static const mbedtls_cipher_info_t chacha20_info = { + MBEDTLS_CIPHER_CHACHA20, + MBEDTLS_MODE_STREAM, + 256, + "CHACHA20", + 12, + 0, + 1, + &chacha20_base_info +}; +#endif /* MBEDTLS_CHACHA20_C */ + +#if defined(MBEDTLS_CHACHAPOLY_C) + +static int chachapoly_setkey_wrap( void *ctx, + const unsigned char *key, + unsigned int key_bitlen ) +{ + if( key_bitlen != 256U ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if ( 0 != mbedtls_chachapoly_setkey( (mbedtls_chachapoly_context*)ctx, key ) ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + return( 0 ); +} + +static void * chachapoly_ctx_alloc( void ) +{ + mbedtls_chachapoly_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_chachapoly_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_chachapoly_init( ctx ); + + return( ctx ); +} + +static void chachapoly_ctx_free( void *ctx ) +{ + mbedtls_chachapoly_free( (mbedtls_chachapoly_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t chachapoly_base_info = { + MBEDTLS_CIPHER_ID_CHACHA20, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + chachapoly_setkey_wrap, + chachapoly_setkey_wrap, + chachapoly_ctx_alloc, + chachapoly_ctx_free +}; +static const mbedtls_cipher_info_t chachapoly_info = { + MBEDTLS_CIPHER_CHACHA20_POLY1305, + MBEDTLS_MODE_CHACHAPOLY, + 256, + "CHACHA20-POLY1305", + 12, + 0, + 1, + &chachapoly_base_info +}; +#endif /* MBEDTLS_CHACHAPOLY_C */ + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +static int null_crypt_stream( void *ctx, size_t length, + const unsigned char *input, + unsigned char *output ) +{ + ((void) ctx); + memmove( output, input, length ); + return( 0 ); +} + +static int null_setkey( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) ctx); + ((void) key); + ((void) key_bitlen); + + return( 0 ); +} + +static void * null_ctx_alloc( void ) +{ + return( (void *) 1 ); +} + +static void null_ctx_free( void *ctx ) +{ + ((void) ctx); +} + +static const mbedtls_cipher_base_t null_base_info = { + MBEDTLS_CIPHER_ID_NULL, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + null_crypt_stream, +#endif + null_setkey, + null_setkey, + null_ctx_alloc, + null_ctx_free +}; + +static const mbedtls_cipher_info_t null_cipher_info = { + MBEDTLS_CIPHER_NULL, + MBEDTLS_MODE_STREAM, + 0, + "NULL", + 0, + 0, + 1, + &null_base_info +}; +#endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */ + +#if defined(MBEDTLS_NIST_KW_C) +static void *kw_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_nist_kw_context ) ); + + if( ctx != NULL ) + mbedtls_nist_kw_init( (mbedtls_nist_kw_context *) ctx ); + + return( ctx ); +} + +static void kw_ctx_free( void *ctx ) +{ + mbedtls_nist_kw_free( ctx ); + mbedtls_free( ctx ); +} + +static int kw_aes_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_nist_kw_setkey( (mbedtls_nist_kw_context *) ctx, + MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 1 ); +} + +static int kw_aes_setkey_unwrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_nist_kw_setkey( (mbedtls_nist_kw_context *) ctx, + MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 0 ); +} + +static const mbedtls_cipher_base_t kw_aes_info = { + MBEDTLS_CIPHER_ID_AES, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + kw_aes_setkey_wrap, + kw_aes_setkey_unwrap, + kw_ctx_alloc, + kw_ctx_free, +}; + +static const mbedtls_cipher_info_t aes_128_nist_kw_info = { + MBEDTLS_CIPHER_AES_128_KW, + MBEDTLS_MODE_KW, + 128, + "AES-128-KW", + 0, + 0, + 16, + &kw_aes_info +}; + +static const mbedtls_cipher_info_t aes_192_nist_kw_info = { + MBEDTLS_CIPHER_AES_192_KW, + MBEDTLS_MODE_KW, + 192, + "AES-192-KW", + 0, + 0, + 16, + &kw_aes_info +}; + +static const mbedtls_cipher_info_t aes_256_nist_kw_info = { + MBEDTLS_CIPHER_AES_256_KW, + MBEDTLS_MODE_KW, + 256, + "AES-256-KW", + 0, + 0, + 16, + &kw_aes_info +}; + +static const mbedtls_cipher_info_t aes_128_nist_kwp_info = { + MBEDTLS_CIPHER_AES_128_KWP, + MBEDTLS_MODE_KWP, + 128, + "AES-128-KWP", + 0, + 0, + 16, + &kw_aes_info +}; + +static const mbedtls_cipher_info_t aes_192_nist_kwp_info = { + MBEDTLS_CIPHER_AES_192_KWP, + MBEDTLS_MODE_KWP, + 192, + "AES-192-KWP", + 0, + 0, + 16, + &kw_aes_info +}; + +static const mbedtls_cipher_info_t aes_256_nist_kwp_info = { + MBEDTLS_CIPHER_AES_256_KWP, + MBEDTLS_MODE_KWP, + 256, + "AES-256-KWP", + 0, + 0, + 16, + &kw_aes_info +}; +#endif /* MBEDTLS_NIST_KW_C */ + +const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] = +{ +#if defined(MBEDTLS_AES_C) + { MBEDTLS_CIPHER_AES_128_ECB, &aes_128_ecb_info }, + { MBEDTLS_CIPHER_AES_192_ECB, &aes_192_ecb_info }, + { MBEDTLS_CIPHER_AES_256_ECB, &aes_256_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_AES_128_CBC, &aes_128_cbc_info }, + { MBEDTLS_CIPHER_AES_192_CBC, &aes_192_cbc_info }, + { MBEDTLS_CIPHER_AES_256_CBC, &aes_256_cbc_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_AES_128_CFB128, &aes_128_cfb128_info }, + { MBEDTLS_CIPHER_AES_192_CFB128, &aes_192_cfb128_info }, + { MBEDTLS_CIPHER_AES_256_CFB128, &aes_256_cfb128_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + { MBEDTLS_CIPHER_AES_128_OFB, &aes_128_ofb_info }, + { MBEDTLS_CIPHER_AES_192_OFB, &aes_192_ofb_info }, + { MBEDTLS_CIPHER_AES_256_OFB, &aes_256_ofb_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_AES_128_CTR, &aes_128_ctr_info }, + { MBEDTLS_CIPHER_AES_192_CTR, &aes_192_ctr_info }, + { MBEDTLS_CIPHER_AES_256_CTR, &aes_256_ctr_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + { MBEDTLS_CIPHER_AES_128_XTS, &aes_128_xts_info }, + { MBEDTLS_CIPHER_AES_256_XTS, &aes_256_xts_info }, +#endif +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info }, + { MBEDTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info }, + { MBEDTLS_CIPHER_AES_256_GCM, &aes_256_gcm_info }, +#endif +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_CIPHER_AES_128_CCM, &aes_128_ccm_info }, + { MBEDTLS_CIPHER_AES_192_CCM, &aes_192_ccm_info }, + { MBEDTLS_CIPHER_AES_256_CCM, &aes_256_ccm_info }, +#endif +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_ARC4_C) + { MBEDTLS_CIPHER_ARC4_128, &arc4_128_info }, +#endif + +#if defined(MBEDTLS_BLOWFISH_C) + { MBEDTLS_CIPHER_BLOWFISH_ECB, &blowfish_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_BLOWFISH_CBC, &blowfish_cbc_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_BLOWFISH_CFB64, &blowfish_cfb64_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_BLOWFISH_CTR, &blowfish_ctr_info }, +#endif +#endif /* MBEDTLS_BLOWFISH_C */ + +#if defined(MBEDTLS_CAMELLIA_C) + { MBEDTLS_CIPHER_CAMELLIA_128_ECB, &camellia_128_ecb_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_ECB, &camellia_192_ecb_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_ECB, &camellia_256_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_CAMELLIA_128_CBC, &camellia_128_cbc_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CBC, &camellia_192_cbc_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CBC, &camellia_256_cbc_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_CAMELLIA_128_CFB128, &camellia_128_cfb128_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CFB128, &camellia_192_cfb128_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CFB128, &camellia_256_cfb128_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_CAMELLIA_128_CTR, &camellia_128_ctr_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CTR, &camellia_192_ctr_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CTR, &camellia_256_ctr_info }, +#endif +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_CIPHER_CAMELLIA_128_GCM, &camellia_128_gcm_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_GCM, &camellia_192_gcm_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_GCM, &camellia_256_gcm_info }, +#endif +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_CIPHER_CAMELLIA_128_CCM, &camellia_128_ccm_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CCM, &camellia_192_ccm_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CCM, &camellia_256_ccm_info }, +#endif +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_ARIA_C) + { MBEDTLS_CIPHER_ARIA_128_ECB, &aria_128_ecb_info }, + { MBEDTLS_CIPHER_ARIA_192_ECB, &aria_192_ecb_info }, + { MBEDTLS_CIPHER_ARIA_256_ECB, &aria_256_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_ARIA_128_CBC, &aria_128_cbc_info }, + { MBEDTLS_CIPHER_ARIA_192_CBC, &aria_192_cbc_info }, + { MBEDTLS_CIPHER_ARIA_256_CBC, &aria_256_cbc_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_ARIA_128_CFB128, &aria_128_cfb128_info }, + { MBEDTLS_CIPHER_ARIA_192_CFB128, &aria_192_cfb128_info }, + { MBEDTLS_CIPHER_ARIA_256_CFB128, &aria_256_cfb128_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_ARIA_128_CTR, &aria_128_ctr_info }, + { MBEDTLS_CIPHER_ARIA_192_CTR, &aria_192_ctr_info }, + { MBEDTLS_CIPHER_ARIA_256_CTR, &aria_256_ctr_info }, +#endif +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_CIPHER_ARIA_128_GCM, &aria_128_gcm_info }, + { MBEDTLS_CIPHER_ARIA_192_GCM, &aria_192_gcm_info }, + { MBEDTLS_CIPHER_ARIA_256_GCM, &aria_256_gcm_info }, +#endif +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_CIPHER_ARIA_128_CCM, &aria_128_ccm_info }, + { MBEDTLS_CIPHER_ARIA_192_CCM, &aria_192_ccm_info }, + { MBEDTLS_CIPHER_ARIA_256_CCM, &aria_256_ccm_info }, +#endif +#endif /* MBEDTLS_ARIA_C */ + +#if defined(MBEDTLS_DES_C) + { MBEDTLS_CIPHER_DES_ECB, &des_ecb_info }, + { MBEDTLS_CIPHER_DES_EDE_ECB, &des_ede_ecb_info }, + { MBEDTLS_CIPHER_DES_EDE3_ECB, &des_ede3_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_DES_CBC, &des_cbc_info }, + { MBEDTLS_CIPHER_DES_EDE_CBC, &des_ede_cbc_info }, + { MBEDTLS_CIPHER_DES_EDE3_CBC, &des_ede3_cbc_info }, +#endif +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_CHACHA20_C) + { MBEDTLS_CIPHER_CHACHA20, &chacha20_info }, +#endif + +#if defined(MBEDTLS_CHACHAPOLY_C) + { MBEDTLS_CIPHER_CHACHA20_POLY1305, &chachapoly_info }, +#endif + +#if defined(MBEDTLS_NIST_KW_C) + { MBEDTLS_CIPHER_AES_128_KW, &aes_128_nist_kw_info }, + { MBEDTLS_CIPHER_AES_192_KW, &aes_192_nist_kw_info }, + { MBEDTLS_CIPHER_AES_256_KW, &aes_256_nist_kw_info }, + { MBEDTLS_CIPHER_AES_128_KWP, &aes_128_nist_kwp_info }, + { MBEDTLS_CIPHER_AES_192_KWP, &aes_192_nist_kwp_info }, + { MBEDTLS_CIPHER_AES_256_KWP, &aes_256_nist_kwp_info }, +#endif + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) + { MBEDTLS_CIPHER_NULL, &null_cipher_info }, +#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ + + { MBEDTLS_CIPHER_NONE, NULL } +}; + +#define NUM_CIPHERS ( sizeof(mbedtls_cipher_definitions) / \ + sizeof(mbedtls_cipher_definitions[0]) ) +int mbedtls_cipher_supported[NUM_CIPHERS]; + +#endif /* MBEDTLS_CIPHER_C */ diff --git a/mbed_aes_gcm/config.h b/mbed_aes_gcm/config.h new file mode 100644 index 0000000..953afea --- /dev/null +++ b/mbed_aes_gcm/config.h @@ -0,0 +1,5 @@ +#pragma once +#define MBEDTLS_GCM_C +#define MBEDTLS_CIPHER_C +#define MBEDTLS_AES_C +#define MBEDTLS_SELF_TEST diff --git a/mbed_aes_gcm/crypto_aead.h b/mbed_aes_gcm/crypto_aead.h new file mode 100644 index 0000000..d913c00 --- /dev/null +++ b/mbed_aes_gcm/crypto_aead.h @@ -0,0 +1,64 @@ +/* Reference implementation of ACE-128 AEAD + Written by: + Kalikinkar Mandal + */ + +typedef unsigned long long u64; + +int ace_init( + unsigned char *state, + const unsigned char *npub, + const unsigned char *k + ); +int ace_ad( + unsigned char *state, + const unsigned char *ad, + const u64 adlen + ); + +int ace_gentag( + unsigned char *tag, + const unsigned char tlen, + unsigned char *state, + const unsigned char *k + ); +int crypto_encrypt( + unsigned char *c,unsigned long long *clen, + const unsigned char *m,unsigned long long mlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k + ); + +int crypto_decrypt( + unsigned char *m,unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c,unsigned long long clen, + const unsigned char *npub, + const unsigned char *k + ); + +int crypto_aead_encrypt( + unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k +); + +int crypto_aead_decrypt( + unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k +); + +int ace_gentag( + unsigned char *tag, + const unsigned char tlen, + unsigned char *state, + const unsigned char *k + ); diff --git a/mbed_aes_gcm/example_decryption.c b/mbed_aes_gcm/example_decryption.c new file mode 100644 index 0000000..fdb53a3 --- /dev/null +++ b/mbed_aes_gcm/example_decryption.c @@ -0,0 +1,54 @@ +#include "gcm.h" +#include "platform_util.h" +#include "api.h" +#include +#include "crypto_aead.h" + +static void single_encryption(void) { + // 32 bytes.. that's 256 bits + const unsigned char k[32] = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }; + unsigned char c[64] = { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, +0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85}; + unsigned char npub[12] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }; + unsigned char ad[1400]; + unsigned long long adlen = 0; + unsigned long long mlen = 0; + unsigned long long clen = 64; + unsigned char m[1400]; + unsigned char nsec[CRYPTO_NSECBYTES]; + + + //mbedtls_gcm_init( &ctx ); + // 128 bits, not bytes! + //ret = mbedtls_gcm_setkey( &ctx, cipher, key, 128 ); + + // Context, flag (1/0), length, nonce, nonce_len, AD, AD_len, PT, output, tag_len, tag + //ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, 64, initial_value, 12, additional, 0, plaintext, buf, 16, tag_buf); + //mbedtls_gcm_free( &ctx ); + + int res; + + res = crypto_aead_decrypt(m, mlen, nsec, c, clen, ad, adlen, npub, k); + if (res == 0) { + printf("Local decryption test workerino!\n"); + } else { + printf("Local test failed -.-\n"); + } + +} + +int main(void) { + //mbedtls_gcm_self_test(1); + single_encryption(); + return 0; +} diff --git a/mbed_aes_gcm/example_encryption.c b/mbed_aes_gcm/example_encryption.c new file mode 100644 index 0000000..1d53362 --- /dev/null +++ b/mbed_aes_gcm/example_encryption.c @@ -0,0 +1,53 @@ +#include "gcm.h" +#include "platform_util.h" +#include "api.h" +#include +#include "crypto_aead.h" + +static void single_encryption(void) { + // 32 bytes.. that's 256 bits + const unsigned char k[32] = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }; + unsigned char m[64] = { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }; + unsigned char npub[12] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }; + unsigned char ad[1400]; + unsigned long long adlen = 0; + unsigned long long mlen = 64; + unsigned long long clen = 0; + unsigned char c[1400]; + unsigned char nsec[CRYPTO_NSECBYTES]; + + + //mbedtls_gcm_init( &ctx ); + // 128 bits, not bytes! + //ret = mbedtls_gcm_setkey( &ctx, cipher, key, 128 ); + + // Context, flag (1/0), length, nonce, nonce_len, AD, AD_len, PT, output, tag_len, tag + //ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, 64, initial_value, 12, additional, 0, plaintext, buf, 16, tag_buf); + //mbedtls_gcm_free( &ctx ); + + int res; + res = crypto_aead_encrypt(c, &clen, m, mlen, ad, adlen, nsec, npub, k); + if (res == 0) { + printf("Local encryption test workerino!\n"); + } else { + printf("Local test failed -.-\n"); + } + +} + +int main(void) { + //mbedtls_gcm_self_test(1); + single_encryption(); + return 0; +} diff --git a/mbed_aes_gcm/gcm b/mbed_aes_gcm/gcm new file mode 100755 index 0000000..7155828 Binary files /dev/null and b/mbed_aes_gcm/gcm differ diff --git a/mbed_aes_gcm/gcm.c b/mbed_aes_gcm/gcm.c new file mode 100644 index 0000000..089240d --- /dev/null +++ b/mbed_aes_gcm/gcm.c @@ -0,0 +1,1067 @@ +/* + * NIST SP800-38D compliant GCM implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf + * + * See also: + * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf + * + * We use the algorithm described as Shoup's method with 4-bit tables in + * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory. + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_GCM_C) + +#include "gcm.h" +#include "crypto_aead.h" +#include "platform_util.h" + +#include + +#if defined(MBEDTLS_AESNI_C) +#include "mbedtls/aesni.h" +#endif + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +#include "aes.h" +#include "platform.h" +#if !defined(MBEDTLS_PLATFORM_C) +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +#if !defined(MBEDTLS_GCM_ALT) + +/* Parameter validation macros */ +#define GCM_VALIDATE_RET( cond ) \ + MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT ) +#define GCM_VALIDATE( cond ) \ + MBEDTLS_INTERNAL_VALIDATE( cond ) + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +/* + * Initialize a context + */ +void mbedtls_gcm_init( mbedtls_gcm_context *ctx ) +{ + GCM_VALIDATE( ctx != NULL ); + memset( ctx, 0, sizeof( mbedtls_gcm_context ) ); +} + +/* + * Encrypt function for NIST API +*/ +int crypto_aead_encrypt( + unsigned char *c,unsigned long long *clen, + const unsigned char *m,unsigned long long mlen, + const unsigned char *ad,unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k + ) +{ + mbedtls_gcm_context ctx; + unsigned char tag_buf[16]; + int ret; + + mbedtls_gcm_init( &ctx ); + ret = mbedtls_gcm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, k, 128); + ret = mbedtls_gcm_crypt_and_tag( &ctx, 1, mlen, npub, 12, ad, adlen, m, c, 16, tag_buf ); + mbedtls_gcm_free( &ctx ); + + return ret; +} + +int crypto_aead_decrypt( + unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k +) +{ + mbedtls_gcm_context ctx; + unsigned char tag_buf[16]; + int ret; + + mbedtls_gcm_init( &ctx ); + ret = mbedtls_gcm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, k, 128); + ret = mbedtls_gcm_crypt_and_tag( &ctx, 0, mlen, npub, 12, ad, adlen, m, c, 16, tag_buf ); + mbedtls_gcm_free( &ctx ); + + return ret; + +} +/* + * Precompute small multiples of H, that is set + * HH[i] || HL[i] = H times i, + * where i is seen as a field element as in [MGV], ie high-order bits + * correspond to low powers of P. The result is stored in the same way, that + * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL + * corresponds to P^127. + */ + +static int gcm_gen_table( mbedtls_gcm_context *ctx ) +{ + int ret, i, j; + uint64_t hi, lo; + uint64_t vl, vh; + unsigned char h[16]; + size_t olen = 0; + + memset( h, 0, 16 ); + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 ) + return( ret ); + + /* pack h as two 64-bits ints, big-endian */ + GET_UINT32_BE( hi, h, 0 ); + GET_UINT32_BE( lo, h, 4 ); + vh = (uint64_t) hi << 32 | lo; + + GET_UINT32_BE( hi, h, 8 ); + GET_UINT32_BE( lo, h, 12 ); + vl = (uint64_t) hi << 32 | lo; + + /* 8 = 1000 corresponds to 1 in GF(2^128) */ + ctx->HL[8] = vl; + ctx->HH[8] = vh; + +#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) + /* With CLMUL support, we need only h, not the rest of the table */ + if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) + return( 0 ); +#endif + + /* 0 corresponds to 0 in GF(2^128) */ + ctx->HH[0] = 0; + ctx->HL[0] = 0; + + for( i = 4; i > 0; i >>= 1 ) + { + uint32_t T = ( vl & 1 ) * 0xe1000000U; + vl = ( vh << 63 ) | ( vl >> 1 ); + vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32); + + ctx->HL[i] = vl; + ctx->HH[i] = vh; + } + + for( i = 2; i <= 8; i *= 2 ) + { + uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i; + vh = *HiH; + vl = *HiL; + for( j = 1; j < i; j++ ) + { + HiH[j] = vh ^ ctx->HH[j]; + HiL[j] = vl ^ ctx->HL[j]; + } + } + + return( 0 ); +} + +int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits ) +{ + int ret; + const mbedtls_cipher_info_t *cipher_info; + + GCM_VALIDATE_RET( ctx != NULL ); + GCM_VALIDATE_RET( key != NULL ); + GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 ); + + cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, + MBEDTLS_MODE_ECB ); + if( cipher_info == NULL ) + return( MBEDTLS_ERR_GCM_BAD_INPUT ); + + if( cipher_info->block_size != 16 ) + return( MBEDTLS_ERR_GCM_BAD_INPUT ); + + mbedtls_cipher_free( &ctx->cipher_ctx ); + + if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, + MBEDTLS_ENCRYPT ) ) != 0 ) + { + return( ret ); + } + + if( ( ret = gcm_gen_table( ctx ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +/* + * Shoup's method for multiplication use this table with + * last4[x] = x times P^128 + * where x and last4[x] are seen as elements of GF(2^128) as in [MGV] + */ +static const uint64_t last4[16] = +{ + 0x0000, 0x1c20, 0x3840, 0x2460, + 0x7080, 0x6ca0, 0x48c0, 0x54e0, + 0xe100, 0xfd20, 0xd940, 0xc560, + 0x9180, 0x8da0, 0xa9c0, 0xb5e0 +}; + +/* + * Sets output to x times H using the precomputed tables. + * x and output are seen as elements of GF(2^128) as in [MGV]. + */ +static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16], + unsigned char output[16] ) +{ + int i = 0; + unsigned char lo, hi, rem; + uint64_t zh, zl; + +#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) + if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) { + unsigned char h[16]; + + PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 ); + PUT_UINT32_BE( ctx->HH[8], h, 4 ); + PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 ); + PUT_UINT32_BE( ctx->HL[8], h, 12 ); + + mbedtls_aesni_gcm_mult( output, x, h ); + return; + } +#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */ + + lo = x[15] & 0xf; + + zh = ctx->HH[lo]; + zl = ctx->HL[lo]; + + for( i = 15; i >= 0; i-- ) + { + lo = x[i] & 0xf; + hi = x[i] >> 4; + + if( i != 15 ) + { + rem = (unsigned char) zl & 0xf; + zl = ( zh << 60 ) | ( zl >> 4 ); + zh = ( zh >> 4 ); + zh ^= (uint64_t) last4[rem] << 48; + zh ^= ctx->HH[lo]; + zl ^= ctx->HL[lo]; + + } + + rem = (unsigned char) zl & 0xf; + zl = ( zh << 60 ) | ( zl >> 4 ); + zh = ( zh >> 4 ); + zh ^= (uint64_t) last4[rem] << 48; + zh ^= ctx->HH[hi]; + zl ^= ctx->HL[hi]; + } + + PUT_UINT32_BE( zh >> 32, output, 0 ); + PUT_UINT32_BE( zh, output, 4 ); + PUT_UINT32_BE( zl >> 32, output, 8 ); + PUT_UINT32_BE( zl, output, 12 ); +} + +int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, + int mode, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len ) +{ + int ret; + unsigned char work_buf[16]; + size_t i; + const unsigned char *p; + size_t use_len, olen = 0; + + GCM_VALIDATE_RET( ctx != NULL ); + GCM_VALIDATE_RET( iv != NULL ); + GCM_VALIDATE_RET( add_len == 0 || add != NULL ); + + /* IV and AD are limited to 2^64 bits, so 2^61 bytes */ + /* IV is not allowed to be zero length */ + if( iv_len == 0 || + ( (uint64_t) iv_len ) >> 61 != 0 || + ( (uint64_t) add_len ) >> 61 != 0 ) + { + return( MBEDTLS_ERR_GCM_BAD_INPUT ); + } + + memset( ctx->y, 0x00, sizeof(ctx->y) ); + memset( ctx->buf, 0x00, sizeof(ctx->buf) ); + + ctx->mode = mode; + ctx->len = 0; + ctx->add_len = 0; + + if( iv_len == 12 ) + { + memcpy( ctx->y, iv, iv_len ); + ctx->y[15] = 1; + } + else + { + memset( work_buf, 0x00, 16 ); + PUT_UINT32_BE( iv_len * 8, work_buf, 12 ); + + p = iv; + while( iv_len > 0 ) + { + use_len = ( iv_len < 16 ) ? iv_len : 16; + + for( i = 0; i < use_len; i++ ) + ctx->y[i] ^= p[i]; + + gcm_mult( ctx, ctx->y, ctx->y ); + + iv_len -= use_len; + p += use_len; + } + + for( i = 0; i < 16; i++ ) + ctx->y[i] ^= work_buf[i]; + + gcm_mult( ctx, ctx->y, ctx->y ); + } + + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, + ctx->base_ectr, &olen ) ) != 0 ) + { + return( ret ); + } + + ctx->add_len = add_len; + p = add; + while( add_len > 0 ) + { + use_len = ( add_len < 16 ) ? add_len : 16; + + for( i = 0; i < use_len; i++ ) + ctx->buf[i] ^= p[i]; + + gcm_mult( ctx, ctx->buf, ctx->buf ); + + add_len -= use_len; + p += use_len; + } + + return( 0 ); +} + +int mbedtls_gcm_update( mbedtls_gcm_context *ctx, + size_t length, + const unsigned char *input, + unsigned char *output ) +{ + int ret; + unsigned char ectr[16]; + size_t i; + const unsigned char *p; + unsigned char *out_p = output; + size_t use_len, olen = 0; + + GCM_VALIDATE_RET( ctx != NULL ); + GCM_VALIDATE_RET( length == 0 || input != NULL ); + GCM_VALIDATE_RET( length == 0 || output != NULL ); + + if( output > input && (size_t) ( output - input ) < length ) + return( MBEDTLS_ERR_GCM_BAD_INPUT ); + + /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes + * Also check for possible overflow */ + if( ctx->len + length < ctx->len || + (uint64_t) ctx->len + length > 0xFFFFFFFE0ull ) + { + return( MBEDTLS_ERR_GCM_BAD_INPUT ); + } + + ctx->len += length; + + p = input; + while( length > 0 ) + { + use_len = ( length < 16 ) ? length : 16; + + for( i = 16; i > 12; i-- ) + if( ++ctx->y[i - 1] != 0 ) + break; + + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr, + &olen ) ) != 0 ) + { + return( ret ); + } + + for( i = 0; i < use_len; i++ ) + { + if( ctx->mode == MBEDTLS_GCM_DECRYPT ) + ctx->buf[i] ^= p[i]; + out_p[i] = ectr[i] ^ p[i]; + if( ctx->mode == MBEDTLS_GCM_ENCRYPT ) + ctx->buf[i] ^= out_p[i]; + } + + gcm_mult( ctx, ctx->buf, ctx->buf ); + + length -= use_len; + p += use_len; + out_p += use_len; + } + + return( 0 ); +} + +int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, + unsigned char *tag, + size_t tag_len ) +{ + unsigned char work_buf[16]; + size_t i; + uint64_t orig_len; + uint64_t orig_add_len; + + GCM_VALIDATE_RET( ctx != NULL ); + GCM_VALIDATE_RET( tag != NULL ); + + orig_len = ctx->len * 8; + orig_add_len = ctx->add_len * 8; + + if( tag_len > 16 || tag_len < 4 ) + return( MBEDTLS_ERR_GCM_BAD_INPUT ); + + memcpy( tag, ctx->base_ectr, tag_len ); + + if( orig_len || orig_add_len ) + { + memset( work_buf, 0x00, 16 ); + + PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 ); + PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 ); + PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 ); + PUT_UINT32_BE( ( orig_len ), work_buf, 12 ); + + for( i = 0; i < 16; i++ ) + ctx->buf[i] ^= work_buf[i]; + + gcm_mult( ctx, ctx->buf, ctx->buf ); + + for( i = 0; i < tag_len; i++ ) + tag[i] ^= ctx->buf[i]; + } + + return( 0 ); +} + +int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, + int mode, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *input, + unsigned char *output, + size_t tag_len, + unsigned char *tag ) +{ + int ret; + + GCM_VALIDATE_RET( ctx != NULL ); + GCM_VALIDATE_RET( iv != NULL ); + GCM_VALIDATE_RET( add_len == 0 || add != NULL ); + GCM_VALIDATE_RET( length == 0 || input != NULL ); + GCM_VALIDATE_RET( length == 0 || output != NULL ); + GCM_VALIDATE_RET( tag != NULL ); + + if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *tag, + size_t tag_len, + const unsigned char *input, + unsigned char *output ) +{ + int ret; + unsigned char check_tag[16]; + size_t i; + int diff; + + GCM_VALIDATE_RET( ctx != NULL ); + GCM_VALIDATE_RET( iv != NULL ); + GCM_VALIDATE_RET( add_len == 0 || add != NULL ); + GCM_VALIDATE_RET( tag != NULL ); + GCM_VALIDATE_RET( length == 0 || input != NULL ); + GCM_VALIDATE_RET( length == 0 || output != NULL ); + + if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length, + iv, iv_len, add, add_len, + input, output, tag_len, check_tag ) ) != 0 ) + { + return( ret ); + } + + /* Check tag in "constant-time" */ + for( diff = 0, i = 0; i < tag_len; i++ ) + diff |= tag[i] ^ check_tag[i]; + + if( diff != 0 ) + { + mbedtls_platform_zeroize( output, length ); + return( MBEDTLS_ERR_GCM_AUTH_FAILED ); + } + + return( 0 ); +} + +void mbedtls_gcm_free( mbedtls_gcm_context *ctx ) +{ + if( ctx == NULL ) + return; + mbedtls_cipher_free( &ctx->cipher_ctx ); + mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) ); +} + +#endif /* !MBEDTLS_GCM_ALT */ + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +/* + * AES-GCM test vectors from: + * + * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip + */ +#define MAX_TESTS 6 + +static const int key_index_test_data[MAX_TESTS] = + { 0, 0, 1, 1, 1, 1 }; + +static const unsigned char key_test_data[MAX_TESTS][32] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, +}; + +static const size_t iv_len_test_data[MAX_TESTS] = + { 12, 12, 12, 12, 8, 60 }; + +static const int iv_index_test_data[MAX_TESTS] = + { 0, 0, 1, 1, 1, 2 }; + +static const unsigned char iv_test_data[MAX_TESTS][64] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b }, +}; + +static const size_t add_len_test_data[MAX_TESTS] = + { 0, 0, 0, 20, 20, 20 }; + +static const int add_index_test_data[MAX_TESTS] = + { 0, 0, 0, 1, 1, 1 }; + +static const unsigned char additional_test_data[MAX_TESTS][64] = +{ + { 0x00 }, + { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2 }, +}; + +static const size_t pt_len_test_data[MAX_TESTS] = + { 0, 16, 64, 60, 60, 60 }; + +static const int pt_index_test_data[MAX_TESTS] = + { 0, 0, 1, 1, 1, 1 }; + +static const unsigned char pt_test_data[MAX_TESTS][64] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, +}; + +static const unsigned char ct_test_data[MAX_TESTS * 3][64] = +{ + { 0x00 }, + { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, + 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, + { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 }, + { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91 }, + { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, + 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, + 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, + 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, + 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, + 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, + 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, + 0xc2, 0x3f, 0x45, 0x98 }, + { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, + 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, + 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, + 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, + 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, + 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, + 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, + 0x4c, 0x34, 0xae, 0xe5 }, + { 0x00 }, + { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, + 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 }, + { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 }, + { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10 }, + { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, + 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, + 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, + 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, + 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, + 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, + 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, + 0xa0, 0xf0, 0x62, 0xf7 }, + { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, + 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, + 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, + 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, + 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, + 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, + 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, + 0xe9, 0xb7, 0x37, 0x3b }, + { 0x00 }, + { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, + 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 }, + { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad }, + { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62 }, + { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, + 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, + 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, + 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, + 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, + 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, + 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, + 0xf4, 0x7c, 0x9b, 0x1f }, + { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, + 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, + 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, + 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, + 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, + 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, + 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, + 0x44, 0xae, 0x7e, 0x3f }, +}; + +static const unsigned char tag_test_data[MAX_TESTS * 3][16] = +{ + { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, + 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }, + { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, + 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }, + { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, + 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 }, + { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, + 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 }, + { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, + 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb }, + { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, + 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 }, + { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, + 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 }, + { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, + 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb }, + { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, + 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 }, + { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, + 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c }, + { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, + 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 }, + { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, + 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 }, + { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, + 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b }, + { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, + 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 }, + { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, + 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c }, + { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, + 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b }, + { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, + 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 }, + { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, + 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a }, +}; + +int mbedtls_gcm_self_test( int verbose ) +{ + mbedtls_gcm_context ctx; + unsigned char buf[64]; + unsigned char tag_buf[16]; + int i, j, ret; + mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; + + for( j = 0; j < 3; j++ ) + { + int key_len = 128 + 64 * j; + + for( i = 0; i < MAX_TESTS; i++ ) + { + mbedtls_gcm_init( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( " AES-GCM-%3d #%d (%s): ", + key_len, i, "enc" ); + + ret = mbedtls_gcm_setkey( &ctx, cipher, + key_test_data[key_index_test_data[i]], + key_len ); + /* + * AES-192 is an optional feature that may be unavailable when + * there is an alternative underlying implementation i.e. when + * MBEDTLS_AES_ALT is defined. + */ + if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 ) + { + mbedtls_printf( "skipped\n" ); + break; + } + else if( ret != 0 ) + { + goto exit; + } + + ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT, + pt_len_test_data[i], + iv_test_data[iv_index_test_data[i]], + iv_len_test_data[i], + additional_test_data[add_index_test_data[i]], + add_len_test_data[i], + pt_test_data[pt_index_test_data[i]], + buf, 16, tag_buf ); + if( ret != 0 ) + goto exit; + + if ( memcmp( buf, ct_test_data[j * 6 + i], + pt_len_test_data[i] ) != 0 || + memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 ) + { + ret = 1; + goto exit; + } + + mbedtls_gcm_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + mbedtls_gcm_init( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( " AES-GCM-%3d #%d (%s): ", + key_len, i, "dec" ); + + ret = mbedtls_gcm_setkey( &ctx, cipher, + key_test_data[key_index_test_data[i]], + key_len ); + if( ret != 0 ) + goto exit; + + ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT, + pt_len_test_data[i], + iv_test_data[iv_index_test_data[i]], + iv_len_test_data[i], + additional_test_data[add_index_test_data[i]], + add_len_test_data[i], + ct_test_data[j * 6 + i], buf, 16, tag_buf ); + + if( ret != 0 ) + goto exit; + + if( memcmp( buf, pt_test_data[pt_index_test_data[i]], + pt_len_test_data[i] ) != 0 || + memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 ) + { + ret = 1; + goto exit; + } + + mbedtls_gcm_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + mbedtls_gcm_init( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", + key_len, i, "enc" ); + + ret = mbedtls_gcm_setkey( &ctx, cipher, + key_test_data[key_index_test_data[i]], + key_len ); + if( ret != 0 ) + goto exit; + + ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT, + iv_test_data[iv_index_test_data[i]], + iv_len_test_data[i], + additional_test_data[add_index_test_data[i]], + add_len_test_data[i] ); + if( ret != 0 ) + goto exit; + + if( pt_len_test_data[i] > 32 ) + { + size_t rest_len = pt_len_test_data[i] - 32; + ret = mbedtls_gcm_update( &ctx, 32, + pt_test_data[pt_index_test_data[i]], + buf ); + if( ret != 0 ) + goto exit; + + ret = mbedtls_gcm_update( &ctx, rest_len, + pt_test_data[pt_index_test_data[i]] + 32, + buf + 32 ); + if( ret != 0 ) + goto exit; + } + else + { + ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i], + pt_test_data[pt_index_test_data[i]], + buf ); + if( ret != 0 ) + goto exit; + } + + ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); + if( ret != 0 ) + goto exit; + + if( memcmp( buf, ct_test_data[j * 6 + i], + pt_len_test_data[i] ) != 0 || + memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 ) + { + ret = 1; + goto exit; + } + + mbedtls_gcm_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + mbedtls_gcm_init( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", + key_len, i, "dec" ); + + ret = mbedtls_gcm_setkey( &ctx, cipher, + key_test_data[key_index_test_data[i]], + key_len ); + if( ret != 0 ) + goto exit; + + ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT, + iv_test_data[iv_index_test_data[i]], + iv_len_test_data[i], + additional_test_data[add_index_test_data[i]], + add_len_test_data[i] ); + if( ret != 0 ) + goto exit; + + if( pt_len_test_data[i] > 32 ) + { + size_t rest_len = pt_len_test_data[i] - 32; + ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i], + buf ); + if( ret != 0 ) + goto exit; + + ret = mbedtls_gcm_update( &ctx, rest_len, + ct_test_data[j * 6 + i] + 32, + buf + 32 ); + if( ret != 0 ) + goto exit; + } + else + { + ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i], + ct_test_data[j * 6 + i], + buf ); + if( ret != 0 ) + goto exit; + } + + ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); + if( ret != 0 ) + goto exit; + + if( memcmp( buf, pt_test_data[pt_index_test_data[i]], + pt_len_test_data[i] ) != 0 || + memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 ) + { + ret = 1; + goto exit; + } + + mbedtls_gcm_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + ret = 0; + +exit: + if( ret != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + mbedtls_gcm_free( &ctx ); + } + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +#endif /* MBEDTLS_GCM_C */ diff --git a/mbed_aes_gcm/gcm.h b/mbed_aes_gcm/gcm.h new file mode 100644 index 0000000..fd130ab --- /dev/null +++ b/mbed_aes_gcm/gcm.h @@ -0,0 +1,326 @@ +/** + * \file gcm.h + * + * \brief This file contains GCM definitions and functions. + * + * The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined + * in D. McGrew, J. Viega, The Galois/Counter Mode of Operation + * (GCM), Natl. Inst. Stand. Technol. + * + * For more information on GCM, see NIST SP 800-38D: Recommendation for + * Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC. + * + */ +/* + * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of Mbed TLS (https://tls.mbed.org) + */ + +#ifndef MBEDTLS_GCM_H +#define MBEDTLS_GCM_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "cipher.h" + +#include + +#define MBEDTLS_GCM_ENCRYPT 1 +#define MBEDTLS_GCM_DECRYPT 0 + +#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */ + +/* MBEDTLS_ERR_GCM_HW_ACCEL_FAILED is deprecated and should not be used. */ +#define MBEDTLS_ERR_GCM_HW_ACCEL_FAILED -0x0013 /**< GCM hardware accelerator failed. */ + +#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(MBEDTLS_GCM_ALT) + +/** + * \brief The GCM context structure. + */ +typedef struct mbedtls_gcm_context +{ + mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */ + uint64_t HL[16]; /*!< Precalculated HTable low. */ + uint64_t HH[16]; /*!< Precalculated HTable high. */ + uint64_t len; /*!< The total length of the encrypted data. */ + uint64_t add_len; /*!< The total length of the additional data. */ + unsigned char base_ectr[16]; /*!< The first ECTR for tag. */ + unsigned char y[16]; /*!< The Y working value. */ + unsigned char buf[16]; /*!< The buf working value. */ + int mode; /*!< The operation to perform: + #MBEDTLS_GCM_ENCRYPT or + #MBEDTLS_GCM_DECRYPT. */ +} +mbedtls_gcm_context; + +#else /* !MBEDTLS_GCM_ALT */ +#include "gcm_alt.h" +#endif /* !MBEDTLS_GCM_ALT */ + +/** + * \brief This function initializes the specified GCM context, + * to make references valid, and prepares the context + * for mbedtls_gcm_setkey() or mbedtls_gcm_free(). + * + * The function does not bind the GCM context to a particular + * cipher, nor set the key. For this purpose, use + * mbedtls_gcm_setkey(). + * + * \param ctx The GCM context to initialize. This must not be \c NULL. + */ +void mbedtls_gcm_init( mbedtls_gcm_context *ctx ); + +/** + * \brief This function associates a GCM context with a + * cipher algorithm and a key. + * + * \param ctx The GCM context. This must be initialized. + * \param cipher The 128-bit block cipher to use. + * \param key The encryption key. This must be a readable buffer of at + * least \p keybits bits. + * \param keybits The key size in bits. Valid options are: + *
  • 128 bits
  • + *
  • 192 bits
  • + *
  • 256 bits
+ * + * \return \c 0 on success. + * \return A cipher-specific error code on failure. + */ +int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits ); + +/** + * \brief This function performs GCM encryption or decryption of a buffer. + * + * \note For encryption, the output buffer can be the same as the + * input buffer. For decryption, the output buffer cannot be + * the same as input buffer. If the buffers overlap, the output + * buffer must trail at least 8 Bytes behind the input buffer. + * + * \warning When this function performs a decryption, it outputs the + * authentication tag and does not verify that the data is + * authentic. You should use this function to perform encryption + * only. For decryption, use mbedtls_gcm_auth_decrypt() instead. + * + * \param ctx The GCM context to use for encryption or decryption. This + * must be initialized. + * \param mode The operation to perform: + * - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption. + * The ciphertext is written to \p output and the + * authentication tag is written to \p tag. + * - #MBEDTLS_GCM_DECRYPT to perform decryption. + * The plaintext is written to \p output and the + * authentication tag is written to \p tag. + * Note that this mode is not recommended, because it does + * not verify the authenticity of the data. For this reason, + * you should use mbedtls_gcm_auth_decrypt() instead of + * calling this function in decryption mode. + * \param length The length of the input data, which is equal to the length + * of the output data. + * \param iv The initialization vector. This must be a readable buffer of + * at least \p iv_len Bytes. + * \param iv_len The length of the IV. + * \param add The buffer holding the additional data. This must be of at + * least that size in Bytes. + * \param add_len The length of the additional data. + * \param input The buffer holding the input data. If \p length is greater + * than zero, this must be a readable buffer of at least that + * size in Bytes. + * \param output The buffer for holding the output data. If \p length is greater + * than zero, this must be a writable buffer of at least that + * size in Bytes. + * \param tag_len The length of the tag to generate. + * \param tag The buffer for holding the tag. This must be a readable + * buffer of at least \p tag_len Bytes. + * + * \return \c 0 if the encryption or decryption was performed + * successfully. Note that in #MBEDTLS_GCM_DECRYPT mode, + * this does not indicate that the data is authentic. + * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are + * not valid or a cipher-specific error code if the encryption + * or decryption failed. + */ +int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, + int mode, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *input, + unsigned char *output, + size_t tag_len, + unsigned char *tag ); + +/** + * \brief This function performs a GCM authenticated decryption of a + * buffer. + * + * \note For decryption, the output buffer cannot be the same as + * input buffer. If the buffers overlap, the output buffer + * must trail at least 8 Bytes behind the input buffer. + * + * \param ctx The GCM context. This must be initialized. + * \param length The length of the ciphertext to decrypt, which is also + * the length of the decrypted plaintext. + * \param iv The initialization vector. This must be a readable buffer + * of at least \p iv_len Bytes. + * \param iv_len The length of the IV. + * \param add The buffer holding the additional data. This must be of at + * least that size in Bytes. + * \param add_len The length of the additional data. + * \param tag The buffer holding the tag to verify. This must be a + * readable buffer of at least \p tag_len Bytes. + * \param tag_len The length of the tag to verify. + * \param input The buffer holding the ciphertext. If \p length is greater + * than zero, this must be a readable buffer of at least that + * size. + * \param output The buffer for holding the decrypted plaintext. If \p length + * is greater than zero, this must be a writable buffer of at + * least that size. + * + * \return \c 0 if successful and authenticated. + * \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match. + * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are + * not valid or a cipher-specific error code if the decryption + * failed. + */ +int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *tag, + size_t tag_len, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief This function starts a GCM encryption or decryption + * operation. + * + * \param ctx The GCM context. This must be initialized. + * \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or + * #MBEDTLS_GCM_DECRYPT. + * \param iv The initialization vector. This must be a readable buffer of + * at least \p iv_len Bytes. + * \param iv_len The length of the IV. + * \param add The buffer holding the additional data, or \c NULL + * if \p add_len is \c 0. + * \param add_len The length of the additional data. If \c 0, + * \p add may be \c NULL. + * + * \return \c 0 on success. + */ +int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, + int mode, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len ); + +/** + * \brief This function feeds an input buffer into an ongoing GCM + * encryption or decryption operation. + * + * ` The function expects input to be a multiple of 16 + * Bytes. Only the last call before calling + * mbedtls_gcm_finish() can be less than 16 Bytes. + * + * \note For decryption, the output buffer cannot be the same as + * input buffer. If the buffers overlap, the output buffer + * must trail at least 8 Bytes behind the input buffer. + * + * \param ctx The GCM context. This must be initialized. + * \param length The length of the input data. This must be a multiple of + * 16 except in the last call before mbedtls_gcm_finish(). + * \param input The buffer holding the input data. If \p length is greater + * than zero, this must be a readable buffer of at least that + * size in Bytes. + * \param output The buffer for holding the output data. If \p length is + * greater than zero, this must be a writable buffer of at + * least that size in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure. + */ +int mbedtls_gcm_update( mbedtls_gcm_context *ctx, + size_t length, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief This function finishes the GCM operation and generates + * the authentication tag. + * + * It wraps up the GCM stream, and generates the + * tag. The tag can have a maximum length of 16 Bytes. + * + * \param ctx The GCM context. This must be initialized. + * \param tag The buffer for holding the tag. This must be a readable + * buffer of at least \p tag_len Bytes. + * \param tag_len The length of the tag to generate. This must be at least + * four. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure. + */ +int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, + unsigned char *tag, + size_t tag_len ); + +/** + * \brief This function clears a GCM context and the underlying + * cipher sub-context. + * + * \param ctx The GCM context to clear. If this is \c NULL, the call has + * no effect. Otherwise, this must be initialized. + */ +void mbedtls_gcm_free( mbedtls_gcm_context *ctx ); + +#if defined(MBEDTLS_SELF_TEST) + +/** + * \brief The GCM checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_gcm_self_test( int verbose ); + +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + + +#endif /* gcm.h */ diff --git a/mbed_aes_gcm/main. b/mbed_aes_gcm/main. new file mode 100644 index 0000000..fdb53a3 --- /dev/null +++ b/mbed_aes_gcm/main. @@ -0,0 +1,54 @@ +#include "gcm.h" +#include "platform_util.h" +#include "api.h" +#include +#include "crypto_aead.h" + +static void single_encryption(void) { + // 32 bytes.. that's 256 bits + const unsigned char k[32] = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }; + unsigned char c[64] = { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, +0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85}; + unsigned char npub[12] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }; + unsigned char ad[1400]; + unsigned long long adlen = 0; + unsigned long long mlen = 0; + unsigned long long clen = 64; + unsigned char m[1400]; + unsigned char nsec[CRYPTO_NSECBYTES]; + + + //mbedtls_gcm_init( &ctx ); + // 128 bits, not bytes! + //ret = mbedtls_gcm_setkey( &ctx, cipher, key, 128 ); + + // Context, flag (1/0), length, nonce, nonce_len, AD, AD_len, PT, output, tag_len, tag + //ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, 64, initial_value, 12, additional, 0, plaintext, buf, 16, tag_buf); + //mbedtls_gcm_free( &ctx ); + + int res; + + res = crypto_aead_decrypt(m, mlen, nsec, c, clen, ad, adlen, npub, k); + if (res == 0) { + printf("Local decryption test workerino!\n"); + } else { + printf("Local test failed -.-\n"); + } + +} + +int main(void) { + //mbedtls_gcm_self_test(1); + single_encryption(); + return 0; +} diff --git a/mbed_aes_gcm/main.c b/mbed_aes_gcm/main.c new file mode 100644 index 0000000..fdb53a3 --- /dev/null +++ b/mbed_aes_gcm/main.c @@ -0,0 +1,54 @@ +#include "gcm.h" +#include "platform_util.h" +#include "api.h" +#include +#include "crypto_aead.h" + +static void single_encryption(void) { + // 32 bytes.. that's 256 bits + const unsigned char k[32] = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }; + unsigned char c[64] = { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, +0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85}; + unsigned char npub[12] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }; + unsigned char ad[1400]; + unsigned long long adlen = 0; + unsigned long long mlen = 0; + unsigned long long clen = 64; + unsigned char m[1400]; + unsigned char nsec[CRYPTO_NSECBYTES]; + + + //mbedtls_gcm_init( &ctx ); + // 128 bits, not bytes! + //ret = mbedtls_gcm_setkey( &ctx, cipher, key, 128 ); + + // Context, flag (1/0), length, nonce, nonce_len, AD, AD_len, PT, output, tag_len, tag + //ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, 64, initial_value, 12, additional, 0, plaintext, buf, 16, tag_buf); + //mbedtls_gcm_free( &ctx ); + + int res; + + res = crypto_aead_decrypt(m, mlen, nsec, c, clen, ad, adlen, npub, k); + if (res == 0) { + printf("Local decryption test workerino!\n"); + } else { + printf("Local test failed -.-\n"); + } + +} + +int main(void) { + //mbedtls_gcm_self_test(1); + single_encryption(); + return 0; +} diff --git a/mbed_aes_gcm/platform.c b/mbed_aes_gcm/platform.c new file mode 100644 index 0000000..8792873 --- /dev/null +++ b/mbed_aes_gcm/platform.c @@ -0,0 +1,391 @@ +/* + * Platform abstraction layer + * + * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PLATFORM_C) + +#include "platform.h" +#include "platform_util.h" + +/* The compile time configuration of memory allocation via the macros + * MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO takes precedence over the runtime + * configuration via mbedtls_platform_set_calloc_free(). So, omit everything + * related to the latter if MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO are defined. */ +#if defined(MBEDTLS_PLATFORM_MEMORY) && \ + !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && \ + defined(MBEDTLS_PLATFORM_FREE_MACRO) ) + +#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) +static void *platform_calloc_uninit( size_t n, size_t size ) +{ + ((void) n); + ((void) size); + return( NULL ); +} + +#define MBEDTLS_PLATFORM_STD_CALLOC platform_calloc_uninit +#endif /* !MBEDTLS_PLATFORM_STD_CALLOC */ + +#if !defined(MBEDTLS_PLATFORM_STD_FREE) +static void platform_free_uninit( void *ptr ) +{ + ((void) ptr); +} + +#define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit +#endif /* !MBEDTLS_PLATFORM_STD_FREE */ + +static void * (*mbedtls_calloc_func)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC; +static void (*mbedtls_free_func)( void * ) = MBEDTLS_PLATFORM_STD_FREE; + +void * mbedtls_calloc( size_t nmemb, size_t size ) +{ + return (*mbedtls_calloc_func)( nmemb, size ); +} + +void mbedtls_free( void * ptr ) +{ + (*mbedtls_free_func)( ptr ); +} + +int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), + void (*free_func)( void * ) ) +{ + mbedtls_calloc_func = calloc_func; + mbedtls_free_func = free_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_MEMORY && + !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && + defined(MBEDTLS_PLATFORM_FREE_MACRO) ) */ + +#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF) +#include +int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ) +{ + int ret; + va_list argp; + + va_start( argp, fmt ); + ret = mbedtls_vsnprintf( s, n, fmt, argp ); + va_end( argp ); + + return( ret ); +} +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_snprintf_uninit( char * s, size_t n, + const char * format, ... ) +{ + ((void) s); + ((void) n); + ((void) format); + return( 0 ); +} + +#define MBEDTLS_PLATFORM_STD_SNPRINTF platform_snprintf_uninit +#endif /* !MBEDTLS_PLATFORM_STD_SNPRINTF */ + +int (*mbedtls_snprintf)( char * s, size_t n, + const char * format, + ... ) = MBEDTLS_PLATFORM_STD_SNPRINTF; + +int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, + const char * format, + ... ) ) +{ + mbedtls_snprintf = snprintf_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ + +#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF) +#include +int mbedtls_platform_win32_vsnprintf( char *s, size_t n, const char *fmt, va_list arg ) +{ + int ret; + + /* Avoid calling the invalid parameter handler by checking ourselves */ + if( s == NULL || n == 0 || fmt == NULL ) + return( -1 ); + +#if defined(_TRUNCATE) + ret = vsnprintf_s( s, n, _TRUNCATE, fmt, arg ); +#else + ret = vsnprintf( s, n, fmt, arg ); + if( ret < 0 || (size_t) ret == n ) + { + s[n-1] = '\0'; + ret = -1; + } +#endif + + return( ret ); +} +#endif + +#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_vsnprintf_uninit( char * s, size_t n, + const char * format, va_list arg ) +{ + ((void) s); + ((void) n); + ((void) format); + ((void) arg); + return( -1 ); +} + +#define MBEDTLS_PLATFORM_STD_VSNPRINTF platform_vsnprintf_uninit +#endif /* !MBEDTLS_PLATFORM_STD_VSNPRINTF */ + +int (*mbedtls_vsnprintf)( char * s, size_t n, + const char * format, + va_list arg ) = MBEDTLS_PLATFORM_STD_VSNPRINTF; + +int mbedtls_platform_set_vsnprintf( int (*vsnprintf_func)( char * s, size_t n, + const char * format, + va_list arg ) ) +{ + mbedtls_vsnprintf = vsnprintf_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */ + +#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_printf_uninit( const char *format, ... ) +{ + ((void) format); + return( 0 ); +} + +#define MBEDTLS_PLATFORM_STD_PRINTF platform_printf_uninit +#endif /* !MBEDTLS_PLATFORM_STD_PRINTF */ + +int (*mbedtls_printf)( const char *, ... ) = MBEDTLS_PLATFORM_STD_PRINTF; + +int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) ) +{ + mbedtls_printf = printf_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ + +#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_fprintf_uninit( FILE *stream, const char *format, ... ) +{ + ((void) stream); + ((void) format); + return( 0 ); +} + +#define MBEDTLS_PLATFORM_STD_FPRINTF platform_fprintf_uninit +#endif /* !MBEDTLS_PLATFORM_STD_FPRINTF */ + +int (*mbedtls_fprintf)( FILE *, const char *, ... ) = + MBEDTLS_PLATFORM_STD_FPRINTF; + +int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *, const char *, ... ) ) +{ + mbedtls_fprintf = fprintf_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ + +#if defined(MBEDTLS_PLATFORM_EXIT_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_EXIT) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static void platform_exit_uninit( int status ) +{ + ((void) status); +} + +#define MBEDTLS_PLATFORM_STD_EXIT platform_exit_uninit +#endif /* !MBEDTLS_PLATFORM_STD_EXIT */ + +void (*mbedtls_exit)( int status ) = MBEDTLS_PLATFORM_STD_EXIT; + +int mbedtls_platform_set_exit( void (*exit_func)( int status ) ) +{ + mbedtls_exit = exit_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ + +#if defined(MBEDTLS_HAVE_TIME) + +#if defined(MBEDTLS_PLATFORM_TIME_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_TIME) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static mbedtls_time_t platform_time_uninit( mbedtls_time_t* timer ) +{ + ((void) timer); + return( 0 ); +} + +#define MBEDTLS_PLATFORM_STD_TIME platform_time_uninit +#endif /* !MBEDTLS_PLATFORM_STD_TIME */ + +mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* timer ) = MBEDTLS_PLATFORM_STD_TIME; + +int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* timer ) ) +{ + mbedtls_time = time_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_TIME_ALT */ + +#endif /* MBEDTLS_HAVE_TIME */ + +#if defined(MBEDTLS_ENTROPY_NV_SEED) +#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) +/* Default implementations for the platform independent seed functions use + * standard libc file functions to read from and write to a pre-defined filename + */ +int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ) +{ + FILE *file; + size_t n; + + if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL ) + return( -1 ); + + if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len ) + { + fclose( file ); + mbedtls_platform_zeroize( buf, buf_len ); + return( -1 ); + } + + fclose( file ); + return( (int)n ); +} + +int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len ) +{ + FILE *file; + size_t n; + + if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL ) + return -1; + + if( ( n = fwrite( buf, 1, buf_len, file ) ) != buf_len ) + { + fclose( file ); + return -1; + } + + fclose( file ); + return( (int)n ); +} +#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ + +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_nv_seed_read_uninit( unsigned char *buf, size_t buf_len ) +{ + ((void) buf); + ((void) buf_len); + return( -1 ); +} + +#define MBEDTLS_PLATFORM_STD_NV_SEED_READ platform_nv_seed_read_uninit +#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_READ */ + +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_nv_seed_write_uninit( unsigned char *buf, size_t buf_len ) +{ + ((void) buf); + ((void) buf_len); + return( -1 ); +} + +#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE platform_nv_seed_write_uninit +#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_WRITE */ + +int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) = + MBEDTLS_PLATFORM_STD_NV_SEED_READ; +int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) = + MBEDTLS_PLATFORM_STD_NV_SEED_WRITE; + +int mbedtls_platform_set_nv_seed( + int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ), + int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) ) +{ + mbedtls_nv_seed_read = nv_seed_read_func; + mbedtls_nv_seed_write = nv_seed_write_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ +#endif /* MBEDTLS_ENTROPY_NV_SEED */ + +#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) +/* + * Placeholder platform setup that does nothing by default + */ +int mbedtls_platform_setup( mbedtls_platform_context *ctx ) +{ + (void)ctx; + + return( 0 ); +} + +/* + * Placeholder platform teardown that does nothing by default + */ +void mbedtls_platform_teardown( mbedtls_platform_context *ctx ) +{ + (void)ctx; +} +#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ + +#endif /* MBEDTLS_PLATFORM_C */ diff --git a/mbed_aes_gcm/platform.h b/mbed_aes_gcm/platform.h new file mode 100644 index 0000000..363d6b3 --- /dev/null +++ b/mbed_aes_gcm/platform.h @@ -0,0 +1,419 @@ +/** + * \file platform.h + * + * \brief This file contains the definitions and functions of the + * Mbed TLS platform abstraction layer. + * + * The platform abstraction layer removes the need for the library + * to directly link to standard C library functions or operating + * system services, making the library easier to port and embed. + * Application developers and users of the library can provide their own + * implementations of these functions, or implementations specific to + * their platform, which can be statically linked to the library or + * dynamically configured at runtime. + */ +/* + * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of Mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_PLATFORM_H +#define MBEDTLS_PLATFORM_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_HAVE_TIME) +#include "platform_time.h" +#endif + +#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED -0x0070 /**< Hardware accelerator failed */ +#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED -0x0072 /**< The requested feature is not supported by the platform */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +/* The older Microsoft Windows common runtime provides non-conforming + * implementations of some standard library functions, including snprintf + * and vsnprintf. This affects MSVC and MinGW builds. + */ +#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900) +#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF +#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF +#endif + +#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) +#include +#include +#include +#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) +#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF) +#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use. */ +#else +#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< The default \c snprintf function to use. */ +#endif +#endif +#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF) +#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF) +#define MBEDTLS_PLATFORM_STD_VSNPRINTF mbedtls_platform_win32_vsnprintf /**< The default \c vsnprintf function to use. */ +#else +#define MBEDTLS_PLATFORM_STD_VSNPRINTF vsnprintf /**< The default \c vsnprintf function to use. */ +#endif +#endif +#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) +#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< The default \c printf function to use. */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) +#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< The default \c fprintf function to use. */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) +#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< The default \c calloc function to use. */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_FREE) +#define MBEDTLS_PLATFORM_STD_FREE free /**< The default \c free function to use. */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_EXIT) +#define MBEDTLS_PLATFORM_STD_EXIT exit /**< The default \c exit function to use. */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_TIME) +#define MBEDTLS_PLATFORM_STD_TIME time /**< The default \c time function to use. */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) +#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS /**< The default exit value to use. */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) +#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE /**< The default exit value to use. */ +#endif +#if defined(MBEDTLS_FS_IO) +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) +#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read +#endif +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) +#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write +#endif +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE) +#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" +#endif +#endif /* MBEDTLS_FS_IO */ +#else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ +#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) +#include MBEDTLS_PLATFORM_STD_MEM_HDR +#endif +#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ + + +/* \} name SECTION: Module settings */ + +/* + * The function pointers for calloc and free. + */ +#if defined(MBEDTLS_PLATFORM_MEMORY) +#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \ + defined(MBEDTLS_PLATFORM_CALLOC_MACRO) +#define mbedtls_free MBEDTLS_PLATFORM_FREE_MACRO +#define mbedtls_calloc MBEDTLS_PLATFORM_CALLOC_MACRO +#else +/* For size_t */ +#include +extern void *mbedtls_calloc( size_t n, size_t size ); +extern void mbedtls_free( void *ptr ); + +/** + * \brief This function dynamically sets the memory-management + * functions used by the library, during runtime. + * + * \param calloc_func The \c calloc function implementation. + * \param free_func The \c free function implementation. + * + * \return \c 0. + */ +int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), + void (*free_func)( void * ) ); +#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */ +#else /* !MBEDTLS_PLATFORM_MEMORY */ +#define mbedtls_free free +#define mbedtls_calloc calloc +#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */ + +/* + * The function pointers for fprintf + */ +#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) +/* We need FILE * */ +#include +extern int (*mbedtls_fprintf)( FILE *stream, const char *format, ... ); + +/** + * \brief This function dynamically configures the fprintf + * function that is called when the + * mbedtls_fprintf() function is invoked by the library. + * + * \param fprintf_func The \c fprintf function implementation. + * + * \return \c 0. + */ +int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *, + ... ) ); +#else +#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) +#define mbedtls_fprintf MBEDTLS_PLATFORM_FPRINTF_MACRO +#else +#define mbedtls_fprintf fprintf +#endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */ +#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ + +/* + * The function pointers for printf + */ +#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) +extern int (*mbedtls_printf)( const char *format, ... ); + +/** + * \brief This function dynamically configures the snprintf + * function that is called when the mbedtls_snprintf() + * function is invoked by the library. + * + * \param printf_func The \c printf function implementation. + * + * \return \c 0 on success. + */ +int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) ); +#else /* !MBEDTLS_PLATFORM_PRINTF_ALT */ +#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) +#define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO +#else +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */ +#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ + +/* + * The function pointers for snprintf + * + * The snprintf implementation should conform to C99: + * - it *must* always correctly zero-terminate the buffer + * (except when n == 0, then it must leave the buffer untouched) + * - however it is acceptable to return -1 instead of the required length when + * the destination buffer is too short. + */ +#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF) +/* For Windows (inc. MSYS2), we provide our own fixed implementation */ +int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ); +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) +extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... ); + +/** + * \brief This function allows configuring a custom + * \c snprintf function pointer. + * + * \param snprintf_func The \c snprintf function implementation. + * + * \return \c 0 on success. + */ +int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, + const char * format, ... ) ); +#else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ +#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) +#define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO +#else +#define mbedtls_snprintf MBEDTLS_PLATFORM_STD_SNPRINTF +#endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */ +#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ + +/* + * The function pointers for vsnprintf + * + * The vsnprintf implementation should conform to C99: + * - it *must* always correctly zero-terminate the buffer + * (except when n == 0, then it must leave the buffer untouched) + * - however it is acceptable to return -1 instead of the required length when + * the destination buffer is too short. + */ +#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF) +#include +/* For Older Windows (inc. MSYS2), we provide our own fixed implementation */ +int mbedtls_platform_win32_vsnprintf( char *s, size_t n, const char *fmt, va_list arg ); +#endif + +#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) +#include +extern int (*mbedtls_vsnprintf)( char * s, size_t n, const char * format, va_list arg ); + +/** + * \brief Set your own snprintf function pointer + * + * \param vsnprintf_func The \c vsnprintf function implementation + * + * \return \c 0 + */ +int mbedtls_platform_set_vsnprintf( int (*vsnprintf_func)( char * s, size_t n, + const char * format, va_list arg ) ); +#else /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */ +#if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO) +#define mbedtls_vsnprintf MBEDTLS_PLATFORM_VSNPRINTF_MACRO +#else +#define mbedtls_vsnprintf vsnprintf +#endif /* MBEDTLS_PLATFORM_VSNPRINTF_MACRO */ +#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */ + +/* + * The function pointers for exit + */ +#if defined(MBEDTLS_PLATFORM_EXIT_ALT) +extern void (*mbedtls_exit)( int status ); + +/** + * \brief This function dynamically configures the exit + * function that is called when the mbedtls_exit() + * function is invoked by the library. + * + * \param exit_func The \c exit function implementation. + * + * \return \c 0 on success. + */ +int mbedtls_platform_set_exit( void (*exit_func)( int status ) ); +#else +#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) +#define mbedtls_exit MBEDTLS_PLATFORM_EXIT_MACRO +#else +#define mbedtls_exit exit +#endif /* MBEDTLS_PLATFORM_EXIT_MACRO */ +#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ + +/* + * The default exit values + */ +#if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) +#define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS +#else +#define MBEDTLS_EXIT_SUCCESS 0 +#endif +#if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) +#define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE +#else +#define MBEDTLS_EXIT_FAILURE 1 +#endif + +/* + * The function pointers for reading from and writing a seed file to + * Non-Volatile storage (NV) in a platform-independent way + * + * Only enabled when the NV seed entropy source is enabled + */ +#if defined(MBEDTLS_ENTROPY_NV_SEED) +#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) +/* Internal standard platform definitions */ +int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ); +int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len ); +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +extern int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ); +extern int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ); + +/** + * \brief This function allows configuring custom seed file writing and + * reading functions. + * + * \param nv_seed_read_func The seed reading function implementation. + * \param nv_seed_write_func The seed writing function implementation. + * + * \return \c 0 on success. + */ +int mbedtls_platform_set_nv_seed( + int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ), + int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) + ); +#else +#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \ + defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) +#define mbedtls_nv_seed_read MBEDTLS_PLATFORM_NV_SEED_READ_MACRO +#define mbedtls_nv_seed_write MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO +#else +#define mbedtls_nv_seed_read mbedtls_platform_std_nv_seed_read +#define mbedtls_nv_seed_write mbedtls_platform_std_nv_seed_write +#endif +#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ +#endif /* MBEDTLS_ENTROPY_NV_SEED */ + +#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) + +/** + * \brief The platform context structure. + * + * \note This structure may be used to assist platform-specific + * setup or teardown operations. + */ +typedef struct mbedtls_platform_context +{ + char dummy; /**< A placeholder member, as empty structs are not portable. */ +} +mbedtls_platform_context; + +#else +#include "platform_alt.h" +#endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ + +/** + * \brief This function performs any platform-specific initialization + * operations. + * + * \note This function should be called before any other library functions. + * + * Its implementation is platform-specific, and unless + * platform-specific code is provided, it does nothing. + * + * \note The usage and necessity of this function is dependent on the platform. + * + * \param ctx The platform context. + * + * \return \c 0 on success. + */ +int mbedtls_platform_setup( mbedtls_platform_context *ctx ); +/** + * \brief This function performs any platform teardown operations. + * + * \note This function should be called after every other Mbed TLS module + * has been correctly freed using the appropriate free function. + * + * Its implementation is platform-specific, and unless + * platform-specific code is provided, it does nothing. + * + * \note The usage and necessity of this function is dependent on the platform. + * + * \param ctx The platform context. + * + */ +void mbedtls_platform_teardown( mbedtls_platform_context *ctx ); + +#ifdef __cplusplus +} +#endif + +#endif /* platform.h */ diff --git a/mbed_aes_gcm/platform_time.h b/mbed_aes_gcm/platform_time.h new file mode 100644 index 0000000..2ed36f5 --- /dev/null +++ b/mbed_aes_gcm/platform_time.h @@ -0,0 +1,82 @@ +/** + * \file platform_time.h + * + * \brief mbed TLS Platform time abstraction + */ +/* + * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_PLATFORM_TIME_H +#define MBEDTLS_PLATFORM_TIME_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +/* + * The time_t datatype + */ +#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) +typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t; +#else +/* For time_t */ +#include +typedef time_t mbedtls_time_t; +#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */ + +/* + * The function pointers for time + */ +#if defined(MBEDTLS_PLATFORM_TIME_ALT) +extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time ); + +/** + * \brief Set your own time function pointer + * + * \param time_func the time function implementation + * + * \return 0 + */ +int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) ); +#else +#if defined(MBEDTLS_PLATFORM_TIME_MACRO) +#define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO +#else +#define mbedtls_time time +#endif /* MBEDTLS_PLATFORM_TIME_MACRO */ +#endif /* MBEDTLS_PLATFORM_TIME_ALT */ + +#ifdef __cplusplus +} +#endif + +#endif /* platform_time.h */ diff --git a/mbed_aes_gcm/platform_util.c b/mbed_aes_gcm/platform_util.c new file mode 100644 index 0000000..04a64b3 --- /dev/null +++ b/mbed_aes_gcm/platform_util.c @@ -0,0 +1,136 @@ +/* + * Common and shared functions used by multiple modules in the Mbed TLS + * library. + * + * Copyright (C) 2018, Arm Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of Mbed TLS (https://tls.mbed.org) + */ + +/* + * Ensure gmtime_r is available even with -std=c99; must be defined before + * config.h, which pulls in glibc's features.h. Harmless on other platforms. + */ +#if !defined(_POSIX_C_SOURCE) +#define _POSIX_C_SOURCE 200112L +#endif + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "platform_util.h" +#include "platform.h" +#include "threading.h" + +#include +#include + +#if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT) +/* + * This implementation should never be optimized out by the compiler + * + * This implementation for mbedtls_platform_zeroize() was inspired from Colin + * Percival's blog article at: + * + * http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html + * + * It uses a volatile function pointer to the standard memset(). Because the + * pointer is volatile the compiler expects it to change at + * any time and will not optimize out the call that could potentially perform + * other operations on the input buffer instead of just setting it to 0. + * Nevertheless, as pointed out by davidtgoldblatt on Hacker News + * (refer to http://www.daemonology.net/blog/2014-09-05-erratum.html for + * details), optimizations of the following form are still possible: + * + * if( memset_func != memset ) + * memset_func( buf, 0, len ); + * + * Note that it is extremely difficult to guarantee that + * mbedtls_platform_zeroize() will not be optimized out by aggressive compilers + * in a portable way. For this reason, Mbed TLS also provides the configuration + * option MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure + * mbedtls_platform_zeroize() to use a suitable implementation for their + * platform and needs. + */ +static void * (* const volatile memset_func)( void *, int, size_t ) = memset; + +void mbedtls_platform_zeroize( void *buf, size_t len ) +{ + memset_func( buf, 0, len ); +} +#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */ + +#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) +#include +#if !defined(_WIN32) && (defined(unix) || \ + defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ + defined(__MACH__))) +#include +#endif /* !_WIN32 && (unix || __unix || __unix__ || + * (__APPLE__ && __MACH__)) */ + +#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ + ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ + _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) +/* + * This is a convenience shorthand macro to avoid checking the long + * preprocessor conditions above. Ideally, we could expose this macro in + * platform_util.h and simply use it in platform_util.c, threading.c and + * threading.h. However, this macro is not part of the Mbed TLS public API, so + * we keep it private by only defining it in this file + */ +#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) +#define PLATFORM_UTIL_USE_GMTIME +#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */ + +#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ + ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ + _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */ + +struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt, + struct tm *tm_buf ) +{ +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + return( ( gmtime_s( tm_buf, tt ) == 0 ) ? tm_buf : NULL ); +#elif !defined(PLATFORM_UTIL_USE_GMTIME) + return( gmtime_r( tt, tm_buf ) ); +#else + struct tm *lt; + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 ) + return( NULL ); +#endif /* MBEDTLS_THREADING_C */ + + lt = gmtime( tt ); + + if( lt != NULL ) + { + memcpy( tm_buf, lt, sizeof( struct tm ) ); + } + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 ) + return( NULL ); +#endif /* MBEDTLS_THREADING_C */ + + return( ( lt == NULL ) ? NULL : tm_buf ); +#endif /* _WIN32 && !EFIX64 && !EFI32 */ +} +#endif /* MBEDTLS_HAVE_TIME_DATE && MBEDTLS_PLATFORM_GMTIME_R_ALT */ diff --git a/mbed_aes_gcm/platform_util.h b/mbed_aes_gcm/platform_util.h new file mode 100644 index 0000000..09d0965 --- /dev/null +++ b/mbed_aes_gcm/platform_util.h @@ -0,0 +1,196 @@ +/** + * \file platform_util.h + * + * \brief Common and shared functions used by multiple modules in the Mbed TLS + * library. + */ +/* + * Copyright (C) 2018, Arm Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of Mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_PLATFORM_UTIL_H +#define MBEDTLS_PLATFORM_UTIL_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include +#if defined(MBEDTLS_HAVE_TIME_DATE) +#include "platform_time.h" +#include +#endif /* MBEDTLS_HAVE_TIME_DATE */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(MBEDTLS_CHECK_PARAMS) + +#if defined(MBEDTLS_CHECK_PARAMS_ASSERT) +/* Allow the user to define MBEDTLS_PARAM_FAILED to something like assert + * (which is what our config.h suggests). */ +#include +#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */ + +#if defined(MBEDTLS_PARAM_FAILED) +/** An alternative definition of MBEDTLS_PARAM_FAILED has been set in config.h. + * + * This flag can be used to check whether it is safe to assume that + * MBEDTLS_PARAM_FAILED() will expand to a call to mbedtls_param_failed(). + */ +#define MBEDTLS_PARAM_FAILED_ALT + +#elif defined(MBEDTLS_CHECK_PARAMS_ASSERT) +#define MBEDTLS_PARAM_FAILED( cond ) assert( cond ) +#define MBEDTLS_PARAM_FAILED_ALT + +#else /* MBEDTLS_PARAM_FAILED */ +#define MBEDTLS_PARAM_FAILED( cond ) \ + mbedtls_param_failed( #cond, __FILE__, __LINE__ ) + +/** + * \brief User supplied callback function for parameter validation failure. + * See #MBEDTLS_CHECK_PARAMS for context. + * + * This function will be called unless an alternative treatement + * is defined through the #MBEDTLS_PARAM_FAILED macro. + * + * This function can return, and the operation will be aborted, or + * alternatively, through use of setjmp()/longjmp() can resume + * execution in the application code. + * + * \param failure_condition The assertion that didn't hold. + * \param file The file where the assertion failed. + * \param line The line in the file where the assertion failed. + */ +void mbedtls_param_failed( const char *failure_condition, + const char *file, + int line ); +#endif /* MBEDTLS_PARAM_FAILED */ + +/* Internal macro meant to be called only from within the library. */ +#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) \ + do { \ + if( !(cond) ) \ + { \ + MBEDTLS_PARAM_FAILED( cond ); \ + return( ret ); \ + } \ + } while( 0 ) + +/* Internal macro meant to be called only from within the library. */ +#define MBEDTLS_INTERNAL_VALIDATE( cond ) \ + do { \ + if( !(cond) ) \ + { \ + MBEDTLS_PARAM_FAILED( cond ); \ + return; \ + } \ + } while( 0 ) + +#else /* MBEDTLS_CHECK_PARAMS */ + +/* Internal macros meant to be called only from within the library. */ +#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) do { } while( 0 ) +#define MBEDTLS_INTERNAL_VALIDATE( cond ) do { } while( 0 ) + +#endif /* MBEDTLS_CHECK_PARAMS */ + +/* Internal helper macros for deprecating API constants. */ +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +/* Deliberately don't (yet) export MBEDTLS_DEPRECATED here + * to avoid conflict with other headers which define and use + * it, too. We might want to move all these definitions here at + * some point for uniformity. */ +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +MBEDTLS_DEPRECATED typedef char const * mbedtls_deprecated_string_constant_t; +#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) \ + ( (mbedtls_deprecated_string_constant_t) ( VAL ) ) +MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t; +#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) \ + ( (mbedtls_deprecated_numeric_constant_t) ( VAL ) ) +#undef MBEDTLS_DEPRECATED +#else /* MBEDTLS_DEPRECATED_WARNING */ +#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) VAL +#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) VAL +#endif /* MBEDTLS_DEPRECATED_WARNING */ +#endif /* MBEDTLS_DEPRECATED_REMOVED */ + +/** + * \brief Securely zeroize a buffer + * + * The function is meant to wipe the data contained in a buffer so + * that it can no longer be recovered even if the program memory + * is later compromised. Call this function on sensitive data + * stored on the stack before returning from a function, and on + * sensitive data stored on the heap before freeing the heap + * object. + * + * It is extremely difficult to guarantee that calls to + * mbedtls_platform_zeroize() are not removed by aggressive + * compiler optimizations in a portable way. For this reason, Mbed + * TLS provides the configuration option + * MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure + * mbedtls_platform_zeroize() to use a suitable implementation for + * their platform and needs + * + * \param buf Buffer to be zeroized + * \param len Length of the buffer in bytes + * + */ +void mbedtls_platform_zeroize( void *buf, size_t len ); + +#if defined(MBEDTLS_HAVE_TIME_DATE) +/** + * \brief Platform-specific implementation of gmtime_r() + * + * The function is a thread-safe abstraction that behaves + * similarly to the gmtime_r() function from Unix/POSIX. + * + * Mbed TLS will try to identify the underlying platform and + * make use of an appropriate underlying implementation (e.g. + * gmtime_r() for POSIX and gmtime_s() for Windows). If this is + * not possible, then gmtime() will be used. In this case, calls + * from the library to gmtime() will be guarded by the mutex + * mbedtls_threading_gmtime_mutex if MBEDTLS_THREADING_C is + * enabled. It is recommended that calls from outside the library + * are also guarded by this mutex. + * + * If MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, then Mbed TLS will + * unconditionally use the alternative implementation for + * mbedtls_platform_gmtime_r() supplied by the user at compile time. + * + * \param tt Pointer to an object containing time (in seconds) since the + * epoch to be converted + * \param tm_buf Pointer to an object where the results will be stored + * + * \return Pointer to an object of type struct tm on success, otherwise + * NULL + */ +struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt, + struct tm *tm_buf ); +#endif /* MBEDTLS_HAVE_TIME_DATE */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_PLATFORM_UTIL_H */ diff --git a/mbed_aes_gcm/threading.c b/mbed_aes_gcm/threading.c new file mode 100644 index 0000000..7c90c7c --- /dev/null +++ b/mbed_aes_gcm/threading.c @@ -0,0 +1,187 @@ +/* + * Threading abstraction layer + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * Ensure gmtime_r is available even with -std=c99; must be defined before + * config.h, which pulls in glibc's features.h. Harmless on other platforms. + */ +#if !defined(_POSIX_C_SOURCE) +#define _POSIX_C_SOURCE 200112L +#endif + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_THREADING_C) + +#include "mbedtls/threading.h" + +#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) + +#if !defined(_WIN32) && (defined(unix) || \ + defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ + defined(__MACH__))) +#include +#endif /* !_WIN32 && (unix || __unix || __unix__ || + * (__APPLE__ && __MACH__)) */ + +#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ + ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ + _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) +/* + * This is a convenience shorthand macro to avoid checking the long + * preprocessor conditions above. Ideally, we could expose this macro in + * platform_util.h and simply use it in platform_util.c, threading.c and + * threading.h. However, this macro is not part of the Mbed TLS public API, so + * we keep it private by only defining it in this file + */ + +#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) +#define THREADING_USE_GMTIME +#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */ + +#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ + ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ + _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */ + +#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */ + +#if defined(MBEDTLS_THREADING_PTHREAD) +static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex ) +{ + if( mutex == NULL ) + return; + + mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0; +} + +static void threading_mutex_free_pthread( mbedtls_threading_mutex_t *mutex ) +{ + if( mutex == NULL || !mutex->is_valid ) + return; + + (void) pthread_mutex_destroy( &mutex->mutex ); + mutex->is_valid = 0; +} + +static int threading_mutex_lock_pthread( mbedtls_threading_mutex_t *mutex ) +{ + if( mutex == NULL || ! mutex->is_valid ) + return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); + + if( pthread_mutex_lock( &mutex->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); + + return( 0 ); +} + +static int threading_mutex_unlock_pthread( mbedtls_threading_mutex_t *mutex ) +{ + if( mutex == NULL || ! mutex->is_valid ) + return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); + + if( pthread_mutex_unlock( &mutex->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); + + return( 0 ); +} + +void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_init_pthread; +void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_free_pthread; +int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_lock_pthread; +int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_unlock_pthread; + +/* + * With phtreads we can statically initialize mutexes + */ +#define MUTEX_INIT = { PTHREAD_MUTEX_INITIALIZER, 1 } + +#endif /* MBEDTLS_THREADING_PTHREAD */ + +#if defined(MBEDTLS_THREADING_ALT) +static int threading_mutex_fail( mbedtls_threading_mutex_t *mutex ) +{ + ((void) mutex ); + return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); +} +static void threading_mutex_dummy( mbedtls_threading_mutex_t *mutex ) +{ + ((void) mutex ); + return; +} + +void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy; +void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy; +int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail; +int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail; + +/* + * Set functions pointers and initialize global mutexes + */ +void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ), + void (*mutex_free)( mbedtls_threading_mutex_t * ), + int (*mutex_lock)( mbedtls_threading_mutex_t * ), + int (*mutex_unlock)( mbedtls_threading_mutex_t * ) ) +{ + mbedtls_mutex_init = mutex_init; + mbedtls_mutex_free = mutex_free; + mbedtls_mutex_lock = mutex_lock; + mbedtls_mutex_unlock = mutex_unlock; + +#if defined(MBEDTLS_FS_IO) + mbedtls_mutex_init( &mbedtls_threading_readdir_mutex ); +#endif +#if defined(THREADING_USE_GMTIME) + mbedtls_mutex_init( &mbedtls_threading_gmtime_mutex ); +#endif +} + +/* + * Free global mutexes + */ +void mbedtls_threading_free_alt( void ) +{ +#if defined(MBEDTLS_FS_IO) + mbedtls_mutex_free( &mbedtls_threading_readdir_mutex ); +#endif +#if defined(THREADING_USE_GMTIME) + mbedtls_mutex_free( &mbedtls_threading_gmtime_mutex ); +#endif +} +#endif /* MBEDTLS_THREADING_ALT */ + +/* + * Define global mutexes + */ +#ifndef MUTEX_INIT +#define MUTEX_INIT +#endif +#if defined(MBEDTLS_FS_IO) +mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex MUTEX_INIT; +#endif +#if defined(THREADING_USE_GMTIME) +mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT; +#endif + +#endif /* MBEDTLS_THREADING_C */ diff --git a/mbed_aes_gcm/threading.h b/mbed_aes_gcm/threading.h new file mode 100644 index 0000000..92e6e6b --- /dev/null +++ b/mbed_aes_gcm/threading.h @@ -0,0 +1,122 @@ +/** + * \file threading.h + * + * \brief Threading abstraction layer + */ +/* + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_THREADING_H +#define MBEDTLS_THREADING_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE is deprecated and should not be + * used. */ +#define MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE -0x001A /**< The selected feature is not available. */ + +#define MBEDTLS_ERR_THREADING_BAD_INPUT_DATA -0x001C /**< Bad input parameters to function. */ +#define MBEDTLS_ERR_THREADING_MUTEX_ERROR -0x001E /**< Locking / unlocking / free failed with error code. */ + +#if defined(MBEDTLS_THREADING_PTHREAD) +#include +typedef struct mbedtls_threading_mutex_t +{ + pthread_mutex_t mutex; + char is_valid; +} mbedtls_threading_mutex_t; +#endif + +#if defined(MBEDTLS_THREADING_ALT) +/* You should define the mbedtls_threading_mutex_t type in your header */ +#include "threading_alt.h" + +/** + * \brief Set your alternate threading implementation function + * pointers and initialize global mutexes. If used, this + * function must be called once in the main thread before any + * other mbed TLS function is called, and + * mbedtls_threading_free_alt() must be called once in the main + * thread after all other mbed TLS functions. + * + * \note mutex_init() and mutex_free() don't return a status code. + * If mutex_init() fails, it should leave its argument (the + * mutex) in a state such that mutex_lock() will fail when + * called with this argument. + * + * \param mutex_init the init function implementation + * \param mutex_free the free function implementation + * \param mutex_lock the lock function implementation + * \param mutex_unlock the unlock function implementation + */ +void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ), + void (*mutex_free)( mbedtls_threading_mutex_t * ), + int (*mutex_lock)( mbedtls_threading_mutex_t * ), + int (*mutex_unlock)( mbedtls_threading_mutex_t * ) ); + +/** + * \brief Free global mutexes. + */ +void mbedtls_threading_free_alt( void ); +#endif /* MBEDTLS_THREADING_ALT */ + +#if defined(MBEDTLS_THREADING_C) +/* + * The function pointers for mutex_init, mutex_free, mutex_ and mutex_unlock + * + * All these functions are expected to work or the result will be undefined. + */ +extern void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t *mutex ); +extern void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t *mutex ); +extern int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t *mutex ); +extern int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t *mutex ); + +/* + * Global mutexes + */ +#if defined(MBEDTLS_FS_IO) +extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex; +#endif + +#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) +/* This mutex may or may not be used in the default definition of + * mbedtls_platform_gmtime_r(), but in order to determine that, + * we need to check POSIX features, hence modify _POSIX_C_SOURCE. + * With the current approach, this declaration is orphaned, lacking + * an accompanying definition, in case mbedtls_platform_gmtime_r() + * doesn't need it, but that's not a problem. */ +extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex; +#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */ + +#endif /* MBEDTLS_THREADING_C */ + +#ifdef __cplusplus +} +#endif + +#endif /* threading.h */ diff --git a/mbed_aes_gcm/utils.c b/mbed_aes_gcm/utils.c new file mode 100644 index 0000000..81cb946 --- /dev/null +++ b/mbed_aes_gcm/utils.c @@ -0,0 +1,36 @@ +#include "utils.h" + +void *memset(void *s, int c, size_t n) +{ + unsigned char* p=s; + while(n--) + *p++ = (unsigned char)c; + return s; +} + +void *memcpy(void *dest, const void *src, size_t n) +{ + char *dp = dest; + const char *sp = src; + while (n--) + *dp++ = *sp++; + return dest; +} + +int memcmp(const void* s1, const void* s2,size_t n) +{ + const unsigned char *p1 = s1, *p2 = s2; + while(n--) + if( *p1 != *p2 ) + return *p1 - *p2; + else + p1++,p2++; + return 0; +} + +int strcmp(const char* s1, const char* s2) +{ + while(*s1 && (*s1==*s2)) + s1++,s2++; + return *(const unsigned char*)s1-*(const unsigned char*)s2; +} diff --git a/mbed_aes_gcm/utils.h b/mbed_aes_gcm/utils.h new file mode 100644 index 0000000..dbe213d --- /dev/null +++ b/mbed_aes_gcm/utils.h @@ -0,0 +1,7 @@ +#pragma once +#include + +int memcmp(const void* s1, const void* s2,size_t n); +void *memcpy(void *dest, const void *src, size_t n); +void *memset(void *s, int c, size_t n); +int strcmp(const char* s1, const char* s2); diff --git a/templates/blackpill/Src/Makefile b/templates/blackpill/Src/Makefile deleted file mode 100644 index 87853fe..0000000 --- a/templates/blackpill/Src/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -CC=gcc -CFLAGS=-c -Wall -LDFLAGS= -SOURCES=aes.c cipher.c cipher_wrap.c gcm.c main.c platform.c platform_util.c -OBJECTS=$(SOURCES:.c=.o) -EXECUTABLE=gcm - -all: $(SOURCES) $(EXECUTABLE) - -$(EXECUTABLE): $(OBJECTS) - $(CC) $(LDFLAGS) $(OBJECTS) -o $@ - -.cpp.o: - $(CC) $(CFLAGS) $< -o $@ - -clean: - rm -rf *.o out - diff --git a/templates/blackpill/Src/aes.c b/templates/blackpill/Src/aes.c deleted file mode 100644 index 560624c..0000000 --- a/templates/blackpill/Src/aes.c +++ /dev/null @@ -1,2209 +0,0 @@ -/* - * FIPS-197 compliant AES implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. - * - * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf - * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_AES_C) - -#include - -#include "aes.h" -#include "platform.h" -#include "platform_util.h" -#if defined(MBEDTLS_PADLOCK_C) -#include "mbedtls/padlock.h" -#endif -#if defined(MBEDTLS_AESNI_C) -#include "mbedtls/aesni.h" -#endif - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_AES_ALT) - -/* Parameter validation macros based on platform_util.h */ -#define AES_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA ) -#define AES_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_UINT32_LE -#define GET_UINT32_LE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] ) \ - | ( (uint32_t) (b)[(i) + 1] << 8 ) \ - | ( (uint32_t) (b)[(i) + 2] << 16 ) \ - | ( (uint32_t) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_UINT32_LE -#define PUT_UINT32_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ - (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ - (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ - (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ -} -#endif - -#if defined(MBEDTLS_PADLOCK_C) && \ - ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) ) -static int aes_padlock_ace = -1; -#endif - -#if defined(MBEDTLS_AES_ROM_TABLES) -/* - * Forward S-box - */ -static const unsigned char FSb[256] = -{ - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, - 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, - 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, - 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, - 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, - 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, - 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, - 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, - 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, - 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, - 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, - 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, - 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, - 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, - 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, - 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, - 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, - 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, - 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, - 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, - 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, - 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, - 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, - 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, - 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, - 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, - 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 -}; - -/* - * Forward tables - */ -#define FT \ -\ - V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \ - V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \ - V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \ - V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \ - V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \ - V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \ - V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \ - V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \ - V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \ - V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \ - V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \ - V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \ - V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \ - V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \ - V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \ - V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \ - V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \ - V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \ - V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \ - V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \ - V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \ - V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \ - V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \ - V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \ - V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \ - V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \ - V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \ - V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \ - V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \ - V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \ - V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \ - V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \ - V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \ - V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \ - V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \ - V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \ - V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \ - V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \ - V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \ - V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \ - V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \ - V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \ - V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \ - V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \ - V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \ - V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \ - V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \ - V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \ - V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \ - V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \ - V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \ - V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \ - V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \ - V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \ - V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \ - V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \ - V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \ - V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \ - V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \ - V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \ - V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \ - V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \ - V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \ - V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C) - -#define V(a,b,c,d) 0x##a##b##c##d -static const uint32_t FT0[256] = { FT }; -#undef V - -#if !defined(MBEDTLS_AES_FEWER_TABLES) - -#define V(a,b,c,d) 0x##b##c##d##a -static const uint32_t FT1[256] = { FT }; -#undef V - -#define V(a,b,c,d) 0x##c##d##a##b -static const uint32_t FT2[256] = { FT }; -#undef V - -#define V(a,b,c,d) 0x##d##a##b##c -static const uint32_t FT3[256] = { FT }; -#undef V - -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - -#undef FT - -/* - * Reverse S-box - */ -static const unsigned char RSb[256] = -{ - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, - 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, - 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, - 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, - 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, - 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, - 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, - 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, - 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, - 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, - 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, - 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, - 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, - 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, - 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, - 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, - 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, - 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, - 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, - 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, - 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, - 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, - 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, - 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, - 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, - 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D -}; - -/* - * Reverse tables - */ -#define RT \ -\ - V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \ - V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \ - V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \ - V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \ - V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \ - V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \ - V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \ - V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \ - V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \ - V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \ - V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \ - V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \ - V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \ - V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \ - V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \ - V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \ - V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \ - V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \ - V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \ - V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \ - V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \ - V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \ - V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \ - V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \ - V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \ - V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \ - V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \ - V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \ - V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \ - V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \ - V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \ - V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \ - V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \ - V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \ - V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \ - V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \ - V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \ - V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \ - V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \ - V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \ - V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \ - V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \ - V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \ - V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \ - V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \ - V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \ - V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \ - V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \ - V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \ - V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \ - V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \ - V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \ - V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \ - V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \ - V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \ - V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \ - V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \ - V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \ - V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \ - V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \ - V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \ - V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \ - V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \ - V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0) - -#define V(a,b,c,d) 0x##a##b##c##d -static const uint32_t RT0[256] = { RT }; -#undef V - -#if !defined(MBEDTLS_AES_FEWER_TABLES) - -#define V(a,b,c,d) 0x##b##c##d##a -static const uint32_t RT1[256] = { RT }; -#undef V - -#define V(a,b,c,d) 0x##c##d##a##b -static const uint32_t RT2[256] = { RT }; -#undef V - -#define V(a,b,c,d) 0x##d##a##b##c -static const uint32_t RT3[256] = { RT }; -#undef V - -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - -#undef RT - -/* - * Round constants - */ -static const uint32_t RCON[10] = -{ - 0x00000001, 0x00000002, 0x00000004, 0x00000008, - 0x00000010, 0x00000020, 0x00000040, 0x00000080, - 0x0000001B, 0x00000036 -}; - -#else /* MBEDTLS_AES_ROM_TABLES */ - -/* - * Forward S-box & tables - */ -static unsigned char FSb[256]; -static uint32_t FT0[256]; -#if !defined(MBEDTLS_AES_FEWER_TABLES) -static uint32_t FT1[256]; -static uint32_t FT2[256]; -static uint32_t FT3[256]; -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - -/* - * Reverse S-box & tables - */ -static unsigned char RSb[256]; -static uint32_t RT0[256]; -#if !defined(MBEDTLS_AES_FEWER_TABLES) -static uint32_t RT1[256]; -static uint32_t RT2[256]; -static uint32_t RT3[256]; -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - -/* - * Round constants - */ -static uint32_t RCON[10]; - -/* - * Tables generation code - */ -#define ROTL8(x) ( ( (x) << 8 ) & 0xFFFFFFFF ) | ( (x) >> 24 ) -#define XTIME(x) ( ( (x) << 1 ) ^ ( ( (x) & 0x80 ) ? 0x1B : 0x00 ) ) -#define MUL(x,y) ( ( (x) && (y) ) ? pow[(log[(x)]+log[(y)]) % 255] : 0 ) - -static int aes_init_done = 0; - -static void aes_gen_tables( void ) -{ - int i, x, y, z; - int pow[256]; - int log[256]; - - /* - * compute pow and log tables over GF(2^8) - */ - for( i = 0, x = 1; i < 256; i++ ) - { - pow[i] = x; - log[x] = i; - x = ( x ^ XTIME( x ) ) & 0xFF; - } - - /* - * calculate the round constants - */ - for( i = 0, x = 1; i < 10; i++ ) - { - RCON[i] = (uint32_t) x; - x = XTIME( x ) & 0xFF; - } - - /* - * generate the forward and reverse S-boxes - */ - FSb[0x00] = 0x63; - RSb[0x63] = 0x00; - - for( i = 1; i < 256; i++ ) - { - x = pow[255 - log[i]]; - - y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; - x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; - x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; - x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; - x ^= y ^ 0x63; - - FSb[i] = (unsigned char) x; - RSb[x] = (unsigned char) i; - } - - /* - * generate the forward and reverse tables - */ - for( i = 0; i < 256; i++ ) - { - x = FSb[i]; - y = XTIME( x ) & 0xFF; - z = ( y ^ x ) & 0xFF; - - FT0[i] = ( (uint32_t) y ) ^ - ( (uint32_t) x << 8 ) ^ - ( (uint32_t) x << 16 ) ^ - ( (uint32_t) z << 24 ); - -#if !defined(MBEDTLS_AES_FEWER_TABLES) - FT1[i] = ROTL8( FT0[i] ); - FT2[i] = ROTL8( FT1[i] ); - FT3[i] = ROTL8( FT2[i] ); -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - - x = RSb[i]; - - RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^ - ( (uint32_t) MUL( 0x09, x ) << 8 ) ^ - ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^ - ( (uint32_t) MUL( 0x0B, x ) << 24 ); - -#if !defined(MBEDTLS_AES_FEWER_TABLES) - RT1[i] = ROTL8( RT0[i] ); - RT2[i] = ROTL8( RT1[i] ); - RT3[i] = ROTL8( RT2[i] ); -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - } -} - -#undef ROTL8 - -#endif /* MBEDTLS_AES_ROM_TABLES */ - -#if defined(MBEDTLS_AES_FEWER_TABLES) - -#define ROTL8(x) ( (uint32_t)( ( x ) << 8 ) + (uint32_t)( ( x ) >> 24 ) ) -#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) ) -#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >> 8 ) ) - -#define AES_RT0(idx) RT0[idx] -#define AES_RT1(idx) ROTL8( RT0[idx] ) -#define AES_RT2(idx) ROTL16( RT0[idx] ) -#define AES_RT3(idx) ROTL24( RT0[idx] ) - -#define AES_FT0(idx) FT0[idx] -#define AES_FT1(idx) ROTL8( FT0[idx] ) -#define AES_FT2(idx) ROTL16( FT0[idx] ) -#define AES_FT3(idx) ROTL24( FT0[idx] ) - -#else /* MBEDTLS_AES_FEWER_TABLES */ - -#define AES_RT0(idx) RT0[idx] -#define AES_RT1(idx) RT1[idx] -#define AES_RT2(idx) RT2[idx] -#define AES_RT3(idx) RT3[idx] - -#define AES_FT0(idx) FT0[idx] -#define AES_FT1(idx) FT1[idx] -#define AES_FT2(idx) FT2[idx] -#define AES_FT3(idx) FT3[idx] - -#endif /* MBEDTLS_AES_FEWER_TABLES */ - -void mbedtls_aes_init( mbedtls_aes_context *ctx ) -{ - AES_VALIDATE( ctx != NULL ); - - memset( ctx, 0, sizeof( mbedtls_aes_context ) ); -} - -void mbedtls_aes_free( mbedtls_aes_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) ); -} - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx ) -{ - AES_VALIDATE( ctx != NULL ); - - mbedtls_aes_init( &ctx->crypt ); - mbedtls_aes_init( &ctx->tweak ); -} - -void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_aes_free( &ctx->crypt ); - mbedtls_aes_free( &ctx->tweak ); -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -/* - * AES key schedule (encryption) - */ -#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT) -int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, - unsigned int keybits ) -{ - unsigned int i; - uint32_t *RK; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( key != NULL ); - - switch( keybits ) - { - case 128: ctx->nr = 10; break; - case 192: ctx->nr = 12; break; - case 256: ctx->nr = 14; break; - default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); - } - -#if !defined(MBEDTLS_AES_ROM_TABLES) - if( aes_init_done == 0 ) - { - aes_gen_tables(); - aes_init_done = 1; - } -#endif - -#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) - if( aes_padlock_ace == -1 ) - aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); - - if( aes_padlock_ace ) - ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); - else -#endif - ctx->rk = RK = ctx->buf; - -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) - if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) - return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) ); -#endif - - for( i = 0; i < ( keybits >> 5 ); i++ ) - { - GET_UINT32_LE( RK[i], key, i << 2 ); - } - - switch( ctx->nr ) - { - case 10: - - for( i = 0; i < 10; i++, RK += 4 ) - { - RK[4] = RK[0] ^ RCON[i] ^ - ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 ); - - RK[5] = RK[1] ^ RK[4]; - RK[6] = RK[2] ^ RK[5]; - RK[7] = RK[3] ^ RK[6]; - } - break; - - case 12: - - for( i = 0; i < 8; i++, RK += 6 ) - { - RK[6] = RK[0] ^ RCON[i] ^ - ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 ); - - RK[7] = RK[1] ^ RK[6]; - RK[8] = RK[2] ^ RK[7]; - RK[9] = RK[3] ^ RK[8]; - RK[10] = RK[4] ^ RK[9]; - RK[11] = RK[5] ^ RK[10]; - } - break; - - case 14: - - for( i = 0; i < 7; i++, RK += 8 ) - { - RK[8] = RK[0] ^ RCON[i] ^ - ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 ); - - RK[9] = RK[1] ^ RK[8]; - RK[10] = RK[2] ^ RK[9]; - RK[11] = RK[3] ^ RK[10]; - - RK[12] = RK[4] ^ - ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 ); - - RK[13] = RK[5] ^ RK[12]; - RK[14] = RK[6] ^ RK[13]; - RK[15] = RK[7] ^ RK[14]; - } - break; - } - - return( 0 ); -} -#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */ - -/* - * AES key schedule (decryption) - */ -#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) -int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, - unsigned int keybits ) -{ - int i, j, ret; - mbedtls_aes_context cty; - uint32_t *RK; - uint32_t *SK; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( key != NULL ); - - mbedtls_aes_init( &cty ); - -#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) - if( aes_padlock_ace == -1 ) - aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); - - if( aes_padlock_ace ) - ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); - else -#endif - ctx->rk = RK = ctx->buf; - - /* Also checks keybits */ - if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 ) - goto exit; - - ctx->nr = cty.nr; - -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) - if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) - { - mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk, - (const unsigned char *) cty.rk, ctx->nr ); - goto exit; - } -#endif - - SK = cty.rk + cty.nr * 4; - - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - - for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 ) - { - for( j = 0; j < 4; j++, SK++ ) - { - *RK++ = AES_RT0( FSb[ ( *SK ) & 0xFF ] ) ^ - AES_RT1( FSb[ ( *SK >> 8 ) & 0xFF ] ) ^ - AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^ - AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] ); - } - } - - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - -exit: - mbedtls_aes_free( &cty ); - - return( ret ); -} - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -static int mbedtls_aes_xts_decode_keys( const unsigned char *key, - unsigned int keybits, - const unsigned char **key1, - unsigned int *key1bits, - const unsigned char **key2, - unsigned int *key2bits ) -{ - const unsigned int half_keybits = keybits / 2; - const unsigned int half_keybytes = half_keybits / 8; - - switch( keybits ) - { - case 256: break; - case 512: break; - default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); - } - - *key1bits = half_keybits; - *key2bits = half_keybits; - *key1 = &key[0]; - *key2 = &key[half_keybytes]; - - return 0; -} - -int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx, - const unsigned char *key, - unsigned int keybits) -{ - int ret; - const unsigned char *key1, *key2; - unsigned int key1bits, key2bits; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( key != NULL ); - - ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits, - &key2, &key2bits ); - if( ret != 0 ) - return( ret ); - - /* Set the tweak key. Always set tweak key for the encryption mode. */ - ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits ); - if( ret != 0 ) - return( ret ); - - /* Set crypt key for encryption. */ - return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits ); -} - -int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx, - const unsigned char *key, - unsigned int keybits) -{ - int ret; - const unsigned char *key1, *key2; - unsigned int key1bits, key2bits; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( key != NULL ); - - ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits, - &key2, &key2bits ); - if( ret != 0 ) - return( ret ); - - /* Set the tweak key. Always set tweak key for encryption. */ - ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits ); - if( ret != 0 ) - return( ret ); - - /* Set crypt key for decryption. */ - return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits ); -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */ - -#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ - do \ - { \ - (X0) = *RK++ ^ AES_FT0( ( (Y0) ) & 0xFF ) ^ \ - AES_FT1( ( (Y1) >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( (Y2) >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( (Y3) >> 24 ) & 0xFF ); \ - \ - (X1) = *RK++ ^ AES_FT0( ( (Y1) ) & 0xFF ) ^ \ - AES_FT1( ( (Y2) >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( (Y3) >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( (Y0) >> 24 ) & 0xFF ); \ - \ - (X2) = *RK++ ^ AES_FT0( ( (Y2) ) & 0xFF ) ^ \ - AES_FT1( ( (Y3) >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( (Y0) >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( (Y1) >> 24 ) & 0xFF ); \ - \ - (X3) = *RK++ ^ AES_FT0( ( (Y3) ) & 0xFF ) ^ \ - AES_FT1( ( (Y0) >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( (Y1) >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( (Y2) >> 24 ) & 0xFF ); \ - } while( 0 ) - -#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ - do \ - { \ - (X0) = *RK++ ^ AES_RT0( ( (Y0) ) & 0xFF ) ^ \ - AES_RT1( ( (Y3) >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( (Y2) >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( (Y1) >> 24 ) & 0xFF ); \ - \ - (X1) = *RK++ ^ AES_RT0( ( (Y1) ) & 0xFF ) ^ \ - AES_RT1( ( (Y0) >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( (Y3) >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( (Y2) >> 24 ) & 0xFF ); \ - \ - (X2) = *RK++ ^ AES_RT0( ( (Y2) ) & 0xFF ) ^ \ - AES_RT1( ( (Y1) >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( (Y0) >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( (Y3) >> 24 ) & 0xFF ); \ - \ - (X3) = *RK++ ^ AES_RT0( ( (Y3) ) & 0xFF ) ^ \ - AES_RT1( ( (Y2) >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( (Y1) >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( (Y0) >> 24 ) & 0xFF ); \ - } while( 0 ) - -/* - * AES-ECB block encryption - */ -#if !defined(MBEDTLS_AES_ENCRYPT_ALT) -int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ) -{ - int i; - uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; - - RK = ctx->rk; - - GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; - GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; - GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; - GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; - - for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) - { - AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); - } - - AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - - X0 = *RK++ ^ \ - ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); - - X1 = *RK++ ^ \ - ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); - - X2 = *RK++ ^ \ - ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); - - X3 = *RK++ ^ \ - ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); - - PUT_UINT32_LE( X0, output, 0 ); - PUT_UINT32_LE( X1, output, 4 ); - PUT_UINT32_LE( X2, output, 8 ); - PUT_UINT32_LE( X3, output, 12 ); - - return( 0 ); -} -#endif /* !MBEDTLS_AES_ENCRYPT_ALT */ - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ) -{ - mbedtls_internal_aes_encrypt( ctx, input, output ); -} -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -/* - * AES-ECB block decryption - */ -#if !defined(MBEDTLS_AES_DECRYPT_ALT) -int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ) -{ - int i; - uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; - - RK = ctx->rk; - - GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; - GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; - GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; - GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; - - for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) - { - AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); - } - - AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - - X0 = *RK++ ^ \ - ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); - - X1 = *RK++ ^ \ - ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); - - X2 = *RK++ ^ \ - ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); - - X3 = *RK++ ^ \ - ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); - - PUT_UINT32_LE( X0, output, 0 ); - PUT_UINT32_LE( X1, output, 4 ); - PUT_UINT32_LE( X2, output, 8 ); - PUT_UINT32_LE( X3, output, 12 ); - - return( 0 ); -} -#endif /* !MBEDTLS_AES_DECRYPT_ALT */ - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ) -{ - mbedtls_internal_aes_decrypt( ctx, input, output ); -} -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -/* - * AES-ECB block encryption/decryption - */ -int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ) -{ - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) - if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) - return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) ); -#endif - -#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) - if( aes_padlock_ace ) - { - if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 ) - return( 0 ); - - // If padlock data misaligned, we just fall back to - // unaccelerated mode - // - } -#endif - - if( mode == MBEDTLS_AES_ENCRYPT ) - return( mbedtls_internal_aes_encrypt( ctx, input, output ) ); - else - return( mbedtls_internal_aes_decrypt( ctx, input, output ) ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * AES-CBC buffer encryption/decryption - */ -int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int i; - unsigned char temp[16]; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - AES_VALIDATE_RET( iv != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - if( length % 16 ) - return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH ); - -#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) - if( aes_padlock_ace ) - { - if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 ) - return( 0 ); - - // If padlock data misaligned, we just fall back to - // unaccelerated mode - // - } -#endif - - if( mode == MBEDTLS_AES_DECRYPT ) - { - while( length > 0 ) - { - memcpy( temp, input, 16 ); - mbedtls_aes_crypt_ecb( ctx, mode, input, output ); - - for( i = 0; i < 16; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); - - memcpy( iv, temp, 16 ); - - input += 16; - output += 16; - length -= 16; - } - } - else - { - while( length > 0 ) - { - for( i = 0; i < 16; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); - - mbedtls_aes_crypt_ecb( ctx, mode, output, output ); - memcpy( iv, output, 16 ); - - input += 16; - output += 16; - length -= 16; - } - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) - -/* Endianess with 64 bits values */ -#ifndef GET_UINT64_LE -#define GET_UINT64_LE(n,b,i) \ -{ \ - (n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \ - | ( (uint64_t) (b)[(i) + 6] << 48 ) \ - | ( (uint64_t) (b)[(i) + 5] << 40 ) \ - | ( (uint64_t) (b)[(i) + 4] << 32 ) \ - | ( (uint64_t) (b)[(i) + 3] << 24 ) \ - | ( (uint64_t) (b)[(i) + 2] << 16 ) \ - | ( (uint64_t) (b)[(i) + 1] << 8 ) \ - | ( (uint64_t) (b)[(i) ] ); \ -} -#endif - -#ifndef PUT_UINT64_LE -#define PUT_UINT64_LE(n,b,i) \ -{ \ - (b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \ - (b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \ - (b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \ - (b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) ] = (unsigned char) ( (n) ); \ -} -#endif - -typedef unsigned char mbedtls_be128[16]; - -/* - * GF(2^128) multiplication function - * - * This function multiplies a field element by x in the polynomial field - * representation. It uses 64-bit word operations to gain speed but compensates - * for machine endianess and hence works correctly on both big and little - * endian machines. - */ -static void mbedtls_gf128mul_x_ble( unsigned char r[16], - const unsigned char x[16] ) -{ - uint64_t a, b, ra, rb; - - GET_UINT64_LE( a, x, 0 ); - GET_UINT64_LE( b, x, 8 ); - - ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) ); - rb = ( a >> 63 ) | ( b << 1 ); - - PUT_UINT64_LE( ra, r, 0 ); - PUT_UINT64_LE( rb, r, 8 ); -} - -/* - * AES-XTS buffer encryption/decryption - */ -int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, - int mode, - size_t length, - const unsigned char data_unit[16], - const unsigned char *input, - unsigned char *output ) -{ - int ret; - size_t blocks = length / 16; - size_t leftover = length % 16; - unsigned char tweak[16]; - unsigned char prev_tweak[16]; - unsigned char tmp[16]; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - AES_VALIDATE_RET( data_unit != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - /* Data units must be at least 16 bytes long. */ - if( length < 16 ) - return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; - - /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */ - if( length > ( 1 << 20 ) * 16 ) - return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; - - /* Compute the tweak. */ - ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT, - data_unit, tweak ); - if( ret != 0 ) - return( ret ); - - while( blocks-- ) - { - size_t i; - - if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 ) - { - /* We are on the last block in a decrypt operation that has - * leftover bytes, so we need to use the next tweak for this block, - * and this tweak for the lefover bytes. Save the current tweak for - * the leftovers and then update the current tweak for use on this, - * the last full block. */ - memcpy( prev_tweak, tweak, sizeof( tweak ) ); - mbedtls_gf128mul_x_ble( tweak, tweak ); - } - - for( i = 0; i < 16; i++ ) - tmp[i] = input[i] ^ tweak[i]; - - ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp ); - if( ret != 0 ) - return( ret ); - - for( i = 0; i < 16; i++ ) - output[i] = tmp[i] ^ tweak[i]; - - /* Update the tweak for the next block. */ - mbedtls_gf128mul_x_ble( tweak, tweak ); - - output += 16; - input += 16; - } - - if( leftover ) - { - /* If we are on the leftover bytes in a decrypt operation, we need to - * use the previous tweak for these bytes (as saved in prev_tweak). */ - unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak; - - /* We are now on the final part of the data unit, which doesn't divide - * evenly by 16. It's time for ciphertext stealing. */ - size_t i; - unsigned char *prev_output = output - 16; - - /* Copy ciphertext bytes from the previous block to our output for each - * byte of cyphertext we won't steal. At the same time, copy the - * remainder of the input for this final round (since the loop bounds - * are the same). */ - for( i = 0; i < leftover; i++ ) - { - output[i] = prev_output[i]; - tmp[i] = input[i] ^ t[i]; - } - - /* Copy ciphertext bytes from the previous block for input in this - * round. */ - for( ; i < 16; i++ ) - tmp[i] = prev_output[i] ^ t[i]; - - ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp ); - if( ret != 0 ) - return ret; - - /* Write the result back to the previous block, overriding the previous - * output we copied. */ - for( i = 0; i < 16; i++ ) - prev_output[i] = tmp[i] ^ t[i]; - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * AES-CFB128 buffer encryption/decryption - */ -int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int c; - size_t n; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - AES_VALIDATE_RET( iv_off != NULL ); - AES_VALIDATE_RET( iv != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - n = *iv_off; - - if( n > 15 ) - return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); - - if( mode == MBEDTLS_AES_DECRYPT ) - { - while( length-- ) - { - if( n == 0 ) - mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); - - c = *input++; - *output++ = (unsigned char)( c ^ iv[n] ); - iv[n] = (unsigned char) c; - - n = ( n + 1 ) & 0x0F; - } - } - else - { - while( length-- ) - { - if( n == 0 ) - mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); - - iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); - - n = ( n + 1 ) & 0x0F; - } - } - - *iv_off = n; - - return( 0 ); -} - -/* - * AES-CFB8 buffer encryption/decryption - */ -int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - unsigned char c; - unsigned char ov[17]; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - AES_VALIDATE_RET( iv != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - while( length-- ) - { - memcpy( ov, iv, 16 ); - mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); - - if( mode == MBEDTLS_AES_DECRYPT ) - ov[16] = *input; - - c = *output++ = (unsigned char)( iv[0] ^ *input++ ); - - if( mode == MBEDTLS_AES_ENCRYPT ) - ov[16] = c; - - memcpy( iv, ov + 1, 16 ); - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -/* - * AES-OFB (Output Feedback Mode) buffer encryption/decryption - */ -int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int ret = 0; - size_t n; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( iv_off != NULL ); - AES_VALIDATE_RET( iv != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - n = *iv_off; - - if( n > 15 ) - return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); - - while( length-- ) - { - if( n == 0 ) - { - ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); - if( ret != 0 ) - goto exit; - } - *output++ = *input++ ^ iv[n]; - - n = ( n + 1 ) & 0x0F; - } - - *iv_off = n; - -exit: - return( ret ); -} -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * AES-CTR buffer encryption/decryption - */ -int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[16], - unsigned char stream_block[16], - const unsigned char *input, - unsigned char *output ) -{ - int c, i; - size_t n; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( nc_off != NULL ); - AES_VALIDATE_RET( nonce_counter != NULL ); - AES_VALIDATE_RET( stream_block != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - n = *nc_off; - - if ( n > 0x0F ) - return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); - - while( length-- ) - { - if( n == 0 ) { - mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block ); - - for( i = 16; i > 0; i-- ) - if( ++nonce_counter[i - 1] != 0 ) - break; - } - c = *input++; - *output++ = (unsigned char)( c ^ stream_block[n] ); - - n = ( n + 1 ) & 0x0F; - } - - *nc_off = n; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#endif /* !MBEDTLS_AES_ALT */ - -#if defined(MBEDTLS_SELF_TEST) -/* - * AES test vectors from: - * - * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip - */ -static const unsigned char aes_test_ecb_dec[3][16] = -{ - { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58, - 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 }, - { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, - 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 }, - { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, - 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE } -}; - -static const unsigned char aes_test_ecb_enc[3][16] = -{ - { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73, - 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F }, - { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11, - 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 }, - { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D, - 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 } -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const unsigned char aes_test_cbc_dec[3][16] = -{ - { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73, - 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 }, - { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75, - 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B }, - { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75, - 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 } -}; - -static const unsigned char aes_test_cbc_enc[3][16] = -{ - { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84, - 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D }, - { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB, - 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 }, - { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5, - 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * AES-CFB128 test vectors from: - * - * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf - */ -static const unsigned char aes_test_cfb128_key[3][32] = -{ - { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, - { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, - 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, - 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, - { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } -}; - -static const unsigned char aes_test_cfb128_iv[16] = -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F -}; - -static const unsigned char aes_test_cfb128_pt[64] = -{ - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 -}; - -static const unsigned char aes_test_cfb128_ct[3][64] = -{ - { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, - 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, - 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F, - 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B, - 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40, - 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF, - 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E, - 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 }, - { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, - 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, - 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21, - 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A, - 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1, - 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9, - 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0, - 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF }, - { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, - 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, - 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8, - 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B, - 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92, - 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9, - 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8, - 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -/* - * AES-OFB test vectors from: - * - * https://csrc.nist.gov/publications/detail/sp/800-38a/final - */ -static const unsigned char aes_test_ofb_key[3][32] = -{ - { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, - { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, - 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, - 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, - { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } -}; - -static const unsigned char aes_test_ofb_iv[16] = -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F -}; - -static const unsigned char aes_test_ofb_pt[64] = -{ - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 -}; - -static const unsigned char aes_test_ofb_ct[3][64] = -{ - { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, - 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, - 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03, - 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25, - 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6, - 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc, - 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78, - 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e }, - { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, - 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, - 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c, - 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01, - 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f, - 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2, - 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e, - 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a }, - { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, - 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, - 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a, - 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d, - 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed, - 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08, - 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8, - 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 } -}; -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * AES-CTR test vectors from: - * - * http://www.faqs.org/rfcs/rfc3686.html - */ - -static const unsigned char aes_test_ctr_key[3][16] = -{ - { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, - 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, - { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, - 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, - { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, - 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } -}; - -static const unsigned char aes_test_ctr_nonce_counter[3][16] = -{ - { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, - { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, - 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, - { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, - 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } -}; - -static const unsigned char aes_test_ctr_pt[3][48] = -{ - { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, - 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 0x20, 0x21, 0x22, 0x23 } -}; - -static const unsigned char aes_test_ctr_ct[3][48] = -{ - { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, - 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 }, - { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9, - 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88, - 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8, - 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 }, - { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, - 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, - 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, - 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, - 0x25, 0xB2, 0x07, 0x2F } -}; - -static const int aes_test_ctr_len[3] = - { 16, 32, 36 }; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/* - * AES-XTS test vectors from: - * - * IEEE P1619/D16 Annex B - * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf - * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf) - */ -static const unsigned char aes_test_xts_key[][32] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, - { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, - 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, -}; - -static const unsigned char aes_test_xts_pt32[][32] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }, - { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }, -}; - -static const unsigned char aes_test_xts_ct32[][32] = -{ - { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec, - 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92, - 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85, - 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e }, - { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e, - 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b, - 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4, - 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 }, - { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a, - 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2, - 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53, - 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 }, -}; - -static const unsigned char aes_test_xts_data_unit[][16] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, -}; - -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -/* - * Checkup routine - */ -int mbedtls_aes_self_test( int verbose ) -{ - int ret = 0, i, j, u, mode; - unsigned int keybits; - unsigned char key[32]; - unsigned char buf[64]; - const unsigned char *aes_tests; -#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) - unsigned char iv[16]; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CBC) - unsigned char prv[16]; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \ - defined(MBEDTLS_CIPHER_MODE_OFB) - size_t offset; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS) - int len; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - unsigned char nonce_counter[16]; - unsigned char stream_block[16]; -#endif - mbedtls_aes_context ctx; - - memset( key, 0, 32 ); - mbedtls_aes_init( &ctx ); - - /* - * ECB mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - keybits = 128 + u * 64; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-ECB-%3d (%s): ", keybits, - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memset( buf, 0, 16 ); - - if( mode == MBEDTLS_AES_DECRYPT ) - { - ret = mbedtls_aes_setkey_dec( &ctx, key, keybits ); - aes_tests = aes_test_ecb_dec[u]; - } - else - { - ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); - aes_tests = aes_test_ecb_enc[u]; - } - - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) - { - mbedtls_printf( "skipped\n" ); - continue; - } - else if( ret != 0 ) - { - goto exit; - } - - for( j = 0; j < 10000; j++ ) - { - ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf ); - if( ret != 0 ) - goto exit; - } - - if( memcmp( buf, aes_tests, 16 ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - /* - * CBC mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - keybits = 128 + u * 64; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-CBC-%3d (%s): ", keybits, - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memset( iv , 0, 16 ); - memset( prv, 0, 16 ); - memset( buf, 0, 16 ); - - if( mode == MBEDTLS_AES_DECRYPT ) - { - ret = mbedtls_aes_setkey_dec( &ctx, key, keybits ); - aes_tests = aes_test_cbc_dec[u]; - } - else - { - ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); - aes_tests = aes_test_cbc_enc[u]; - } - - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) - { - mbedtls_printf( "skipped\n" ); - continue; - } - else if( ret != 0 ) - { - goto exit; - } - - for( j = 0; j < 10000; j++ ) - { - if( mode == MBEDTLS_AES_ENCRYPT ) - { - unsigned char tmp[16]; - - memcpy( tmp, prv, 16 ); - memcpy( prv, buf, 16 ); - memcpy( buf, tmp, 16 ); - } - - ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf ); - if( ret != 0 ) - goto exit; - - } - - if( memcmp( buf, aes_tests, 16 ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) - /* - * CFB128 mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - keybits = 128 + u * 64; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-CFB128-%3d (%s): ", keybits, - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memcpy( iv, aes_test_cfb128_iv, 16 ); - memcpy( key, aes_test_cfb128_key[u], keybits / 8 ); - - offset = 0; - ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) - { - mbedtls_printf( "skipped\n" ); - continue; - } - else if( ret != 0 ) - { - goto exit; - } - - if( mode == MBEDTLS_AES_DECRYPT ) - { - memcpy( buf, aes_test_cfb128_ct[u], 64 ); - aes_tests = aes_test_cfb128_pt; - } - else - { - memcpy( buf, aes_test_cfb128_pt, 64 ); - aes_tests = aes_test_cfb128_ct[u]; - } - - ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, aes_tests, 64 ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) - /* - * OFB mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - keybits = 128 + u * 64; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-OFB-%3d (%s): ", keybits, - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memcpy( iv, aes_test_ofb_iv, 16 ); - memcpy( key, aes_test_ofb_key[u], keybits / 8 ); - - offset = 0; - ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) - { - mbedtls_printf( "skipped\n" ); - continue; - } - else if( ret != 0 ) - { - goto exit; - } - - if( mode == MBEDTLS_AES_DECRYPT ) - { - memcpy( buf, aes_test_ofb_ct[u], 64 ); - aes_tests = aes_test_ofb_pt; - } - else - { - memcpy( buf, aes_test_ofb_pt, 64 ); - aes_tests = aes_test_ofb_ct[u]; - } - - ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, aes_tests, 64 ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - /* - * CTR mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-CTR-128 (%s): ", - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); - memcpy( key, aes_test_ctr_key[u], 16 ); - - offset = 0; - if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 ) - goto exit; - - len = aes_test_ctr_len[u]; - - if( mode == MBEDTLS_AES_DECRYPT ) - { - memcpy( buf, aes_test_ctr_ct[u], len ); - aes_tests = aes_test_ctr_pt[u]; - } - else - { - memcpy( buf, aes_test_ctr_pt[u], len ); - aes_tests = aes_test_ctr_ct[u]; - } - - ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, - stream_block, buf, buf ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, aes_tests, len ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) - { - static const int num_tests = - sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key); - mbedtls_aes_xts_context ctx_xts; - - /* - * XTS mode - */ - mbedtls_aes_xts_init( &ctx_xts ); - - for( i = 0; i < num_tests << 1; i++ ) - { - const unsigned char *data_unit; - u = i >> 1; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-XTS-128 (%s): ", - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memset( key, 0, sizeof( key ) ); - memcpy( key, aes_test_xts_key[u], 32 ); - data_unit = aes_test_xts_data_unit[u]; - - len = sizeof( *aes_test_xts_ct32 ); - - if( mode == MBEDTLS_AES_DECRYPT ) - { - ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 ); - if( ret != 0) - goto exit; - memcpy( buf, aes_test_xts_ct32[u], len ); - aes_tests = aes_test_xts_pt32[u]; - } - else - { - ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 ); - if( ret != 0) - goto exit; - memcpy( buf, aes_test_xts_pt32[u], len ); - aes_tests = aes_test_xts_ct32[u]; - } - - - ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit, - buf, buf ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, aes_tests, len ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - mbedtls_aes_xts_free( &ctx_xts ); - } -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - - ret = 0; - -exit: - if( ret != 0 && verbose != 0 ) - mbedtls_printf( "failed\n" ); - - mbedtls_aes_free( &ctx ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_AES_C */ diff --git a/templates/blackpill/Src/aes.h b/templates/blackpill/Src/aes.h deleted file mode 100644 index 94e7282..0000000 --- a/templates/blackpill/Src/aes.h +++ /dev/null @@ -1,674 +0,0 @@ -/** - * \file aes.h - * - * \brief This file contains AES definitions and functions. - * - * The Advanced Encryption Standard (AES) specifies a FIPS-approved - * cryptographic algorithm that can be used to protect electronic - * data. - * - * The AES algorithm is a symmetric block cipher that can - * encrypt and decrypt information. For more information, see - * FIPS Publication 197: Advanced Encryption Standard and - * ISO/IEC 18033-2:2006: Information technology -- Security - * techniques -- Encryption algorithms -- Part 2: Asymmetric - * ciphers. - * - * The AES-XTS block mode is standardized by NIST SP 800-38E - * - * and described in detail by IEEE P1619 - * . - */ - -/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of Mbed TLS (https://tls.mbed.org) - */ - -#ifndef MBEDTLS_AES_H -#define MBEDTLS_AES_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -/* padlock.c and aesni.c rely on these values! */ -#define MBEDTLS_AES_ENCRYPT 1 /**< AES encryption. */ -#define MBEDTLS_AES_DECRYPT 0 /**< AES decryption. */ - -/* Error codes in range 0x0020-0x0022 */ -#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */ -#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */ - -/* Error codes in range 0x0021-0x0025 */ -#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021 /**< Invalid input data. */ - -/* MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE is deprecated and should not be used. */ -#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE -0x0023 /**< Feature not available. For example, an unsupported AES key size. */ - -/* MBEDTLS_ERR_AES_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_AES_HW_ACCEL_FAILED -0x0025 /**< AES hardware accelerator failed. */ - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_AES_ALT) -// Regular implementation -// - -/** - * \brief The AES context-type definition. - */ -typedef struct mbedtls_aes_context -{ - int nr; /*!< The number of rounds. */ - uint32_t *rk; /*!< AES round keys. */ - uint32_t buf[68]; /*!< Unaligned data buffer. This buffer can - hold 32 extra Bytes, which can be used for - one of the following purposes: -
  • Alignment if VIA padlock is - used.
  • -
  • Simplifying key expansion in the 256-bit - case by generating an extra round key. -
*/ -} -mbedtls_aes_context; - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/** - * \brief The AES XTS context-type definition. - */ -typedef struct mbedtls_aes_xts_context -{ - mbedtls_aes_context crypt; /*!< The AES context to use for AES block - encryption or decryption. */ - mbedtls_aes_context tweak; /*!< The AES context used for tweak - computation. */ -} mbedtls_aes_xts_context; -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#else /* MBEDTLS_AES_ALT */ -#include "aes_alt.h" -#endif /* MBEDTLS_AES_ALT */ - -/** - * \brief This function initializes the specified AES context. - * - * It must be the first API called before using - * the context. - * - * \param ctx The AES context to initialize. This must not be \c NULL. - */ -void mbedtls_aes_init( mbedtls_aes_context *ctx ); - -/** - * \brief This function releases and clears the specified AES context. - * - * \param ctx The AES context to clear. - * If this is \c NULL, this function does nothing. - * Otherwise, the context must have been at least initialized. - */ -void mbedtls_aes_free( mbedtls_aes_context *ctx ); - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/** - * \brief This function initializes the specified AES XTS context. - * - * It must be the first API called before using - * the context. - * - * \param ctx The AES XTS context to initialize. This must not be \c NULL. - */ -void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx ); - -/** - * \brief This function releases and clears the specified AES XTS context. - * - * \param ctx The AES XTS context to clear. - * If this is \c NULL, this function does nothing. - * Otherwise, the context must have been at least initialized. - */ -void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx ); -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -/** - * \brief This function sets the encryption key. - * - * \param ctx The AES context to which the key should be bound. - * It must be initialized. - * \param key The encryption key. - * This must be a readable buffer of size \p keybits bits. - * \param keybits The size of data passed in bits. Valid options are: - *
  • 128 bits
  • - *
  • 192 bits
  • - *
  • 256 bits
- * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. - */ -int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, - unsigned int keybits ); - -/** - * \brief This function sets the decryption key. - * - * \param ctx The AES context to which the key should be bound. - * It must be initialized. - * \param key The decryption key. - * This must be a readable buffer of size \p keybits bits. - * \param keybits The size of data passed. Valid options are: - *
  • 128 bits
  • - *
  • 192 bits
  • - *
  • 256 bits
- * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. - */ -int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, - unsigned int keybits ); - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/** - * \brief This function prepares an XTS context for encryption and - * sets the encryption key. - * - * \param ctx The AES XTS context to which the key should be bound. - * It must be initialized. - * \param key The encryption key. This is comprised of the XTS key1 - * concatenated with the XTS key2. - * This must be a readable buffer of size \p keybits bits. - * \param keybits The size of \p key passed in bits. Valid options are: - *
  • 256 bits (each of key1 and key2 is a 128-bit key)
  • - *
  • 512 bits (each of key1 and key2 is a 256-bit key)
- * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. - */ -int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx, - const unsigned char *key, - unsigned int keybits ); - -/** - * \brief This function prepares an XTS context for decryption and - * sets the decryption key. - * - * \param ctx The AES XTS context to which the key should be bound. - * It must be initialized. - * \param key The decryption key. This is comprised of the XTS key1 - * concatenated with the XTS key2. - * This must be a readable buffer of size \p keybits bits. - * \param keybits The size of \p key passed in bits. Valid options are: - *
  • 256 bits (each of key1 and key2 is a 128-bit key)
  • - *
  • 512 bits (each of key1 and key2 is a 256-bit key)
- * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. - */ -int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx, - const unsigned char *key, - unsigned int keybits ); -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -/** - * \brief This function performs an AES single-block encryption or - * decryption operation. - * - * It performs the operation defined in the \p mode parameter - * (encrypt or decrypt), on the input data buffer defined in - * the \p input parameter. - * - * mbedtls_aes_init(), and either mbedtls_aes_setkey_enc() or - * mbedtls_aes_setkey_dec() must be called before the first - * call to this API with the same context. - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or - * #MBEDTLS_AES_DECRYPT. - * \param input The buffer holding the input data. - * It must be readable and at least \c 16 Bytes long. - * \param output The buffer where the output data will be written. - * It must be writeable and at least \c 16 Bytes long. - - * \return \c 0 on success. - */ -int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/** - * \brief This function performs an AES-CBC encryption or decryption operation - * on full blocks. - * - * It performs the operation defined in the \p mode - * parameter (encrypt/decrypt), on the input data buffer defined in - * the \p input parameter. - * - * It can be called as many times as needed, until all the input - * data is processed. mbedtls_aes_init(), and either - * mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called - * before the first call to this API with the same context. - * - * \note This function operates on full blocks, that is, the input size - * must be a multiple of the AES block size of \c 16 Bytes. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the same function again on the next - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If you need to retain the contents of the IV, you should - * either save it manually or use the cipher module instead. - * - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or - * #MBEDTLS_AES_DECRYPT. - * \param length The length of the input data in Bytes. This must be a - * multiple of the block size (\c 16 Bytes). - * \param iv Initialization vector (updated after use). - * It must be a readable and writeable buffer of \c 16 Bytes. - * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. - * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH - * on failure. - */ -int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/** - * \brief This function performs an AES-XTS encryption or decryption - * operation for an entire XTS data unit. - * - * AES-XTS encrypts or decrypts blocks based on their location as - * defined by a data unit number. The data unit number must be - * provided by \p data_unit. - * - * NIST SP 800-38E limits the maximum size of a data unit to 2^20 - * AES blocks. If the data unit is larger than this, this function - * returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH. - * - * \param ctx The AES XTS context to use for AES XTS operations. - * It must be initialized and bound to a key. - * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or - * #MBEDTLS_AES_DECRYPT. - * \param length The length of a data unit in Bytes. This can be any - * length between 16 bytes and 2^24 bytes inclusive - * (between 1 and 2^20 block cipher blocks). - * \param data_unit The address of the data unit encoded as an array of 16 - * bytes in little-endian format. For disk encryption, this - * is typically the index of the block device sector that - * contains the data. - * \param input The buffer holding the input data (which is an entire - * data unit). This function reads \p length Bytes from \p - * input. - * \param output The buffer holding the output data (which is an entire - * data unit). This function writes \p length Bytes to \p - * output. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is - * smaller than an AES block in size (16 Bytes) or if \p - * length is larger than 2^20 blocks (16 MiB). - */ -int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, - int mode, - size_t length, - const unsigned char data_unit[16], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/** - * \brief This function performs an AES-CFB128 encryption or decryption - * operation. - * - * It performs the operation defined in the \p mode - * parameter (encrypt or decrypt), on the input data buffer - * defined in the \p input parameter. - * - * For CFB, you must set up the context with mbedtls_aes_setkey_enc(), - * regardless of whether you are performing an encryption or decryption - * operation, that is, regardless of the \p mode parameter. This is - * because CFB mode uses the same key schedule for encryption and - * decryption. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the same function again on the next - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If you need to retain the contents of the - * IV, you must either save it manually or use the cipher - * module instead. - * - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or - * #MBEDTLS_AES_DECRYPT. - * \param length The length of the input data in Bytes. - * \param iv_off The offset in IV (updated after use). - * It must point to a valid \c size_t. - * \param iv The initialization vector (updated after use). - * It must be a readable and writeable buffer of \c 16 Bytes. - * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. - * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. - * - * \return \c 0 on success. - */ -int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); - -/** - * \brief This function performs an AES-CFB8 encryption or decryption - * operation. - * - * It performs the operation defined in the \p mode - * parameter (encrypt/decrypt), on the input data buffer defined - * in the \p input parameter. - * - * Due to the nature of CFB, you must use the same key schedule for - * both encryption and decryption operations. Therefore, you must - * use the context initialized with mbedtls_aes_setkey_enc() for - * both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the same function again on the next - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If you need to retain the contents of the - * IV, you should either save it manually or use the cipher - * module instead. - * - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or - * #MBEDTLS_AES_DECRYPT - * \param length The length of the input data. - * \param iv The initialization vector (updated after use). - * It must be a readable and writeable buffer of \c 16 Bytes. - * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. - * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. - * - * \return \c 0 on success. - */ -int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); -#endif /*MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -/** - * \brief This function performs an AES-OFB (Output Feedback Mode) - * encryption or decryption operation. - * - * For OFB, you must set up the context with - * mbedtls_aes_setkey_enc(), regardless of whether you are - * performing an encryption or decryption operation. This is - * because OFB mode uses the same key schedule for encryption and - * decryption. - * - * The OFB operation is identical for encryption or decryption, - * therefore no operation mode needs to be specified. - * - * \note Upon exit, the content of iv, the Initialisation Vector, is - * updated so that you can call the same function again on the next - * block(s) of data and get the same result as if it was encrypted - * in one call. This allows a "streaming" usage, by initialising - * iv_off to 0 before the first call, and preserving its value - * between calls. - * - * For non-streaming use, the iv should be initialised on each call - * to a unique value, and iv_off set to 0 on each call. - * - * If you need to retain the contents of the initialisation vector, - * you must either save it manually or use the cipher module - * instead. - * - * \warning For the OFB mode, the initialisation vector must be unique - * every encryption operation. Reuse of an initialisation vector - * will compromise security. - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param length The length of the input data. - * \param iv_off The offset in IV (updated after use). - * It must point to a valid \c size_t. - * \param iv The initialization vector (updated after use). - * It must be a readable and writeable buffer of \c 16 Bytes. - * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. - * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. - * - * \return \c 0 on success. - */ -int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); - -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/** - * \brief This function performs an AES-CTR encryption or decryption - * operation. - * - * This function performs the operation defined in the \p mode - * parameter (encrypt/decrypt), on the input data buffer - * defined in the \p input parameter. - * - * Due to the nature of CTR, you must use the same key schedule - * for both encryption and decryption operations. Therefore, you - * must use the context initialized with mbedtls_aes_setkey_enc() - * for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT. - * - * \warning You must never reuse a nonce value with the same key. Doing so - * would void the encryption for the two messages encrypted with - * the same nonce and key. - * - * There are two common strategies for managing nonces with CTR: - * - * 1. You can handle everything as a single message processed over - * successive calls to this function. In that case, you want to - * set \p nonce_counter and \p nc_off to 0 for the first call, and - * then preserve the values of \p nonce_counter, \p nc_off and \p - * stream_block across calls to this function as they will be - * updated by this function. - * - * With this strategy, you must not encrypt more than 2**128 - * blocks of data with the same key. - * - * 2. You can encrypt separate messages by dividing the \p - * nonce_counter buffer in two areas: the first one used for a - * per-message nonce, handled by yourself, and the second one - * updated by this function internally. - * - * For example, you might reserve the first 12 bytes for the - * per-message nonce, and the last 4 bytes for internal use. In that - * case, before calling this function on a new message you need to - * set the first 12 bytes of \p nonce_counter to your chosen nonce - * value, the last 4 to 0, and \p nc_off to 0 (which will cause \p - * stream_block to be ignored). That way, you can encrypt at most - * 2**96 messages of up to 2**32 blocks each with the same key. - * - * The per-message nonce (or information sufficient to reconstruct - * it) needs to be communicated with the ciphertext and must be unique. - * The recommended way to ensure uniqueness is to use a message - * counter. An alternative is to generate random nonces, but this - * limits the number of messages that can be securely encrypted: - * for example, with 96-bit random nonces, you should not encrypt - * more than 2**32 messages with the same key. - * - * Note that for both stategies, sizes are measured in blocks and - * that an AES block is 16 bytes. - * - * \warning Upon return, \p stream_block contains sensitive data. Its - * content must not be written to insecure storage and should be - * securely discarded as soon as it's no longer needed. - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param length The length of the input data. - * \param nc_off The offset in the current \p stream_block, for - * resuming within the current cipher stream. The - * offset pointer should be 0 at the start of a stream. - * It must point to a valid \c size_t. - * \param nonce_counter The 128-bit nonce and counter. - * It must be a readable-writeable buffer of \c 16 Bytes. - * \param stream_block The saved stream block for resuming. This is - * overwritten by the function. - * It must be a readable-writeable buffer of \c 16 Bytes. - * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. - * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. - * - * \return \c 0 on success. - */ -int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[16], - unsigned char stream_block[16], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -/** - * \brief Internal AES block encryption function. This is only - * exposed to allow overriding it using - * \c MBEDTLS_AES_ENCRYPT_ALT. - * - * \param ctx The AES context to use for encryption. - * \param input The plaintext block. - * \param output The output (ciphertext) block. - * - * \return \c 0 on success. - */ -int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ); - -/** - * \brief Internal AES block decryption function. This is only - * exposed to allow overriding it using see - * \c MBEDTLS_AES_DECRYPT_ALT. - * - * \param ctx The AES context to use for decryption. - * \param input The ciphertext block. - * \param output The output (plaintext) block. - * - * \return \c 0 on success. - */ -int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief Deprecated internal AES block encryption function - * without return value. - * - * \deprecated Superseded by mbedtls_internal_aes_encrypt() - * - * \param ctx The AES context to use for encryption. - * \param input Plaintext block. - * \param output Output (ciphertext) block. - */ -MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ); - -/** - * \brief Deprecated internal AES block decryption function - * without return value. - * - * \deprecated Superseded by mbedtls_internal_aes_decrypt() - * - * \param ctx The AES context to use for decryption. - * \param input Ciphertext block. - * \param output Output (plaintext) block. - */ -MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ); - -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief Checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_aes_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* aes.h */ diff --git a/templates/blackpill/Src/cipher.c b/templates/blackpill/Src/cipher.c deleted file mode 100644 index 0a46dae..0000000 --- a/templates/blackpill/Src/cipher.c +++ /dev/null @@ -1,1540 +0,0 @@ -/** - * \file cipher.c - * - * \brief Generic cipher wrapper for mbed TLS - * - * \author Adriaan de Jong - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CIPHER_C) - -#include "cipher.h" -#include "cipher_internal.h" -#include "platform_util.h" - -#include -#include - -#if defined(MBEDTLS_CHACHAPOLY_C) -#include "mbedtls/chachapoly.h" -#endif - -#if defined(MBEDTLS_GCM_C) -#include "gcm.h" -#endif - -#if defined(MBEDTLS_CCM_C) -#include "mbedtls/ccm.h" -#endif - -#if defined(MBEDTLS_CHACHA20_C) -#include "mbedtls/chacha20.h" -#endif - -#if defined(MBEDTLS_CMAC_C) -#include "mbedtls/cmac.h" -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#include "mbedtls/psa_util.h" -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_NIST_KW_C) -#include "mbedtls/nist_kw.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#define CIPHER_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ) -#define CIPHER_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -/* Compare the contents of two buffers in constant time. - * Returns 0 if the contents are bitwise identical, otherwise returns - * a non-zero value. - * This is currently only used by GCM and ChaCha20+Poly1305. - */ -static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, - size_t len ) -{ - const unsigned char *p1 = (const unsigned char*) v1; - const unsigned char *p2 = (const unsigned char*) v2; - size_t i; - unsigned char diff; - - for( diff = 0, i = 0; i < len; i++ ) - diff |= p1[i] ^ p2[i]; - - return( (int)diff ); -} -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ - -static int supported_init = 0; - -const int *mbedtls_cipher_list( void ) -{ - const mbedtls_cipher_definition_t *def; - int *type; - - if( ! supported_init ) - { - def = mbedtls_cipher_definitions; - type = mbedtls_cipher_supported; - - while( def->type != 0 ) - *type++ = (*def++).type; - - *type = 0; - - supported_init = 1; - } - - return( mbedtls_cipher_supported ); -} - -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( - const mbedtls_cipher_type_t cipher_type ) -{ - const mbedtls_cipher_definition_t *def; - - for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) - if( def->type == cipher_type ) - return( def->info ); - - return( NULL ); -} - -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( - const char *cipher_name ) -{ - const mbedtls_cipher_definition_t *def; - - if( NULL == cipher_name ) - return( NULL ); - - for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) - if( ! strcmp( def->info->name, cipher_name ) ) - return( def->info ); - - return( NULL ); -} - -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( - const mbedtls_cipher_id_t cipher_id, - int key_bitlen, - const mbedtls_cipher_mode_t mode ) -{ - const mbedtls_cipher_definition_t *def; - - for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) - if( def->info->base->cipher == cipher_id && - def->info->key_bitlen == (unsigned) key_bitlen && - def->info->mode == mode ) - return( def->info ); - - return( NULL ); -} - -void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ) -{ - CIPHER_VALIDATE( ctx != NULL ); - memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); -} - -void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ) -{ - if( ctx == NULL ) - return; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - if( ctx->cipher_ctx != NULL ) - { - mbedtls_cipher_context_psa * const cipher_psa = - (mbedtls_cipher_context_psa *) ctx->cipher_ctx; - - if( cipher_psa->slot_state == MBEDTLS_CIPHER_PSA_KEY_OWNED ) - { - /* xxx_free() doesn't allow to return failures. */ - (void) psa_destroy_key( cipher_psa->slot ); - } - - mbedtls_platform_zeroize( cipher_psa, sizeof( *cipher_psa ) ); - mbedtls_free( cipher_psa ); - } - - mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) ); - return; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_CMAC_C) - if( ctx->cmac_ctx ) - { - mbedtls_platform_zeroize( ctx->cmac_ctx, - sizeof( mbedtls_cmac_context_t ) ); - mbedtls_free( ctx->cmac_ctx ); - } -#endif - - if( ctx->cipher_ctx ) - ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx ); - - mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) ); -} - -int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, - const mbedtls_cipher_info_t *cipher_info ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - if( cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); - - if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) ) - return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); - - ctx->cipher_info = cipher_info; - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) - /* - * Ignore possible errors caused by a cipher mode that doesn't use padding - */ -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) - (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 ); -#else - (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE ); -#endif -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - - return( 0 ); -} - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx, - const mbedtls_cipher_info_t *cipher_info, - size_t taglen ) -{ - psa_algorithm_t alg; - mbedtls_cipher_context_psa *cipher_psa; - - if( NULL == cipher_info || NULL == ctx ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - /* Check that the underlying cipher mode and cipher type are - * supported by the underlying PSA Crypto implementation. */ - alg = mbedtls_psa_translate_cipher_mode( cipher_info->mode, taglen ); - if( alg == 0 ) - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - if( mbedtls_psa_translate_cipher_type( cipher_info->type ) == 0 ) - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - - memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); - - cipher_psa = mbedtls_calloc( 1, sizeof(mbedtls_cipher_context_psa ) ); - if( cipher_psa == NULL ) - return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); - cipher_psa->alg = alg; - ctx->cipher_ctx = cipher_psa; - ctx->cipher_info = cipher_info; - ctx->psa_enabled = 1; - return( 0 ); -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, - const unsigned char *key, - int key_bitlen, - const mbedtls_operation_t operation ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( key != NULL ); - CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT || - operation == MBEDTLS_DECRYPT ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - mbedtls_cipher_context_psa * const cipher_psa = - (mbedtls_cipher_context_psa *) ctx->cipher_ctx; - - size_t const key_bytelen = ( (size_t) key_bitlen + 7 ) / 8; - - psa_status_t status; - psa_key_type_t key_type; - psa_key_usage_t key_usage; - psa_key_policy_t key_policy; - - /* PSA Crypto API only accepts byte-aligned keys. */ - if( key_bitlen % 8 != 0 ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - /* Don't allow keys to be set multiple times. */ - if( cipher_psa->slot_state != MBEDTLS_CIPHER_PSA_KEY_UNSET ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - key_type = mbedtls_psa_translate_cipher_type( - ctx->cipher_info->type ); - if( key_type == 0 ) - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - - /* Allocate a key slot to use. */ - status = psa_allocate_key( &cipher_psa->slot ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); - - /* Indicate that we own the key slot and need to - * destroy it in mbedtls_cipher_free(). */ - cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED; - - /* From that point on, the responsibility for destroying the - * key slot is on mbedtls_cipher_free(). This includes the case - * where the policy setup or key import below fail, as - * mbedtls_cipher_free() needs to be called in any case. */ - - /* Setup policy for the new key slot. */ - key_policy = psa_key_policy_init(); - - /* Mbed TLS' cipher layer doesn't enforce the mode of operation - * (encrypt vs. decrypt): it is possible to setup a key for encryption - * and use it for AEAD decryption. Until tests relying on this - * are changed, allow any usage in PSA. */ - /* key_usage = mbedtls_psa_translate_cipher_operation( operation ); */ - key_usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT; - psa_key_policy_set_usage( &key_policy, key_usage, cipher_psa->alg ); - status = psa_set_key_policy( cipher_psa->slot, &key_policy ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); - - /* Populate new key slot. */ - status = psa_import_key( cipher_psa->slot, - key_type, key, key_bytelen ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); - - ctx->key_bitlen = key_bitlen; - ctx->operation = operation; - return( 0 ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 && - (int) ctx->cipher_info->key_bitlen != key_bitlen ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - ctx->key_bitlen = key_bitlen; - ctx->operation = operation; - - /* - * For OFB, CFB and CTR mode always use the encryption key schedule - */ - if( MBEDTLS_ENCRYPT == operation || - MBEDTLS_MODE_CFB == ctx->cipher_info->mode || - MBEDTLS_MODE_OFB == ctx->cipher_info->mode || - MBEDTLS_MODE_CTR == ctx->cipher_info->mode ) - { - return( ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key, - ctx->key_bitlen ) ); - } - - if( MBEDTLS_DECRYPT == operation ) - return( ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key, - ctx->key_bitlen ) ); - - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); -} - -int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, - size_t iv_len ) -{ - size_t actual_iv_size; - - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* While PSA Crypto has an API for multipart - * operations, we currently don't make it - * accessible through the cipher layer. */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - /* avoid buffer overflow in ctx->iv */ - if( iv_len > MBEDTLS_MAX_IV_LENGTH ) - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - - if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 ) - actual_iv_size = iv_len; - else - { - actual_iv_size = ctx->cipher_info->iv_size; - - /* avoid reading past the end of input buffer */ - if( actual_iv_size > iv_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_CHACHA20_C) - if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 ) - { - if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx, - iv, - 0U ) ) /* Initial counter value */ - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - } -#endif - - if ( actual_iv_size != 0 ) - { - memcpy( ctx->iv, iv, actual_iv_size ); - ctx->iv_size = actual_iv_size; - } - - return( 0 ); -} - -int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* We don't support resetting PSA-based - * cipher contexts, yet. */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - ctx->unprocessed_len = 0; - - return( 0 ); -} - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, - const unsigned char *ad, size_t ad_len ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* While PSA Crypto has an API for multipart - * operations, we currently don't make it - * accessible through the cipher layer. */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_GCM_C) - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - { - return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation, - ctx->iv, ctx->iv_size, ad, ad_len ) ); - } -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - int result; - mbedtls_chachapoly_mode_t mode; - - mode = ( ctx->operation == MBEDTLS_ENCRYPT ) - ? MBEDTLS_CHACHAPOLY_ENCRYPT - : MBEDTLS_CHACHAPOLY_DECRYPT; - - result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - ctx->iv, - mode ); - if ( result != 0 ) - return( result ); - - return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - ad, ad_len ) ); - } -#endif - - return( 0 ); -} -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ - -int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, - size_t ilen, unsigned char *output, size_t *olen ) -{ - int ret; - size_t block_size; - - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* While PSA Crypto has an API for multipart - * operations, we currently don't make it - * accessible through the cipher layer. */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - *olen = 0; - block_size = mbedtls_cipher_get_block_size( ctx ); - - if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB ) - { - if( ilen != block_size ) - return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); - - *olen = ilen; - - if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx, - ctx->operation, input, output ) ) ) - { - return( ret ); - } - - return( 0 ); - } - -#if defined(MBEDTLS_GCM_C) - if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM ) - { - *olen = ilen; - return( mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input, - output ) ); - } -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) - { - *olen = ilen; - return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - ilen, input, output ) ); - } -#endif - - if ( 0 == block_size ) - { - return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT ); - } - - if( input == output && - ( ctx->unprocessed_len != 0 || ilen % block_size ) ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC ) - { - size_t copy_len = 0; - - /* - * If there is not enough data for a full block, cache it. - */ - if( ( ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding && - ilen <= block_size - ctx->unprocessed_len ) || - ( ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding && - ilen < block_size - ctx->unprocessed_len ) || - ( ctx->operation == MBEDTLS_ENCRYPT && - ilen < block_size - ctx->unprocessed_len ) ) - { - memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, - ilen ); - - ctx->unprocessed_len += ilen; - return( 0 ); - } - - /* - * Process cached data first - */ - if( 0 != ctx->unprocessed_len ) - { - copy_len = block_size - ctx->unprocessed_len; - - memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, - copy_len ); - - if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, - ctx->operation, block_size, ctx->iv, - ctx->unprocessed_data, output ) ) ) - { - return( ret ); - } - - *olen += block_size; - output += block_size; - ctx->unprocessed_len = 0; - - input += copy_len; - ilen -= copy_len; - } - - /* - * Cache final, incomplete block - */ - if( 0 != ilen ) - { - if( 0 == block_size ) - { - return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT ); - } - - /* Encryption: only cache partial blocks - * Decryption w/ padding: always keep at least one whole block - * Decryption w/o padding: only cache partial blocks - */ - copy_len = ilen % block_size; - if( copy_len == 0 && - ctx->operation == MBEDTLS_DECRYPT && - NULL != ctx->add_padding) - { - copy_len = block_size; - } - - memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), - copy_len ); - - ctx->unprocessed_len += copy_len; - ilen -= copy_len; - } - - /* - * Process remaining full blocks - */ - if( ilen ) - { - if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, - ctx->operation, ilen, ctx->iv, input, output ) ) ) - { - return( ret ); - } - - *olen += ilen; - } - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) - if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB ) - { - if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx, - ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv, - input, output ) ) ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) - if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB ) - { - if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx, - ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR ) - { - if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx, - ilen, &ctx->unprocessed_len, ctx->iv, - ctx->unprocessed_data, input, output ) ) ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) - if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS ) - { - if( ctx->unprocessed_len > 0 ) { - /* We can only process an entire data unit at a time. */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } - - ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx, - ctx->operation, ilen, ctx->iv, input, output ); - if( ret != 0 ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM ) - { - if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx, - ilen, input, output ) ) ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_STREAM */ - - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); -} - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) -/* - * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len - */ -static void add_pkcs_padding( unsigned char *output, size_t output_len, - size_t data_len ) -{ - size_t padding_len = output_len - data_len; - unsigned char i; - - for( i = 0; i < padding_len; i++ ) - output[data_len + i] = (unsigned char) padding_len; -} - -static int get_pkcs_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - size_t i, pad_idx; - unsigned char padding_len, bad = 0; - - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - padding_len = input[input_len - 1]; - *data_len = input_len - padding_len; - - /* Avoid logical || since it results in a branch */ - bad |= padding_len > input_len; - bad |= padding_len == 0; - - /* The number of bytes checked must be independent of padding_len, - * so pick input_len, which is usually 8 or 16 (one block) */ - pad_idx = input_len - padding_len; - for( i = 0; i < input_len; i++ ) - bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx ); - - return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); -} -#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ - -#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) -/* - * One and zeros padding: fill with 80 00 ... 00 - */ -static void add_one_and_zeros_padding( unsigned char *output, - size_t output_len, size_t data_len ) -{ - size_t padding_len = output_len - data_len; - unsigned char i = 0; - - output[data_len] = 0x80; - for( i = 1; i < padding_len; i++ ) - output[data_len + i] = 0x00; -} - -static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - size_t i; - unsigned char done = 0, prev_done, bad; - - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - bad = 0x80; - *data_len = 0; - for( i = input_len; i > 0; i-- ) - { - prev_done = done; - done |= ( input[i - 1] != 0 ); - *data_len |= ( i - 1 ) * ( done != prev_done ); - bad ^= input[i - 1] * ( done != prev_done ); - } - - return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); - -} -#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ - -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) -/* - * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length - */ -static void add_zeros_and_len_padding( unsigned char *output, - size_t output_len, size_t data_len ) -{ - size_t padding_len = output_len - data_len; - unsigned char i = 0; - - for( i = 1; i < padding_len; i++ ) - output[data_len + i - 1] = 0x00; - output[output_len - 1] = (unsigned char) padding_len; -} - -static int get_zeros_and_len_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - size_t i, pad_idx; - unsigned char padding_len, bad = 0; - - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - padding_len = input[input_len - 1]; - *data_len = input_len - padding_len; - - /* Avoid logical || since it results in a branch */ - bad |= padding_len > input_len; - bad |= padding_len == 0; - - /* The number of bytes checked must be independent of padding_len */ - pad_idx = input_len - padding_len; - for( i = 0; i < input_len - 1; i++ ) - bad |= input[i] * ( i >= pad_idx ); - - return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); -} -#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ - -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) -/* - * Zero padding: fill with 00 ... 00 - */ -static void add_zeros_padding( unsigned char *output, - size_t output_len, size_t data_len ) -{ - size_t i; - - for( i = data_len; i < output_len; i++ ) - output[i] = 0x00; -} - -static int get_zeros_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - size_t i; - unsigned char done = 0, prev_done; - - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - *data_len = 0; - for( i = input_len; i > 0; i-- ) - { - prev_done = done; - done |= ( input[i-1] != 0 ); - *data_len |= i * ( done != prev_done ); - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ - -/* - * No padding: don't pad :) - * - * There is no add_padding function (check for NULL in mbedtls_cipher_finish) - * but a trivial get_padding function - */ -static int get_no_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - *data_len = input_len; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - -int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, - unsigned char *output, size_t *olen ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* While PSA Crypto has an API for multipart - * operations, we currently don't make it - * accessible through the cipher layer. */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - *olen = 0; - - if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode || - MBEDTLS_MODE_OFB == ctx->cipher_info->mode || - MBEDTLS_MODE_CTR == ctx->cipher_info->mode || - MBEDTLS_MODE_GCM == ctx->cipher_info->mode || - MBEDTLS_MODE_XTS == ctx->cipher_info->mode || - MBEDTLS_MODE_STREAM == ctx->cipher_info->mode ) - { - return( 0 ); - } - - if ( ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) || - ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) ) - { - return( 0 ); - } - - if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode ) - { - if( ctx->unprocessed_len != 0 ) - return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); - - return( 0 ); - } - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode ) - { - int ret = 0; - - if( MBEDTLS_ENCRYPT == ctx->operation ) - { - /* check for 'no padding' mode */ - if( NULL == ctx->add_padding ) - { - if( 0 != ctx->unprocessed_len ) - return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); - - return( 0 ); - } - - ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ), - ctx->unprocessed_len ); - } - else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len ) - { - /* - * For decrypt operations, expect a full block, - * or an empty block if no padding - */ - if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len ) - return( 0 ); - - return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); - } - - /* cipher block */ - if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, - ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv, - ctx->unprocessed_data, output ) ) ) - { - return( ret ); - } - - /* Set output size for decryption */ - if( MBEDTLS_DECRYPT == ctx->operation ) - return( ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ), - olen ) ); - - /* Set output size for encryption */ - *olen = mbedtls_cipher_get_block_size( ctx ); - return( 0 ); - } -#else - ((void) output); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); -} - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) -int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, - mbedtls_cipher_padding_t mode ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - - if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* While PSA Crypto knows about CBC padding - * schemes, we currently don't make them - * accessible through the cipher layer. */ - if( mode != MBEDTLS_PADDING_NONE ) - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - - return( 0 ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - switch( mode ) - { -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) - case MBEDTLS_PADDING_PKCS7: - ctx->add_padding = add_pkcs_padding; - ctx->get_padding = get_pkcs_padding; - break; -#endif -#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) - case MBEDTLS_PADDING_ONE_AND_ZEROS: - ctx->add_padding = add_one_and_zeros_padding; - ctx->get_padding = get_one_and_zeros_padding; - break; -#endif -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) - case MBEDTLS_PADDING_ZEROS_AND_LEN: - ctx->add_padding = add_zeros_and_len_padding; - ctx->get_padding = get_zeros_and_len_padding; - break; -#endif -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) - case MBEDTLS_PADDING_ZEROS: - ctx->add_padding = add_zeros_padding; - ctx->get_padding = get_zeros_padding; - break; -#endif - case MBEDTLS_PADDING_NONE: - ctx->add_padding = NULL; - ctx->get_padding = get_no_padding; - break; - - default: - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, - unsigned char *tag, size_t tag_len ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( MBEDTLS_ENCRYPT != ctx->operation ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* While PSA Crypto has an API for multipart - * operations, we currently don't make it - * accessible through the cipher layer. */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - - return( 0 ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_GCM_C) - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, - tag, tag_len ) ); -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - /* Don't allow truncated MAC for Poly1305 */ - if ( tag_len != 16U ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - return( mbedtls_chachapoly_finish( - (mbedtls_chachapoly_context*) ctx->cipher_ctx, tag ) ); - } -#endif - - return( 0 ); -} - -int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, - const unsigned char *tag, size_t tag_len ) -{ - unsigned char check_tag[16]; - int ret; - - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( MBEDTLS_DECRYPT != ctx->operation ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* While PSA Crypto has an API for multipart - * operations, we currently don't make it - * accessible through the cipher layer. */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_GCM_C) - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - { - if( tag_len > sizeof( check_tag ) ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( 0 != ( ret = mbedtls_gcm_finish( - (mbedtls_gcm_context *) ctx->cipher_ctx, - check_tag, tag_len ) ) ) - { - return( ret ); - } - - /* Check the tag in "constant-time" */ - if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) - return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); - - return( 0 ); - } -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - /* Don't allow truncated MAC for Poly1305 */ - if ( tag_len != sizeof( check_tag ) ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - ret = mbedtls_chachapoly_finish( - (mbedtls_chachapoly_context*) ctx->cipher_ctx, check_tag ); - if ( ret != 0 ) - { - return( ret ); - } - - /* Check the tag in "constant-time" */ - if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) - return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); - - return( 0 ); - } -#endif /* MBEDTLS_CHACHAPOLY_C */ - - return( 0 ); -} -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ - -/* - * Packet-oriented wrapper for non-AEAD modes - */ -int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen ) -{ - int ret; - size_t finish_olen; - - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); - CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* As in the non-PSA case, we don't check that - * a key has been set. If not, the key slot will - * still be in its default state of 0, which is - * guaranteed to be invalid, hence the PSA-call - * below will gracefully fail. */ - mbedtls_cipher_context_psa * const cipher_psa = - (mbedtls_cipher_context_psa *) ctx->cipher_ctx; - - psa_status_t status; - psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT; - size_t part_len; - - if( ctx->operation == MBEDTLS_DECRYPT ) - { - status = psa_cipher_decrypt_setup( &cipher_op, - cipher_psa->slot, - cipher_psa->alg ); - } - else if( ctx->operation == MBEDTLS_ENCRYPT ) - { - status = psa_cipher_encrypt_setup( &cipher_op, - cipher_psa->slot, - cipher_psa->alg ); - } - else - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - /* In the following, we can immediately return on an error, - * because the PSA Crypto API guarantees that cipher operations - * are terminated by unsuccessful calls to psa_cipher_update(), - * and by any call to psa_cipher_finish(). */ - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); - - status = psa_cipher_set_iv( &cipher_op, iv, iv_len ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); - - status = psa_cipher_update( &cipher_op, - input, ilen, - output, ilen, olen ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); - - status = psa_cipher_finish( &cipher_op, - output + *olen, ilen - *olen, - &part_len ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); - - *olen += part_len; - return( 0 ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_update( ctx, input, ilen, - output, olen ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, - &finish_olen ) ) != 0 ) - return( ret ); - - *olen += finish_olen; - - return( 0 ); -} - -#if defined(MBEDTLS_CIPHER_MODE_AEAD) -/* - * Packet-oriented encryption for AEAD modes - */ -int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, - unsigned char *tag, size_t tag_len ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv != NULL ); - CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); - CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* As in the non-PSA case, we don't check that - * a key has been set. If not, the key slot will - * still be in its default state of 0, which is - * guaranteed to be invalid, hence the PSA-call - * below will gracefully fail. */ - mbedtls_cipher_context_psa * const cipher_psa = - (mbedtls_cipher_context_psa *) ctx->cipher_ctx; - - psa_status_t status; - - /* PSA Crypto API always writes the authentication tag - * at the end of the encrypted message. */ - if( tag != output + ilen ) - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - - status = psa_aead_encrypt( cipher_psa->slot, - cipher_psa->alg, - iv, iv_len, - ad, ad_len, - input, ilen, - output, ilen + tag_len, olen ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); - - *olen -= tag_len; - return( 0 ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_GCM_C) - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - { - *olen = ilen; - return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, - ilen, iv, iv_len, ad, ad_len, - input, output, tag_len, tag ) ); - } -#endif /* MBEDTLS_GCM_C */ -#if defined(MBEDTLS_CCM_C) - if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) - { - *olen = ilen; - return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen, - iv, iv_len, ad, ad_len, input, output, - tag, tag_len ) ); - } -#endif /* MBEDTLS_CCM_C */ -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - /* ChachaPoly has fixed length nonce and MAC (tag) */ - if ( ( iv_len != ctx->cipher_info->iv_size ) || - ( tag_len != 16U ) ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - *olen = ilen; - return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx, - ilen, iv, ad, ad_len, input, output, tag ) ); - } -#endif /* MBEDTLS_CHACHAPOLY_C */ -#if defined(MBEDTLS_NIST_KW_C) - if( MBEDTLS_MODE_KW == ctx->cipher_info->mode || - MBEDTLS_MODE_KWP == ctx->cipher_info->mode ) - { - mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ? - MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP; - - /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */ - if( iv_len != 0 || tag_len != 0 || ad_len != 0 ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - return( mbedtls_nist_kw_wrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) ); - } -#endif /* MBEDTLS_NIST_KW_C */ - - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); -} - -/* - * Packet-oriented decryption for AEAD modes - */ -int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, - const unsigned char *tag, size_t tag_len ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv != NULL ); - CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); - CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* As in the non-PSA case, we don't check that - * a key has been set. If not, the key slot will - * still be in its default state of 0, which is - * guaranteed to be invalid, hence the PSA-call - * below will gracefully fail. */ - mbedtls_cipher_context_psa * const cipher_psa = - (mbedtls_cipher_context_psa *) ctx->cipher_ctx; - - psa_status_t status; - - /* PSA Crypto API always writes the authentication tag - * at the end of the encrypted message. */ - if( tag != input + ilen ) - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - - status = psa_aead_decrypt( cipher_psa->slot, - cipher_psa->alg, - iv, iv_len, - ad, ad_len, - input, ilen + tag_len, - output, ilen, olen ); - if( status == PSA_ERROR_INVALID_SIGNATURE ) - return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); - else if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); - - return( 0 ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_GCM_C) - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - { - int ret; - - *olen = ilen; - ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen, - iv, iv_len, ad, ad_len, - tag, tag_len, input, output ); - - if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED ) - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - - return( ret ); - } -#endif /* MBEDTLS_GCM_C */ -#if defined(MBEDTLS_CCM_C) - if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) - { - int ret; - - *olen = ilen; - ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen, - iv, iv_len, ad, ad_len, - input, output, tag, tag_len ); - - if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED ) - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - - return( ret ); - } -#endif /* MBEDTLS_CCM_C */ -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - int ret; - - /* ChachaPoly has fixed length nonce and MAC (tag) */ - if ( ( iv_len != ctx->cipher_info->iv_size ) || - ( tag_len != 16U ) ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - *olen = ilen; - ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen, - iv, ad, ad_len, tag, input, output ); - - if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ) - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - - return( ret ); - } -#endif /* MBEDTLS_CHACHAPOLY_C */ -#if defined(MBEDTLS_NIST_KW_C) - if( MBEDTLS_MODE_KW == ctx->cipher_info->mode || - MBEDTLS_MODE_KWP == ctx->cipher_info->mode ) - { - mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ? - MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP; - - /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */ - if( iv_len != 0 || tag_len != 0 || ad_len != 0 ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - return( mbedtls_nist_kw_unwrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) ); - } -#endif /* MBEDTLS_NIST_KW_C */ - - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); -} -#endif /* MBEDTLS_CIPHER_MODE_AEAD */ - -#endif /* MBEDTLS_CIPHER_C */ diff --git a/templates/blackpill/Src/cipher.h b/templates/blackpill/Src/cipher.h deleted file mode 100644 index ea00703..0000000 --- a/templates/blackpill/Src/cipher.h +++ /dev/null @@ -1,926 +0,0 @@ -/** - * \file cipher.h - * - * \brief This file contains an abstraction interface for use with the cipher - * primitives provided by the library. It provides a common interface to all of - * the available cipher operations. - * - * \author Adriaan de Jong - */ -/* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of Mbed TLS (https://tls.mbed.org) - */ - -#ifndef MBEDTLS_CIPHER_H -#define MBEDTLS_CIPHER_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include "platform_util.h" - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -#define MBEDTLS_CIPHER_MODE_AEAD -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#define MBEDTLS_CIPHER_MODE_WITH_PADDING -#endif - -#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \ - defined(MBEDTLS_CHACHA20_C) -#define MBEDTLS_CIPHER_MODE_STREAM -#endif - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */ -#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters. */ -#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */ -#define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */ -#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */ -#define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */ -#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 /**< The context is invalid. For example, because it was freed. */ - -/* MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED -0x6400 /**< Cipher hardware accelerator failed. */ - -#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length. */ -#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length. */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Supported cipher types. - * - * \warning RC4 and DES are considered weak ciphers and their use - * constitutes a security risk. Arm recommends considering stronger - * ciphers instead. - */ -typedef enum { - MBEDTLS_CIPHER_ID_NONE = 0, /**< Placeholder to mark the end of cipher ID lists. */ - MBEDTLS_CIPHER_ID_NULL, /**< The identity cipher, treated as a stream cipher. */ - MBEDTLS_CIPHER_ID_AES, /**< The AES cipher. */ - MBEDTLS_CIPHER_ID_DES, /**< The DES cipher. */ - MBEDTLS_CIPHER_ID_3DES, /**< The Triple DES cipher. */ - MBEDTLS_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */ - MBEDTLS_CIPHER_ID_BLOWFISH, /**< The Blowfish cipher. */ - MBEDTLS_CIPHER_ID_ARC4, /**< The RC4 cipher. */ - MBEDTLS_CIPHER_ID_ARIA, /**< The Aria cipher. */ - MBEDTLS_CIPHER_ID_CHACHA20, /**< The ChaCha20 cipher. */ -} mbedtls_cipher_id_t; - -/** - * \brief Supported {cipher type, cipher mode} pairs. - * - * \warning RC4 and DES are considered weak ciphers and their use - * constitutes a security risk. Arm recommends considering stronger - * ciphers instead. - */ -typedef enum { - MBEDTLS_CIPHER_NONE = 0, /**< Placeholder to mark the end of cipher-pair lists. */ - MBEDTLS_CIPHER_NULL, /**< The identity stream cipher. */ - MBEDTLS_CIPHER_AES_128_ECB, /**< AES cipher with 128-bit ECB mode. */ - MBEDTLS_CIPHER_AES_192_ECB, /**< AES cipher with 192-bit ECB mode. */ - MBEDTLS_CIPHER_AES_256_ECB, /**< AES cipher with 256-bit ECB mode. */ - MBEDTLS_CIPHER_AES_128_CBC, /**< AES cipher with 128-bit CBC mode. */ - MBEDTLS_CIPHER_AES_192_CBC, /**< AES cipher with 192-bit CBC mode. */ - MBEDTLS_CIPHER_AES_256_CBC, /**< AES cipher with 256-bit CBC mode. */ - MBEDTLS_CIPHER_AES_128_CFB128, /**< AES cipher with 128-bit CFB128 mode. */ - MBEDTLS_CIPHER_AES_192_CFB128, /**< AES cipher with 192-bit CFB128 mode. */ - MBEDTLS_CIPHER_AES_256_CFB128, /**< AES cipher with 256-bit CFB128 mode. */ - MBEDTLS_CIPHER_AES_128_CTR, /**< AES cipher with 128-bit CTR mode. */ - MBEDTLS_CIPHER_AES_192_CTR, /**< AES cipher with 192-bit CTR mode. */ - MBEDTLS_CIPHER_AES_256_CTR, /**< AES cipher with 256-bit CTR mode. */ - MBEDTLS_CIPHER_AES_128_GCM, /**< AES cipher with 128-bit GCM mode. */ - MBEDTLS_CIPHER_AES_192_GCM, /**< AES cipher with 192-bit GCM mode. */ - MBEDTLS_CIPHER_AES_256_GCM, /**< AES cipher with 256-bit GCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_ECB, /**< Camellia cipher with 128-bit ECB mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_ECB, /**< Camellia cipher with 192-bit ECB mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_ECB, /**< Camellia cipher with 256-bit ECB mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_CBC, /**< Camellia cipher with 128-bit CBC mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_CBC, /**< Camellia cipher with 192-bit CBC mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_CBC, /**< Camellia cipher with 256-bit CBC mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_CFB128, /**< Camellia cipher with 128-bit CFB128 mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_CFB128, /**< Camellia cipher with 192-bit CFB128 mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_CFB128, /**< Camellia cipher with 256-bit CFB128 mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_CTR, /**< Camellia cipher with 128-bit CTR mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_CTR, /**< Camellia cipher with 192-bit CTR mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_CTR, /**< Camellia cipher with 256-bit CTR mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_GCM, /**< Camellia cipher with 128-bit GCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_GCM, /**< Camellia cipher with 192-bit GCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_GCM, /**< Camellia cipher with 256-bit GCM mode. */ - MBEDTLS_CIPHER_DES_ECB, /**< DES cipher with ECB mode. */ - MBEDTLS_CIPHER_DES_CBC, /**< DES cipher with CBC mode. */ - MBEDTLS_CIPHER_DES_EDE_ECB, /**< DES cipher with EDE ECB mode. */ - MBEDTLS_CIPHER_DES_EDE_CBC, /**< DES cipher with EDE CBC mode. */ - MBEDTLS_CIPHER_DES_EDE3_ECB, /**< DES cipher with EDE3 ECB mode. */ - MBEDTLS_CIPHER_DES_EDE3_CBC, /**< DES cipher with EDE3 CBC mode. */ - MBEDTLS_CIPHER_BLOWFISH_ECB, /**< Blowfish cipher with ECB mode. */ - MBEDTLS_CIPHER_BLOWFISH_CBC, /**< Blowfish cipher with CBC mode. */ - MBEDTLS_CIPHER_BLOWFISH_CFB64, /**< Blowfish cipher with CFB64 mode. */ - MBEDTLS_CIPHER_BLOWFISH_CTR, /**< Blowfish cipher with CTR mode. */ - MBEDTLS_CIPHER_ARC4_128, /**< RC4 cipher with 128-bit mode. */ - MBEDTLS_CIPHER_AES_128_CCM, /**< AES cipher with 128-bit CCM mode. */ - MBEDTLS_CIPHER_AES_192_CCM, /**< AES cipher with 192-bit CCM mode. */ - MBEDTLS_CIPHER_AES_256_CCM, /**< AES cipher with 256-bit CCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_CCM, /**< Camellia cipher with 128-bit CCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_CCM, /**< Camellia cipher with 192-bit CCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_CCM, /**< Camellia cipher with 256-bit CCM mode. */ - MBEDTLS_CIPHER_ARIA_128_ECB, /**< Aria cipher with 128-bit key and ECB mode. */ - MBEDTLS_CIPHER_ARIA_192_ECB, /**< Aria cipher with 192-bit key and ECB mode. */ - MBEDTLS_CIPHER_ARIA_256_ECB, /**< Aria cipher with 256-bit key and ECB mode. */ - MBEDTLS_CIPHER_ARIA_128_CBC, /**< Aria cipher with 128-bit key and CBC mode. */ - MBEDTLS_CIPHER_ARIA_192_CBC, /**< Aria cipher with 192-bit key and CBC mode. */ - MBEDTLS_CIPHER_ARIA_256_CBC, /**< Aria cipher with 256-bit key and CBC mode. */ - MBEDTLS_CIPHER_ARIA_128_CFB128, /**< Aria cipher with 128-bit key and CFB-128 mode. */ - MBEDTLS_CIPHER_ARIA_192_CFB128, /**< Aria cipher with 192-bit key and CFB-128 mode. */ - MBEDTLS_CIPHER_ARIA_256_CFB128, /**< Aria cipher with 256-bit key and CFB-128 mode. */ - MBEDTLS_CIPHER_ARIA_128_CTR, /**< Aria cipher with 128-bit key and CTR mode. */ - MBEDTLS_CIPHER_ARIA_192_CTR, /**< Aria cipher with 192-bit key and CTR mode. */ - MBEDTLS_CIPHER_ARIA_256_CTR, /**< Aria cipher with 256-bit key and CTR mode. */ - MBEDTLS_CIPHER_ARIA_128_GCM, /**< Aria cipher with 128-bit key and GCM mode. */ - MBEDTLS_CIPHER_ARIA_192_GCM, /**< Aria cipher with 192-bit key and GCM mode. */ - MBEDTLS_CIPHER_ARIA_256_GCM, /**< Aria cipher with 256-bit key and GCM mode. */ - MBEDTLS_CIPHER_ARIA_128_CCM, /**< Aria cipher with 128-bit key and CCM mode. */ - MBEDTLS_CIPHER_ARIA_192_CCM, /**< Aria cipher with 192-bit key and CCM mode. */ - MBEDTLS_CIPHER_ARIA_256_CCM, /**< Aria cipher with 256-bit key and CCM mode. */ - MBEDTLS_CIPHER_AES_128_OFB, /**< AES 128-bit cipher in OFB mode. */ - MBEDTLS_CIPHER_AES_192_OFB, /**< AES 192-bit cipher in OFB mode. */ - MBEDTLS_CIPHER_AES_256_OFB, /**< AES 256-bit cipher in OFB mode. */ - MBEDTLS_CIPHER_AES_128_XTS, /**< AES 128-bit cipher in XTS block mode. */ - MBEDTLS_CIPHER_AES_256_XTS, /**< AES 256-bit cipher in XTS block mode. */ - MBEDTLS_CIPHER_CHACHA20, /**< ChaCha20 stream cipher. */ - MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< ChaCha20-Poly1305 AEAD cipher. */ - MBEDTLS_CIPHER_AES_128_KW, /**< AES cipher with 128-bit NIST KW mode. */ - MBEDTLS_CIPHER_AES_192_KW, /**< AES cipher with 192-bit NIST KW mode. */ - MBEDTLS_CIPHER_AES_256_KW, /**< AES cipher with 256-bit NIST KW mode. */ - MBEDTLS_CIPHER_AES_128_KWP, /**< AES cipher with 128-bit NIST KWP mode. */ - MBEDTLS_CIPHER_AES_192_KWP, /**< AES cipher with 192-bit NIST KWP mode. */ - MBEDTLS_CIPHER_AES_256_KWP, /**< AES cipher with 256-bit NIST KWP mode. */ -} mbedtls_cipher_type_t; - -/** Supported cipher modes. */ -typedef enum { - MBEDTLS_MODE_NONE = 0, /**< None. */ - MBEDTLS_MODE_ECB, /**< The ECB cipher mode. */ - MBEDTLS_MODE_CBC, /**< The CBC cipher mode. */ - MBEDTLS_MODE_CFB, /**< The CFB cipher mode. */ - MBEDTLS_MODE_OFB, /**< The OFB cipher mode. */ - MBEDTLS_MODE_CTR, /**< The CTR cipher mode. */ - MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */ - MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */ - MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */ - MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */ - MBEDTLS_MODE_CHACHAPOLY, /**< The ChaCha-Poly cipher mode. */ - MBEDTLS_MODE_KW, /**< The SP800-38F KW mode */ - MBEDTLS_MODE_KWP, /**< The SP800-38F KWP mode */ -} mbedtls_cipher_mode_t; - -/** Supported cipher padding types. */ -typedef enum { - MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default). */ - MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding. */ - MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding. */ - MBEDTLS_PADDING_ZEROS, /**< Zero padding (not reversible). */ - MBEDTLS_PADDING_NONE, /**< Never pad (full blocks only). */ -} mbedtls_cipher_padding_t; - -/** Type of operation. */ -typedef enum { - MBEDTLS_OPERATION_NONE = -1, - MBEDTLS_DECRYPT = 0, - MBEDTLS_ENCRYPT, -} mbedtls_operation_t; - -enum { - /** Undefined key length. */ - MBEDTLS_KEY_LENGTH_NONE = 0, - /** Key length, in bits (including parity), for DES keys. */ - MBEDTLS_KEY_LENGTH_DES = 64, - /** Key length in bits, including parity, for DES in two-key EDE. */ - MBEDTLS_KEY_LENGTH_DES_EDE = 128, - /** Key length in bits, including parity, for DES in three-key EDE. */ - MBEDTLS_KEY_LENGTH_DES_EDE3 = 192, -}; - -/** Maximum length of any IV, in Bytes. */ -#define MBEDTLS_MAX_IV_LENGTH 16 -/** Maximum block size of any cipher, in Bytes. */ -#define MBEDTLS_MAX_BLOCK_LENGTH 16 - -/** - * Base cipher information (opaque struct). - */ -typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t; - -/** - * CMAC context (opaque struct). - */ -typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t; - -/** - * Cipher information. Allows calling cipher functions - * in a generic way. - */ -typedef struct mbedtls_cipher_info_t -{ - /** Full cipher identifier. For example, - * MBEDTLS_CIPHER_AES_256_CBC. - */ - mbedtls_cipher_type_t type; - - /** The cipher mode. For example, MBEDTLS_MODE_CBC. */ - mbedtls_cipher_mode_t mode; - - /** The cipher key length, in bits. This is the - * default length for variable sized ciphers. - * Includes parity bits for ciphers like DES. - */ - unsigned int key_bitlen; - - /** Name of the cipher. */ - const char * name; - - /** IV or nonce size, in Bytes. - * For ciphers that accept variable IV sizes, - * this is the recommended size. - */ - unsigned int iv_size; - - /** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and - * MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the - * cipher supports variable IV or variable key sizes, respectively. - */ - int flags; - - /** The block size, in Bytes. */ - unsigned int block_size; - - /** Struct for base cipher information and functions. */ - const mbedtls_cipher_base_t *base; - -} mbedtls_cipher_info_t; - -/** - * Generic cipher context. - */ -typedef struct mbedtls_cipher_context_t -{ - /** Information about the associated cipher. */ - const mbedtls_cipher_info_t *cipher_info; - - /** Key length to use. */ - int key_bitlen; - - /** Operation that the key of the context has been - * initialized for. - */ - mbedtls_operation_t operation; - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) - /** Padding functions to use, if relevant for - * the specific cipher mode. - */ - void (*add_padding)( unsigned char *output, size_t olen, size_t data_len ); - int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len ); -#endif - - /** Buffer for input that has not been processed yet. */ - unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH]; - - /** Number of Bytes that have not been processed yet. */ - size_t unprocessed_len; - - /** Current IV or NONCE_COUNTER for CTR-mode, data unit (or sector) number - * for XTS-mode. */ - unsigned char iv[MBEDTLS_MAX_IV_LENGTH]; - - /** IV size in Bytes, for ciphers with variable-length IVs. */ - size_t iv_size; - - /** The cipher-specific context. */ - void *cipher_ctx; - -#if defined(MBEDTLS_CMAC_C) - /** CMAC-specific context. */ - mbedtls_cmac_context_t *cmac_ctx; -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - /** Indicates whether the cipher operations should be performed - * by Mbed TLS' own crypto library or an external implementation - * of the PSA Crypto API. - * This is unset if the cipher context was established through - * mbedtls_cipher_setup(), and set if it was established through - * mbedtls_cipher_setup_psa(). - */ - unsigned char psa_enabled; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -} mbedtls_cipher_context_t; - -/** - * \brief This function retrieves the list of ciphers supported - * by the generic cipher module. - * - * For any cipher identifier in the returned list, you can - * obtain the corresponding generic cipher information structure - * via mbedtls_cipher_info_from_type(), which can then be used - * to prepare a cipher context via mbedtls_cipher_setup(). - * - * - * \return A statically-allocated array of cipher identifiers - * of type cipher_type_t. The last entry is zero. - */ -const int *mbedtls_cipher_list( void ); - -/** - * \brief This function retrieves the cipher-information - * structure associated with the given cipher name. - * - * \param cipher_name Name of the cipher to search for. This must not be - * \c NULL. - * - * \return The cipher information structure associated with the - * given \p cipher_name. - * \return \c NULL if the associated cipher information is not found. - */ -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name ); - -/** - * \brief This function retrieves the cipher-information - * structure associated with the given cipher type. - * - * \param cipher_type Type of the cipher to search for. - * - * \return The cipher information structure associated with the - * given \p cipher_type. - * \return \c NULL if the associated cipher information is not found. - */ -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type ); - -/** - * \brief This function retrieves the cipher-information - * structure associated with the given cipher ID, - * key size and mode. - * - * \param cipher_id The ID of the cipher to search for. For example, - * #MBEDTLS_CIPHER_ID_AES. - * \param key_bitlen The length of the key in bits. - * \param mode The cipher mode. For example, #MBEDTLS_MODE_CBC. - * - * \return The cipher information structure associated with the - * given \p cipher_id. - * \return \c NULL if the associated cipher information is not found. - */ -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id, - int key_bitlen, - const mbedtls_cipher_mode_t mode ); - -/** - * \brief This function initializes a \p cipher_context as NONE. - * - * \param ctx The context to be initialized. This must not be \c NULL. - */ -void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ); - -/** - * \brief This function frees and clears the cipher-specific - * context of \p ctx. Freeing \p ctx itself remains the - * responsibility of the caller. - * - * \param ctx The context to be freed. If this is \c NULL, the - * function has no effect, otherwise this must point to an - * initialized context. - */ -void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ); - - -/** - * \brief This function initializes a cipher context for - * use with the given cipher primitive. - * - * \param ctx The context to initialize. This must be initialized. - * \param cipher_info The cipher to use. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the - * cipher-specific context fails. - * - * \internal Currently, the function also clears the structure. - * In future versions, the caller will be required to call - * mbedtls_cipher_init() on the structure first. - */ -int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, - const mbedtls_cipher_info_t *cipher_info ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/** - * \brief This function initializes a cipher context for - * PSA-based use with the given cipher primitive. - * - * \note See #MBEDTLS_USE_PSA_CRYPTO for information on PSA. - * - * \param ctx The context to initialize. May not be \c NULL. - * \param cipher_info The cipher to use. - * \param taglen For AEAD ciphers, the length in bytes of the - * authentication tag to use. Subsequent uses of - * mbedtls_cipher_auth_encrypt() or - * mbedtls_cipher_auth_decrypt() must provide - * the same tag length. - * For non-AEAD ciphers, the value must be \c 0. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the - * cipher-specific context fails. - */ -int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx, - const mbedtls_cipher_info_t *cipher_info, - size_t taglen ); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -/** - * \brief This function returns the block size of the given cipher. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The block size of the underlying cipher. - * \return \c 0 if \p ctx has not been initialized. - */ -static inline unsigned int mbedtls_cipher_get_block_size( - const mbedtls_cipher_context_t *ctx ) -{ - MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 ); - if( ctx->cipher_info == NULL ) - return 0; - - return ctx->cipher_info->block_size; -} - -/** - * \brief This function returns the mode of operation for - * the cipher. For example, MBEDTLS_MODE_CBC. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The mode of operation. - * \return #MBEDTLS_MODE_NONE if \p ctx has not been initialized. - */ -static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( - const mbedtls_cipher_context_t *ctx ) -{ - MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, MBEDTLS_MODE_NONE ); - if( ctx->cipher_info == NULL ) - return MBEDTLS_MODE_NONE; - - return ctx->cipher_info->mode; -} - -/** - * \brief This function returns the size of the IV or nonce - * of the cipher, in Bytes. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The recommended IV size if no IV has been set. - * \return \c 0 for ciphers not using an IV or a nonce. - * \return The actual size if an IV has been set. - */ -static inline int mbedtls_cipher_get_iv_size( - const mbedtls_cipher_context_t *ctx ) -{ - MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 ); - if( ctx->cipher_info == NULL ) - return 0; - - if( ctx->iv_size != 0 ) - return (int) ctx->iv_size; - - return (int) ctx->cipher_info->iv_size; -} - -/** - * \brief This function returns the type of the given cipher. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The type of the cipher. - * \return #MBEDTLS_CIPHER_NONE if \p ctx has not been initialized. - */ -static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( - const mbedtls_cipher_context_t *ctx ) -{ - MBEDTLS_INTERNAL_VALIDATE_RET( - ctx != NULL, MBEDTLS_CIPHER_NONE ); - if( ctx->cipher_info == NULL ) - return MBEDTLS_CIPHER_NONE; - - return ctx->cipher_info->type; -} - -/** - * \brief This function returns the name of the given cipher - * as a string. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The name of the cipher. - * \return NULL if \p ctx has not been not initialized. - */ -static inline const char *mbedtls_cipher_get_name( - const mbedtls_cipher_context_t *ctx ) -{ - MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 ); - if( ctx->cipher_info == NULL ) - return 0; - - return ctx->cipher_info->name; -} - -/** - * \brief This function returns the key length of the cipher. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The key length of the cipher in bits. - * \return #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been - * initialized. - */ -static inline int mbedtls_cipher_get_key_bitlen( - const mbedtls_cipher_context_t *ctx ) -{ - MBEDTLS_INTERNAL_VALIDATE_RET( - ctx != NULL, MBEDTLS_KEY_LENGTH_NONE ); - if( ctx->cipher_info == NULL ) - return MBEDTLS_KEY_LENGTH_NONE; - - return (int) ctx->cipher_info->key_bitlen; -} - -/** - * \brief This function returns the operation of the given cipher. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The type of operation: #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT. - * \return #MBEDTLS_OPERATION_NONE if \p ctx has not been initialized. - */ -static inline mbedtls_operation_t mbedtls_cipher_get_operation( - const mbedtls_cipher_context_t *ctx ) -{ - MBEDTLS_INTERNAL_VALIDATE_RET( - ctx != NULL, MBEDTLS_OPERATION_NONE ); - if( ctx->cipher_info == NULL ) - return MBEDTLS_OPERATION_NONE; - - return ctx->operation; -} - -/** - * \brief This function sets the key to use with the given context. - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a cipher information structure. - * \param key The key to use. This must be a readable buffer of at - * least \p key_bitlen Bits. - * \param key_bitlen The key length to use, in Bits. - * \param operation The operation that the key will be used for: - * #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, - const unsigned char *key, - int key_bitlen, - const mbedtls_operation_t operation ); - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) -/** - * \brief This function sets the padding mode, for cipher modes - * that use padding. - * - * The default passing mode is PKCS7 padding. - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a cipher information structure. - * \param mode The padding mode. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE - * if the selected padding mode is not supported. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode - * does not support padding. - */ -int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, - mbedtls_cipher_padding_t mode ); -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - -/** - * \brief This function sets the initialization vector (IV) - * or nonce. - * - * \note Some ciphers do not use IVs nor nonce. For these - * ciphers, this function has no effect. - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a cipher information structure. - * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. This - * must be a readable buffer of at least \p iv_len Bytes. - * \param iv_len The IV length for ciphers with variable-size IV. - * This parameter is discarded by ciphers with fixed-size IV. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - */ -int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, - size_t iv_len ); - -/** - * \brief This function resets the cipher state. - * - * \param ctx The generic cipher context. This must be initialized. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - */ -int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ); - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -/** - * \brief This function adds additional data for AEAD ciphers. - * Currently supported with GCM and ChaCha20+Poly1305. - * This must be called exactly once, after - * mbedtls_cipher_reset(). - * - * \param ctx The generic cipher context. This must be initialized. - * \param ad The additional data to use. This must be a readable - * buffer of at least \p ad_len Bytes. - * \param ad_len The length of \p ad in Bytes. - * - * \return \c 0 on success. - * \return A specific error code on failure. - */ -int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, - const unsigned char *ad, size_t ad_len ); -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ - -/** - * \brief The generic cipher update function. It encrypts or - * decrypts using the given cipher context. Writes as - * many block-sized blocks of data as possible to output. - * Any data that cannot be written immediately is either - * added to the next block, or flushed when - * mbedtls_cipher_finish() is called. - * Exception: For MBEDTLS_MODE_ECB, expects a single block - * in size. For example, 16 Bytes for AES. - * - * \note If the underlying cipher is used in GCM mode, all calls - * to this function, except for the last one before - * mbedtls_cipher_finish(), must have \p ilen as a - * multiple of the block size of the cipher. - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a key. - * \param input The buffer holding the input data. This must be a - * readable buffer of at least \p ilen Bytes. - * \param ilen The length of the input data. - * \param output The buffer for the output data. This must be able to - * hold at least `ilen + block_size`. This must not be the - * same buffer as \p input. - * \param olen The length of the output data, to be updated with the - * actual number of Bytes written. This must not be - * \c NULL. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an - * unsupported mode for a cipher. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, - const unsigned char *input, - size_t ilen, unsigned char *output, - size_t *olen ); - -/** - * \brief The generic cipher finalization function. If data still - * needs to be flushed from an incomplete block, the data - * contained in it is padded to the size of - * the last block, and written to the \p output buffer. - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a key. - * \param output The buffer to write data to. This needs to be a writable - * buffer of at least \p block_size Bytes. - * \param olen The length of the data written to the \p output buffer. - * This may not be \c NULL. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption - * expecting a full block but not receiving one. - * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding - * while decrypting. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, - unsigned char *output, size_t *olen ); - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -/** - * \brief This function writes a tag for AEAD ciphers. - * Currently supported with GCM and ChaCha20+Poly1305. - * This must be called after mbedtls_cipher_finish(). - * - * \param ctx The generic cipher context. This must be initialized, - * bound to a key, and have just completed a cipher - * operation through mbedtls_cipher_finish() the tag for - * which should be written. - * \param tag The buffer to write the tag to. This must be a writable - * buffer of at least \p tag_len Bytes. - * \param tag_len The length of the tag to write. - * - * \return \c 0 on success. - * \return A specific error code on failure. - */ -int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, - unsigned char *tag, size_t tag_len ); - -/** - * \brief This function checks the tag for AEAD ciphers. - * Currently supported with GCM and ChaCha20+Poly1305. - * This must be called after mbedtls_cipher_finish(). - * - * \param ctx The generic cipher context. This must be initialized. - * \param tag The buffer holding the tag. This must be a readable - * buffer of at least \p tag_len Bytes. - * \param tag_len The length of the tag to check. - * - * \return \c 0 on success. - * \return A specific error code on failure. - */ -int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, - const unsigned char *tag, size_t tag_len ); -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ - -/** - * \brief The generic all-in-one encryption/decryption function, - * for all ciphers except AEAD constructs. - * - * \param ctx The generic cipher context. This must be initialized. - * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. - * This must be a readable buffer of at least \p iv_len - * Bytes. - * \param iv_len The IV length for ciphers with variable-size IV. - * This parameter is discarded by ciphers with fixed-size - * IV. - * \param input The buffer holding the input data. This must be a - * readable buffer of at least \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * \param output The buffer for the output data. This must be able to - * hold at least `ilen + block_size`. This must not be the - * same buffer as \p input. - * \param olen The length of the output data, to be updated with the - * actual number of Bytes written. This must not be - * \c NULL. - * - * \note Some ciphers do not use IVs nor nonce. For these - * ciphers, use \p iv = NULL and \p iv_len = 0. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption - * expecting a full block but not receiving one. - * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding - * while decrypting. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen ); - -#if defined(MBEDTLS_CIPHER_MODE_AEAD) -/** - * \brief The generic autenticated encryption (AEAD) function. - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a key. - * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. - * This must be a readable buffer of at least \p iv_len - * Bytes. - * \param iv_len The IV length for ciphers with variable-size IV. - * This parameter is discarded by ciphers with fixed-size IV. - * \param ad The additional data to authenticate. This must be a - * readable buffer of at least \p ad_len Bytes. - * \param ad_len The length of \p ad. - * \param input The buffer holding the input data. This must be a - * readable buffer of at least \p ilen Bytes. - * \param ilen The length of the input data. - * \param output The buffer for the output data. This must be able to - * hold at least \p ilen Bytes. - * \param olen The length of the output data, to be updated with the - * actual number of Bytes written. This must not be - * \c NULL. - * \param tag The buffer for the authentication tag. This must be a - * writable buffer of at least \p tag_len Bytes. - * \param tag_len The desired length of the authentication tag. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, - unsigned char *tag, size_t tag_len ); - -/** - * \brief The generic autenticated decryption (AEAD) function. - * - * \note If the data is not authentic, then the output buffer - * is zeroed out to prevent the unauthentic plaintext being - * used, making this interface safer. - * - * \param ctx The generic cipher context. This must be initialized and - * and bound to a key. - * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. - * This must be a readable buffer of at least \p iv_len - * Bytes. - * \param iv_len The IV length for ciphers with variable-size IV. - * This parameter is discarded by ciphers with fixed-size IV. - * \param ad The additional data to be authenticated. This must be a - * readable buffer of at least \p ad_len Bytes. - * \param ad_len The length of \p ad. - * \param input The buffer holding the input data. This must be a - * readable buffer of at least \p ilen Bytes. - * \param ilen The length of the input data. - * \param output The buffer for the output data. - * This must be able to hold at least \p ilen Bytes. - * \param olen The length of the output data, to be updated with the - * actual number of Bytes written. This must not be - * \c NULL. - * \param tag The buffer holding the authentication tag. This must be - * a readable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the authentication tag. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, - const unsigned char *tag, size_t tag_len ); -#endif /* MBEDTLS_CIPHER_MODE_AEAD */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CIPHER_H */ diff --git a/templates/blackpill/Src/cipher_internal.h b/templates/blackpill/Src/cipher_internal.h deleted file mode 100644 index d711339..0000000 --- a/templates/blackpill/Src/cipher_internal.h +++ /dev/null @@ -1,153 +0,0 @@ -/** - * \file cipher_internal.h - * - * \brief Cipher wrappers. - * - * \author Adriaan de Jong - */ -/* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_CIPHER_WRAP_H -#define MBEDTLS_CIPHER_WRAP_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "cipher.h" - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Base cipher information. The non-mode specific functions and values. - */ -struct mbedtls_cipher_base_t -{ - /** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */ - mbedtls_cipher_id_t cipher; - - /** Encrypt using ECB */ - int (*ecb_func)( void *ctx, mbedtls_operation_t mode, - const unsigned char *input, unsigned char *output ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - /** Encrypt using CBC */ - int (*cbc_func)( void *ctx, mbedtls_operation_t mode, size_t length, - unsigned char *iv, const unsigned char *input, - unsigned char *output ); -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CFB) - /** Encrypt using CFB (Full length) */ - int (*cfb_func)( void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off, - unsigned char *iv, const unsigned char *input, - unsigned char *output ); -#endif - -#if defined(MBEDTLS_CIPHER_MODE_OFB) - /** Encrypt using OFB (Full length) */ - int (*ofb_func)( void *ctx, size_t length, size_t *iv_off, - unsigned char *iv, - const unsigned char *input, - unsigned char *output ); -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - /** Encrypt using CTR */ - int (*ctr_func)( void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ); -#endif - -#if defined(MBEDTLS_CIPHER_MODE_XTS) - /** Encrypt or decrypt using XTS. */ - int (*xts_func)( void *ctx, mbedtls_operation_t mode, size_t length, - const unsigned char data_unit[16], - const unsigned char *input, unsigned char *output ); -#endif - -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - /** Encrypt using STREAM */ - int (*stream_func)( void *ctx, size_t length, - const unsigned char *input, unsigned char *output ); -#endif - - /** Set key for encryption purposes */ - int (*setkey_enc_func)( void *ctx, const unsigned char *key, - unsigned int key_bitlen ); - - /** Set key for decryption purposes */ - int (*setkey_dec_func)( void *ctx, const unsigned char *key, - unsigned int key_bitlen); - - /** Allocate a new context */ - void * (*ctx_alloc_func)( void ); - - /** Free the given context */ - void (*ctx_free_func)( void *ctx ); - -}; - -typedef struct -{ - mbedtls_cipher_type_t type; - const mbedtls_cipher_info_t *info; -} mbedtls_cipher_definition_t; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -typedef enum -{ - MBEDTLS_CIPHER_PSA_KEY_UNSET = 0, - MBEDTLS_CIPHER_PSA_KEY_OWNED, /* Used for PSA-based cipher contexts which */ - /* use raw key material internally imported */ - /* into a allocated key slot, and which */ - /* hence need to destroy that key slot */ - /* when they are no longer needed. */ - MBEDTLS_CIPHER_PSA_KEY_NOT_OWNED, /* Used for PSA-based cipher contexts */ - /* which use a key from a key slot */ - /* provided by the user, and which */ - /* hence should not be destroyed when */ - /* the context is no longer needed. */ -} mbedtls_cipher_psa_key_ownership; - -typedef struct -{ - psa_algorithm_t alg; - psa_key_handle_t slot; - mbedtls_cipher_psa_key_ownership slot_state; -} mbedtls_cipher_context_psa; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[]; - -extern int mbedtls_cipher_supported[]; - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CIPHER_WRAP_H */ diff --git a/templates/blackpill/Src/cipher_wrap.c b/templates/blackpill/Src/cipher_wrap.c deleted file mode 100644 index fcbc92d..0000000 --- a/templates/blackpill/Src/cipher_wrap.c +++ /dev/null @@ -1,2411 +0,0 @@ -/** - * \file cipher_wrap.c - * - * \brief Generic cipher wrapper for mbed TLS - * - * \author Adriaan de Jong - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CIPHER_C) - -#include "cipher_internal.h" - -#if defined(MBEDTLS_CHACHAPOLY_C) -#include "mbedtls/chachapoly.h" -#endif - -#if defined(MBEDTLS_AES_C) -#include "aes.h" -#endif - -#if defined(MBEDTLS_ARC4_C) -#include "mbedtls/arc4.h" -#endif - -#if defined(MBEDTLS_CAMELLIA_C) -#include "mbedtls/camellia.h" -#endif - -#if defined(MBEDTLS_ARIA_C) -#include "mbedtls/aria.h" -#endif - -#if defined(MBEDTLS_DES_C) -#include "mbedtls/des.h" -#endif - -#if defined(MBEDTLS_BLOWFISH_C) -#include "mbedtls/blowfish.h" -#endif - -#if defined(MBEDTLS_CHACHA20_C) -#include "mbedtls/chacha20.h" -#endif - -#if defined(MBEDTLS_GCM_C) -#include "gcm.h" -#endif - -#if defined(MBEDTLS_CCM_C) -#include "mbedtls/ccm.h" -#endif - -#if defined(MBEDTLS_NIST_KW_C) -#include "mbedtls/nist_kw.h" -#endif - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#include -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#if defined(MBEDTLS_GCM_C) -/* shared by all GCM ciphers */ -static void *gcm_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_gcm_context ) ); - - if( ctx != NULL ) - mbedtls_gcm_init( (mbedtls_gcm_context *) ctx ); - - return( ctx ); -} - -static void gcm_ctx_free( void *ctx ) -{ - mbedtls_gcm_free( ctx ); - mbedtls_free( ctx ); -} -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CCM_C) -/* shared by all CCM ciphers */ -static void *ccm_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ccm_context ) ); - - if( ctx != NULL ) - mbedtls_ccm_init( (mbedtls_ccm_context *) ctx ); - - return( ctx ); -} - -static void ccm_ctx_free( void *ctx ) -{ - mbedtls_ccm_free( ctx ); - mbedtls_free( ctx ); -} -#endif /* MBEDTLS_CCM_C */ - -#if defined(MBEDTLS_AES_C) - -static int aes_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_ecb( (mbedtls_aes_context *) ctx, operation, input, output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int aes_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, - unsigned char *iv, const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_cbc( (mbedtls_aes_context *) ctx, operation, length, iv, input, - output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static int aes_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, size_t *iv_off, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_cfb128( (mbedtls_aes_context *) ctx, operation, length, iv_off, iv, - input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -static int aes_crypt_ofb_wrap( void *ctx, size_t length, size_t *iv_off, - unsigned char *iv, const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_ofb( (mbedtls_aes_context *) ctx, length, iv_off, - iv, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_ctr( (mbedtls_aes_context *) ctx, length, nc_off, nonce_counter, - stream_block, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -static int aes_crypt_xts_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, - const unsigned char data_unit[16], - const unsigned char *input, - unsigned char *output ) -{ - mbedtls_aes_xts_context *xts_ctx = ctx; - int mode; - - switch( operation ) - { - case MBEDTLS_ENCRYPT: - mode = MBEDTLS_AES_ENCRYPT; - break; - case MBEDTLS_DECRYPT: - mode = MBEDTLS_AES_DECRYPT; - break; - default: - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - return mbedtls_aes_crypt_xts( xts_ctx, mode, length, - data_unit, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_aes_setkey_dec( (mbedtls_aes_context *) ctx, key, key_bitlen ); -} - -static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_aes_setkey_enc( (mbedtls_aes_context *) ctx, key, key_bitlen ); -} - -static void * aes_ctx_alloc( void ) -{ - mbedtls_aes_context *aes = mbedtls_calloc( 1, sizeof( mbedtls_aes_context ) ); - - if( aes == NULL ) - return( NULL ); - - mbedtls_aes_init( aes ); - - return( aes ); -} - -static void aes_ctx_free( void *ctx ) -{ - mbedtls_aes_free( (mbedtls_aes_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t aes_info = { - MBEDTLS_CIPHER_ID_AES, - aes_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - aes_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - aes_crypt_cfb128_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - aes_crypt_ofb_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - aes_crypt_ctr_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - aes_setkey_enc_wrap, - aes_setkey_dec_wrap, - aes_ctx_alloc, - aes_ctx_free -}; - -static const mbedtls_cipher_info_t aes_128_ecb_info = { - MBEDTLS_CIPHER_AES_128_ECB, - MBEDTLS_MODE_ECB, - 128, - "AES-128-ECB", - 0, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_ecb_info = { - MBEDTLS_CIPHER_AES_192_ECB, - MBEDTLS_MODE_ECB, - 192, - "AES-192-ECB", - 0, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_ecb_info = { - MBEDTLS_CIPHER_AES_256_ECB, - MBEDTLS_MODE_ECB, - 256, - "AES-256-ECB", - 0, - 0, - 16, - &aes_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t aes_128_cbc_info = { - MBEDTLS_CIPHER_AES_128_CBC, - MBEDTLS_MODE_CBC, - 128, - "AES-128-CBC", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_cbc_info = { - MBEDTLS_CIPHER_AES_192_CBC, - MBEDTLS_MODE_CBC, - 192, - "AES-192-CBC", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_cbc_info = { - MBEDTLS_CIPHER_AES_256_CBC, - MBEDTLS_MODE_CBC, - 256, - "AES-256-CBC", - 16, - 0, - 16, - &aes_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t aes_128_cfb128_info = { - MBEDTLS_CIPHER_AES_128_CFB128, - MBEDTLS_MODE_CFB, - 128, - "AES-128-CFB128", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_cfb128_info = { - MBEDTLS_CIPHER_AES_192_CFB128, - MBEDTLS_MODE_CFB, - 192, - "AES-192-CFB128", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_cfb128_info = { - MBEDTLS_CIPHER_AES_256_CFB128, - MBEDTLS_MODE_CFB, - 256, - "AES-256-CFB128", - 16, - 0, - 16, - &aes_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -static const mbedtls_cipher_info_t aes_128_ofb_info = { - MBEDTLS_CIPHER_AES_128_OFB, - MBEDTLS_MODE_OFB, - 128, - "AES-128-OFB", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_ofb_info = { - MBEDTLS_CIPHER_AES_192_OFB, - MBEDTLS_MODE_OFB, - 192, - "AES-192-OFB", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_ofb_info = { - MBEDTLS_CIPHER_AES_256_OFB, - MBEDTLS_MODE_OFB, - 256, - "AES-256-OFB", - 16, - 0, - 16, - &aes_info -}; -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t aes_128_ctr_info = { - MBEDTLS_CIPHER_AES_128_CTR, - MBEDTLS_MODE_CTR, - 128, - "AES-128-CTR", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_ctr_info = { - MBEDTLS_CIPHER_AES_192_CTR, - MBEDTLS_MODE_CTR, - 192, - "AES-192-CTR", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_ctr_info = { - MBEDTLS_CIPHER_AES_256_CTR, - MBEDTLS_MODE_CTR, - 256, - "AES-256-CTR", - 16, - 0, - 16, - &aes_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -static int xts_aes_setkey_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - mbedtls_aes_xts_context *xts_ctx = ctx; - return( mbedtls_aes_xts_setkey_enc( xts_ctx, key, key_bitlen ) ); -} - -static int xts_aes_setkey_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - mbedtls_aes_xts_context *xts_ctx = ctx; - return( mbedtls_aes_xts_setkey_dec( xts_ctx, key, key_bitlen ) ); -} - -static void *xts_aes_ctx_alloc( void ) -{ - mbedtls_aes_xts_context *xts_ctx = mbedtls_calloc( 1, sizeof( *xts_ctx ) ); - - if( xts_ctx != NULL ) - mbedtls_aes_xts_init( xts_ctx ); - - return( xts_ctx ); -} - -static void xts_aes_ctx_free( void *ctx ) -{ - mbedtls_aes_xts_context *xts_ctx = ctx; - - if( xts_ctx == NULL ) - return; - - mbedtls_aes_xts_free( xts_ctx ); - mbedtls_free( xts_ctx ); -} - -static const mbedtls_cipher_base_t xts_aes_info = { - MBEDTLS_CIPHER_ID_AES, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - aes_crypt_xts_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - xts_aes_setkey_enc_wrap, - xts_aes_setkey_dec_wrap, - xts_aes_ctx_alloc, - xts_aes_ctx_free -}; - -static const mbedtls_cipher_info_t aes_128_xts_info = { - MBEDTLS_CIPHER_AES_128_XTS, - MBEDTLS_MODE_XTS, - 256, - "AES-128-XTS", - 16, - 0, - 16, - &xts_aes_info -}; - -static const mbedtls_cipher_info_t aes_256_xts_info = { - MBEDTLS_CIPHER_AES_256_XTS, - MBEDTLS_MODE_XTS, - 512, - "AES-256-XTS", - 16, - 0, - 16, - &xts_aes_info -}; -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#if defined(MBEDTLS_GCM_C) -static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_AES, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t gcm_aes_info = { - MBEDTLS_CIPHER_ID_AES, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - gcm_aes_setkey_wrap, - gcm_aes_setkey_wrap, - gcm_ctx_alloc, - gcm_ctx_free, -}; - -static const mbedtls_cipher_info_t aes_128_gcm_info = { - MBEDTLS_CIPHER_AES_128_GCM, - MBEDTLS_MODE_GCM, - 128, - "AES-128-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aes_info -}; - -static const mbedtls_cipher_info_t aes_192_gcm_info = { - MBEDTLS_CIPHER_AES_192_GCM, - MBEDTLS_MODE_GCM, - 192, - "AES-192-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aes_info -}; - -static const mbedtls_cipher_info_t aes_256_gcm_info = { - MBEDTLS_CIPHER_AES_256_GCM, - MBEDTLS_MODE_GCM, - 256, - "AES-256-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aes_info -}; -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CCM_C) -static int ccm_aes_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_AES, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t ccm_aes_info = { - MBEDTLS_CIPHER_ID_AES, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - ccm_aes_setkey_wrap, - ccm_aes_setkey_wrap, - ccm_ctx_alloc, - ccm_ctx_free, -}; - -static const mbedtls_cipher_info_t aes_128_ccm_info = { - MBEDTLS_CIPHER_AES_128_CCM, - MBEDTLS_MODE_CCM, - 128, - "AES-128-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aes_info -}; - -static const mbedtls_cipher_info_t aes_192_ccm_info = { - MBEDTLS_CIPHER_AES_192_CCM, - MBEDTLS_MODE_CCM, - 192, - "AES-192-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aes_info -}; - -static const mbedtls_cipher_info_t aes_256_ccm_info = { - MBEDTLS_CIPHER_AES_256_CCM, - MBEDTLS_MODE_CCM, - 256, - "AES-256-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aes_info -}; -#endif /* MBEDTLS_CCM_C */ - -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) - -static int camellia_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_camellia_crypt_ecb( (mbedtls_camellia_context *) ctx, operation, input, - output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int camellia_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_camellia_crypt_cbc( (mbedtls_camellia_context *) ctx, operation, length, iv, - input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static int camellia_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, size_t *iv_off, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_camellia_crypt_cfb128( (mbedtls_camellia_context *) ctx, operation, length, - iv_off, iv, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static int camellia_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_camellia_crypt_ctr( (mbedtls_camellia_context *) ctx, length, nc_off, - nonce_counter, stream_block, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_camellia_setkey_dec( (mbedtls_camellia_context *) ctx, key, key_bitlen ); -} - -static int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_camellia_setkey_enc( (mbedtls_camellia_context *) ctx, key, key_bitlen ); -} - -static void * camellia_ctx_alloc( void ) -{ - mbedtls_camellia_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_camellia_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_camellia_init( ctx ); - - return( ctx ); -} - -static void camellia_ctx_free( void *ctx ) -{ - mbedtls_camellia_free( (mbedtls_camellia_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t camellia_info = { - MBEDTLS_CIPHER_ID_CAMELLIA, - camellia_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - camellia_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - camellia_crypt_cfb128_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - camellia_crypt_ctr_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - camellia_setkey_enc_wrap, - camellia_setkey_dec_wrap, - camellia_ctx_alloc, - camellia_ctx_free -}; - -static const mbedtls_cipher_info_t camellia_128_ecb_info = { - MBEDTLS_CIPHER_CAMELLIA_128_ECB, - MBEDTLS_MODE_ECB, - 128, - "CAMELLIA-128-ECB", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_ecb_info = { - MBEDTLS_CIPHER_CAMELLIA_192_ECB, - MBEDTLS_MODE_ECB, - 192, - "CAMELLIA-192-ECB", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_ecb_info = { - MBEDTLS_CIPHER_CAMELLIA_256_ECB, - MBEDTLS_MODE_ECB, - 256, - "CAMELLIA-256-ECB", - 16, - 0, - 16, - &camellia_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t camellia_128_cbc_info = { - MBEDTLS_CIPHER_CAMELLIA_128_CBC, - MBEDTLS_MODE_CBC, - 128, - "CAMELLIA-128-CBC", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_cbc_info = { - MBEDTLS_CIPHER_CAMELLIA_192_CBC, - MBEDTLS_MODE_CBC, - 192, - "CAMELLIA-192-CBC", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_cbc_info = { - MBEDTLS_CIPHER_CAMELLIA_256_CBC, - MBEDTLS_MODE_CBC, - 256, - "CAMELLIA-256-CBC", - 16, - 0, - 16, - &camellia_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t camellia_128_cfb128_info = { - MBEDTLS_CIPHER_CAMELLIA_128_CFB128, - MBEDTLS_MODE_CFB, - 128, - "CAMELLIA-128-CFB128", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_cfb128_info = { - MBEDTLS_CIPHER_CAMELLIA_192_CFB128, - MBEDTLS_MODE_CFB, - 192, - "CAMELLIA-192-CFB128", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_cfb128_info = { - MBEDTLS_CIPHER_CAMELLIA_256_CFB128, - MBEDTLS_MODE_CFB, - 256, - "CAMELLIA-256-CFB128", - 16, - 0, - 16, - &camellia_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t camellia_128_ctr_info = { - MBEDTLS_CIPHER_CAMELLIA_128_CTR, - MBEDTLS_MODE_CTR, - 128, - "CAMELLIA-128-CTR", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_ctr_info = { - MBEDTLS_CIPHER_CAMELLIA_192_CTR, - MBEDTLS_MODE_CTR, - 192, - "CAMELLIA-192-CTR", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_ctr_info = { - MBEDTLS_CIPHER_CAMELLIA_256_CTR, - MBEDTLS_MODE_CTR, - 256, - "CAMELLIA-256-CTR", - 16, - 0, - 16, - &camellia_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_GCM_C) -static int gcm_camellia_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t gcm_camellia_info = { - MBEDTLS_CIPHER_ID_CAMELLIA, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - gcm_camellia_setkey_wrap, - gcm_camellia_setkey_wrap, - gcm_ctx_alloc, - gcm_ctx_free, -}; - -static const mbedtls_cipher_info_t camellia_128_gcm_info = { - MBEDTLS_CIPHER_CAMELLIA_128_GCM, - MBEDTLS_MODE_GCM, - 128, - "CAMELLIA-128-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_gcm_info = { - MBEDTLS_CIPHER_CAMELLIA_192_GCM, - MBEDTLS_MODE_GCM, - 192, - "CAMELLIA-192-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_gcm_info = { - MBEDTLS_CIPHER_CAMELLIA_256_GCM, - MBEDTLS_MODE_GCM, - 256, - "CAMELLIA-256-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_camellia_info -}; -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CCM_C) -static int ccm_camellia_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t ccm_camellia_info = { - MBEDTLS_CIPHER_ID_CAMELLIA, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - ccm_camellia_setkey_wrap, - ccm_camellia_setkey_wrap, - ccm_ctx_alloc, - ccm_ctx_free, -}; - -static const mbedtls_cipher_info_t camellia_128_ccm_info = { - MBEDTLS_CIPHER_CAMELLIA_128_CCM, - MBEDTLS_MODE_CCM, - 128, - "CAMELLIA-128-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_ccm_info = { - MBEDTLS_CIPHER_CAMELLIA_192_CCM, - MBEDTLS_MODE_CCM, - 192, - "CAMELLIA-192-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_ccm_info = { - MBEDTLS_CIPHER_CAMELLIA_256_CCM, - MBEDTLS_MODE_CCM, - 256, - "CAMELLIA-256-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_camellia_info -}; -#endif /* MBEDTLS_CCM_C */ - -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_ARIA_C) - -static int aria_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - (void) operation; - return mbedtls_aria_crypt_ecb( (mbedtls_aria_context *) ctx, input, - output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int aria_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aria_crypt_cbc( (mbedtls_aria_context *) ctx, operation, length, iv, - input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static int aria_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, size_t *iv_off, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aria_crypt_cfb128( (mbedtls_aria_context *) ctx, operation, length, - iv_off, iv, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static int aria_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aria_crypt_ctr( (mbedtls_aria_context *) ctx, length, nc_off, - nonce_counter, stream_block, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -static int aria_setkey_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_aria_setkey_dec( (mbedtls_aria_context *) ctx, key, key_bitlen ); -} - -static int aria_setkey_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_aria_setkey_enc( (mbedtls_aria_context *) ctx, key, key_bitlen ); -} - -static void * aria_ctx_alloc( void ) -{ - mbedtls_aria_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_aria_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_aria_init( ctx ); - - return( ctx ); -} - -static void aria_ctx_free( void *ctx ) -{ - mbedtls_aria_free( (mbedtls_aria_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t aria_info = { - MBEDTLS_CIPHER_ID_ARIA, - aria_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - aria_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - aria_crypt_cfb128_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - aria_crypt_ctr_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - aria_setkey_enc_wrap, - aria_setkey_dec_wrap, - aria_ctx_alloc, - aria_ctx_free -}; - -static const mbedtls_cipher_info_t aria_128_ecb_info = { - MBEDTLS_CIPHER_ARIA_128_ECB, - MBEDTLS_MODE_ECB, - 128, - "ARIA-128-ECB", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_192_ecb_info = { - MBEDTLS_CIPHER_ARIA_192_ECB, - MBEDTLS_MODE_ECB, - 192, - "ARIA-192-ECB", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_256_ecb_info = { - MBEDTLS_CIPHER_ARIA_256_ECB, - MBEDTLS_MODE_ECB, - 256, - "ARIA-256-ECB", - 16, - 0, - 16, - &aria_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t aria_128_cbc_info = { - MBEDTLS_CIPHER_ARIA_128_CBC, - MBEDTLS_MODE_CBC, - 128, - "ARIA-128-CBC", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_192_cbc_info = { - MBEDTLS_CIPHER_ARIA_192_CBC, - MBEDTLS_MODE_CBC, - 192, - "ARIA-192-CBC", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_256_cbc_info = { - MBEDTLS_CIPHER_ARIA_256_CBC, - MBEDTLS_MODE_CBC, - 256, - "ARIA-256-CBC", - 16, - 0, - 16, - &aria_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t aria_128_cfb128_info = { - MBEDTLS_CIPHER_ARIA_128_CFB128, - MBEDTLS_MODE_CFB, - 128, - "ARIA-128-CFB128", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_192_cfb128_info = { - MBEDTLS_CIPHER_ARIA_192_CFB128, - MBEDTLS_MODE_CFB, - 192, - "ARIA-192-CFB128", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_256_cfb128_info = { - MBEDTLS_CIPHER_ARIA_256_CFB128, - MBEDTLS_MODE_CFB, - 256, - "ARIA-256-CFB128", - 16, - 0, - 16, - &aria_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t aria_128_ctr_info = { - MBEDTLS_CIPHER_ARIA_128_CTR, - MBEDTLS_MODE_CTR, - 128, - "ARIA-128-CTR", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_192_ctr_info = { - MBEDTLS_CIPHER_ARIA_192_CTR, - MBEDTLS_MODE_CTR, - 192, - "ARIA-192-CTR", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_256_ctr_info = { - MBEDTLS_CIPHER_ARIA_256_CTR, - MBEDTLS_MODE_CTR, - 256, - "ARIA-256-CTR", - 16, - 0, - 16, - &aria_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_GCM_C) -static int gcm_aria_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t gcm_aria_info = { - MBEDTLS_CIPHER_ID_ARIA, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - gcm_aria_setkey_wrap, - gcm_aria_setkey_wrap, - gcm_ctx_alloc, - gcm_ctx_free, -}; - -static const mbedtls_cipher_info_t aria_128_gcm_info = { - MBEDTLS_CIPHER_ARIA_128_GCM, - MBEDTLS_MODE_GCM, - 128, - "ARIA-128-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aria_info -}; - -static const mbedtls_cipher_info_t aria_192_gcm_info = { - MBEDTLS_CIPHER_ARIA_192_GCM, - MBEDTLS_MODE_GCM, - 192, - "ARIA-192-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aria_info -}; - -static const mbedtls_cipher_info_t aria_256_gcm_info = { - MBEDTLS_CIPHER_ARIA_256_GCM, - MBEDTLS_MODE_GCM, - 256, - "ARIA-256-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aria_info -}; -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CCM_C) -static int ccm_aria_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t ccm_aria_info = { - MBEDTLS_CIPHER_ID_ARIA, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - ccm_aria_setkey_wrap, - ccm_aria_setkey_wrap, - ccm_ctx_alloc, - ccm_ctx_free, -}; - -static const mbedtls_cipher_info_t aria_128_ccm_info = { - MBEDTLS_CIPHER_ARIA_128_CCM, - MBEDTLS_MODE_CCM, - 128, - "ARIA-128-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aria_info -}; - -static const mbedtls_cipher_info_t aria_192_ccm_info = { - MBEDTLS_CIPHER_ARIA_192_CCM, - MBEDTLS_MODE_CCM, - 192, - "ARIA-192-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aria_info -}; - -static const mbedtls_cipher_info_t aria_256_ccm_info = { - MBEDTLS_CIPHER_ARIA_256_CCM, - MBEDTLS_MODE_CCM, - 256, - "ARIA-256-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aria_info -}; -#endif /* MBEDTLS_CCM_C */ - -#endif /* MBEDTLS_ARIA_C */ - -#if defined(MBEDTLS_DES_C) - -static int des_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - ((void) operation); - return mbedtls_des_crypt_ecb( (mbedtls_des_context *) ctx, input, output ); -} - -static int des3_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - ((void) operation); - return mbedtls_des3_crypt_ecb( (mbedtls_des3_context *) ctx, input, output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int des_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, - unsigned char *iv, const unsigned char *input, unsigned char *output ) -{ - return mbedtls_des_crypt_cbc( (mbedtls_des_context *) ctx, operation, length, iv, input, - output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int des3_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, - unsigned char *iv, const unsigned char *input, unsigned char *output ) -{ - return mbedtls_des3_crypt_cbc( (mbedtls_des3_context *) ctx, operation, length, iv, input, - output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -static int des_setkey_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des_setkey_dec( (mbedtls_des_context *) ctx, key ); -} - -static int des_setkey_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des_setkey_enc( (mbedtls_des_context *) ctx, key ); -} - -static int des3_set2key_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des3_set2key_dec( (mbedtls_des3_context *) ctx, key ); -} - -static int des3_set2key_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des3_set2key_enc( (mbedtls_des3_context *) ctx, key ); -} - -static int des3_set3key_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des3_set3key_dec( (mbedtls_des3_context *) ctx, key ); -} - -static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des3_set3key_enc( (mbedtls_des3_context *) ctx, key ); -} - -static void * des_ctx_alloc( void ) -{ - mbedtls_des_context *des = mbedtls_calloc( 1, sizeof( mbedtls_des_context ) ); - - if( des == NULL ) - return( NULL ); - - mbedtls_des_init( des ); - - return( des ); -} - -static void des_ctx_free( void *ctx ) -{ - mbedtls_des_free( (mbedtls_des_context *) ctx ); - mbedtls_free( ctx ); -} - -static void * des3_ctx_alloc( void ) -{ - mbedtls_des3_context *des3; - des3 = mbedtls_calloc( 1, sizeof( mbedtls_des3_context ) ); - - if( des3 == NULL ) - return( NULL ); - - mbedtls_des3_init( des3 ); - - return( des3 ); -} - -static void des3_ctx_free( void *ctx ) -{ - mbedtls_des3_free( (mbedtls_des3_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t des_info = { - MBEDTLS_CIPHER_ID_DES, - des_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - des_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - des_setkey_enc_wrap, - des_setkey_dec_wrap, - des_ctx_alloc, - des_ctx_free -}; - -static const mbedtls_cipher_info_t des_ecb_info = { - MBEDTLS_CIPHER_DES_ECB, - MBEDTLS_MODE_ECB, - MBEDTLS_KEY_LENGTH_DES, - "DES-ECB", - 8, - 0, - 8, - &des_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t des_cbc_info = { - MBEDTLS_CIPHER_DES_CBC, - MBEDTLS_MODE_CBC, - MBEDTLS_KEY_LENGTH_DES, - "DES-CBC", - 8, - 0, - 8, - &des_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -static const mbedtls_cipher_base_t des_ede_info = { - MBEDTLS_CIPHER_ID_DES, - des3_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - des3_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - des3_set2key_enc_wrap, - des3_set2key_dec_wrap, - des3_ctx_alloc, - des3_ctx_free -}; - -static const mbedtls_cipher_info_t des_ede_ecb_info = { - MBEDTLS_CIPHER_DES_EDE_ECB, - MBEDTLS_MODE_ECB, - MBEDTLS_KEY_LENGTH_DES_EDE, - "DES-EDE-ECB", - 8, - 0, - 8, - &des_ede_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t des_ede_cbc_info = { - MBEDTLS_CIPHER_DES_EDE_CBC, - MBEDTLS_MODE_CBC, - MBEDTLS_KEY_LENGTH_DES_EDE, - "DES-EDE-CBC", - 8, - 0, - 8, - &des_ede_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -static const mbedtls_cipher_base_t des_ede3_info = { - MBEDTLS_CIPHER_ID_3DES, - des3_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - des3_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - des3_set3key_enc_wrap, - des3_set3key_dec_wrap, - des3_ctx_alloc, - des3_ctx_free -}; - -static const mbedtls_cipher_info_t des_ede3_ecb_info = { - MBEDTLS_CIPHER_DES_EDE3_ECB, - MBEDTLS_MODE_ECB, - MBEDTLS_KEY_LENGTH_DES_EDE3, - "DES-EDE3-ECB", - 8, - 0, - 8, - &des_ede3_info -}; -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t des_ede3_cbc_info = { - MBEDTLS_CIPHER_DES_EDE3_CBC, - MBEDTLS_MODE_CBC, - MBEDTLS_KEY_LENGTH_DES_EDE3, - "DES-EDE3-CBC", - 8, - 0, - 8, - &des_ede3_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_BLOWFISH_C) - -static int blowfish_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_blowfish_crypt_ecb( (mbedtls_blowfish_context *) ctx, operation, input, - output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int blowfish_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, unsigned char *iv, const unsigned char *input, - unsigned char *output ) -{ - return mbedtls_blowfish_crypt_cbc( (mbedtls_blowfish_context *) ctx, operation, length, iv, - input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static int blowfish_crypt_cfb64_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, size_t *iv_off, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_blowfish_crypt_cfb64( (mbedtls_blowfish_context *) ctx, operation, length, - iv_off, iv, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_blowfish_crypt_ctr( (mbedtls_blowfish_context *) ctx, length, nc_off, - nonce_counter, stream_block, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -static int blowfish_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_blowfish_setkey( (mbedtls_blowfish_context *) ctx, key, key_bitlen ); -} - -static void * blowfish_ctx_alloc( void ) -{ - mbedtls_blowfish_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_blowfish_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_blowfish_init( ctx ); - - return( ctx ); -} - -static void blowfish_ctx_free( void *ctx ) -{ - mbedtls_blowfish_free( (mbedtls_blowfish_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t blowfish_info = { - MBEDTLS_CIPHER_ID_BLOWFISH, - blowfish_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - blowfish_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - blowfish_crypt_cfb64_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - blowfish_crypt_ctr_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - blowfish_setkey_wrap, - blowfish_setkey_wrap, - blowfish_ctx_alloc, - blowfish_ctx_free -}; - -static const mbedtls_cipher_info_t blowfish_ecb_info = { - MBEDTLS_CIPHER_BLOWFISH_ECB, - MBEDTLS_MODE_ECB, - 128, - "BLOWFISH-ECB", - 8, - MBEDTLS_CIPHER_VARIABLE_KEY_LEN, - 8, - &blowfish_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t blowfish_cbc_info = { - MBEDTLS_CIPHER_BLOWFISH_CBC, - MBEDTLS_MODE_CBC, - 128, - "BLOWFISH-CBC", - 8, - MBEDTLS_CIPHER_VARIABLE_KEY_LEN, - 8, - &blowfish_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t blowfish_cfb64_info = { - MBEDTLS_CIPHER_BLOWFISH_CFB64, - MBEDTLS_MODE_CFB, - 128, - "BLOWFISH-CFB64", - 8, - MBEDTLS_CIPHER_VARIABLE_KEY_LEN, - 8, - &blowfish_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t blowfish_ctr_info = { - MBEDTLS_CIPHER_BLOWFISH_CTR, - MBEDTLS_MODE_CTR, - 128, - "BLOWFISH-CTR", - 8, - MBEDTLS_CIPHER_VARIABLE_KEY_LEN, - 8, - &blowfish_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ -#endif /* MBEDTLS_BLOWFISH_C */ - -#if defined(MBEDTLS_ARC4_C) -static int arc4_crypt_stream_wrap( void *ctx, size_t length, - const unsigned char *input, - unsigned char *output ) -{ - return( mbedtls_arc4_crypt( (mbedtls_arc4_context *) ctx, length, input, output ) ); -} - -static int arc4_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - /* we get key_bitlen in bits, arc4 expects it in bytes */ - if( key_bitlen % 8 != 0 ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - mbedtls_arc4_setup( (mbedtls_arc4_context *) ctx, key, key_bitlen / 8 ); - return( 0 ); -} - -static void * arc4_ctx_alloc( void ) -{ - mbedtls_arc4_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_arc4_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_arc4_init( ctx ); - - return( ctx ); -} - -static void arc4_ctx_free( void *ctx ) -{ - mbedtls_arc4_free( (mbedtls_arc4_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t arc4_base_info = { - MBEDTLS_CIPHER_ID_ARC4, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - arc4_crypt_stream_wrap, -#endif - arc4_setkey_wrap, - arc4_setkey_wrap, - arc4_ctx_alloc, - arc4_ctx_free -}; - -static const mbedtls_cipher_info_t arc4_128_info = { - MBEDTLS_CIPHER_ARC4_128, - MBEDTLS_MODE_STREAM, - 128, - "ARC4-128", - 0, - 0, - 1, - &arc4_base_info -}; -#endif /* MBEDTLS_ARC4_C */ - -#if defined(MBEDTLS_CHACHA20_C) - -static int chacha20_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - if( key_bitlen != 256U ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if ( 0 != mbedtls_chacha20_setkey( (mbedtls_chacha20_context*)ctx, key ) ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - return( 0 ); -} - -static int chacha20_stream_wrap( void *ctx, size_t length, - const unsigned char *input, - unsigned char *output ) -{ - int ret; - - ret = mbedtls_chacha20_update( ctx, length, input, output ); - if( ret == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - return( ret ); -} - -static void * chacha20_ctx_alloc( void ) -{ - mbedtls_chacha20_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_chacha20_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_chacha20_init( ctx ); - - return( ctx ); -} - -static void chacha20_ctx_free( void *ctx ) -{ - mbedtls_chacha20_free( (mbedtls_chacha20_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t chacha20_base_info = { - MBEDTLS_CIPHER_ID_CHACHA20, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - chacha20_stream_wrap, -#endif - chacha20_setkey_wrap, - chacha20_setkey_wrap, - chacha20_ctx_alloc, - chacha20_ctx_free -}; -static const mbedtls_cipher_info_t chacha20_info = { - MBEDTLS_CIPHER_CHACHA20, - MBEDTLS_MODE_STREAM, - 256, - "CHACHA20", - 12, - 0, - 1, - &chacha20_base_info -}; -#endif /* MBEDTLS_CHACHA20_C */ - -#if defined(MBEDTLS_CHACHAPOLY_C) - -static int chachapoly_setkey_wrap( void *ctx, - const unsigned char *key, - unsigned int key_bitlen ) -{ - if( key_bitlen != 256U ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if ( 0 != mbedtls_chachapoly_setkey( (mbedtls_chachapoly_context*)ctx, key ) ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - return( 0 ); -} - -static void * chachapoly_ctx_alloc( void ) -{ - mbedtls_chachapoly_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_chachapoly_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_chachapoly_init( ctx ); - - return( ctx ); -} - -static void chachapoly_ctx_free( void *ctx ) -{ - mbedtls_chachapoly_free( (mbedtls_chachapoly_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t chachapoly_base_info = { - MBEDTLS_CIPHER_ID_CHACHA20, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - chachapoly_setkey_wrap, - chachapoly_setkey_wrap, - chachapoly_ctx_alloc, - chachapoly_ctx_free -}; -static const mbedtls_cipher_info_t chachapoly_info = { - MBEDTLS_CIPHER_CHACHA20_POLY1305, - MBEDTLS_MODE_CHACHAPOLY, - 256, - "CHACHA20-POLY1305", - 12, - 0, - 1, - &chachapoly_base_info -}; -#endif /* MBEDTLS_CHACHAPOLY_C */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -static int null_crypt_stream( void *ctx, size_t length, - const unsigned char *input, - unsigned char *output ) -{ - ((void) ctx); - memmove( output, input, length ); - return( 0 ); -} - -static int null_setkey( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) ctx); - ((void) key); - ((void) key_bitlen); - - return( 0 ); -} - -static void * null_ctx_alloc( void ) -{ - return( (void *) 1 ); -} - -static void null_ctx_free( void *ctx ) -{ - ((void) ctx); -} - -static const mbedtls_cipher_base_t null_base_info = { - MBEDTLS_CIPHER_ID_NULL, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - null_crypt_stream, -#endif - null_setkey, - null_setkey, - null_ctx_alloc, - null_ctx_free -}; - -static const mbedtls_cipher_info_t null_cipher_info = { - MBEDTLS_CIPHER_NULL, - MBEDTLS_MODE_STREAM, - 0, - "NULL", - 0, - 0, - 1, - &null_base_info -}; -#endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */ - -#if defined(MBEDTLS_NIST_KW_C) -static void *kw_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_nist_kw_context ) ); - - if( ctx != NULL ) - mbedtls_nist_kw_init( (mbedtls_nist_kw_context *) ctx ); - - return( ctx ); -} - -static void kw_ctx_free( void *ctx ) -{ - mbedtls_nist_kw_free( ctx ); - mbedtls_free( ctx ); -} - -static int kw_aes_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_nist_kw_setkey( (mbedtls_nist_kw_context *) ctx, - MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 1 ); -} - -static int kw_aes_setkey_unwrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_nist_kw_setkey( (mbedtls_nist_kw_context *) ctx, - MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 0 ); -} - -static const mbedtls_cipher_base_t kw_aes_info = { - MBEDTLS_CIPHER_ID_AES, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - kw_aes_setkey_wrap, - kw_aes_setkey_unwrap, - kw_ctx_alloc, - kw_ctx_free, -}; - -static const mbedtls_cipher_info_t aes_128_nist_kw_info = { - MBEDTLS_CIPHER_AES_128_KW, - MBEDTLS_MODE_KW, - 128, - "AES-128-KW", - 0, - 0, - 16, - &kw_aes_info -}; - -static const mbedtls_cipher_info_t aes_192_nist_kw_info = { - MBEDTLS_CIPHER_AES_192_KW, - MBEDTLS_MODE_KW, - 192, - "AES-192-KW", - 0, - 0, - 16, - &kw_aes_info -}; - -static const mbedtls_cipher_info_t aes_256_nist_kw_info = { - MBEDTLS_CIPHER_AES_256_KW, - MBEDTLS_MODE_KW, - 256, - "AES-256-KW", - 0, - 0, - 16, - &kw_aes_info -}; - -static const mbedtls_cipher_info_t aes_128_nist_kwp_info = { - MBEDTLS_CIPHER_AES_128_KWP, - MBEDTLS_MODE_KWP, - 128, - "AES-128-KWP", - 0, - 0, - 16, - &kw_aes_info -}; - -static const mbedtls_cipher_info_t aes_192_nist_kwp_info = { - MBEDTLS_CIPHER_AES_192_KWP, - MBEDTLS_MODE_KWP, - 192, - "AES-192-KWP", - 0, - 0, - 16, - &kw_aes_info -}; - -static const mbedtls_cipher_info_t aes_256_nist_kwp_info = { - MBEDTLS_CIPHER_AES_256_KWP, - MBEDTLS_MODE_KWP, - 256, - "AES-256-KWP", - 0, - 0, - 16, - &kw_aes_info -}; -#endif /* MBEDTLS_NIST_KW_C */ - -const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] = -{ -#if defined(MBEDTLS_AES_C) - { MBEDTLS_CIPHER_AES_128_ECB, &aes_128_ecb_info }, - { MBEDTLS_CIPHER_AES_192_ECB, &aes_192_ecb_info }, - { MBEDTLS_CIPHER_AES_256_ECB, &aes_256_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_AES_128_CBC, &aes_128_cbc_info }, - { MBEDTLS_CIPHER_AES_192_CBC, &aes_192_cbc_info }, - { MBEDTLS_CIPHER_AES_256_CBC, &aes_256_cbc_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - { MBEDTLS_CIPHER_AES_128_CFB128, &aes_128_cfb128_info }, - { MBEDTLS_CIPHER_AES_192_CFB128, &aes_192_cfb128_info }, - { MBEDTLS_CIPHER_AES_256_CFB128, &aes_256_cfb128_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - { MBEDTLS_CIPHER_AES_128_OFB, &aes_128_ofb_info }, - { MBEDTLS_CIPHER_AES_192_OFB, &aes_192_ofb_info }, - { MBEDTLS_CIPHER_AES_256_OFB, &aes_256_ofb_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - { MBEDTLS_CIPHER_AES_128_CTR, &aes_128_ctr_info }, - { MBEDTLS_CIPHER_AES_192_CTR, &aes_192_ctr_info }, - { MBEDTLS_CIPHER_AES_256_CTR, &aes_256_ctr_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - { MBEDTLS_CIPHER_AES_128_XTS, &aes_128_xts_info }, - { MBEDTLS_CIPHER_AES_256_XTS, &aes_256_xts_info }, -#endif -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info }, - { MBEDTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info }, - { MBEDTLS_CIPHER_AES_256_GCM, &aes_256_gcm_info }, -#endif -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_CIPHER_AES_128_CCM, &aes_128_ccm_info }, - { MBEDTLS_CIPHER_AES_192_CCM, &aes_192_ccm_info }, - { MBEDTLS_CIPHER_AES_256_CCM, &aes_256_ccm_info }, -#endif -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_ARC4_C) - { MBEDTLS_CIPHER_ARC4_128, &arc4_128_info }, -#endif - -#if defined(MBEDTLS_BLOWFISH_C) - { MBEDTLS_CIPHER_BLOWFISH_ECB, &blowfish_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_BLOWFISH_CBC, &blowfish_cbc_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - { MBEDTLS_CIPHER_BLOWFISH_CFB64, &blowfish_cfb64_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - { MBEDTLS_CIPHER_BLOWFISH_CTR, &blowfish_ctr_info }, -#endif -#endif /* MBEDTLS_BLOWFISH_C */ - -#if defined(MBEDTLS_CAMELLIA_C) - { MBEDTLS_CIPHER_CAMELLIA_128_ECB, &camellia_128_ecb_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_ECB, &camellia_192_ecb_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_ECB, &camellia_256_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_CAMELLIA_128_CBC, &camellia_128_cbc_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CBC, &camellia_192_cbc_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CBC, &camellia_256_cbc_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - { MBEDTLS_CIPHER_CAMELLIA_128_CFB128, &camellia_128_cfb128_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CFB128, &camellia_192_cfb128_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CFB128, &camellia_256_cfb128_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - { MBEDTLS_CIPHER_CAMELLIA_128_CTR, &camellia_128_ctr_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CTR, &camellia_192_ctr_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CTR, &camellia_256_ctr_info }, -#endif -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_CIPHER_CAMELLIA_128_GCM, &camellia_128_gcm_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_GCM, &camellia_192_gcm_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_GCM, &camellia_256_gcm_info }, -#endif -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_CIPHER_CAMELLIA_128_CCM, &camellia_128_ccm_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CCM, &camellia_192_ccm_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CCM, &camellia_256_ccm_info }, -#endif -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_ARIA_C) - { MBEDTLS_CIPHER_ARIA_128_ECB, &aria_128_ecb_info }, - { MBEDTLS_CIPHER_ARIA_192_ECB, &aria_192_ecb_info }, - { MBEDTLS_CIPHER_ARIA_256_ECB, &aria_256_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_ARIA_128_CBC, &aria_128_cbc_info }, - { MBEDTLS_CIPHER_ARIA_192_CBC, &aria_192_cbc_info }, - { MBEDTLS_CIPHER_ARIA_256_CBC, &aria_256_cbc_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - { MBEDTLS_CIPHER_ARIA_128_CFB128, &aria_128_cfb128_info }, - { MBEDTLS_CIPHER_ARIA_192_CFB128, &aria_192_cfb128_info }, - { MBEDTLS_CIPHER_ARIA_256_CFB128, &aria_256_cfb128_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - { MBEDTLS_CIPHER_ARIA_128_CTR, &aria_128_ctr_info }, - { MBEDTLS_CIPHER_ARIA_192_CTR, &aria_192_ctr_info }, - { MBEDTLS_CIPHER_ARIA_256_CTR, &aria_256_ctr_info }, -#endif -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_CIPHER_ARIA_128_GCM, &aria_128_gcm_info }, - { MBEDTLS_CIPHER_ARIA_192_GCM, &aria_192_gcm_info }, - { MBEDTLS_CIPHER_ARIA_256_GCM, &aria_256_gcm_info }, -#endif -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_CIPHER_ARIA_128_CCM, &aria_128_ccm_info }, - { MBEDTLS_CIPHER_ARIA_192_CCM, &aria_192_ccm_info }, - { MBEDTLS_CIPHER_ARIA_256_CCM, &aria_256_ccm_info }, -#endif -#endif /* MBEDTLS_ARIA_C */ - -#if defined(MBEDTLS_DES_C) - { MBEDTLS_CIPHER_DES_ECB, &des_ecb_info }, - { MBEDTLS_CIPHER_DES_EDE_ECB, &des_ede_ecb_info }, - { MBEDTLS_CIPHER_DES_EDE3_ECB, &des_ede3_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_DES_CBC, &des_cbc_info }, - { MBEDTLS_CIPHER_DES_EDE_CBC, &des_ede_cbc_info }, - { MBEDTLS_CIPHER_DES_EDE3_CBC, &des_ede3_cbc_info }, -#endif -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_CHACHA20_C) - { MBEDTLS_CIPHER_CHACHA20, &chacha20_info }, -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - { MBEDTLS_CIPHER_CHACHA20_POLY1305, &chachapoly_info }, -#endif - -#if defined(MBEDTLS_NIST_KW_C) - { MBEDTLS_CIPHER_AES_128_KW, &aes_128_nist_kw_info }, - { MBEDTLS_CIPHER_AES_192_KW, &aes_192_nist_kw_info }, - { MBEDTLS_CIPHER_AES_256_KW, &aes_256_nist_kw_info }, - { MBEDTLS_CIPHER_AES_128_KWP, &aes_128_nist_kwp_info }, - { MBEDTLS_CIPHER_AES_192_KWP, &aes_192_nist_kwp_info }, - { MBEDTLS_CIPHER_AES_256_KWP, &aes_256_nist_kwp_info }, -#endif - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) - { MBEDTLS_CIPHER_NULL, &null_cipher_info }, -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ - - { MBEDTLS_CIPHER_NONE, NULL } -}; - -#define NUM_CIPHERS ( sizeof(mbedtls_cipher_definitions) / \ - sizeof(mbedtls_cipher_definitions[0]) ) -int mbedtls_cipher_supported[NUM_CIPHERS]; - -#endif /* MBEDTLS_CIPHER_C */ diff --git a/templates/blackpill/Src/gcm.c b/templates/blackpill/Src/gcm.c deleted file mode 100644 index d3af74c..0000000 --- a/templates/blackpill/Src/gcm.c +++ /dev/null @@ -1,1020 +0,0 @@ -/* - * NIST SP800-38D compliant GCM implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf - * - * See also: - * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf - * - * We use the algorithm described as Shoup's method with 4-bit tables in - * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory. - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_GCM_C) - -#include "gcm.h" -#include "platform_util.h" - -#include - -#if defined(MBEDTLS_AESNI_C) -#include "mbedtls/aesni.h" -#endif - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -#include "aes.h" -#include "platform.h" -#if !defined(MBEDTLS_PLATFORM_C) -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#if !defined(MBEDTLS_GCM_ALT) - -/* Parameter validation macros */ -#define GCM_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT ) -#define GCM_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -/* - * Initialize a context - */ -void mbedtls_gcm_init( mbedtls_gcm_context *ctx ) -{ - GCM_VALIDATE( ctx != NULL ); - memset( ctx, 0, sizeof( mbedtls_gcm_context ) ); -} - -/* - * Precompute small multiples of H, that is set - * HH[i] || HL[i] = H times i, - * where i is seen as a field element as in [MGV], ie high-order bits - * correspond to low powers of P. The result is stored in the same way, that - * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL - * corresponds to P^127. - */ -static int gcm_gen_table( mbedtls_gcm_context *ctx ) -{ - int ret, i, j; - uint64_t hi, lo; - uint64_t vl, vh; - unsigned char h[16]; - size_t olen = 0; - - memset( h, 0, 16 ); - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 ) - return( ret ); - - /* pack h as two 64-bits ints, big-endian */ - GET_UINT32_BE( hi, h, 0 ); - GET_UINT32_BE( lo, h, 4 ); - vh = (uint64_t) hi << 32 | lo; - - GET_UINT32_BE( hi, h, 8 ); - GET_UINT32_BE( lo, h, 12 ); - vl = (uint64_t) hi << 32 | lo; - - /* 8 = 1000 corresponds to 1 in GF(2^128) */ - ctx->HL[8] = vl; - ctx->HH[8] = vh; - -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) - /* With CLMUL support, we need only h, not the rest of the table */ - if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) - return( 0 ); -#endif - - /* 0 corresponds to 0 in GF(2^128) */ - ctx->HH[0] = 0; - ctx->HL[0] = 0; - - for( i = 4; i > 0; i >>= 1 ) - { - uint32_t T = ( vl & 1 ) * 0xe1000000U; - vl = ( vh << 63 ) | ( vl >> 1 ); - vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32); - - ctx->HL[i] = vl; - ctx->HH[i] = vh; - } - - for( i = 2; i <= 8; i *= 2 ) - { - uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i; - vh = *HiH; - vl = *HiL; - for( j = 1; j < i; j++ ) - { - HiH[j] = vh ^ ctx->HH[j]; - HiL[j] = vl ^ ctx->HL[j]; - } - } - - return( 0 ); -} - -int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits ) -{ - int ret; - const mbedtls_cipher_info_t *cipher_info; - - GCM_VALIDATE_RET( ctx != NULL ); - GCM_VALIDATE_RET( key != NULL ); - GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 ); - - cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, - MBEDTLS_MODE_ECB ); - if( cipher_info == NULL ) - return( MBEDTLS_ERR_GCM_BAD_INPUT ); - - if( cipher_info->block_size != 16 ) - return( MBEDTLS_ERR_GCM_BAD_INPUT ); - - mbedtls_cipher_free( &ctx->cipher_ctx ); - - if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, - MBEDTLS_ENCRYPT ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = gcm_gen_table( ctx ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -/* - * Shoup's method for multiplication use this table with - * last4[x] = x times P^128 - * where x and last4[x] are seen as elements of GF(2^128) as in [MGV] - */ -static const uint64_t last4[16] = -{ - 0x0000, 0x1c20, 0x3840, 0x2460, - 0x7080, 0x6ca0, 0x48c0, 0x54e0, - 0xe100, 0xfd20, 0xd940, 0xc560, - 0x9180, 0x8da0, 0xa9c0, 0xb5e0 -}; - -/* - * Sets output to x times H using the precomputed tables. - * x and output are seen as elements of GF(2^128) as in [MGV]. - */ -static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16], - unsigned char output[16] ) -{ - int i = 0; - unsigned char lo, hi, rem; - uint64_t zh, zl; - -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) - if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) { - unsigned char h[16]; - - PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 ); - PUT_UINT32_BE( ctx->HH[8], h, 4 ); - PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 ); - PUT_UINT32_BE( ctx->HL[8], h, 12 ); - - mbedtls_aesni_gcm_mult( output, x, h ); - return; - } -#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */ - - lo = x[15] & 0xf; - - zh = ctx->HH[lo]; - zl = ctx->HL[lo]; - - for( i = 15; i >= 0; i-- ) - { - lo = x[i] & 0xf; - hi = x[i] >> 4; - - if( i != 15 ) - { - rem = (unsigned char) zl & 0xf; - zl = ( zh << 60 ) | ( zl >> 4 ); - zh = ( zh >> 4 ); - zh ^= (uint64_t) last4[rem] << 48; - zh ^= ctx->HH[lo]; - zl ^= ctx->HL[lo]; - - } - - rem = (unsigned char) zl & 0xf; - zl = ( zh << 60 ) | ( zl >> 4 ); - zh = ( zh >> 4 ); - zh ^= (uint64_t) last4[rem] << 48; - zh ^= ctx->HH[hi]; - zl ^= ctx->HL[hi]; - } - - PUT_UINT32_BE( zh >> 32, output, 0 ); - PUT_UINT32_BE( zh, output, 4 ); - PUT_UINT32_BE( zl >> 32, output, 8 ); - PUT_UINT32_BE( zl, output, 12 ); -} - -int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, - int mode, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len ) -{ - int ret; - unsigned char work_buf[16]; - size_t i; - const unsigned char *p; - size_t use_len, olen = 0; - - GCM_VALIDATE_RET( ctx != NULL ); - GCM_VALIDATE_RET( iv != NULL ); - GCM_VALIDATE_RET( add_len == 0 || add != NULL ); - - /* IV and AD are limited to 2^64 bits, so 2^61 bytes */ - /* IV is not allowed to be zero length */ - if( iv_len == 0 || - ( (uint64_t) iv_len ) >> 61 != 0 || - ( (uint64_t) add_len ) >> 61 != 0 ) - { - return( MBEDTLS_ERR_GCM_BAD_INPUT ); - } - - memset( ctx->y, 0x00, sizeof(ctx->y) ); - memset( ctx->buf, 0x00, sizeof(ctx->buf) ); - - ctx->mode = mode; - ctx->len = 0; - ctx->add_len = 0; - - if( iv_len == 12 ) - { - memcpy( ctx->y, iv, iv_len ); - ctx->y[15] = 1; - } - else - { - memset( work_buf, 0x00, 16 ); - PUT_UINT32_BE( iv_len * 8, work_buf, 12 ); - - p = iv; - while( iv_len > 0 ) - { - use_len = ( iv_len < 16 ) ? iv_len : 16; - - for( i = 0; i < use_len; i++ ) - ctx->y[i] ^= p[i]; - - gcm_mult( ctx, ctx->y, ctx->y ); - - iv_len -= use_len; - p += use_len; - } - - for( i = 0; i < 16; i++ ) - ctx->y[i] ^= work_buf[i]; - - gcm_mult( ctx, ctx->y, ctx->y ); - } - - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, - ctx->base_ectr, &olen ) ) != 0 ) - { - return( ret ); - } - - ctx->add_len = add_len; - p = add; - while( add_len > 0 ) - { - use_len = ( add_len < 16 ) ? add_len : 16; - - for( i = 0; i < use_len; i++ ) - ctx->buf[i] ^= p[i]; - - gcm_mult( ctx, ctx->buf, ctx->buf ); - - add_len -= use_len; - p += use_len; - } - - return( 0 ); -} - -int mbedtls_gcm_update( mbedtls_gcm_context *ctx, - size_t length, - const unsigned char *input, - unsigned char *output ) -{ - int ret; - unsigned char ectr[16]; - size_t i; - const unsigned char *p; - unsigned char *out_p = output; - size_t use_len, olen = 0; - - GCM_VALIDATE_RET( ctx != NULL ); - GCM_VALIDATE_RET( length == 0 || input != NULL ); - GCM_VALIDATE_RET( length == 0 || output != NULL ); - - if( output > input && (size_t) ( output - input ) < length ) - return( MBEDTLS_ERR_GCM_BAD_INPUT ); - - /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes - * Also check for possible overflow */ - if( ctx->len + length < ctx->len || - (uint64_t) ctx->len + length > 0xFFFFFFFE0ull ) - { - return( MBEDTLS_ERR_GCM_BAD_INPUT ); - } - - ctx->len += length; - - p = input; - while( length > 0 ) - { - use_len = ( length < 16 ) ? length : 16; - - for( i = 16; i > 12; i-- ) - if( ++ctx->y[i - 1] != 0 ) - break; - - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr, - &olen ) ) != 0 ) - { - return( ret ); - } - - for( i = 0; i < use_len; i++ ) - { - if( ctx->mode == MBEDTLS_GCM_DECRYPT ) - ctx->buf[i] ^= p[i]; - out_p[i] = ectr[i] ^ p[i]; - if( ctx->mode == MBEDTLS_GCM_ENCRYPT ) - ctx->buf[i] ^= out_p[i]; - } - - gcm_mult( ctx, ctx->buf, ctx->buf ); - - length -= use_len; - p += use_len; - out_p += use_len; - } - - return( 0 ); -} - -int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, - unsigned char *tag, - size_t tag_len ) -{ - unsigned char work_buf[16]; - size_t i; - uint64_t orig_len; - uint64_t orig_add_len; - - GCM_VALIDATE_RET( ctx != NULL ); - GCM_VALIDATE_RET( tag != NULL ); - - orig_len = ctx->len * 8; - orig_add_len = ctx->add_len * 8; - - if( tag_len > 16 || tag_len < 4 ) - return( MBEDTLS_ERR_GCM_BAD_INPUT ); - - memcpy( tag, ctx->base_ectr, tag_len ); - - if( orig_len || orig_add_len ) - { - memset( work_buf, 0x00, 16 ); - - PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 ); - PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 ); - PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 ); - PUT_UINT32_BE( ( orig_len ), work_buf, 12 ); - - for( i = 0; i < 16; i++ ) - ctx->buf[i] ^= work_buf[i]; - - gcm_mult( ctx, ctx->buf, ctx->buf ); - - for( i = 0; i < tag_len; i++ ) - tag[i] ^= ctx->buf[i]; - } - - return( 0 ); -} - -int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, - int mode, - size_t length, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len, - const unsigned char *input, - unsigned char *output, - size_t tag_len, - unsigned char *tag ) -{ - int ret; - - GCM_VALIDATE_RET( ctx != NULL ); - GCM_VALIDATE_RET( iv != NULL ); - GCM_VALIDATE_RET( add_len == 0 || add != NULL ); - GCM_VALIDATE_RET( length == 0 || input != NULL ); - GCM_VALIDATE_RET( length == 0 || output != NULL ); - GCM_VALIDATE_RET( tag != NULL ); - - if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx, - size_t length, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len, - const unsigned char *tag, - size_t tag_len, - const unsigned char *input, - unsigned char *output ) -{ - int ret; - unsigned char check_tag[16]; - size_t i; - int diff; - - GCM_VALIDATE_RET( ctx != NULL ); - GCM_VALIDATE_RET( iv != NULL ); - GCM_VALIDATE_RET( add_len == 0 || add != NULL ); - GCM_VALIDATE_RET( tag != NULL ); - GCM_VALIDATE_RET( length == 0 || input != NULL ); - GCM_VALIDATE_RET( length == 0 || output != NULL ); - - if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length, - iv, iv_len, add, add_len, - input, output, tag_len, check_tag ) ) != 0 ) - { - return( ret ); - } - - /* Check tag in "constant-time" */ - for( diff = 0, i = 0; i < tag_len; i++ ) - diff |= tag[i] ^ check_tag[i]; - - if( diff != 0 ) - { - mbedtls_platform_zeroize( output, length ); - return( MBEDTLS_ERR_GCM_AUTH_FAILED ); - } - - return( 0 ); -} - -void mbedtls_gcm_free( mbedtls_gcm_context *ctx ) -{ - if( ctx == NULL ) - return; - mbedtls_cipher_free( &ctx->cipher_ctx ); - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) ); -} - -#endif /* !MBEDTLS_GCM_ALT */ - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -/* - * AES-GCM test vectors from: - * - * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip - */ -#define MAX_TESTS 6 - -static const int key_index_test_data[MAX_TESTS] = - { 0, 0, 1, 1, 1, 1 }; - -static const unsigned char key_test_data[MAX_TESTS][32] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, -}; - -static const size_t iv_len_test_data[MAX_TESTS] = - { 12, 12, 12, 12, 8, 60 }; - -static const int iv_index_test_data[MAX_TESTS] = - { 0, 0, 1, 1, 1, 2 }; - -static const unsigned char iv_test_data[MAX_TESTS][64] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }, - { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 }, - { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, - 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, - 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, - 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, - 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, - 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, - 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, - 0xa6, 0x37, 0xb3, 0x9b }, -}; - -static const size_t add_len_test_data[MAX_TESTS] = - { 0, 0, 0, 20, 20, 20 }; - -static const int add_index_test_data[MAX_TESTS] = - { 0, 0, 0, 1, 1, 1 }; - -static const unsigned char additional_test_data[MAX_TESTS][64] = -{ - { 0x00 }, - { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, - 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, - 0xab, 0xad, 0xda, 0xd2 }, -}; - -static const size_t pt_len_test_data[MAX_TESTS] = - { 0, 16, 64, 60, 60, 60 }; - -static const int pt_index_test_data[MAX_TESTS] = - { 0, 0, 1, 1, 1, 1 }; - -static const unsigned char pt_test_data[MAX_TESTS][64] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, -}; - -static const unsigned char ct_test_data[MAX_TESTS * 3][64] = -{ - { 0x00 }, - { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, - 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, - { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, - 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, - 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, - 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, - 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, - 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, - 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, - 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 }, - { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, - 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, - 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, - 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, - 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, - 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, - 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, - 0x3d, 0x58, 0xe0, 0x91 }, - { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, - 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, - 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, - 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, - 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, - 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, - 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, - 0xc2, 0x3f, 0x45, 0x98 }, - { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, - 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, - 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, - 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, - 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, - 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, - 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, - 0x4c, 0x34, 0xae, 0xe5 }, - { 0x00 }, - { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, - 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 }, - { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, - 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, - 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, - 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, - 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, - 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, - 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, - 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 }, - { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, - 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, - 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, - 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, - 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, - 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, - 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, - 0xcc, 0xda, 0x27, 0x10 }, - { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, - 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, - 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, - 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, - 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, - 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, - 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, - 0xa0, 0xf0, 0x62, 0xf7 }, - { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, - 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, - 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, - 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, - 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, - 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, - 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, - 0xe9, 0xb7, 0x37, 0x3b }, - { 0x00 }, - { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, - 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 }, - { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, - 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, - 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, - 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, - 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, - 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, - 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, - 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad }, - { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, - 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, - 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, - 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, - 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, - 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, - 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, - 0xbc, 0xc9, 0xf6, 0x62 }, - { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, - 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, - 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, - 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, - 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, - 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, - 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, - 0xf4, 0x7c, 0x9b, 0x1f }, - { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, - 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, - 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, - 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, - 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, - 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, - 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, - 0x44, 0xae, 0x7e, 0x3f }, -}; - -static const unsigned char tag_test_data[MAX_TESTS * 3][16] = -{ - { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, - 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }, - { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, - 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }, - { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, - 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 }, - { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, - 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 }, - { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, - 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb }, - { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, - 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 }, - { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, - 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 }, - { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, - 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb }, - { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, - 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 }, - { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, - 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c }, - { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, - 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 }, - { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, - 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 }, - { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, - 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b }, - { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, - 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 }, - { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, - 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c }, - { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, - 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b }, - { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, - 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 }, - { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, - 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a }, -}; - -int mbedtls_gcm_self_test( int verbose ) -{ - mbedtls_gcm_context ctx; - unsigned char buf[64]; - unsigned char tag_buf[16]; - int i, j, ret; - mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; - - for( j = 0; j < 3; j++ ) - { - int key_len = 128 + 64 * j; - - for( i = 0; i < MAX_TESTS; i++ ) - { - mbedtls_gcm_init( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( " AES-GCM-%3d #%d (%s): ", - key_len, i, "enc" ); - - ret = mbedtls_gcm_setkey( &ctx, cipher, - key_test_data[key_index_test_data[i]], - key_len ); - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 ) - { - mbedtls_printf( "skipped\n" ); - break; - } - else if( ret != 0 ) - { - goto exit; - } - - ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT, - pt_len_test_data[i], - iv_test_data[iv_index_test_data[i]], - iv_len_test_data[i], - additional_test_data[add_index_test_data[i]], - add_len_test_data[i], - pt_test_data[pt_index_test_data[i]], - buf, 16, tag_buf ); - if( ret != 0 ) - goto exit; - - if ( memcmp( buf, ct_test_data[j * 6 + i], - pt_len_test_data[i] ) != 0 || - memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 ) - { - ret = 1; - goto exit; - } - - mbedtls_gcm_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - mbedtls_gcm_init( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( " AES-GCM-%3d #%d (%s): ", - key_len, i, "dec" ); - - ret = mbedtls_gcm_setkey( &ctx, cipher, - key_test_data[key_index_test_data[i]], - key_len ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT, - pt_len_test_data[i], - iv_test_data[iv_index_test_data[i]], - iv_len_test_data[i], - additional_test_data[add_index_test_data[i]], - add_len_test_data[i], - ct_test_data[j * 6 + i], buf, 16, tag_buf ); - - if( ret != 0 ) - goto exit; - - if( memcmp( buf, pt_test_data[pt_index_test_data[i]], - pt_len_test_data[i] ) != 0 || - memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 ) - { - ret = 1; - goto exit; - } - - mbedtls_gcm_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - mbedtls_gcm_init( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", - key_len, i, "enc" ); - - ret = mbedtls_gcm_setkey( &ctx, cipher, - key_test_data[key_index_test_data[i]], - key_len ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT, - iv_test_data[iv_index_test_data[i]], - iv_len_test_data[i], - additional_test_data[add_index_test_data[i]], - add_len_test_data[i] ); - if( ret != 0 ) - goto exit; - - if( pt_len_test_data[i] > 32 ) - { - size_t rest_len = pt_len_test_data[i] - 32; - ret = mbedtls_gcm_update( &ctx, 32, - pt_test_data[pt_index_test_data[i]], - buf ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_gcm_update( &ctx, rest_len, - pt_test_data[pt_index_test_data[i]] + 32, - buf + 32 ); - if( ret != 0 ) - goto exit; - } - else - { - ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i], - pt_test_data[pt_index_test_data[i]], - buf ); - if( ret != 0 ) - goto exit; - } - - ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, ct_test_data[j * 6 + i], - pt_len_test_data[i] ) != 0 || - memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 ) - { - ret = 1; - goto exit; - } - - mbedtls_gcm_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - mbedtls_gcm_init( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", - key_len, i, "dec" ); - - ret = mbedtls_gcm_setkey( &ctx, cipher, - key_test_data[key_index_test_data[i]], - key_len ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT, - iv_test_data[iv_index_test_data[i]], - iv_len_test_data[i], - additional_test_data[add_index_test_data[i]], - add_len_test_data[i] ); - if( ret != 0 ) - goto exit; - - if( pt_len_test_data[i] > 32 ) - { - size_t rest_len = pt_len_test_data[i] - 32; - ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i], - buf ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_gcm_update( &ctx, rest_len, - ct_test_data[j * 6 + i] + 32, - buf + 32 ); - if( ret != 0 ) - goto exit; - } - else - { - ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i], - ct_test_data[j * 6 + i], - buf ); - if( ret != 0 ) - goto exit; - } - - ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, pt_test_data[pt_index_test_data[i]], - pt_len_test_data[i] ) != 0 || - memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 ) - { - ret = 1; - goto exit; - } - - mbedtls_gcm_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - ret = 0; - -exit: - if( ret != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - mbedtls_gcm_free( &ctx ); - } - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#endif /* MBEDTLS_GCM_C */ diff --git a/templates/blackpill/Src/gcm.h b/templates/blackpill/Src/gcm.h deleted file mode 100644 index fd130ab..0000000 --- a/templates/blackpill/Src/gcm.h +++ /dev/null @@ -1,326 +0,0 @@ -/** - * \file gcm.h - * - * \brief This file contains GCM definitions and functions. - * - * The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined - * in D. McGrew, J. Viega, The Galois/Counter Mode of Operation - * (GCM), Natl. Inst. Stand. Technol. - * - * For more information on GCM, see NIST SP 800-38D: Recommendation for - * Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC. - * - */ -/* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of Mbed TLS (https://tls.mbed.org) - */ - -#ifndef MBEDTLS_GCM_H -#define MBEDTLS_GCM_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "cipher.h" - -#include - -#define MBEDTLS_GCM_ENCRYPT 1 -#define MBEDTLS_GCM_DECRYPT 0 - -#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */ - -/* MBEDTLS_ERR_GCM_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_GCM_HW_ACCEL_FAILED -0x0013 /**< GCM hardware accelerator failed. */ - -#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_GCM_ALT) - -/** - * \brief The GCM context structure. - */ -typedef struct mbedtls_gcm_context -{ - mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */ - uint64_t HL[16]; /*!< Precalculated HTable low. */ - uint64_t HH[16]; /*!< Precalculated HTable high. */ - uint64_t len; /*!< The total length of the encrypted data. */ - uint64_t add_len; /*!< The total length of the additional data. */ - unsigned char base_ectr[16]; /*!< The first ECTR for tag. */ - unsigned char y[16]; /*!< The Y working value. */ - unsigned char buf[16]; /*!< The buf working value. */ - int mode; /*!< The operation to perform: - #MBEDTLS_GCM_ENCRYPT or - #MBEDTLS_GCM_DECRYPT. */ -} -mbedtls_gcm_context; - -#else /* !MBEDTLS_GCM_ALT */ -#include "gcm_alt.h" -#endif /* !MBEDTLS_GCM_ALT */ - -/** - * \brief This function initializes the specified GCM context, - * to make references valid, and prepares the context - * for mbedtls_gcm_setkey() or mbedtls_gcm_free(). - * - * The function does not bind the GCM context to a particular - * cipher, nor set the key. For this purpose, use - * mbedtls_gcm_setkey(). - * - * \param ctx The GCM context to initialize. This must not be \c NULL. - */ -void mbedtls_gcm_init( mbedtls_gcm_context *ctx ); - -/** - * \brief This function associates a GCM context with a - * cipher algorithm and a key. - * - * \param ctx The GCM context. This must be initialized. - * \param cipher The 128-bit block cipher to use. - * \param key The encryption key. This must be a readable buffer of at - * least \p keybits bits. - * \param keybits The key size in bits. Valid options are: - *
  • 128 bits
  • - *
  • 192 bits
  • - *
  • 256 bits
- * - * \return \c 0 on success. - * \return A cipher-specific error code on failure. - */ -int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits ); - -/** - * \brief This function performs GCM encryption or decryption of a buffer. - * - * \note For encryption, the output buffer can be the same as the - * input buffer. For decryption, the output buffer cannot be - * the same as input buffer. If the buffers overlap, the output - * buffer must trail at least 8 Bytes behind the input buffer. - * - * \warning When this function performs a decryption, it outputs the - * authentication tag and does not verify that the data is - * authentic. You should use this function to perform encryption - * only. For decryption, use mbedtls_gcm_auth_decrypt() instead. - * - * \param ctx The GCM context to use for encryption or decryption. This - * must be initialized. - * \param mode The operation to perform: - * - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption. - * The ciphertext is written to \p output and the - * authentication tag is written to \p tag. - * - #MBEDTLS_GCM_DECRYPT to perform decryption. - * The plaintext is written to \p output and the - * authentication tag is written to \p tag. - * Note that this mode is not recommended, because it does - * not verify the authenticity of the data. For this reason, - * you should use mbedtls_gcm_auth_decrypt() instead of - * calling this function in decryption mode. - * \param length The length of the input data, which is equal to the length - * of the output data. - * \param iv The initialization vector. This must be a readable buffer of - * at least \p iv_len Bytes. - * \param iv_len The length of the IV. - * \param add The buffer holding the additional data. This must be of at - * least that size in Bytes. - * \param add_len The length of the additional data. - * \param input The buffer holding the input data. If \p length is greater - * than zero, this must be a readable buffer of at least that - * size in Bytes. - * \param output The buffer for holding the output data. If \p length is greater - * than zero, this must be a writable buffer of at least that - * size in Bytes. - * \param tag_len The length of the tag to generate. - * \param tag The buffer for holding the tag. This must be a readable - * buffer of at least \p tag_len Bytes. - * - * \return \c 0 if the encryption or decryption was performed - * successfully. Note that in #MBEDTLS_GCM_DECRYPT mode, - * this does not indicate that the data is authentic. - * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are - * not valid or a cipher-specific error code if the encryption - * or decryption failed. - */ -int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, - int mode, - size_t length, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len, - const unsigned char *input, - unsigned char *output, - size_t tag_len, - unsigned char *tag ); - -/** - * \brief This function performs a GCM authenticated decryption of a - * buffer. - * - * \note For decryption, the output buffer cannot be the same as - * input buffer. If the buffers overlap, the output buffer - * must trail at least 8 Bytes behind the input buffer. - * - * \param ctx The GCM context. This must be initialized. - * \param length The length of the ciphertext to decrypt, which is also - * the length of the decrypted plaintext. - * \param iv The initialization vector. This must be a readable buffer - * of at least \p iv_len Bytes. - * \param iv_len The length of the IV. - * \param add The buffer holding the additional data. This must be of at - * least that size in Bytes. - * \param add_len The length of the additional data. - * \param tag The buffer holding the tag to verify. This must be a - * readable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the tag to verify. - * \param input The buffer holding the ciphertext. If \p length is greater - * than zero, this must be a readable buffer of at least that - * size. - * \param output The buffer for holding the decrypted plaintext. If \p length - * is greater than zero, this must be a writable buffer of at - * least that size. - * - * \return \c 0 if successful and authenticated. - * \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match. - * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are - * not valid or a cipher-specific error code if the decryption - * failed. - */ -int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx, - size_t length, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len, - const unsigned char *tag, - size_t tag_len, - const unsigned char *input, - unsigned char *output ); - -/** - * \brief This function starts a GCM encryption or decryption - * operation. - * - * \param ctx The GCM context. This must be initialized. - * \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or - * #MBEDTLS_GCM_DECRYPT. - * \param iv The initialization vector. This must be a readable buffer of - * at least \p iv_len Bytes. - * \param iv_len The length of the IV. - * \param add The buffer holding the additional data, or \c NULL - * if \p add_len is \c 0. - * \param add_len The length of the additional data. If \c 0, - * \p add may be \c NULL. - * - * \return \c 0 on success. - */ -int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, - int mode, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len ); - -/** - * \brief This function feeds an input buffer into an ongoing GCM - * encryption or decryption operation. - * - * ` The function expects input to be a multiple of 16 - * Bytes. Only the last call before calling - * mbedtls_gcm_finish() can be less than 16 Bytes. - * - * \note For decryption, the output buffer cannot be the same as - * input buffer. If the buffers overlap, the output buffer - * must trail at least 8 Bytes behind the input buffer. - * - * \param ctx The GCM context. This must be initialized. - * \param length The length of the input data. This must be a multiple of - * 16 except in the last call before mbedtls_gcm_finish(). - * \param input The buffer holding the input data. If \p length is greater - * than zero, this must be a readable buffer of at least that - * size in Bytes. - * \param output The buffer for holding the output data. If \p length is - * greater than zero, this must be a writable buffer of at - * least that size in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure. - */ -int mbedtls_gcm_update( mbedtls_gcm_context *ctx, - size_t length, - const unsigned char *input, - unsigned char *output ); - -/** - * \brief This function finishes the GCM operation and generates - * the authentication tag. - * - * It wraps up the GCM stream, and generates the - * tag. The tag can have a maximum length of 16 Bytes. - * - * \param ctx The GCM context. This must be initialized. - * \param tag The buffer for holding the tag. This must be a readable - * buffer of at least \p tag_len Bytes. - * \param tag_len The length of the tag to generate. This must be at least - * four. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure. - */ -int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, - unsigned char *tag, - size_t tag_len ); - -/** - * \brief This function clears a GCM context and the underlying - * cipher sub-context. - * - * \param ctx The GCM context to clear. If this is \c NULL, the call has - * no effect. Otherwise, this must be initialized. - */ -void mbedtls_gcm_free( mbedtls_gcm_context *ctx ); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief The GCM checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_gcm_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - - -#endif /* gcm.h */ diff --git a/templates/blackpill/Src/mygcmmain.c b/templates/blackpill/Src/mygcmmain.c deleted file mode 100644 index b292efc..0000000 --- a/templates/blackpill/Src/mygcmmain.c +++ /dev/null @@ -1,54 +0,0 @@ -#include "gcm.h" -#include "platform_util.h" -#include - -static void single_encryption(void) { - mbedtls_gcm_context ctx; - unsigned char buf[64]; - unsigned char tag_buf[16]; - int ret; - mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; - // 32 bytes.. that's 256 bits - const unsigned char key[32] = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }; - unsigned char plaintext[64] = { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }; - unsigned char expected_ciphertext[64] = { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, - 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, - 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, - 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, - 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, - 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, - 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, - 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85}; - const unsigned char initial_value[12] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 }; - const unsigned char additional[] = {}; - - mbedtls_gcm_init( &ctx ); - // 128 bits, not bytes! - ret = mbedtls_gcm_setkey( &ctx, cipher, key, 128 ); - - ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, 64, initial_value, 12, additional, 0, plaintext, buf, 16, tag_buf); - mbedtls_gcm_free( &ctx ); - if (memcmp(buf, expected_ciphertext, 64) == 0) { - printf("Local test workerino!\n"); - } else { - printf("Local test failed -.-\n"); - } - -} - -int main(void) { - mbedtls_gcm_self_test(1); - single_encryption(); - return 0; -} diff --git a/templates/blackpill/Src/platform.c b/templates/blackpill/Src/platform.c deleted file mode 100644 index 8792873..0000000 --- a/templates/blackpill/Src/platform.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Platform abstraction layer - * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PLATFORM_C) - -#include "platform.h" -#include "platform_util.h" - -/* The compile time configuration of memory allocation via the macros - * MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO takes precedence over the runtime - * configuration via mbedtls_platform_set_calloc_free(). So, omit everything - * related to the latter if MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO are defined. */ -#if defined(MBEDTLS_PLATFORM_MEMORY) && \ - !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && \ - defined(MBEDTLS_PLATFORM_FREE_MACRO) ) - -#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) -static void *platform_calloc_uninit( size_t n, size_t size ) -{ - ((void) n); - ((void) size); - return( NULL ); -} - -#define MBEDTLS_PLATFORM_STD_CALLOC platform_calloc_uninit -#endif /* !MBEDTLS_PLATFORM_STD_CALLOC */ - -#if !defined(MBEDTLS_PLATFORM_STD_FREE) -static void platform_free_uninit( void *ptr ) -{ - ((void) ptr); -} - -#define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit -#endif /* !MBEDTLS_PLATFORM_STD_FREE */ - -static void * (*mbedtls_calloc_func)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC; -static void (*mbedtls_free_func)( void * ) = MBEDTLS_PLATFORM_STD_FREE; - -void * mbedtls_calloc( size_t nmemb, size_t size ) -{ - return (*mbedtls_calloc_func)( nmemb, size ); -} - -void mbedtls_free( void * ptr ) -{ - (*mbedtls_free_func)( ptr ); -} - -int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), - void (*free_func)( void * ) ) -{ - mbedtls_calloc_func = calloc_func; - mbedtls_free_func = free_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_MEMORY && - !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && - defined(MBEDTLS_PLATFORM_FREE_MACRO) ) */ - -#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF) -#include -int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ) -{ - int ret; - va_list argp; - - va_start( argp, fmt ); - ret = mbedtls_vsnprintf( s, n, fmt, argp ); - va_end( argp ); - - return( ret ); -} -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_snprintf_uninit( char * s, size_t n, - const char * format, ... ) -{ - ((void) s); - ((void) n); - ((void) format); - return( 0 ); -} - -#define MBEDTLS_PLATFORM_STD_SNPRINTF platform_snprintf_uninit -#endif /* !MBEDTLS_PLATFORM_STD_SNPRINTF */ - -int (*mbedtls_snprintf)( char * s, size_t n, - const char * format, - ... ) = MBEDTLS_PLATFORM_STD_SNPRINTF; - -int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, - const char * format, - ... ) ) -{ - mbedtls_snprintf = snprintf_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ - -#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF) -#include -int mbedtls_platform_win32_vsnprintf( char *s, size_t n, const char *fmt, va_list arg ) -{ - int ret; - - /* Avoid calling the invalid parameter handler by checking ourselves */ - if( s == NULL || n == 0 || fmt == NULL ) - return( -1 ); - -#if defined(_TRUNCATE) - ret = vsnprintf_s( s, n, _TRUNCATE, fmt, arg ); -#else - ret = vsnprintf( s, n, fmt, arg ); - if( ret < 0 || (size_t) ret == n ) - { - s[n-1] = '\0'; - ret = -1; - } -#endif - - return( ret ); -} -#endif - -#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_vsnprintf_uninit( char * s, size_t n, - const char * format, va_list arg ) -{ - ((void) s); - ((void) n); - ((void) format); - ((void) arg); - return( -1 ); -} - -#define MBEDTLS_PLATFORM_STD_VSNPRINTF platform_vsnprintf_uninit -#endif /* !MBEDTLS_PLATFORM_STD_VSNPRINTF */ - -int (*mbedtls_vsnprintf)( char * s, size_t n, - const char * format, - va_list arg ) = MBEDTLS_PLATFORM_STD_VSNPRINTF; - -int mbedtls_platform_set_vsnprintf( int (*vsnprintf_func)( char * s, size_t n, - const char * format, - va_list arg ) ) -{ - mbedtls_vsnprintf = vsnprintf_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */ - -#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_printf_uninit( const char *format, ... ) -{ - ((void) format); - return( 0 ); -} - -#define MBEDTLS_PLATFORM_STD_PRINTF platform_printf_uninit -#endif /* !MBEDTLS_PLATFORM_STD_PRINTF */ - -int (*mbedtls_printf)( const char *, ... ) = MBEDTLS_PLATFORM_STD_PRINTF; - -int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) ) -{ - mbedtls_printf = printf_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ - -#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_fprintf_uninit( FILE *stream, const char *format, ... ) -{ - ((void) stream); - ((void) format); - return( 0 ); -} - -#define MBEDTLS_PLATFORM_STD_FPRINTF platform_fprintf_uninit -#endif /* !MBEDTLS_PLATFORM_STD_FPRINTF */ - -int (*mbedtls_fprintf)( FILE *, const char *, ... ) = - MBEDTLS_PLATFORM_STD_FPRINTF; - -int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *, const char *, ... ) ) -{ - mbedtls_fprintf = fprintf_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ - -#if defined(MBEDTLS_PLATFORM_EXIT_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_EXIT) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static void platform_exit_uninit( int status ) -{ - ((void) status); -} - -#define MBEDTLS_PLATFORM_STD_EXIT platform_exit_uninit -#endif /* !MBEDTLS_PLATFORM_STD_EXIT */ - -void (*mbedtls_exit)( int status ) = MBEDTLS_PLATFORM_STD_EXIT; - -int mbedtls_platform_set_exit( void (*exit_func)( int status ) ) -{ - mbedtls_exit = exit_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ - -#if defined(MBEDTLS_HAVE_TIME) - -#if defined(MBEDTLS_PLATFORM_TIME_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_TIME) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static mbedtls_time_t platform_time_uninit( mbedtls_time_t* timer ) -{ - ((void) timer); - return( 0 ); -} - -#define MBEDTLS_PLATFORM_STD_TIME platform_time_uninit -#endif /* !MBEDTLS_PLATFORM_STD_TIME */ - -mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* timer ) = MBEDTLS_PLATFORM_STD_TIME; - -int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* timer ) ) -{ - mbedtls_time = time_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_TIME_ALT */ - -#endif /* MBEDTLS_HAVE_TIME */ - -#if defined(MBEDTLS_ENTROPY_NV_SEED) -#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) -/* Default implementations for the platform independent seed functions use - * standard libc file functions to read from and write to a pre-defined filename - */ -int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ) -{ - FILE *file; - size_t n; - - if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL ) - return( -1 ); - - if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len ) - { - fclose( file ); - mbedtls_platform_zeroize( buf, buf_len ); - return( -1 ); - } - - fclose( file ); - return( (int)n ); -} - -int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len ) -{ - FILE *file; - size_t n; - - if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL ) - return -1; - - if( ( n = fwrite( buf, 1, buf_len, file ) ) != buf_len ) - { - fclose( file ); - return -1; - } - - fclose( file ); - return( (int)n ); -} -#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ - -#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_nv_seed_read_uninit( unsigned char *buf, size_t buf_len ) -{ - ((void) buf); - ((void) buf_len); - return( -1 ); -} - -#define MBEDTLS_PLATFORM_STD_NV_SEED_READ platform_nv_seed_read_uninit -#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_READ */ - -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_nv_seed_write_uninit( unsigned char *buf, size_t buf_len ) -{ - ((void) buf); - ((void) buf_len); - return( -1 ); -} - -#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE platform_nv_seed_write_uninit -#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_WRITE */ - -int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) = - MBEDTLS_PLATFORM_STD_NV_SEED_READ; -int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) = - MBEDTLS_PLATFORM_STD_NV_SEED_WRITE; - -int mbedtls_platform_set_nv_seed( - int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ), - int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) ) -{ - mbedtls_nv_seed_read = nv_seed_read_func; - mbedtls_nv_seed_write = nv_seed_write_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ -#endif /* MBEDTLS_ENTROPY_NV_SEED */ - -#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) -/* - * Placeholder platform setup that does nothing by default - */ -int mbedtls_platform_setup( mbedtls_platform_context *ctx ) -{ - (void)ctx; - - return( 0 ); -} - -/* - * Placeholder platform teardown that does nothing by default - */ -void mbedtls_platform_teardown( mbedtls_platform_context *ctx ) -{ - (void)ctx; -} -#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ - -#endif /* MBEDTLS_PLATFORM_C */ diff --git a/templates/blackpill/Src/platform.h b/templates/blackpill/Src/platform.h deleted file mode 100644 index 363d6b3..0000000 --- a/templates/blackpill/Src/platform.h +++ /dev/null @@ -1,419 +0,0 @@ -/** - * \file platform.h - * - * \brief This file contains the definitions and functions of the - * Mbed TLS platform abstraction layer. - * - * The platform abstraction layer removes the need for the library - * to directly link to standard C library functions or operating - * system services, making the library easier to port and embed. - * Application developers and users of the library can provide their own - * implementations of these functions, or implementations specific to - * their platform, which can be statically linked to the library or - * dynamically configured at runtime. - */ -/* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of Mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_PLATFORM_H -#define MBEDTLS_PLATFORM_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_HAVE_TIME) -#include "platform_time.h" -#endif - -#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED -0x0070 /**< Hardware accelerator failed */ -#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED -0x0072 /**< The requested feature is not supported by the platform */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h or define them on the compiler command line. - * \{ - */ - -/* The older Microsoft Windows common runtime provides non-conforming - * implementations of some standard library functions, including snprintf - * and vsnprintf. This affects MSVC and MinGW builds. - */ -#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900) -#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF -#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF -#endif - -#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) -#include -#include -#include -#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) -#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF) -#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use. */ -#else -#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< The default \c snprintf function to use. */ -#endif -#endif -#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF) -#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF) -#define MBEDTLS_PLATFORM_STD_VSNPRINTF mbedtls_platform_win32_vsnprintf /**< The default \c vsnprintf function to use. */ -#else -#define MBEDTLS_PLATFORM_STD_VSNPRINTF vsnprintf /**< The default \c vsnprintf function to use. */ -#endif -#endif -#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) -#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< The default \c printf function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) -#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< The default \c fprintf function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) -#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< The default \c calloc function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_FREE) -#define MBEDTLS_PLATFORM_STD_FREE free /**< The default \c free function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_EXIT) -#define MBEDTLS_PLATFORM_STD_EXIT exit /**< The default \c exit function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_TIME) -#define MBEDTLS_PLATFORM_STD_TIME time /**< The default \c time function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) -#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS /**< The default exit value to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) -#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE /**< The default exit value to use. */ -#endif -#if defined(MBEDTLS_FS_IO) -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) -#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read -#endif -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) -#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write -#endif -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE) -#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" -#endif -#endif /* MBEDTLS_FS_IO */ -#else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ -#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) -#include MBEDTLS_PLATFORM_STD_MEM_HDR -#endif -#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ - - -/* \} name SECTION: Module settings */ - -/* - * The function pointers for calloc and free. - */ -#if defined(MBEDTLS_PLATFORM_MEMORY) -#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \ - defined(MBEDTLS_PLATFORM_CALLOC_MACRO) -#define mbedtls_free MBEDTLS_PLATFORM_FREE_MACRO -#define mbedtls_calloc MBEDTLS_PLATFORM_CALLOC_MACRO -#else -/* For size_t */ -#include -extern void *mbedtls_calloc( size_t n, size_t size ); -extern void mbedtls_free( void *ptr ); - -/** - * \brief This function dynamically sets the memory-management - * functions used by the library, during runtime. - * - * \param calloc_func The \c calloc function implementation. - * \param free_func The \c free function implementation. - * - * \return \c 0. - */ -int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), - void (*free_func)( void * ) ); -#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */ -#else /* !MBEDTLS_PLATFORM_MEMORY */ -#define mbedtls_free free -#define mbedtls_calloc calloc -#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */ - -/* - * The function pointers for fprintf - */ -#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) -/* We need FILE * */ -#include -extern int (*mbedtls_fprintf)( FILE *stream, const char *format, ... ); - -/** - * \brief This function dynamically configures the fprintf - * function that is called when the - * mbedtls_fprintf() function is invoked by the library. - * - * \param fprintf_func The \c fprintf function implementation. - * - * \return \c 0. - */ -int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *, - ... ) ); -#else -#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) -#define mbedtls_fprintf MBEDTLS_PLATFORM_FPRINTF_MACRO -#else -#define mbedtls_fprintf fprintf -#endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */ -#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ - -/* - * The function pointers for printf - */ -#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) -extern int (*mbedtls_printf)( const char *format, ... ); - -/** - * \brief This function dynamically configures the snprintf - * function that is called when the mbedtls_snprintf() - * function is invoked by the library. - * - * \param printf_func The \c printf function implementation. - * - * \return \c 0 on success. - */ -int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) ); -#else /* !MBEDTLS_PLATFORM_PRINTF_ALT */ -#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) -#define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO -#else -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */ -#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ - -/* - * The function pointers for snprintf - * - * The snprintf implementation should conform to C99: - * - it *must* always correctly zero-terminate the buffer - * (except when n == 0, then it must leave the buffer untouched) - * - however it is acceptable to return -1 instead of the required length when - * the destination buffer is too short. - */ -#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF) -/* For Windows (inc. MSYS2), we provide our own fixed implementation */ -int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ); -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) -extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... ); - -/** - * \brief This function allows configuring a custom - * \c snprintf function pointer. - * - * \param snprintf_func The \c snprintf function implementation. - * - * \return \c 0 on success. - */ -int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, - const char * format, ... ) ); -#else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ -#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) -#define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO -#else -#define mbedtls_snprintf MBEDTLS_PLATFORM_STD_SNPRINTF -#endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */ -#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ - -/* - * The function pointers for vsnprintf - * - * The vsnprintf implementation should conform to C99: - * - it *must* always correctly zero-terminate the buffer - * (except when n == 0, then it must leave the buffer untouched) - * - however it is acceptable to return -1 instead of the required length when - * the destination buffer is too short. - */ -#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF) -#include -/* For Older Windows (inc. MSYS2), we provide our own fixed implementation */ -int mbedtls_platform_win32_vsnprintf( char *s, size_t n, const char *fmt, va_list arg ); -#endif - -#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) -#include -extern int (*mbedtls_vsnprintf)( char * s, size_t n, const char * format, va_list arg ); - -/** - * \brief Set your own snprintf function pointer - * - * \param vsnprintf_func The \c vsnprintf function implementation - * - * \return \c 0 - */ -int mbedtls_platform_set_vsnprintf( int (*vsnprintf_func)( char * s, size_t n, - const char * format, va_list arg ) ); -#else /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */ -#if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO) -#define mbedtls_vsnprintf MBEDTLS_PLATFORM_VSNPRINTF_MACRO -#else -#define mbedtls_vsnprintf vsnprintf -#endif /* MBEDTLS_PLATFORM_VSNPRINTF_MACRO */ -#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */ - -/* - * The function pointers for exit - */ -#if defined(MBEDTLS_PLATFORM_EXIT_ALT) -extern void (*mbedtls_exit)( int status ); - -/** - * \brief This function dynamically configures the exit - * function that is called when the mbedtls_exit() - * function is invoked by the library. - * - * \param exit_func The \c exit function implementation. - * - * \return \c 0 on success. - */ -int mbedtls_platform_set_exit( void (*exit_func)( int status ) ); -#else -#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) -#define mbedtls_exit MBEDTLS_PLATFORM_EXIT_MACRO -#else -#define mbedtls_exit exit -#endif /* MBEDTLS_PLATFORM_EXIT_MACRO */ -#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ - -/* - * The default exit values - */ -#if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) -#define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS -#else -#define MBEDTLS_EXIT_SUCCESS 0 -#endif -#if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) -#define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE -#else -#define MBEDTLS_EXIT_FAILURE 1 -#endif - -/* - * The function pointers for reading from and writing a seed file to - * Non-Volatile storage (NV) in a platform-independent way - * - * Only enabled when the NV seed entropy source is enabled - */ -#if defined(MBEDTLS_ENTROPY_NV_SEED) -#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) -/* Internal standard platform definitions */ -int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ); -int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len ); -#endif - -#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) -extern int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ); -extern int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ); - -/** - * \brief This function allows configuring custom seed file writing and - * reading functions. - * - * \param nv_seed_read_func The seed reading function implementation. - * \param nv_seed_write_func The seed writing function implementation. - * - * \return \c 0 on success. - */ -int mbedtls_platform_set_nv_seed( - int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ), - int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) - ); -#else -#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \ - defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) -#define mbedtls_nv_seed_read MBEDTLS_PLATFORM_NV_SEED_READ_MACRO -#define mbedtls_nv_seed_write MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO -#else -#define mbedtls_nv_seed_read mbedtls_platform_std_nv_seed_read -#define mbedtls_nv_seed_write mbedtls_platform_std_nv_seed_write -#endif -#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ -#endif /* MBEDTLS_ENTROPY_NV_SEED */ - -#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) - -/** - * \brief The platform context structure. - * - * \note This structure may be used to assist platform-specific - * setup or teardown operations. - */ -typedef struct mbedtls_platform_context -{ - char dummy; /**< A placeholder member, as empty structs are not portable. */ -} -mbedtls_platform_context; - -#else -#include "platform_alt.h" -#endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ - -/** - * \brief This function performs any platform-specific initialization - * operations. - * - * \note This function should be called before any other library functions. - * - * Its implementation is platform-specific, and unless - * platform-specific code is provided, it does nothing. - * - * \note The usage and necessity of this function is dependent on the platform. - * - * \param ctx The platform context. - * - * \return \c 0 on success. - */ -int mbedtls_platform_setup( mbedtls_platform_context *ctx ); -/** - * \brief This function performs any platform teardown operations. - * - * \note This function should be called after every other Mbed TLS module - * has been correctly freed using the appropriate free function. - * - * Its implementation is platform-specific, and unless - * platform-specific code is provided, it does nothing. - * - * \note The usage and necessity of this function is dependent on the platform. - * - * \param ctx The platform context. - * - */ -void mbedtls_platform_teardown( mbedtls_platform_context *ctx ); - -#ifdef __cplusplus -} -#endif - -#endif /* platform.h */ diff --git a/templates/blackpill/Src/platform_time.h b/templates/blackpill/Src/platform_time.h deleted file mode 100644 index 2ed36f5..0000000 --- a/templates/blackpill/Src/platform_time.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * \file platform_time.h - * - * \brief mbed TLS Platform time abstraction - */ -/* - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_PLATFORM_TIME_H -#define MBEDTLS_PLATFORM_TIME_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h or define them on the compiler command line. - * \{ - */ - -/* - * The time_t datatype - */ -#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) -typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t; -#else -/* For time_t */ -#include -typedef time_t mbedtls_time_t; -#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */ - -/* - * The function pointers for time - */ -#if defined(MBEDTLS_PLATFORM_TIME_ALT) -extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time ); - -/** - * \brief Set your own time function pointer - * - * \param time_func the time function implementation - * - * \return 0 - */ -int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) ); -#else -#if defined(MBEDTLS_PLATFORM_TIME_MACRO) -#define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO -#else -#define mbedtls_time time -#endif /* MBEDTLS_PLATFORM_TIME_MACRO */ -#endif /* MBEDTLS_PLATFORM_TIME_ALT */ - -#ifdef __cplusplus -} -#endif - -#endif /* platform_time.h */ diff --git a/templates/blackpill/Src/platform_util.c b/templates/blackpill/Src/platform_util.c deleted file mode 100644 index 04a64b3..0000000 --- a/templates/blackpill/Src/platform_util.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Common and shared functions used by multiple modules in the Mbed TLS - * library. - * - * Copyright (C) 2018, Arm Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of Mbed TLS (https://tls.mbed.org) - */ - -/* - * Ensure gmtime_r is available even with -std=c99; must be defined before - * config.h, which pulls in glibc's features.h. Harmless on other platforms. - */ -#if !defined(_POSIX_C_SOURCE) -#define _POSIX_C_SOURCE 200112L -#endif - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "platform_util.h" -#include "platform.h" -#include "threading.h" - -#include -#include - -#if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT) -/* - * This implementation should never be optimized out by the compiler - * - * This implementation for mbedtls_platform_zeroize() was inspired from Colin - * Percival's blog article at: - * - * http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html - * - * It uses a volatile function pointer to the standard memset(). Because the - * pointer is volatile the compiler expects it to change at - * any time and will not optimize out the call that could potentially perform - * other operations on the input buffer instead of just setting it to 0. - * Nevertheless, as pointed out by davidtgoldblatt on Hacker News - * (refer to http://www.daemonology.net/blog/2014-09-05-erratum.html for - * details), optimizations of the following form are still possible: - * - * if( memset_func != memset ) - * memset_func( buf, 0, len ); - * - * Note that it is extremely difficult to guarantee that - * mbedtls_platform_zeroize() will not be optimized out by aggressive compilers - * in a portable way. For this reason, Mbed TLS also provides the configuration - * option MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure - * mbedtls_platform_zeroize() to use a suitable implementation for their - * platform and needs. - */ -static void * (* const volatile memset_func)( void *, int, size_t ) = memset; - -void mbedtls_platform_zeroize( void *buf, size_t len ) -{ - memset_func( buf, 0, len ); -} -#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */ - -#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) -#include -#if !defined(_WIN32) && (defined(unix) || \ - defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ - defined(__MACH__))) -#include -#endif /* !_WIN32 && (unix || __unix || __unix__ || - * (__APPLE__ && __MACH__)) */ - -#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ - ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) -/* - * This is a convenience shorthand macro to avoid checking the long - * preprocessor conditions above. Ideally, we could expose this macro in - * platform_util.h and simply use it in platform_util.c, threading.c and - * threading.h. However, this macro is not part of the Mbed TLS public API, so - * we keep it private by only defining it in this file - */ -#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) -#define PLATFORM_UTIL_USE_GMTIME -#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */ - -#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ - ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */ - -struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt, - struct tm *tm_buf ) -{ -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) - return( ( gmtime_s( tm_buf, tt ) == 0 ) ? tm_buf : NULL ); -#elif !defined(PLATFORM_UTIL_USE_GMTIME) - return( gmtime_r( tt, tm_buf ) ); -#else - struct tm *lt; - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 ) - return( NULL ); -#endif /* MBEDTLS_THREADING_C */ - - lt = gmtime( tt ); - - if( lt != NULL ) - { - memcpy( tm_buf, lt, sizeof( struct tm ) ); - } - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 ) - return( NULL ); -#endif /* MBEDTLS_THREADING_C */ - - return( ( lt == NULL ) ? NULL : tm_buf ); -#endif /* _WIN32 && !EFIX64 && !EFI32 */ -} -#endif /* MBEDTLS_HAVE_TIME_DATE && MBEDTLS_PLATFORM_GMTIME_R_ALT */ diff --git a/templates/blackpill/Src/platform_util.h b/templates/blackpill/Src/platform_util.h deleted file mode 100644 index 09d0965..0000000 --- a/templates/blackpill/Src/platform_util.h +++ /dev/null @@ -1,196 +0,0 @@ -/** - * \file platform_util.h - * - * \brief Common and shared functions used by multiple modules in the Mbed TLS - * library. - */ -/* - * Copyright (C) 2018, Arm Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of Mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_PLATFORM_UTIL_H -#define MBEDTLS_PLATFORM_UTIL_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#if defined(MBEDTLS_HAVE_TIME_DATE) -#include "platform_time.h" -#include -#endif /* MBEDTLS_HAVE_TIME_DATE */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(MBEDTLS_CHECK_PARAMS) - -#if defined(MBEDTLS_CHECK_PARAMS_ASSERT) -/* Allow the user to define MBEDTLS_PARAM_FAILED to something like assert - * (which is what our config.h suggests). */ -#include -#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */ - -#if defined(MBEDTLS_PARAM_FAILED) -/** An alternative definition of MBEDTLS_PARAM_FAILED has been set in config.h. - * - * This flag can be used to check whether it is safe to assume that - * MBEDTLS_PARAM_FAILED() will expand to a call to mbedtls_param_failed(). - */ -#define MBEDTLS_PARAM_FAILED_ALT - -#elif defined(MBEDTLS_CHECK_PARAMS_ASSERT) -#define MBEDTLS_PARAM_FAILED( cond ) assert( cond ) -#define MBEDTLS_PARAM_FAILED_ALT - -#else /* MBEDTLS_PARAM_FAILED */ -#define MBEDTLS_PARAM_FAILED( cond ) \ - mbedtls_param_failed( #cond, __FILE__, __LINE__ ) - -/** - * \brief User supplied callback function for parameter validation failure. - * See #MBEDTLS_CHECK_PARAMS for context. - * - * This function will be called unless an alternative treatement - * is defined through the #MBEDTLS_PARAM_FAILED macro. - * - * This function can return, and the operation will be aborted, or - * alternatively, through use of setjmp()/longjmp() can resume - * execution in the application code. - * - * \param failure_condition The assertion that didn't hold. - * \param file The file where the assertion failed. - * \param line The line in the file where the assertion failed. - */ -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ); -#endif /* MBEDTLS_PARAM_FAILED */ - -/* Internal macro meant to be called only from within the library. */ -#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) \ - do { \ - if( !(cond) ) \ - { \ - MBEDTLS_PARAM_FAILED( cond ); \ - return( ret ); \ - } \ - } while( 0 ) - -/* Internal macro meant to be called only from within the library. */ -#define MBEDTLS_INTERNAL_VALIDATE( cond ) \ - do { \ - if( !(cond) ) \ - { \ - MBEDTLS_PARAM_FAILED( cond ); \ - return; \ - } \ - } while( 0 ) - -#else /* MBEDTLS_CHECK_PARAMS */ - -/* Internal macros meant to be called only from within the library. */ -#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) do { } while( 0 ) -#define MBEDTLS_INTERNAL_VALIDATE( cond ) do { } while( 0 ) - -#endif /* MBEDTLS_CHECK_PARAMS */ - -/* Internal helper macros for deprecating API constants. */ -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -/* Deliberately don't (yet) export MBEDTLS_DEPRECATED here - * to avoid conflict with other headers which define and use - * it, too. We might want to move all these definitions here at - * some point for uniformity. */ -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -MBEDTLS_DEPRECATED typedef char const * mbedtls_deprecated_string_constant_t; -#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) \ - ( (mbedtls_deprecated_string_constant_t) ( VAL ) ) -MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t; -#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) \ - ( (mbedtls_deprecated_numeric_constant_t) ( VAL ) ) -#undef MBEDTLS_DEPRECATED -#else /* MBEDTLS_DEPRECATED_WARNING */ -#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) VAL -#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) VAL -#endif /* MBEDTLS_DEPRECATED_WARNING */ -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -/** - * \brief Securely zeroize a buffer - * - * The function is meant to wipe the data contained in a buffer so - * that it can no longer be recovered even if the program memory - * is later compromised. Call this function on sensitive data - * stored on the stack before returning from a function, and on - * sensitive data stored on the heap before freeing the heap - * object. - * - * It is extremely difficult to guarantee that calls to - * mbedtls_platform_zeroize() are not removed by aggressive - * compiler optimizations in a portable way. For this reason, Mbed - * TLS provides the configuration option - * MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure - * mbedtls_platform_zeroize() to use a suitable implementation for - * their platform and needs - * - * \param buf Buffer to be zeroized - * \param len Length of the buffer in bytes - * - */ -void mbedtls_platform_zeroize( void *buf, size_t len ); - -#if defined(MBEDTLS_HAVE_TIME_DATE) -/** - * \brief Platform-specific implementation of gmtime_r() - * - * The function is a thread-safe abstraction that behaves - * similarly to the gmtime_r() function from Unix/POSIX. - * - * Mbed TLS will try to identify the underlying platform and - * make use of an appropriate underlying implementation (e.g. - * gmtime_r() for POSIX and gmtime_s() for Windows). If this is - * not possible, then gmtime() will be used. In this case, calls - * from the library to gmtime() will be guarded by the mutex - * mbedtls_threading_gmtime_mutex if MBEDTLS_THREADING_C is - * enabled. It is recommended that calls from outside the library - * are also guarded by this mutex. - * - * If MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, then Mbed TLS will - * unconditionally use the alternative implementation for - * mbedtls_platform_gmtime_r() supplied by the user at compile time. - * - * \param tt Pointer to an object containing time (in seconds) since the - * epoch to be converted - * \param tm_buf Pointer to an object where the results will be stored - * - * \return Pointer to an object of type struct tm on success, otherwise - * NULL - */ -struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt, - struct tm *tm_buf ); -#endif /* MBEDTLS_HAVE_TIME_DATE */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_PLATFORM_UTIL_H */ diff --git a/templates/blackpill/Src/threading.c b/templates/blackpill/Src/threading.c deleted file mode 100644 index 7c90c7c..0000000 --- a/templates/blackpill/Src/threading.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Threading abstraction layer - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * Ensure gmtime_r is available even with -std=c99; must be defined before - * config.h, which pulls in glibc's features.h. Harmless on other platforms. - */ -#if !defined(_POSIX_C_SOURCE) -#define _POSIX_C_SOURCE 200112L -#endif - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_THREADING_C) - -#include "mbedtls/threading.h" - -#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) - -#if !defined(_WIN32) && (defined(unix) || \ - defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ - defined(__MACH__))) -#include -#endif /* !_WIN32 && (unix || __unix || __unix__ || - * (__APPLE__ && __MACH__)) */ - -#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ - ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) -/* - * This is a convenience shorthand macro to avoid checking the long - * preprocessor conditions above. Ideally, we could expose this macro in - * platform_util.h and simply use it in platform_util.c, threading.c and - * threading.h. However, this macro is not part of the Mbed TLS public API, so - * we keep it private by only defining it in this file - */ - -#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) -#define THREADING_USE_GMTIME -#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */ - -#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ - ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */ - -#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */ - -#if defined(MBEDTLS_THREADING_PTHREAD) -static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex ) -{ - if( mutex == NULL ) - return; - - mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0; -} - -static void threading_mutex_free_pthread( mbedtls_threading_mutex_t *mutex ) -{ - if( mutex == NULL || !mutex->is_valid ) - return; - - (void) pthread_mutex_destroy( &mutex->mutex ); - mutex->is_valid = 0; -} - -static int threading_mutex_lock_pthread( mbedtls_threading_mutex_t *mutex ) -{ - if( mutex == NULL || ! mutex->is_valid ) - return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); - - if( pthread_mutex_lock( &mutex->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); - - return( 0 ); -} - -static int threading_mutex_unlock_pthread( mbedtls_threading_mutex_t *mutex ) -{ - if( mutex == NULL || ! mutex->is_valid ) - return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); - - if( pthread_mutex_unlock( &mutex->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); - - return( 0 ); -} - -void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_init_pthread; -void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_free_pthread; -int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_lock_pthread; -int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_unlock_pthread; - -/* - * With phtreads we can statically initialize mutexes - */ -#define MUTEX_INIT = { PTHREAD_MUTEX_INITIALIZER, 1 } - -#endif /* MBEDTLS_THREADING_PTHREAD */ - -#if defined(MBEDTLS_THREADING_ALT) -static int threading_mutex_fail( mbedtls_threading_mutex_t *mutex ) -{ - ((void) mutex ); - return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); -} -static void threading_mutex_dummy( mbedtls_threading_mutex_t *mutex ) -{ - ((void) mutex ); - return; -} - -void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy; -void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy; -int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail; -int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail; - -/* - * Set functions pointers and initialize global mutexes - */ -void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ), - void (*mutex_free)( mbedtls_threading_mutex_t * ), - int (*mutex_lock)( mbedtls_threading_mutex_t * ), - int (*mutex_unlock)( mbedtls_threading_mutex_t * ) ) -{ - mbedtls_mutex_init = mutex_init; - mbedtls_mutex_free = mutex_free; - mbedtls_mutex_lock = mutex_lock; - mbedtls_mutex_unlock = mutex_unlock; - -#if defined(MBEDTLS_FS_IO) - mbedtls_mutex_init( &mbedtls_threading_readdir_mutex ); -#endif -#if defined(THREADING_USE_GMTIME) - mbedtls_mutex_init( &mbedtls_threading_gmtime_mutex ); -#endif -} - -/* - * Free global mutexes - */ -void mbedtls_threading_free_alt( void ) -{ -#if defined(MBEDTLS_FS_IO) - mbedtls_mutex_free( &mbedtls_threading_readdir_mutex ); -#endif -#if defined(THREADING_USE_GMTIME) - mbedtls_mutex_free( &mbedtls_threading_gmtime_mutex ); -#endif -} -#endif /* MBEDTLS_THREADING_ALT */ - -/* - * Define global mutexes - */ -#ifndef MUTEX_INIT -#define MUTEX_INIT -#endif -#if defined(MBEDTLS_FS_IO) -mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex MUTEX_INIT; -#endif -#if defined(THREADING_USE_GMTIME) -mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT; -#endif - -#endif /* MBEDTLS_THREADING_C */ diff --git a/templates/blackpill/Src/threading.h b/templates/blackpill/Src/threading.h deleted file mode 100644 index 92e6e6b..0000000 --- a/templates/blackpill/Src/threading.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - * \file threading.h - * - * \brief Threading abstraction layer - */ -/* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_THREADING_H -#define MBEDTLS_THREADING_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE is deprecated and should not be - * used. */ -#define MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE -0x001A /**< The selected feature is not available. */ - -#define MBEDTLS_ERR_THREADING_BAD_INPUT_DATA -0x001C /**< Bad input parameters to function. */ -#define MBEDTLS_ERR_THREADING_MUTEX_ERROR -0x001E /**< Locking / unlocking / free failed with error code. */ - -#if defined(MBEDTLS_THREADING_PTHREAD) -#include -typedef struct mbedtls_threading_mutex_t -{ - pthread_mutex_t mutex; - char is_valid; -} mbedtls_threading_mutex_t; -#endif - -#if defined(MBEDTLS_THREADING_ALT) -/* You should define the mbedtls_threading_mutex_t type in your header */ -#include "threading_alt.h" - -/** - * \brief Set your alternate threading implementation function - * pointers and initialize global mutexes. If used, this - * function must be called once in the main thread before any - * other mbed TLS function is called, and - * mbedtls_threading_free_alt() must be called once in the main - * thread after all other mbed TLS functions. - * - * \note mutex_init() and mutex_free() don't return a status code. - * If mutex_init() fails, it should leave its argument (the - * mutex) in a state such that mutex_lock() will fail when - * called with this argument. - * - * \param mutex_init the init function implementation - * \param mutex_free the free function implementation - * \param mutex_lock the lock function implementation - * \param mutex_unlock the unlock function implementation - */ -void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ), - void (*mutex_free)( mbedtls_threading_mutex_t * ), - int (*mutex_lock)( mbedtls_threading_mutex_t * ), - int (*mutex_unlock)( mbedtls_threading_mutex_t * ) ); - -/** - * \brief Free global mutexes. - */ -void mbedtls_threading_free_alt( void ); -#endif /* MBEDTLS_THREADING_ALT */ - -#if defined(MBEDTLS_THREADING_C) -/* - * The function pointers for mutex_init, mutex_free, mutex_ and mutex_unlock - * - * All these functions are expected to work or the result will be undefined. - */ -extern void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t *mutex ); -extern void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t *mutex ); -extern int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t *mutex ); -extern int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t *mutex ); - -/* - * Global mutexes - */ -#if defined(MBEDTLS_FS_IO) -extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex; -#endif - -#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) -/* This mutex may or may not be used in the default definition of - * mbedtls_platform_gmtime_r(), but in order to determine that, - * we need to check POSIX features, hence modify _POSIX_C_SOURCE. - * With the current approach, this declaration is orphaned, lacking - * an accompanying definition, in case mbedtls_platform_gmtime_r() - * doesn't need it, but that's not a problem. */ -extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex; -#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */ - -#endif /* MBEDTLS_THREADING_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* threading.h */ diff --git a/templates/blackpill/Src/utils.c b/templates/blackpill/Src/utils.c deleted file mode 100644 index 81cb946..0000000 --- a/templates/blackpill/Src/utils.c +++ /dev/null @@ -1,36 +0,0 @@ -#include "utils.h" - -void *memset(void *s, int c, size_t n) -{ - unsigned char* p=s; - while(n--) - *p++ = (unsigned char)c; - return s; -} - -void *memcpy(void *dest, const void *src, size_t n) -{ - char *dp = dest; - const char *sp = src; - while (n--) - *dp++ = *sp++; - return dest; -} - -int memcmp(const void* s1, const void* s2,size_t n) -{ - const unsigned char *p1 = s1, *p2 = s2; - while(n--) - if( *p1 != *p2 ) - return *p1 - *p2; - else - p1++,p2++; - return 0; -} - -int strcmp(const char* s1, const char* s2) -{ - while(*s1 && (*s1==*s2)) - s1++,s2++; - return *(const unsigned char*)s1-*(const unsigned char*)s2; -} diff --git a/templates/blackpill/Src/utils.h b/templates/blackpill/Src/utils.h deleted file mode 100644 index dbe213d..0000000 --- a/templates/blackpill/Src/utils.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include - -int memcmp(const void* s1, const void* s2,size_t n); -void *memcpy(void *dest, const void *src, size_t n); -void *memset(void *s, int c, size_t n); -int strcmp(const char* s1, const char* s2); -- libgit2 0.26.0