diff --git a/CMakeLists.txt b/CMakeLists.txt
index b9a0ce02da..0ade1d4cb8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,8 +8,13 @@ option(ENABLE_PROGRAMS "Build mbed TLS programs." ON)
option(UNSAFE_BUILD "Allow unsafe builds. These builds ARE NOT SECURE." OFF)
+string(REGEX MATCH "Clang" CMAKE_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}")
+string(REGEX MATCH "GNU" CMAKE_COMPILER_IS_GNU "${CMAKE_C_COMPILER_ID}")
+string(REGEX MATCH "IAR" CMAKE_COMPILER_IS_IAR "${CMAKE_C_COMPILER_ID}")
+string(REGEX MATCH "MSVC" CMAKE_COMPILER_IS_MSVC "${CMAKE_C_COMPILER_ID}")
+
# the test suites currently have compile errors with MSVC
-if(MSVC)
+if(CMAKE_COMPILER_IS_MSVC)
option(ENABLE_TESTING "Build mbed TLS tests." OFF)
else()
option(ENABLE_TESTING "Build mbed TLS tests." ON)
@@ -86,7 +91,7 @@ endfunction(link_to_source)
string(REGEX MATCH "Clang" CMAKE_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}")
-if(CMAKE_COMPILER_IS_GNUCC)
+if(CMAKE_COMPILER_IS_GNU)
# some warnings we want are not available with old GCC versions
# note: starting with CMake 2.8 we could use CMAKE_C_COMPILER_VERSION
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
@@ -105,30 +110,34 @@ if(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_FLAGS_ASANDBG "-Werror -fsanitize=address -fno-common -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls ")
set(CMAKE_C_FLAGS_CHECK "-Werror -Os")
set(CMAKE_C_FLAGS_CHECKFULL "${CMAKE_C_FLAGS_CHECK} -Wcast-qual")
-endif(CMAKE_COMPILER_IS_GNUCC)
+endif(CMAKE_COMPILER_IS_GNU)
if(CMAKE_COMPILER_IS_CLANG)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow")
set(CMAKE_C_FLAGS_RELEASE "-O2")
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3")
set(CMAKE_C_FLAGS_COVERAGE "-O0 -g3 --coverage")
- set(CMAKE_C_FLAGS_ASAN "-Werror -fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover -O3")
- set(CMAKE_C_FLAGS_ASANDBG "-Werror -fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls ")
+ set(CMAKE_C_FLAGS_ASAN "-Werror -fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O3")
+ set(CMAKE_C_FLAGS_ASANDBG "-Werror -fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls ")
set(CMAKE_C_FLAGS_MEMSAN "-Werror -fsanitize=memory -O3")
set(CMAKE_C_FLAGS_MEMSANDBG "-Werror -fsanitize=memory -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2")
set(CMAKE_C_FLAGS_CHECK "-Werror -Os")
endif(CMAKE_COMPILER_IS_CLANG)
-if(MSVC)
+if(CMAKE_COMPILER_IS_IAR)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --warn_about_c_style_casts --warnings_are_errors -Ohz")
+endif(CMAKE_COMPILER_IS_IAR)
+
+if(CMAKE_COMPILER_IS_MSVC)
# Strictest warnings, and treat as errors
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
-endif(MSVC)
+endif(CMAKE_COMPILER_IS_MSVC)
if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
- if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
+ if(CMAKE_COMPILER_IS_GNU OR CMAKE_COMPILER_IS_CLANG)
set(CMAKE_SHARED_LINKER_FLAGS "--coverage")
- endif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
+ endif(CMAKE_COMPILER_IS_GNU OR CMAKE_COMPILER_IS_CLANG)
endif(CMAKE_BUILD_TYPE STREQUAL "Coverage")
if(LIB_INSTALL_DIR)
diff --git a/ChangeLog b/ChangeLog
index aca6e0fc17..1d1ec7c046 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,31 @@ Features
in ECP, ECDSA, PK and X509 (CRL not supported yet), and using existing
functions in ECDH and SSL (currently only implemented client-side, for
ECDHE-ECDSA ciphersuites with TLS 1.2, including client authentication).
+ * Add additional block mode, OFB (Output Feedback), to the AES module and
+ cipher abstraction module.
+ * Implement the HMAC-based extract-and-expand key derivation function
+ (HKDF) per RFC 5869. Contributed by Thomas Fossati.
+ * Add support for the CCM* block cipher mode as defined in IEEE Std. 802.15.4.
+ * Add support for the XTS block cipher mode with AES (AES-XTS).
+ Contributed by Aorimn in pull request #414.
+ * In TLS servers, support offloading private key operations to an external
+ cryptoprocessor. Private key operations can be asynchronous to allow
+ non-blocking operation of the TLS server stack.
+
+Bugfix
+ * Fix the cert_write example to handle certificates signed with elliptic
+ curves as well as RSA. Fixes #777 found by dbedev.
+ * Fix for redefinition of _WIN32_WINNT to avoid overriding a definition
+ used by user applications. Found and fixed by Fabio Alessandrelli.
+ * Fix compilation warnings with IAR toolchain, on 32 bit platform.
+ Reported by rahmanih in #683
+ * Fix braces in mbedtls_memory_buffer_alloc_status(). Found by sbranden, #552.
+
+Changes
+ * Changed CMake defaults for IAR to treat all compiler warnings as errors.
+ * Changed the Clang parameters used in the CMake build files to work for
+ versions later than 3.6. Versions of Clang earlier than this may no longer
+ work. Fixes #1072
= mbed TLS 2.10.0 branch released 2018-06-06
diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h
index 9449cbbba9..ed78eb4b57 100644
--- a/doxygen/input/doc_mainpage.h
+++ b/doxygen/input/doc_mainpage.h
@@ -24,7 +24,7 @@
*/
/**
- * @mainpage mbed TLS v2.10.0 source code documentation
+ * @mainpage mbed TLS v2.11.0 source code documentation
*
* This documentation describes the internal structure of mbed TLS. It was
* automatically generated from specially formatted comment blocks in
diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile
index ddcbc2e048..fdeab7a554 100644
--- a/doxygen/mbedtls.doxyfile
+++ b/doxygen/mbedtls.doxyfile
@@ -28,7 +28,7 @@ DOXYFILE_ENCODING = UTF-8
# identify the project. Note that if you do not use Doxywizard you need
# to put quotes around the project name if it contains spaces.
-PROJECT_NAME = "mbed TLS v2.10.0"
+PROJECT_NAME = "mbed TLS v2.11.0"
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
diff --git a/include/mbedtls/aes.h b/include/mbedtls/aes.h
index dd5c1183a5..f6603d5962 100644
--- a/include/mbedtls/aes.h
+++ b/include/mbedtls/aes.h
@@ -13,6 +13,11 @@
* 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.
@@ -89,6 +94,19 @@ typedef struct
}
mbedtls_aes_context;
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+/**
+ * \brief The AES XTS context-type definition.
+ */
+typedef struct
+{
+ 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 */
@@ -110,6 +128,25 @@ void mbedtls_aes_init( mbedtls_aes_context *ctx );
*/
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.
+ */
+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.
+ */
+void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx );
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
/**
* \brief This function sets the encryption key.
*
@@ -142,6 +179,44 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
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.
+ * \param key The encryption key. This is comprised of the XTS key1
+ * concatenated with the XTS key2.
+ * \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.
+ * \param key The decryption key. This is comprised of the XTS key1
+ * concatenated with the XTS key2.
+ * \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.
@@ -213,6 +288,49 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
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.
+ * \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
@@ -296,6 +414,56 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
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.
+ * \param length The length of the input data.
+ * \param iv_off The offset in IV (updated after use).
+ * \param iv The initialization vector (updated after use).
+ * \param input The buffer holding the input data.
+ * \param output The buffer holding the output data.
+ *
+ * \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
diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h
index 8585ce5e7c..5d727e7cca 100644
--- a/include/mbedtls/ccm.h
+++ b/include/mbedtls/ccm.h
@@ -14,6 +14,18 @@
* Nonce - A unique value that is assigned to the payload and the
* associated data.
*
+ * Definition of CCM:
+ * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
+ * RFC 3610 "Counter with CBC-MAC (CCM)"
+ *
+ * Related:
+ * RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
+ *
+ * Definition of CCM*:
+ * IEEE 802.15.4 - IEEE Standard for Local and metropolitan area networks
+ * Integer representation is fixed most-significant-octet-first order and
+ * the representation of octets is most-significant-bit-first order. This is
+ * consistent with RFC 3610.
*/
/*
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
@@ -102,7 +114,6 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx );
/**
* \brief This function encrypts a buffer using CCM.
*
- *
* \note The tag is written to a separate buffer. To concatenate
* the \p tag with the \p output, as done in RFC-3610:
* Counter with CBC-MAC (CCM), use
@@ -112,15 +123,17 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx );
* \param ctx The CCM context to use for encryption.
* \param length The length of the input data in Bytes.
* \param iv Initialization vector (nonce).
- * \param iv_len The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13.
+ * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
+ * or 13. The length L of the message length field is
+ * 15 - \p iv_len.
* \param add The additional data field.
* \param add_len The length of additional data in Bytes.
* Must be less than 2^16 - 2^8.
* \param input The buffer holding the input data.
* \param output The buffer holding the output data.
* Must be at least \p length Bytes wide.
- * \param tag The buffer holding the tag.
- * \param tag_len The length of the tag to generate in Bytes:
+ * \param tag The buffer holding the authentication field.
+ * \param tag_len The length of the authentication field to generate in Bytes:
* 4, 6, 8, 10, 12, 14 or 16.
*
* \return \c 0 on success.
@@ -133,21 +146,64 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
unsigned char *tag, size_t tag_len );
/**
- * \brief This function performs a CCM authenticated decryption of a
- * buffer.
+ * \brief This function encrypts a buffer using CCM*.
*
- * \param ctx The CCM context to use for decryption.
+ * \note The tag is written to a separate buffer. To concatenate
+ * the \p tag with the \p output, as done in RFC-3610:
+ * Counter with CBC-MAC (CCM), use
+ * \p tag = \p output + \p length, and make sure that the
+ * output buffer is at least \p length + \p tag_len wide.
+ *
+ * \note When using this function in a variable tag length context,
+ * the tag length has to be encoded into the \p iv passed to
+ * this function.
+ *
+ * \param ctx The CCM context to use for encryption.
* \param length The length of the input data in Bytes.
- * \param iv Initialization vector.
- * \param iv_len The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13.
+ * \param iv Initialization vector (nonce).
+ * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
+ * or 13. The length L of the message length field is
+ * 15 - \p iv_len.
* \param add The additional data field.
* \param add_len The length of additional data in Bytes.
* Must be less than 2^16 - 2^8.
* \param input The buffer holding the input data.
* \param output The buffer holding the output data.
* Must be at least \p length Bytes wide.
- * \param tag The buffer holding the tag.
- * \param tag_len The length of the tag in Bytes.
+ * \param tag The buffer holding the authentication field.
+ * \param tag_len The length of the authentication field to generate in Bytes:
+ * 0, 4, 6, 8, 10, 12, 14 or 16.
+ *
+ * \warning Passing 0 as \p tag_len means that the message is no
+ * longer authenticated.
+ *
+ * \return \c 0 on success.
+ * \return A CCM or cipher-specific error code on failure.
+ */
+int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, 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,
+ unsigned char *tag, size_t tag_len );
+
+/**
+ * \brief This function performs a CCM authenticated decryption of a
+ * buffer.
+ *
+ * \param ctx The CCM context to use for decryption.
+ * \param length The length of the input data in Bytes.
+ * \param iv Initialization vector (nonce).
+ * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
+ * or 13. The length L of the message length field is
+ * 15 - \p iv_len.
+ * \param add The additional data field.
+ * \param add_len The length of additional data in Bytes.
+ * Must be less than 2^16 - 2^8.
+ * \param input The buffer holding the input data.
+ * \param output The buffer holding the output data.
+ * Must be at least \p length Bytes wide.
+ * \param tag The buffer holding the authentication field.
+ * \param tag_len The length of the authentication field in Bytes.
* 4, 6, 8, 10, 12, 14 or 16.
*
* \return \c 0 on success. This indicates that the message is authentic.
@@ -160,6 +216,43 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *input, unsigned char *output,
const unsigned char *tag, size_t tag_len );
+/**
+ * \brief This function performs a CCM* authenticated decryption of a
+ * buffer.
+ *
+ * \note When using this function in a variable tag length context,
+ * the tag length has to be decoded from \p iv and passed to
+ * this function as \p tag_len. (\p tag needs to be adjusted
+ * accordingly.)
+ *
+ * \param ctx The CCM context to use for decryption.
+ * \param length The length of the input data in Bytes.
+ * \param iv Initialization vector (nonce).
+ * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
+ * or 13. The length L of the message length field is
+ * 15 - \p iv_len.
+ * \param add The additional data field.
+ * \param add_len The length of additional data in Bytes.
+ * Must be less than 2^16 - 2^8.
+ * \param input The buffer holding the input data.
+ * \param output The buffer holding the output data.
+ * Must be at least \p length Bytes wide.
+ * \param tag The buffer holding the authentication field.
+ * \param tag_len The length of the authentication field in Bytes.
+ * 0, 4, 6, 8, 10, 12, 14 or 16.
+ *
+ * \warning Passing 0 as \p tag_len means that the message is no
+ * longer authenticated.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match.
+ * \return A cipher-specific error code on calculation failure.
+ */
+int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, 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,
+ const unsigned char *tag, size_t tag_len );
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
/**
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index be80332963..4689f3a4d2 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -4,7 +4,7 @@
* \brief Consistency checks for configuration options
*/
/*
- * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -191,6 +191,10 @@
#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites"
#endif
+#if defined(MBEDTLS_HKDF_C) && !defined(MBEDTLS_MD_C)
+#error "MBEDTLS_HKDF_C defined, but not all prerequisites"
+#endif
+
#if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C)
#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites"
#endif
diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h
index 46b3bdfefa..0a545eb3c1 100644
--- a/include/mbedtls/cipher.h
+++ b/include/mbedtls/cipher.h
@@ -164,6 +164,11 @@ typedef enum {
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_type_t;
/** Supported cipher modes. */
@@ -172,11 +177,12 @@ typedef enum {
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 - unsupported. */
+ 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_cipher_mode_t;
/** Supported cipher padding types. */
@@ -292,7 +298,8 @@ typedef struct {
/** Number of Bytes that have not been processed yet. */
size_t unprocessed_len;
- /** Current IV or NONCE_COUNTER for CTR-mode. */
+ /** 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. */
diff --git a/include/mbedtls/cipher_internal.h b/include/mbedtls/cipher_internal.h
index 969ff9ccb8..c6def0bef7 100644
--- a/include/mbedtls/cipher_internal.h
+++ b/include/mbedtls/cipher_internal.h
@@ -64,6 +64,14 @@ struct mbedtls_cipher_base_t
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,
@@ -71,6 +79,13 @@ struct mbedtls_cipher_base_t
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,
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index f13b28a9ab..08bda9525b 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -8,7 +8,7 @@
* memory footprint.
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -515,6 +515,20 @@
*/
#define MBEDTLS_CIPHER_MODE_CTR
+/**
+ * \def MBEDTLS_CIPHER_MODE_OFB
+ *
+ * Enable Output Feedback mode (OFB) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_OFB
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_XTS
+ *
+ * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES.
+ */
+#define MBEDTLS_CIPHER_MODE_XTS
+
/**
* \def MBEDTLS_CIPHER_NULL_CIPHER
*
@@ -1151,6 +1165,17 @@
*/
#define MBEDTLS_SSL_ALL_ALERT_MESSAGES
+/**
+ * \def MBEDTLS_SSL_ASYNC_PRIVATE
+ *
+ * Enable asynchronous external private key operations in SSL. This allows
+ * you to configure an SSL connection to call an external cryptographic
+ * module to perform private key operations instead of performing the
+ * operation inside the library.
+ *
+ */
+//#define MBEDTLS_SSL_ASYNC_PRIVATE
+
/**
* \def MBEDTLS_SSL_DEBUG_ALL
*
@@ -2166,6 +2191,21 @@
*/
//#define MBEDTLS_HAVEGE_C
+/**
+ * \def MBEDTLS_HKDF_C
+ *
+ * Enable the HKDF algorithm (RFC 5869).
+ *
+ * Module: library/hkdf.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * This module adds support for the Hashed Message Authentication Code
+ * (HMAC)-based key derivation function (HKDF).
+ */
+#define MBEDTLS_HKDF_C
+
/**
* \def MBEDTLS_HMAC_DRBG_C
*
diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h
index 29c1c21a93..2a606adeab 100644
--- a/include/mbedtls/error.h
+++ b/include/mbedtls/error.h
@@ -4,7 +4,7 @@
* \brief Error to string translation
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -89,8 +89,9 @@
* RSA 4 11
* ECP 4 10 (Started from top)
* MD 5 5
+ * HKDF 5 1 (Started from top)
* CIPHER 6 8
- * SSL 6 22 (Started from top)
+ * SSL 6 23 (Started from top)
* SSL 7 31
*
* Module dependent error code (5 bits 0x.00.-0x.F8.)
diff --git a/include/mbedtls/gcm.h b/include/mbedtls/gcm.h
index bec5577142..87535ab957 100644
--- a/include/mbedtls/gcm.h
+++ b/include/mbedtls/gcm.h
@@ -113,21 +113,41 @@ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
* 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.
- * \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or
- * #MBEDTLS_GCM_DECRYPT.
- * \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 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.
* \param iv_len The length of the IV.
* \param add The buffer holding the additional data.
* \param add_len The length of the additional data.
- * \param input The buffer holding the input data.
- * \param output The buffer for holding the output data.
+ * \param input The buffer holding the input data. Its size is \b length.
+ * \param output The buffer for holding the output data. It must have room
+ * for \b length bytes.
* \param tag_len The length of the tag to generate.
* \param tag The buffer for holding the tag.
*
- * \return \c 0 on success.
+ * \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 are not valid.
+ * \return #MBEDTLS_ERR_GCM_HW_ACCEL_FAILED or a cipher-specific
+ * error code if the encryption or decryption failed.
*/
int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
int mode,
@@ -150,19 +170,23 @@ int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
* must trail at least 8 Bytes behind the input buffer.
*
* \param ctx The GCM context.
- * \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 length The length of the ciphertext to decrypt, which is also
+ * the length of the decrypted plaintext.
* \param iv The initialization vector.
* \param iv_len The length of the IV.
* \param add The buffer holding the additional data.
* \param add_len The length of the additional data.
- * \param tag The buffer holding the tag.
- * \param tag_len The length of the tag.
- * \param input The buffer holding the input data.
- * \param output The buffer for holding the output data.
+ * \param tag The buffer holding the tag to verify.
+ * \param tag_len The length of the tag to verify.
+ * \param input The buffer holding the ciphertext. Its size is \b length.
+ * \param output The buffer for holding the decrypted plaintext. It must
+ * have room for \b length bytes.
*
- * \return 0 if successful and authenticated.
- * \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match.
+ * \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 are not valid.
+ * \return #MBEDTLS_ERR_GCM_HW_ACCEL_FAILED or a cipher-specific
+ * error code if the decryption failed.
*/
int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
size_t length,
diff --git a/include/mbedtls/hkdf.h b/include/mbedtls/hkdf.h
new file mode 100644
index 0000000000..6833e7272e
--- /dev/null
+++ b/include/mbedtls/hkdf.h
@@ -0,0 +1,125 @@
+/**
+ * \file hkdf.h
+ *
+ * \brief This file contains the HKDF interface.
+ *
+ * The HMAC-based Extract-and-Expand Key Derivation Function (HKDF) is
+ * specified by RFC 5869.
+ */
+/*
+ * Copyright (C) 2016-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_HKDF_H
+#define MBEDTLS_HKDF_H
+
+#include "md.h"
+
+/**
+ * \name HKDF Error codes
+ * \{
+ */
+#define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA -0x5F80 /**< Bad input parameters to function. */
+/* \} name */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief This is the HMAC-based Extract-and-Expand Key Derivation Function
+ * (HKDF).
+ *
+ * \param md A hash function; md.size denotes the length of the hash
+ * function output in bytes.
+ * \param salt An optional salt value (a non-secret random value);
+ * if the salt is not provided, a string of all zeros of
+ * md.size length is used as the salt.
+ * \param salt_len The length in bytes of the optional \p salt.
+ * \param ikm The input keying material.
+ * \param ikm_len The length in bytes of \p ikm.
+ * \param info An optional context and application specific information
+ * string. This can be a zero-length string.
+ * \param info_len The length of \p info in bytes.
+ * \param okm The output keying material of \p okm_len bytes.
+ * \param okm_len The length of the output keying material in bytes. This
+ * must be less than or equal to 255 * md.size bytes.
+ *
+ * \return 0 on success.
+ * \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
+ * \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
+ * MD layer.
+ */
+int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt,
+ size_t salt_len, const unsigned char *ikm, size_t ikm_len,
+ const unsigned char *info, size_t info_len,
+ unsigned char *okm, size_t okm_len );
+
+/**
+ * \brief Take the input keying material \p ikm and extract from it a
+ * fixed-length pseudorandom key \p prk.
+ *
+ * \param md A hash function; md.size denotes the length of the
+ * hash function output in bytes.
+ * \param salt An optional salt value (a non-secret random value);
+ * if the salt is not provided, a string of all zeros
+ * of md.size length is used as the salt.
+ * \param salt_len The length in bytes of the optional \p salt.
+ * \param ikm The input keying material.
+ * \param ikm_len The length in bytes of \p ikm.
+ * \param[out] prk A pseudorandom key of at least md.size bytes.
+ *
+ * \return 0 on success.
+ * \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
+ * \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
+ * MD layer.
+ */
+int mbedtls_hkdf_extract( const mbedtls_md_info_t *md,
+ const unsigned char *salt, size_t salt_len,
+ const unsigned char *ikm, size_t ikm_len,
+ unsigned char *prk );
+
+/**
+ * \brief Expand the supplied \p prk into several additional pseudorandom
+ * keys, which is the output of the HKDF.
+ *
+ * \param md A hash function; md.size denotes the length of the hash
+ * function output in bytes.
+ * \param prk A pseudorandom key of at least md.size bytes. \p prk is usually,
+ * the output from the HKDF extract step.
+ * \param prk_len The length in bytes of \p prk.
+ * \param info An optional context and application specific information
+ * string. This can be a zero-length string.
+ * \param info_len The length of \p info in bytes.
+ * \param okm The output keying material of \p okm_len bytes.
+ * \param okm_len The length of the output keying material in bytes. This
+ * must be less than or equal to 255 * md.size bytes.
+ *
+ * \return 0 on success.
+ * \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
+ * \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
+ * MD layer.
+ */
+int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk,
+ size_t prk_len, const unsigned char *info,
+ size_t info_len, unsigned char *okm, size_t okm_len );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* hkdf.h */
diff --git a/include/mbedtls/platform.h b/include/mbedtls/platform.h
index bba770911e..9d9c5293eb 100644
--- a/include/mbedtls/platform.h
+++ b/include/mbedtls/platform.h
@@ -121,8 +121,8 @@ extern "C" {
#else
/* For size_t */
#include
-extern void * (*mbedtls_calloc)( size_t n, size_t size );
-extern void (*mbedtls_free)( void *ptr );
+extern void *mbedtls_calloc( size_t n, size_t size );
+extern void mbedtls_free( void *ptr );
/**
* \brief This function dynamically sets the memory-management
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index def20dbec7..1a806408e3 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -120,7 +120,8 @@
#define MBEDTLS_ERR_SSL_NON_FATAL -0x6680 /**< The alert message received indicates a non-fatal error. */
#define MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH -0x6600 /**< Couldn't set the hash for verifying CertificateVerify */
#define MBEDTLS_ERR_SSL_CONTINUE_PROCESSING -0x6580 /**< Internal-only message signaling that further message-processing should be done */
-#define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS -0x6500 /**< A cryptographic operation is in progress. Try again later. */
+#define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS -0x6500 /**< The asynchronous operation is not completed yet. */
+#define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS -0x6480 /**< A cryptographic operation is in progress. Try again later. */
/*
* Various constants
@@ -537,7 +538,6 @@ typedef void mbedtls_ssl_set_timer_t( void * ctx,
*/
typedef int mbedtls_ssl_get_timer_t( void * ctx );
-
/* Defined below */
typedef struct mbedtls_ssl_session mbedtls_ssl_session;
typedef struct mbedtls_ssl_context mbedtls_ssl_context;
@@ -554,6 +554,218 @@ typedef struct mbedtls_ssl_key_cert mbedtls_ssl_key_cert;
typedef struct mbedtls_ssl_flight_item mbedtls_ssl_flight_item;
#endif
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/**
+ * \brief Callback type: start external signature operation.
+ *
+ * This callback is called during an SSL handshake to start
+ * a signature decryption operation using an
+ * external processor. The parameter \p cert contains
+ * the public key; it is up to the callback function to
+ * determine how to access the associated private key.
+ *
+ * This function typically sends or enqueues a request, and
+ * does not wait for the operation to complete. This allows
+ * the handshake step to be non-blocking.
+ *
+ * The parameters \p ssl and \p cert are guaranteed to remain
+ * valid throughout the handshake. On the other hand, this
+ * function must save the contents of \p hash if the value
+ * is needed for later processing, because the \p hash buffer
+ * is no longer valid after this function returns.
+ *
+ * This function may call mbedtls_ssl_set_async_operation_data()
+ * to store an operation context for later retrieval
+ * by the resume or cancel callback.
+ *
+ * \note For RSA signatures, this function must produce output
+ * that is consistent with PKCS#1 v1.5 in the same way as
+ * mbedtls_rsa_pkcs1_sign(). Before the private key operation,
+ * apply the padding steps described in RFC 8017, section 9.2
+ * "EMSA-PKCS1-v1_5" as follows.
+ * - If \p md_alg is #MBEDTLS_MD_NONE, apply the PKCS#1 v1.5
+ * encoding, treating \p hash as the DigestInfo to be
+ * padded. In other words, apply EMSA-PKCS1-v1_5 starting
+ * from step 3, with `T = hash` and `tLen = hash_len`.
+ * - If `md_alg != MBEDTLS_MD_NONE`, apply the PKCS#1 v1.5
+ * encoding, treating \p hash as the hash to be encoded and
+ * padded. In other words, apply EMSA-PKCS1-v1_5 starting
+ * from step 2, with `digestAlgorithm` obtained by calling
+ * mbedtls_oid_get_oid_by_md() on \p md_alg.
+ *
+ * \note For ECDSA signatures, the output format is the DER encoding
+ * `Ecdsa-Sig-Value` defined in
+ * [RFC 4492 section 5.4](https://tools.ietf.org/html/rfc4492#section-5.4).
+ *
+ * \param ssl The SSL connection instance. It should not be
+ * modified other than via
+ * mbedtls_ssl_set_async_operation_data().
+ * \param cert Certificate containing the public key.
+ * In simple cases, this is one of the pointers passed to
+ * mbedtls_ssl_conf_own_cert() when configuring the SSL
+ * connection. However, if other callbacks are used, this
+ * property may not hold. For example, if an SNI callback
+ * is registered with mbedtls_ssl_conf_sni(), then
+ * this callback determines what certificate is used.
+ * \param md_alg Hash algorithm.
+ * \param hash Buffer containing the hash. This buffer is
+ * no longer valid when the function returns.
+ * \param hash_len Size of the \c hash buffer in bytes.
+ *
+ * \return 0 if the operation was started successfully and the SSL
+ * stack should call the resume callback immediately.
+ * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation
+ * was started successfully and the SSL stack should return
+ * immediately without calling the resume callback yet.
+ * \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external
+ * processor does not support this key. The SSL stack will
+ * use the private key object instead.
+ * \return Any other error indicates a fatal failure and is
+ * propagated up the call chain. The callback should
+ * use \c MBEDTLS_ERR_PK_xxx error codes, and must not
+ * use \c MBEDTLS_ERR_SSL_xxx error codes except as
+ * directed in the documentation of this callback.
+ */
+typedef int mbedtls_ssl_async_sign_t( mbedtls_ssl_context *ssl,
+ mbedtls_x509_crt *cert,
+ mbedtls_md_type_t md_alg,
+ const unsigned char *hash,
+ size_t hash_len );
+
+/**
+ * \brief Callback type: start external decryption operation.
+ *
+ * This callback is called during an SSL handshake to start
+ * an RSA decryption operation using an
+ * external processor. The parameter \p cert contains
+ * the public key; it is up to the callback function to
+ * determine how to access the associated private key.
+ *
+ * This function typically sends or enqueues a request, and
+ * does not wait for the operation to complete. This allows
+ * the handshake step to be non-blocking.
+ *
+ * The parameters \p ssl and \p cert are guaranteed to remain
+ * valid throughout the handshake. On the other hand, this
+ * function must save the contents of \p input if the value
+ * is needed for later processing, because the \p input buffer
+ * is no longer valid after this function returns.
+ *
+ * This function may call mbedtls_ssl_set_async_operation_data()
+ * to store an operation context for later retrieval
+ * by the resume or cancel callback.
+ *
+ * \warning RSA decryption as used in TLS is subject to a potential
+ * timing side channel attack first discovered by Bleichenbacher
+ * in 1998. This attack can be remotely exploitable
+ * in practice. To avoid this attack, you must ensure that
+ * if the callback performs an RSA decryption, the time it
+ * takes to execute and return the result does not depend
+ * on whether the RSA decryption succeeded or reported
+ * invalid padding.
+ *
+ * \param ssl The SSL connection instance. It should not be
+ * modified other than via
+ * mbedtls_ssl_set_async_operation_data().
+ * \param cert Certificate containing the public key.
+ * In simple cases, this is one of the pointers passed to
+ * mbedtls_ssl_conf_own_cert() when configuring the SSL
+ * connection. However, if other callbacks are used, this
+ * property may not hold. For example, if an SNI callback
+ * is registered with mbedtls_ssl_conf_sni(), then
+ * this callback determines what certificate is used.
+ * \param input Buffer containing the input ciphertext. This buffer
+ * is no longer valid when the function returns.
+ * \param input_len Size of the \p input buffer in bytes.
+ *
+ * \return 0 if the operation was started successfully and the SSL
+ * stack should call the resume callback immediately.
+ * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation
+ * was started successfully and the SSL stack should return
+ * immediately without calling the resume callback yet.
+ * \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external
+ * processor does not support this key. The SSL stack will
+ * use the private key object instead.
+ * \return Any other error indicates a fatal failure and is
+ * propagated up the call chain. The callback should
+ * use \c MBEDTLS_ERR_PK_xxx error codes, and must not
+ * use \c MBEDTLS_ERR_SSL_xxx error codes except as
+ * directed in the documentation of this callback.
+ */
+typedef int mbedtls_ssl_async_decrypt_t( mbedtls_ssl_context *ssl,
+ mbedtls_x509_crt *cert,
+ const unsigned char *input,
+ size_t input_len );
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+/**
+ * \brief Callback type: resume external operation.
+ *
+ * This callback is called during an SSL handshake to resume
+ * an external operation started by the
+ * ::mbedtls_ssl_async_sign_t or
+ * ::mbedtls_ssl_async_decrypt_t callback.
+ *
+ * This function typically checks the status of a pending
+ * request or causes the request queue to make progress, and
+ * does not wait for the operation to complete. This allows
+ * the handshake step to be non-blocking.
+ *
+ * This function may call mbedtls_ssl_get_async_operation_data()
+ * to retrieve an operation context set by the start callback.
+ * It may call mbedtls_ssl_set_async_operation_data() to modify
+ * this context.
+ *
+ * Note that when this function returns a status other than
+ * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, it must free any
+ * resources associated with the operation.
+ *
+ * \param ssl The SSL connection instance. It should not be
+ * modified other than via
+ * mbedtls_ssl_set_async_operation_data().
+ * \param output Buffer containing the output (signature or decrypted
+ * data) on success.
+ * \param output_len On success, number of bytes written to \p output.
+ * \param output_size Size of the \p output buffer in bytes.
+ *
+ * \return 0 if output of the operation is available in the
+ * \p output buffer.
+ * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation
+ * is still in progress. Subsequent requests for progress
+ * on the SSL connection will call the resume callback
+ * again.
+ * \return Any other error means that the operation is aborted.
+ * The SSL handshake is aborted. The callback should
+ * use \c MBEDTLS_ERR_PK_xxx error codes, and must not
+ * use \c MBEDTLS_ERR_SSL_xxx error codes except as
+ * directed in the documentation of this callback.
+ */
+typedef int mbedtls_ssl_async_resume_t( mbedtls_ssl_context *ssl,
+ unsigned char *output,
+ size_t *output_len,
+ size_t output_size );
+
+/**
+ * \brief Callback type: cancel external operation.
+ *
+ * This callback is called if an SSL connection is closed
+ * while an asynchronous operation is in progress. Note that
+ * this callback is not called if the
+ * ::mbedtls_ssl_async_resume_t callback has run and has
+ * returned a value other than
+ * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, since in that case
+ * the asynchronous operation has already completed.
+ *
+ * This function may call mbedtls_ssl_get_async_operation_data()
+ * to retrieve an operation context set by the start callback.
+ *
+ * \param ssl The SSL connection instance. It should not be
+ * modified.
+ */
+typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl );
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
/*
* This structure is used for storing current session data.
*/
@@ -670,6 +882,16 @@ struct mbedtls_ssl_config
mbedtls_x509_crl *ca_crl; /*!< trusted CAs CRLs */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ mbedtls_ssl_async_sign_t *f_async_sign_start; /*!< start asynchronous signature operation */
+ mbedtls_ssl_async_decrypt_t *f_async_decrypt_start; /*!< start asynchronous decryption operation */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+ mbedtls_ssl_async_resume_t *f_async_resume; /*!< resume asynchronous operation */
+ mbedtls_ssl_async_cancel_t *f_async_cancel; /*!< cancel asynchronous operation */
+ void *p_async_config_data; /*!< Configuration data set by mbedtls_ssl_conf_async_private_cb(). */
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
const int *sig_hashes; /*!< allowed signature hashes */
#endif
@@ -1308,6 +1530,85 @@ void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
void *p_export_keys );
#endif /* MBEDTLS_SSL_EXPORT_KEYS */
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+/**
+ * \brief Configure asynchronous private key operation callbacks.
+ *
+ * \param conf SSL configuration context
+ * \param f_async_sign Callback to start a signature operation. See
+ * the description of ::mbedtls_ssl_async_sign_t
+ * for more information. This may be \c NULL if the
+ * external processor does not support any signature
+ * operation; in this case the private key object
+ * associated with the certificate will be used.
+ * \param f_async_decrypt Callback to start a decryption operation. See
+ * the description of ::mbedtls_ssl_async_decrypt_t
+ * for more information. This may be \c NULL if the
+ * external processor does not support any decryption
+ * operation; in this case the private key object
+ * associated with the certificate will be used.
+ * \param f_async_resume Callback to resume an asynchronous operation. See
+ * the description of ::mbedtls_ssl_async_resume_t
+ * for more information. This may not be \c NULL unless
+ * \p f_async_sign and \p f_async_decrypt are both
+ * \c NULL.
+ * \param f_async_cancel Callback to cancel an asynchronous operation. See
+ * the description of ::mbedtls_ssl_async_cancel_t
+ * for more information. This may be \c NULL if
+ * no cleanup is needed.
+ * \param config_data A pointer to configuration data which can be
+ * retrieved with
+ * mbedtls_ssl_conf_get_async_config_data(). The
+ * library stores this value without dereferencing it.
+ */
+void mbedtls_ssl_conf_async_private_cb( mbedtls_ssl_config *conf,
+ mbedtls_ssl_async_sign_t *f_async_sign,
+ mbedtls_ssl_async_decrypt_t *f_async_decrypt,
+ mbedtls_ssl_async_resume_t *f_async_resume,
+ mbedtls_ssl_async_cancel_t *f_async_cancel,
+ void *config_data );
+
+/**
+ * \brief Retrieve the configuration data set by
+ * mbedtls_ssl_conf_async_private_cb().
+ *
+ * \param conf SSL configuration context
+ * \return The configuration data set by
+ * mbedtls_ssl_conf_async_private_cb().
+ */
+void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf );
+
+/**
+ * \brief Retrieve the asynchronous operation user context.
+ *
+ * \note This function may only be called while a handshake
+ * is in progress.
+ *
+ * \param ssl The SSL context to access.
+ *
+ * \return The asynchronous operation user context that was last
+ * set during the current handshake. If
+ * mbedtls_ssl_set_async_operation_data() has not yet been
+ * called during the current handshake, this function returns
+ * \c NULL.
+ */
+void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl );
+
+/**
+ * \brief Retrieve the asynchronous operation user context.
+ *
+ * \note This function may only be called while a handshake
+ * is in progress.
+ *
+ * \param ssl The SSL context to access.
+ * \param ctx The new value of the asynchronous operation user context.
+ * Call mbedtls_ssl_get_async_operation_data() later during the
+ * same handshake to retrieve this value.
+ */
+void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl,
+ void *ctx );
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
/**
* \brief Callback type: generate a cookie
*
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 6f8bebe2c2..89fc88f6c1 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -327,6 +327,19 @@ struct mbedtls_ssl_handshake_params
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
int extended_ms; /*!< use Extended Master Secret? */
#endif
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ unsigned int async_in_progress : 1; /*!< an asynchronous operation is in progress */
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ /** Asynchronous operation context. This field is meant for use by the
+ * asynchronous operation callbacks (mbedtls_ssl_config::f_async_sign_start,
+ * mbedtls_ssl_config::f_async_decrypt_start,
+ * mbedtls_ssl_config::f_async_resume, mbedtls_ssl_config::f_async_cancel).
+ * The library does not use it internally. */
+ void *user_async_ctx;
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
};
/*
@@ -430,9 +443,9 @@ void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform );
* \brief Free referenced items in an SSL handshake context and clear
* memory
*
- * \param handshake SSL handshake context
+ * \param ssl SSL context
*/
-void mbedtls_ssl_handshake_free( mbedtls_ssl_handshake_params *handshake );
+void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl );
int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl );
int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl );
@@ -650,7 +663,13 @@ static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t
volatile unsigned char diff = 0;
for( i = 0; i < n; i++ )
- diff |= A[i] ^ B[i];
+ {
+ /* Read volatile data in order before computing diff.
+ * This avoids IAR compiler warning:
+ * 'the order of volatile accesses is undefined ..' */
+ unsigned char x = A[i], y = B[i];
+ diff |= x ^ y;
+ }
return( diff );
}
@@ -666,9 +685,9 @@ int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_2)
int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
- unsigned char *output,
- unsigned char *data, size_t data_len,
- mbedtls_md_type_t md_alg );
+ unsigned char *hash, size_t *hashlen,
+ unsigned char *data, size_t data_len,
+ mbedtls_md_type_t md_alg );
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
MBEDTLS_SSL_PROTO_TLS1_2 */
diff --git a/include/mbedtls/version.h b/include/mbedtls/version.h
index 83e3c1726b..c8050b9ba1 100644
--- a/include/mbedtls/version.h
+++ b/include/mbedtls/version.h
@@ -39,7 +39,7 @@
* Major, Minor, Patchlevel
*/
#define MBEDTLS_VERSION_MAJOR 2
-#define MBEDTLS_VERSION_MINOR 10
+#define MBEDTLS_VERSION_MINOR 11
#define MBEDTLS_VERSION_PATCH 0
/**
@@ -47,9 +47,9 @@
* MMNNPP00
* Major version | Minor version | Patch version
*/
-#define MBEDTLS_VERSION_NUMBER 0x020A0000
-#define MBEDTLS_VERSION_STRING "2.10.0"
-#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.10.0"
+#define MBEDTLS_VERSION_NUMBER 0x020B0000
+#define MBEDTLS_VERSION_STRING "2.11.0"
+#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.11.0"
#if defined(MBEDTLS_VERSION_C)
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 6e5faa5a04..5243baf465 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -30,6 +30,7 @@ set(src_crypto
error.c
gcm.c
havege.c
+ hkdf.c
hmac_drbg.c
md.c
md2.c
@@ -143,15 +144,15 @@ endif(USE_STATIC_MBEDTLS_LIBRARY)
if(USE_SHARED_MBEDTLS_LIBRARY)
add_library(mbedcrypto SHARED ${src_crypto})
- set_target_properties(mbedcrypto PROPERTIES VERSION 2.10.0 SOVERSION 2)
+ set_target_properties(mbedcrypto PROPERTIES VERSION 2.11.0 SOVERSION 3)
target_link_libraries(mbedcrypto ${libs})
add_library(mbedx509 SHARED ${src_x509})
- set_target_properties(mbedx509 PROPERTIES VERSION 2.10.0 SOVERSION 0)
+ set_target_properties(mbedx509 PROPERTIES VERSION 2.11.0 SOVERSION 0)
target_link_libraries(mbedx509 ${libs} mbedcrypto)
add_library(mbedtls SHARED ${src_tls})
- set_target_properties(mbedtls PROPERTIES VERSION 2.10.0 SOVERSION 10)
+ set_target_properties(mbedtls PROPERTIES VERSION 2.11.0 SOVERSION 11)
target_link_libraries(mbedtls ${libs} mbedx509)
install(TARGETS mbedtls mbedx509 mbedcrypto
diff --git a/library/Makefile b/library/Makefile
index 25ec374d4e..f7eb89655f 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -31,9 +31,9 @@ LOCAL_CFLAGS += -fPIC -fpic
endif
endif
-SOEXT_TLS=so.10
+SOEXT_TLS=so.11
SOEXT_X509=so.0
-SOEXT_CRYPTO=so.2
+SOEXT_CRYPTO=so.3
# Set DLEXT=dylib to compile as a shared library for Mac OS X
DLEXT ?= so
@@ -57,6 +57,7 @@ OBJS_CRYPTO= aes.o aesni.o arc4.o \
ecjpake.o ecp.o \
ecp_curves.o entropy.o entropy_poll.o \
error.o gcm.o havege.o \
+ hkdf.o \
hmac_drbg.o md.o md2.o \
md4.o md5.o md_wrap.o \
memory_buffer_alloc.o oid.o \
diff --git a/library/aes.c b/library/aes.c
index fea9b5383d..5c939bba47 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -521,6 +521,20 @@ void mbedtls_aes_free( mbedtls_aes_context *ctx )
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) );
}
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
+{
+ mbedtls_aes_init( &ctx->crypt );
+ mbedtls_aes_init( &ctx->tweak );
+}
+
+void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
+{
+ mbedtls_aes_free( &ctx->crypt );
+ mbedtls_aes_free( &ctx->tweak );
+}
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
/*
* AES key schedule (encryption)
*/
@@ -702,6 +716,78 @@ exit:
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;
+
+ 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;
+
+ 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) \
@@ -983,6 +1069,165 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
}
#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];
+
+ /* Sectors must be at least 16 bytes. */
+ if( length < 16 )
+ return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+
+ /* NIST SP 80-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
@@ -1061,7 +1306,41 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
return( 0 );
}
-#endif /*MBEDTLS_CIPHER_MODE_CFB */
+#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 = *iv_off;
+
+ 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)
/*
@@ -1218,6 +1497,72 @@ static const unsigned char aes_test_cfb128_ct[3][64] =
};
#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:
@@ -1281,6 +1626,74 @@ 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
*/
@@ -1297,11 +1710,14 @@ int mbedtls_aes_self_test( int verbose )
#if defined(MBEDTLS_CIPHER_MODE_CBC)
unsigned char prv[16];
#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB)
+#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)
+#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
@@ -1509,6 +1925,69 @@ int mbedtls_aes_self_test( int verbose )
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_AES_FEATURE_UNAVAILABLE && 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
@@ -1561,6 +2040,73 @@ int mbedtls_aes_self_test( int verbose )
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:
diff --git a/library/asn1write.c b/library/asn1write.c
index c01c836550..72acdf3012 100644
--- a/library/asn1write.c
+++ b/library/asn1write.c
@@ -83,7 +83,9 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len
return( 4 );
}
+#if SIZE_MAX > 0xFFFFFFFF
if( len <= 0xFFFFFFFF )
+#endif
{
if( *p - start < 5 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
@@ -96,7 +98,9 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len
return( 5 );
}
+#if SIZE_MAX > 0xFFFFFFFF
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+#endif
}
int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag )
diff --git a/library/ccm.c b/library/ccm.c
index cf6520935e..804eaf80f1 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -152,8 +152,10 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
* Check length requirements: SP800-38C A.1
* Additional requirement: a < 2^16 - 2^8 to simplify the code.
* 'length' checked later (when writing it to the first block)
+ *
+ * Also, loosen the requirements to enable support for CCM* (IEEE 802.15.4).
*/
- if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
+ if( tag_len == 2 || tag_len > 16 || tag_len % 2 != 0 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
/* Also implies q is within bounds */
@@ -302,7 +304,7 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
/*
* Authenticated encryption
*/
-int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
+int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, 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,
@@ -312,10 +314,23 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
add, add_len, input, output, tag, tag_len ) );
}
+int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, 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,
+ unsigned char *tag, size_t tag_len )
+{
+ if( tag_len == 0 )
+ return( MBEDTLS_ERR_CCM_BAD_INPUT );
+
+ return( mbedtls_ccm_star_encrypt_and_tag( ctx, length, iv, iv_len, add,
+ add_len, input, output, tag, tag_len ) );
+}
+
/*
* Authenticated decryption
*/
-int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
+int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, 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,
@@ -346,6 +361,18 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
return( 0 );
}
+int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, 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,
+ const unsigned char *tag, size_t tag_len )
+{
+ if( tag_len == 0 )
+ return( MBEDTLS_ERR_CCM_BAD_INPUT );
+
+ return( mbedtls_ccm_star_auth_decrypt( ctx, length, iv, iv_len, add,
+ add_len, input, output, tag, tag_len ) );
+}
#endif /* !MBEDTLS_CCM_ALT */
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
diff --git a/library/cipher.c b/library/cipher.c
index a5cd61cdf3..2d85228aa5 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -191,10 +191,11 @@ int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *k
ctx->operation = operation;
/*
- * For CFB and CTR mode always use the encryption key schedule
+ * 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,
@@ -424,6 +425,21 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
}
#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 )
{
@@ -440,6 +456,27 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
}
#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 )
{
@@ -639,8 +676,10 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
*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 );
diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c
index a9ef8195ca..16e0a9d9bb 100644
--- a/library/cipher_wrap.c
+++ b/library/cipher_wrap.c
@@ -142,6 +142,15 @@ static int aes_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation,
}
#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,
@@ -152,6 +161,33 @@ static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
}
#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 )
{
@@ -191,9 +227,15 @@ static const mbedtls_cipher_base_t aes_info = {
#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
@@ -306,6 +348,41 @@ static const mbedtls_cipher_info_t aes_256_cfb128_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,
@@ -341,6 +418,92 @@ static const mbedtls_cipher_info_t aes_256_ctr_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 )
@@ -358,9 +521,15 @@ static const mbedtls_cipher_base_t gcm_aes_info = {
#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
@@ -421,9 +590,15 @@ static const mbedtls_cipher_base_t ccm_aes_info = {
#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
@@ -548,9 +723,15 @@ static const mbedtls_cipher_base_t camellia_info = {
#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
@@ -715,9 +896,15 @@ static const mbedtls_cipher_base_t gcm_camellia_info = {
#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
@@ -778,9 +965,15 @@ static const mbedtls_cipher_base_t ccm_camellia_info = {
#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
@@ -906,9 +1099,15 @@ static const mbedtls_cipher_base_t aria_info = {
#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
@@ -1073,9 +1272,15 @@ static const mbedtls_cipher_base_t gcm_aria_info = {
#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
@@ -1136,9 +1341,15 @@ static const mbedtls_cipher_base_t ccm_aria_info = {
#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
@@ -1312,9 +1523,15 @@ static const mbedtls_cipher_base_t des_info = {
#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
@@ -1357,9 +1574,15 @@ static const mbedtls_cipher_base_t des_ede_info = {
#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
@@ -1402,9 +1625,15 @@ static const mbedtls_cipher_base_t des_ede3_info = {
#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
@@ -1511,9 +1740,15 @@ static const mbedtls_cipher_base_t blowfish_info = {
#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
@@ -1621,9 +1856,15 @@ static const mbedtls_cipher_base_t arc4_base_info = {
#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
@@ -1684,9 +1925,15 @@ static const mbedtls_cipher_base_t null_base_info = {
#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
@@ -1724,11 +1971,20 @@ const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] =
{ 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 },
diff --git a/library/entropy_poll.c b/library/entropy_poll.c
index 67900c46c8..fd96258ce7 100644
--- a/library/entropy_poll.c
+++ b/library/entropy_poll.c
@@ -25,13 +25,14 @@
#include MBEDTLS_CONFIG_FILE
#endif
+#include
+
#if defined(MBEDTLS_ENTROPY_C)
#include "mbedtls/entropy.h"
#include "mbedtls/entropy_poll.h"
#if defined(MBEDTLS_TIMING_C)
-#include
#include "mbedtls/timing.h"
#endif
#if defined(MBEDTLS_HAVEGE_C)
diff --git a/library/error.c b/library/error.c
index 4dc13a4263..9bccc8b15d 100644
--- a/library/error.c
+++ b/library/error.c
@@ -105,6 +105,10 @@
#include "mbedtls/gcm.h"
#endif
+#if defined(MBEDTLS_HKDF_C)
+#include "mbedtls/hkdf.h"
+#endif
+
#if defined(MBEDTLS_HMAC_DRBG_C)
#include "mbedtls/hmac_drbg.h"
#endif
@@ -499,6 +503,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "SSL - Couldn't set the hash for verifying CertificateVerify" );
if( use_ret == -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) )
mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that further message-processing should be done" );
+ if( use_ret == -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) )
+ mbedtls_snprintf( buf, buflen, "SSL - The asynchronous operation is not completed yet" );
if( use_ret == -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) )
mbedtls_snprintf( buf, buflen, "SSL - A cryptographic operation is in progress. Try again later" );
#endif /* MBEDTLS_SSL_TLS_C */
@@ -719,6 +725,11 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" );
#endif /* MBEDTLS_GCM_C */
+#if defined(MBEDTLS_HKDF_C)
+ if( use_ret == -(MBEDTLS_ERR_HKDF_BAD_INPUT_DATA) )
+ mbedtls_snprintf( buf, buflen, "HKDF - Bad input parameters to function" );
+#endif /* MBEDTLS_HKDF_C */
+
#if defined(MBEDTLS_HMAC_DRBG_C)
if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG) )
mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Too many random requested in single call" );
diff --git a/library/hkdf.c b/library/hkdf.c
new file mode 100644
index 0000000000..d2e55e869b
--- /dev/null
+++ b/library/hkdf.c
@@ -0,0 +1,180 @@
+/*
+ * HKDF implementation -- RFC 5869
+ *
+ * Copyright (C) 2016-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)
+ */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_HKDF_C)
+
+#include
+#include "mbedtls/hkdf.h"
+#include "mbedtls/platform_util.h"
+
+int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt,
+ size_t salt_len, const unsigned char *ikm, size_t ikm_len,
+ const unsigned char *info, size_t info_len,
+ unsigned char *okm, size_t okm_len )
+{
+ int ret;
+ unsigned char prk[MBEDTLS_MD_MAX_SIZE];
+
+ ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, prk );
+
+ if( ret == 0 )
+ {
+ ret = mbedtls_hkdf_expand( md, prk, mbedtls_md_get_size( md ),
+ info, info_len, okm, okm_len );
+ }
+
+ mbedtls_platform_zeroize( prk, sizeof( prk ) );
+
+ return( ret );
+}
+
+int mbedtls_hkdf_extract( const mbedtls_md_info_t *md,
+ const unsigned char *salt, size_t salt_len,
+ const unsigned char *ikm, size_t ikm_len,
+ unsigned char *prk )
+{
+ unsigned char null_salt[MBEDTLS_MD_MAX_SIZE] = { '\0' };
+
+ if( salt == NULL )
+ {
+ size_t hash_len;
+
+ hash_len = mbedtls_md_get_size( md );
+
+ if( hash_len == 0 )
+ {
+ return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA;
+ }
+
+ salt = null_salt;
+ salt_len = hash_len;
+ }
+
+ return( mbedtls_md_hmac( md, salt, salt_len, ikm, ikm_len, prk ) );
+}
+
+int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk,
+ size_t prk_len, const unsigned char *info,
+ size_t info_len, unsigned char *okm, size_t okm_len )
+{
+ size_t hash_len;
+ size_t where = 0;
+ size_t n;
+ size_t t_len = 0;
+ size_t i;
+ int ret = 0;
+ mbedtls_md_context_t ctx;
+ unsigned char t[MBEDTLS_MD_MAX_SIZE];
+
+ if( okm == NULL )
+ {
+ return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
+ }
+
+ hash_len = mbedtls_md_get_size( md );
+
+ if( prk_len < hash_len || hash_len == 0 )
+ {
+ return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
+ }
+
+ if( info == NULL )
+ {
+ info = (const unsigned char *) "";
+ info_len = 0;
+ }
+
+ n = okm_len / hash_len;
+
+ if( (okm_len % hash_len) != 0 )
+ {
+ n++;
+ }
+
+ if( n > 255 )
+ {
+ return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
+ }
+
+ mbedtls_md_init( &ctx );
+
+ if( (ret = mbedtls_md_setup( &ctx, md, 1) ) != 0 )
+ {
+ goto exit;
+ }
+
+ /* RFC 5869 Section 2.3. */
+ for( i = 1; i <= n; i++ )
+ {
+ size_t num_to_copy;
+ unsigned char c = i & 0xff;
+
+ ret = mbedtls_md_hmac_starts( &ctx, prk, prk_len );
+ if( ret != 0 )
+ {
+ goto exit;
+ }
+
+ ret = mbedtls_md_hmac_update( &ctx, t, t_len );
+ if( ret != 0 )
+ {
+ goto exit;
+ }
+
+ ret = mbedtls_md_hmac_update( &ctx, info, info_len );
+ if( ret != 0 )
+ {
+ goto exit;
+ }
+
+ /* The constant concatenated to the end of each t(n) is a single octet.
+ * */
+ ret = mbedtls_md_hmac_update( &ctx, &c, 1 );
+ if( ret != 0 )
+ {
+ goto exit;
+ }
+
+ ret = mbedtls_md_hmac_finish( &ctx, t );
+ if( ret != 0 )
+ {
+ goto exit;
+ }
+
+ num_to_copy = i != n ? hash_len : okm_len - where;
+ memcpy( okm + where, t, num_to_copy );
+ where += hash_len;
+ t_len = hash_len;
+ }
+
+exit:
+ mbedtls_md_free( &ctx );
+ mbedtls_platform_zeroize( t, sizeof( t ) );
+
+ return( ret );
+}
+
+#endif /* MBEDTLS_HKDF_C */
diff --git a/library/memory_buffer_alloc.c b/library/memory_buffer_alloc.c
index ceaeda1e73..51ea7c41d7 100644
--- a/library/memory_buffer_alloc.c
+++ b/library/memory_buffer_alloc.c
@@ -518,7 +518,9 @@ void mbedtls_memory_buffer_alloc_status( void )
heap.alloc_count, heap.free_count );
if( heap.first->next == NULL )
+ {
mbedtls_fprintf( stderr, "All memory de-allocated in stack buffer\n" );
+ }
else
{
mbedtls_fprintf( stderr, "Memory currently allocated:\n" );
diff --git a/library/net_sockets.c b/library/net_sockets.c
index 7b4a423ccd..202da01714 100644
--- a/library/net_sockets.c
+++ b/library/net_sockets.c
@@ -47,11 +47,12 @@
#define IS_EINTR( ret ) ( ( ret ) == WSAEINTR )
-#ifdef _WIN32_WINNT
+#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501)
#undef _WIN32_WINNT
-#endif
/* Enables getaddrinfo() & Co */
#define _WIN32_WINNT 0x0501
+#endif
+
#include
#include
diff --git a/library/pkcs5.c b/library/pkcs5.c
index 440a174b5b..f04f0ab25e 100644
--- a/library/pkcs5.c
+++ b/library/pkcs5.c
@@ -249,8 +249,10 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
memset( counter, 0, 4 );
counter[3] = 1;
+#if UINT_MAX > 0xFFFFFFFF
if( iteration_count > 0xFFFFFFFF )
return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA );
+#endif
while( key_length )
{
diff --git a/library/platform.c b/library/platform.c
index 9e992875d9..b24b2fa652 100644
--- a/library/platform.c
+++ b/library/platform.c
@@ -51,14 +51,24 @@ static void platform_free_uninit( void *ptr )
#define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit
#endif /* !MBEDTLS_PLATFORM_STD_FREE */
-void * (*mbedtls_calloc)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC;
-void (*mbedtls_free)( void * ) = 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 = calloc_func;
- mbedtls_free = free_func;
+ mbedtls_calloc_func = calloc_func;
+ mbedtls_free_func = free_func;
return( 0 );
}
#endif /* MBEDTLS_PLATFORM_MEMORY */
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 1937ec519e..b3a8ba93d1 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -2571,10 +2571,9 @@ start_processing:
defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( md_alg != MBEDTLS_MD_NONE )
{
- /* Info from md_alg will be used instead */
- hashlen = 0;
- ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, params,
- params_len, md_alg );
+ ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen,
+ params, params_len,
+ md_alg );
if( ret != 0 )
return( ret );
}
@@ -2586,8 +2585,7 @@ start_processing:
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
- MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen :
- (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
if( ssl->session_negotiate->peer_cert == NULL )
{
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 09b7a3fed3..0ccab588eb 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -709,7 +709,7 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate",
cur->cert );
- if( ! mbedtls_pk_can_do( cur->key, pk_alg ) )
+ if( ! mbedtls_pk_can_do( &cur->cert->pk, pk_alg ) )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) );
continue;
@@ -733,7 +733,7 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_ECDSA_C)
if( pk_alg == MBEDTLS_PK_ECDSA &&
- ssl_check_key_curve( cur->key, ssl->handshake->curves ) != 0 )
+ ssl_check_key_curve( &cur->cert->pk, ssl->handshake->curves ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) );
continue;
@@ -2828,54 +2828,56 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
-static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \
+ defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl,
+ size_t *signature_len )
+{
+ /* Append the signature to ssl->out_msg, leaving 2 bytes for the
+ * signature length which will be added in ssl_write_server_key_exchange
+ * after the call to ssl_prepare_server_key_exchange.
+ * ssl_write_server_key_exchange also takes care of incrementing
+ * ssl->out_msglen. */
+ unsigned char *sig_start = ssl->out_msg + ssl->out_msglen + 2;
+ size_t sig_max_len = ( ssl->out_buf + MBEDTLS_SSL_MAX_CONTENT_LEN
+ - sig_start );
+ int ret = ssl->conf->f_async_resume( ssl,
+ sig_start, signature_len, sig_max_len );
+ if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
+ {
+ ssl->handshake->async_in_progress = 0;
+ mbedtls_ssl_set_async_operation_data( ssl, NULL );
+ }
+ MBEDTLS_SSL_DEBUG_RET( 2, "ssl_resume_server_key_exchange", ret );
+ return( ret );
+}
+#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) &&
+ defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
+
+/* Prepare the ServerKeyExchange message, up to and including
+ * calculating the signature if any, but excluding formatting the
+ * signature and sending the message. */
+static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
+ size_t *signature_len )
{
- int ret;
- size_t n = 0;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
-
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED)
- unsigned char *p = ssl->out_msg + 4;
- size_t len;
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
- unsigned char *dig_signed = p;
- size_t dig_signed_len = 0;
+ unsigned char *dig_signed = NULL;
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
+ (void) ciphersuite_info; /* unused in some configurations */
+#if !defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+ (void) signature_len;
+#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
+
+ ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */
/*
*
- * Part 1: Extract static ECDH parameters and abort
- * if ServerKeyExchange not needed.
- *
- */
-
- /* For suites involving ECDH, extract DH parameters
- * from certificate at this point. */
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
- if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) )
- {
- ssl_get_ecdh_params_from_cert( ssl );
- }
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */
-
- /* Key exchanges not involving ephemeral keys don't use
- * ServerKeyExchange, so end here. */
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
- if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
- ssl->state++;
- return( 0 );
- }
-#endif /* MBEDTLS_KEY_EXCHANGE__NON_PFS__ENABLED */
-
- /*
- *
- * Part 2: Provide key exchange parameters for chosen ciphersuite.
+ * Part 1: Provide key exchange parameters for chosen ciphersuite.
*
*/
@@ -2885,18 +2887,21 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
+ int ret;
+ size_t len = 0;
- ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
- p, end - p, &len, ssl->conf->f_rng, ssl->conf->p_rng );
+ ret = mbedtls_ecjpake_write_round_two(
+ &ssl->handshake->ecjpake_ctx,
+ ssl->out_msg + ssl->out_msglen,
+ MBEDTLS_SSL_MAX_CONTENT_LEN - ssl->out_msglen, &len,
+ ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
return( ret );
}
- p += len;
- n += len;
+ ssl->out_msglen += len;
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
@@ -2910,10 +2915,8 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
{
- *(p++) = 0x00;
- *(p++) = 0x00;
-
- n += 2;
+ ssl->out_msg[ssl->out_msglen++] = 0x00;
+ ssl->out_msg[ssl->out_msglen++] = 0x00;
}
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
@@ -2924,6 +2927,9 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_dhe( ciphersuite_info ) )
{
+ int ret;
+ size_t len = 0;
+
if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "no DH parameters set" ) );
@@ -2947,21 +2953,21 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
return( ret );
}
- if( ( ret = mbedtls_dhm_make_params( &ssl->handshake->dhm_ctx,
- (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
- p, &len, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+ if( ( ret = mbedtls_dhm_make_params(
+ &ssl->handshake->dhm_ctx,
+ (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
+ ssl->out_msg + ssl->out_msglen, &len,
+ ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_params", ret );
return( ret );
}
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
- dig_signed = p;
- dig_signed_len = len;
+ dig_signed = ssl->out_msg + ssl->out_msglen;
#endif
- p += len;
- n += len;
+ ssl->out_msglen += len;
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X );
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P );
@@ -2986,6 +2992,8 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
*/
const mbedtls_ecp_curve_info **curve = NULL;
const mbedtls_ecp_group_id *gid;
+ int ret;
+ size_t len = 0;
/* Match our preference list against the offered curves */
for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ )
@@ -3009,21 +3017,21 @@ curve_matching_done:
return( ret );
}
- if( ( ret = mbedtls_ecdh_make_params( &ssl->handshake->ecdh_ctx, &len,
- p, MBEDTLS_SSL_MAX_CONTENT_LEN - n,
- ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+ if( ( ret = mbedtls_ecdh_make_params(
+ &ssl->handshake->ecdh_ctx, &len,
+ ssl->out_msg + ssl->out_msglen,
+ MBEDTLS_SSL_MAX_CONTENT_LEN - ssl->out_msglen,
+ ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret );
return( ret );
}
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
- dig_signed = p;
- dig_signed_len = len;
+ dig_signed = ssl->out_msg + ssl->out_msglen;
#endif
- p += len;
- n += len;
+ ssl->out_msglen += len;
MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q ", &ssl->handshake->ecdh_ctx.Q );
}
@@ -3031,19 +3039,20 @@ curve_matching_done:
/*
*
- * Part 3: For key exchanges involving the server signing the
+ * Part 2: For key exchanges involving the server signing the
* exchange parameters, compute and add the signature here.
*
*/
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) )
{
- size_t signature_len = 0;
- unsigned int hashlen = 0;
- unsigned char hash[64];
+ size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed;
+ size_t hashlen = 0;
+ unsigned char hash[MBEDTLS_MD_MAX_SIZE];
+ int ret;
/*
- * 3.1: Choose hash algorithm:
+ * 2.1: Choose hash algorithm:
* A: For TLS 1.2, obey signature-hash-algorithm extension
* to choose appropriate hash.
* B: For SSL3, TLS1.0, TLS1.1 and ECDHE_ECDSA, use SHA1
@@ -3090,7 +3099,7 @@ curve_matching_done:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %d for signing", md_alg ) );
/*
- * 3.2: Compute the hash to be signed
+ * 2.2: Compute the hash to be signed
*/
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_1)
@@ -3110,9 +3119,7 @@ curve_matching_done:
defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( md_alg != MBEDTLS_MD_NONE )
{
- /* Info from md_alg will be used instead */
- hashlen = 0;
- ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash,
+ ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen,
dig_signed,
dig_signed_len,
md_alg );
@@ -3127,18 +3134,11 @@ curve_matching_done:
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
- MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen :
- (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
/*
- * 3.3: Compute and add the signature
+ * 2.3: Compute and add the signature
*/
- if( mbedtls_ssl_own_key( ssl ) == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key" ) );
- return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
- }
-
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{
@@ -3158,33 +3158,150 @@ curve_matching_done:
*
*/
- *(p++) = mbedtls_ssl_hash_from_md_alg( md_alg );
- *(p++) = mbedtls_ssl_sig_from_pk_alg( sig_alg );
-
- n += 2;
+ ssl->out_msg[ssl->out_msglen++] =
+ mbedtls_ssl_hash_from_md_alg( md_alg );
+ ssl->out_msg[ssl->out_msglen++] =
+ mbedtls_ssl_sig_from_pk_alg( sig_alg );
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash, hashlen,
- p + 2 , &signature_len, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ if( ssl->conf->f_async_sign_start != NULL )
+ {
+ ret = ssl->conf->f_async_sign_start( ssl,
+ mbedtls_ssl_own_cert( ssl ),
+ md_alg, hash, hashlen );
+ switch( ret )
+ {
+ case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH:
+ /* act as if f_async_sign was null */
+ break;
+ case 0:
+ ssl->handshake->async_in_progress = 1;
+ return( ssl_resume_server_key_exchange( ssl, signature_len ) );
+ case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
+ ssl->handshake->async_in_progress = 1;
+ return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS );
+ default:
+ MBEDTLS_SSL_DEBUG_RET( 1, "f_async_sign_start", ret );
+ return( ret );
+ }
+ }
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+ if( mbedtls_ssl_own_key( ssl ) == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key" ) );
+ return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
+ }
+
+ /* Append the signature to ssl->out_msg, leaving 2 bytes for the
+ * signature length which will be added in ssl_write_server_key_exchange
+ * after the call to ssl_prepare_server_key_exchange.
+ * ssl_write_server_key_exchange also takes care of incrementing
+ * ssl->out_msglen. */
+ if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ),
+ md_alg, hash, hashlen,
+ ssl->out_msg + ssl->out_msglen + 2,
+ signature_len,
+ ssl->conf->f_rng,
+ ssl->conf->p_rng ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
return( ret );
}
-
- *(p++) = (unsigned char)( signature_len >> 8 );
- *(p++) = (unsigned char)( signature_len );
- n += 2;
-
- MBEDTLS_SSL_DEBUG_BUF( 3, "my signature", p, signature_len );
-
- n += signature_len;
}
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
- /* Done with actual work; add header and send. */
+ return( 0 );
+}
- ssl->out_msglen = 4 + n;
+/* Prepare the ServerKeyExchange message and send it. For ciphersuites
+ * that do not include a ServerKeyExchange message, do nothing. Either
+ * way, if successful, move on to the next step in the SSL state
+ * machine. */
+static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
+{
+ int ret;
+ size_t signature_len = 0;
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+ ssl->transform_negotiate->ciphersuite_info;
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
+ /* Extract static ECDH parameters and abort if ServerKeyExchange
+ * is not needed. */
+ if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) )
+ {
+ /* For suites involving ECDH, extract DH parameters
+ * from certificate at this point. */
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
+ if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) )
+ {
+ ssl_get_ecdh_params_from_cert( ssl );
+ }
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */
+
+ /* Key exchanges not involving ephemeral keys don't use
+ * ServerKeyExchange, so end here. */
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
+ ssl->state++;
+ return( 0 );
+ }
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \
+ defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ /* If we have already prepared the message and there is an ongoing
+ * signature operation, resume signing. */
+ if( ssl->handshake->async_in_progress != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming signature operation" ) );
+ ret = ssl_resume_server_key_exchange( ssl, &signature_len );
+ }
+ else
+#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) &&
+ defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
+ {
+ /* ServerKeyExchange is needed. Prepare the message. */
+ ret = ssl_prepare_server_key_exchange( ssl, &signature_len );
+ }
+
+ if( ret != 0 )
+ {
+ /* If we're starting to write a new message, set ssl->out_msglen
+ * to 0. But if we're resuming after an asynchronous message,
+ * out_msglen is the amount of data written so far and mst be
+ * preserved. */
+ if( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange (pending)" ) );
+ else
+ ssl->out_msglen = 0;
+ return( ret );
+ }
+
+ /* If there is a signature, write its length.
+ * ssl_prepare_server_key_exchange already wrote the signature
+ * itself at its proper place in the output buffer. */
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+ if( signature_len != 0 )
+ {
+ ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len >> 8 );
+ ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len );
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "my signature",
+ ssl->out_msg + ssl->out_msglen,
+ signature_len );
+
+ /* Skip over the already-written signature */
+ ssl->out_msglen += signature_len;
+ }
+#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
+
+ /* Add header and send. */
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE;
@@ -3197,7 +3314,6 @@ curve_matching_done:
}
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) );
-
return( 0 );
}
@@ -3272,28 +3388,50 @@ static int ssl_parse_client_dh_public( mbedtls_ssl_context *ssl, unsigned char *
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
-static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
- const unsigned char *p,
- const unsigned char *end,
- size_t pms_offset )
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+static int ssl_resume_decrypt_pms( mbedtls_ssl_context *ssl,
+ unsigned char *peer_pms,
+ size_t *peer_pmslen,
+ size_t peer_pmssize )
+{
+ int ret = ssl->conf->f_async_resume( ssl,
+ peer_pms, peer_pmslen, peer_pmssize );
+ if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
+ {
+ ssl->handshake->async_in_progress = 0;
+ mbedtls_ssl_set_async_operation_data( ssl, NULL );
+ }
+ MBEDTLS_SSL_DEBUG_RET( 2, "ssl_decrypt_encrypted_pms", ret );
+ return( ret );
+}
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl,
+ const unsigned char *p,
+ const unsigned char *end,
+ unsigned char *peer_pms,
+ size_t *peer_pmslen,
+ size_t peer_pmssize )
{
int ret;
- size_t len = mbedtls_pk_get_len( mbedtls_ssl_own_key( ssl ) );
- unsigned char *pms = ssl->handshake->premaster + pms_offset;
- unsigned char ver[2];
- unsigned char fake_pms[48], peer_pms[48];
- unsigned char mask;
- size_t i, peer_pmslen;
- unsigned int diff;
+ mbedtls_pk_context *private_key = mbedtls_ssl_own_key( ssl );
+ mbedtls_pk_context *public_key = &mbedtls_ssl_own_cert( ssl )->pk;
+ size_t len = mbedtls_pk_get_len( public_key );
- if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_RSA ) )
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ /* If we have already started decoding the message and there is an ongoing
+ * decryption operation, resume signing. */
+ if( ssl->handshake->async_in_progress != 0 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no RSA private key" ) );
- return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming decryption operation" ) );
+ return( ssl_resume_decrypt_pms( ssl,
+ peer_pms, peer_pmslen, peer_pmssize ) );
}
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
/*
- * Decrypt the premaster using own private RSA key
+ * Prepare to decrypt the premaster using own private RSA key
*/
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_2)
@@ -3314,30 +3452,120 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
}
+ /*
+ * Decrypt the premaster secret
+ */
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ if( ssl->conf->f_async_decrypt_start != NULL )
+ {
+ ret = ssl->conf->f_async_decrypt_start( ssl,
+ mbedtls_ssl_own_cert( ssl ),
+ p, len );
+ switch( ret )
+ {
+ case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH:
+ /* act as if f_async_decrypt_start was null */
+ break;
+ case 0:
+ ssl->handshake->async_in_progress = 1;
+ return( ssl_resume_decrypt_pms( ssl,
+ peer_pms,
+ peer_pmslen,
+ peer_pmssize ) );
+ case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
+ ssl->handshake->async_in_progress = 1;
+ return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS );
+ default:
+ MBEDTLS_SSL_DEBUG_RET( 1, "f_async_decrypt_start", ret );
+ return( ret );
+ }
+ }
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+ if( ! mbedtls_pk_can_do( private_key, MBEDTLS_PK_RSA ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no RSA private key" ) );
+ return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
+ }
+
+ ret = mbedtls_pk_decrypt( private_key, p, len,
+ peer_pms, peer_pmslen, peer_pmssize,
+ ssl->conf->f_rng, ssl->conf->p_rng );
+ return( ret );
+}
+
+static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
+ const unsigned char *p,
+ const unsigned char *end,
+ size_t pms_offset )
+{
+ int ret;
+ unsigned char *pms = ssl->handshake->premaster + pms_offset;
+ unsigned char ver[2];
+ unsigned char fake_pms[48], peer_pms[48];
+ unsigned char mask;
+ size_t i, peer_pmslen;
+ unsigned int diff;
+
+ /* In case of a failure in decryption, the decryption may write less than
+ * 2 bytes of output, but we always read the first two bytes. It doesn't
+ * matter in the end because diff will be nonzero in that case due to
+ * peer_pmslen being less than 48, and we only care whether diff is 0.
+ * But do initialize peer_pms for robustness anyway. This also makes
+ * memory analyzers happy (don't access uninitialized memory, even
+ * if it's an unsigned char). */
+ peer_pms[0] = peer_pms[1] = ~0;
+
+ ret = ssl_decrypt_encrypted_pms( ssl, p, end,
+ peer_pms,
+ &peer_pmslen,
+ sizeof( peer_pms ) );
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ if ( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
+ return( ret );
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
mbedtls_ssl_write_version( ssl->handshake->max_major_ver,
- ssl->handshake->max_minor_ver,
- ssl->conf->transport, ver );
+ ssl->handshake->max_minor_ver,
+ ssl->conf->transport, ver );
+
+ /* Avoid data-dependent branches while checking for invalid
+ * padding, to protect against timing-based Bleichenbacher-type
+ * attacks. */
+ diff = (unsigned int) ret;
+ diff |= peer_pmslen ^ 48;
+ diff |= peer_pms[0] ^ ver[0];
+ diff |= peer_pms[1] ^ ver[1];
+
+ /* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */
+ /* MSVC has a warning about unary minus on unsigned, but this is
+ * well-defined and precisely what we want to do here */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+ mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) );
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
/*
* Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding
* must not cause the connection to end immediately; instead, send a
* bad_record_mac later in the handshake.
- * Also, avoid data-dependant branches here to protect against
- * timing-based variants.
+ * To protect against timing-based variants of the attack, we must
+ * not have any branch that depends on whether the decryption was
+ * successful. In particular, always generate the fake premaster secret,
+ * regardless of whether it will ultimately influence the output or not.
*/
ret = ssl->conf->f_rng( ssl->conf->p_rng, fake_pms, sizeof( fake_pms ) );
if( ret != 0 )
+ {
+ /* It's ok to abort on an RNG failure, since this does not reveal
+ * anything about the RSA decryption. */
return( ret );
-
- ret = mbedtls_pk_decrypt( mbedtls_ssl_own_key( ssl ), p, len,
- peer_pms, &peer_pmslen,
- sizeof( peer_pms ),
- ssl->conf->f_rng, ssl->conf->p_rng );
-
- diff = (unsigned int) ret;
- diff |= peer_pmslen ^ 48;
- diff |= peer_pms[0] ^ ver[0];
- diff |= peer_pms[1] ^ ver[1];
+ }
#if defined(MBEDTLS_SSL_DEBUG_ALL)
if( diff != 0 )
@@ -3352,18 +3580,8 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
}
ssl->handshake->pmslen = 48;
- /* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */
- /* MSVC has a warning about unary minus on unsigned, but this is
- * well-defined and precisely what we want to do here */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
- mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) );
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
+ /* Set pms to either the true or the fake PMS, without
+ * data-dependent branches. */
for( i = 0; i < ssl->handshake->pmslen; i++ )
pms[i] = ( mask & fake_pms[i] ) | ( (~mask) & peer_pms[i] );
@@ -3445,6 +3663,20 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) );
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) && \
+ ( defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) )
+ if( ( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
+ ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) &&
+ ( ssl->handshake->async_in_progress != 0 ) )
+ {
+ /* We've already read a record and there is an asynchronous
+ * operation in progress to decrypt it. So skip reading the
+ * record. */
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "will resume decryption of previously-read record" ) );
+ }
+ else
+#endif
if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
@@ -3557,6 +3789,19 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
{
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ if ( ssl->handshake->async_in_progress != 0 )
+ {
+ /* There is an asynchronous operation in progress to
+ * decrypt the encrypted premaster secret, so skip
+ * directly to resuming this operation. */
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "PSK identity already parsed" ) );
+ /* Update p to skip the PSK identity. ssl_parse_encrypted_pms
+ * won't actually use it, but maintain p anyway for robustness. */
+ p += ssl->conf->psk_identity_len + 2;
+ }
+ else
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 2ebf128772..6baf3e1e12 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -5249,7 +5249,7 @@ static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl )
/*
* Free our handshake params
*/
- mbedtls_ssl_handshake_free( ssl->handshake );
+ mbedtls_ssl_handshake_free( ssl );
mbedtls_free( ssl->handshake );
ssl->handshake = NULL;
@@ -5608,7 +5608,7 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl )
if( ssl->session_negotiate )
mbedtls_ssl_session_free( ssl->session_negotiate );
if( ssl->handshake )
- mbedtls_ssl_handshake_free( ssl->handshake );
+ mbedtls_ssl_handshake_free( ssl );
/*
* Either the pointers are now NULL or cleared properly and can be freed.
@@ -6531,6 +6531,43 @@ void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
}
#endif
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+void mbedtls_ssl_conf_async_private_cb(
+ mbedtls_ssl_config *conf,
+ mbedtls_ssl_async_sign_t *f_async_sign,
+ mbedtls_ssl_async_decrypt_t *f_async_decrypt,
+ mbedtls_ssl_async_resume_t *f_async_resume,
+ mbedtls_ssl_async_cancel_t *f_async_cancel,
+ void *async_config_data )
+{
+ conf->f_async_sign_start = f_async_sign;
+ conf->f_async_decrypt_start = f_async_decrypt;
+ conf->f_async_resume = f_async_resume;
+ conf->f_async_cancel = f_async_cancel;
+ conf->p_async_config_data = async_config_data;
+}
+
+void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf )
+{
+ return( conf->p_async_config_data );
+}
+
+void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl )
+{
+ if( ssl->handshake == NULL )
+ return( NULL );
+ else
+ return( ssl->handshake->user_async_ctx );
+}
+
+void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl,
+ void *ctx )
+{
+ if( ssl->handshake != NULL )
+ ssl->handshake->user_async_ctx = ctx;
+}
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
/*
* SSL get accessors
*/
@@ -7438,11 +7475,21 @@ static void ssl_key_cert_free( mbedtls_ssl_key_cert *key_cert )
}
#endif /* MBEDTLS_X509_CRT_PARSE_C */
-void mbedtls_ssl_handshake_free( mbedtls_ssl_handshake_params *handshake )
+void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
{
+ mbedtls_ssl_handshake_params *handshake = ssl->handshake;
+
if( handshake == NULL )
return;
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ if( ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0 )
+ {
+ ssl->conf->f_async_cancel( ssl );
+ handshake->async_in_progress = 0;
+ }
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_1)
mbedtls_md5_free( &handshake->fin_md5 );
@@ -7577,7 +7624,7 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl )
if( ssl->handshake )
{
- mbedtls_ssl_handshake_free( ssl->handshake );
+ mbedtls_ssl_handshake_free( ssl );
mbedtls_ssl_transform_free( ssl->transform_negotiate );
mbedtls_ssl_session_free( ssl->session_negotiate );
@@ -8344,13 +8391,14 @@ exit:
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_2)
int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
- unsigned char *output,
- unsigned char *data, size_t data_len,
- mbedtls_md_type_t md_alg )
+ unsigned char *hash, size_t *hashlen,
+ unsigned char *data, size_t data_len,
+ mbedtls_md_type_t md_alg )
{
int ret = 0;
mbedtls_md_context_t ctx;
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
+ *hashlen = mbedtls_md_get_size( md_info );
mbedtls_md_init( &ctx );
@@ -8381,7 +8429,7 @@ int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret );
goto exit;
}
- if( ( ret = mbedtls_md_finish( &ctx, output ) ) != 0 )
+ if( ( ret = mbedtls_md_finish( &ctx, hash ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_finish", ret );
goto exit;
diff --git a/library/version_features.c b/library/version_features.c
index 02a464319b..b1b5f30602 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -255,6 +255,12 @@ static const char *features[] = {
#if defined(MBEDTLS_CIPHER_MODE_CTR)
"MBEDTLS_CIPHER_MODE_CTR",
#endif /* MBEDTLS_CIPHER_MODE_CTR */
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ "MBEDTLS_CIPHER_MODE_OFB",
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ "MBEDTLS_CIPHER_MODE_XTS",
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
"MBEDTLS_CIPHER_NULL_CIPHER",
#endif /* MBEDTLS_CIPHER_NULL_CIPHER */
@@ -408,6 +414,9 @@ static const char *features[] = {
#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
"MBEDTLS_SSL_ALL_ALERT_MESSAGES",
#endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ "MBEDTLS_SSL_ASYNC_PRIVATE",
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
#if defined(MBEDTLS_SSL_DEBUG_ALL)
"MBEDTLS_SSL_DEBUG_ALL",
#endif /* MBEDTLS_SSL_DEBUG_ALL */
@@ -588,6 +597,9 @@ static const char *features[] = {
#if defined(MBEDTLS_HAVEGE_C)
"MBEDTLS_HAVEGE_C",
#endif /* MBEDTLS_HAVEGE_C */
+#if defined(MBEDTLS_HKDF_C)
+ "MBEDTLS_HKDF_C",
+#endif /* MBEDTLS_HKDF_C */
#if defined(MBEDTLS_HMAC_DRBG_C)
"MBEDTLS_HMAC_DRBG_C",
#endif /* MBEDTLS_HMAC_DRBG_C */
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 6bfb210f2f..3a413ad5e5 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -109,6 +109,10 @@ int main( void )
#define DFL_KEY_FILE ""
#define DFL_CRT_FILE2 ""
#define DFL_KEY_FILE2 ""
+#define DFL_ASYNC_OPERATIONS "-"
+#define DFL_ASYNC_PRIVATE_DELAY1 ( -1 )
+#define DFL_ASYNC_PRIVATE_DELAY2 ( -1 )
+#define DFL_ASYNC_PRIVATE_ERROR ( 0 )
#define DFL_PSK ""
#define DFL_PSK_IDENTITY "Client_identity"
#define DFL_ECJPAKE_PW NULL
@@ -196,6 +200,18 @@ int main( void )
#define USAGE_IO ""
#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+#define USAGE_SSL_ASYNC \
+ " async_operations=%%c... d=decrypt, s=sign (default: -=off)\n" \
+ " async_private_delay1=%%d Asynchronous delay for key_file or preloaded key\n" \
+ " async_private_delay2=%%d Asynchronous delay for key_file2 and sni\n" \
+ " default: -1 (not asynchronous)\n" \
+ " async_private_error=%%d Async callback error injection (default=0=none,\n" \
+ " 1=start, 2=cancel, 3=resume, negative=first time only)"
+#else
+#define USAGE_SSL_ASYNC ""
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
#define USAGE_PSK \
" psk=%%s default: \"\" (in hex, without 0x)\n" \
@@ -346,6 +362,7 @@ int main( void )
" cert_req_ca_list=%%d default: 1 (send ca list)\n" \
" options: 1 (send ca list), 0 (don't send)\n" \
USAGE_IO \
+ USAGE_SSL_ASYNC \
USAGE_SNI \
"\n" \
USAGE_PSK \
@@ -410,6 +427,10 @@ struct options
const char *key_file; /* the file with the server key */
const char *crt_file2; /* the file with the 2nd server certificate */
const char *key_file2; /* the file with the 2nd server key */
+ const char *async_operations; /* supported SSL asynchronous operations */
+ int async_private_delay1; /* number of times f_async_resume needs to be called for key 1, or -1 for no async */
+ int async_private_delay2; /* number of times f_async_resume needs to be called for key 2, or -1 for no async */
+ int async_private_error; /* inject error in async private callback */
const char *psk; /* the pre-shared key */
const char *psk_identity; /* the pre-shared key identity */
char *psk_list; /* list of PSK id/key pairs for callback */
@@ -841,6 +862,244 @@ static int ssl_sig_hashes_for_test[] = {
};
#endif /* MBEDTLS_X509_CRT_PARSE_C */
+/** Return true if \p ret is a status code indicating that there is an
+ * operation in progress on an SSL connection, and false if it indicates
+ * success or a fatal error.
+ *
+ * The possible operations in progress are:
+ *
+ * - A read, when the SSL input buffer does not contain a full message.
+ * - A write, when the SSL output buffer contains some data that has not
+ * been sent over the network yet.
+ * - An asynchronous callback that has not completed yet. */
+static int mbedtls_status_is_ssl_in_progress( int ret )
+{
+ return( ret == MBEDTLS_ERR_SSL_WANT_READ ||
+ ret == MBEDTLS_ERR_SSL_WANT_WRITE ||
+ ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS );
+}
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+typedef struct
+{
+ mbedtls_x509_crt *cert; /*!< Certificate corresponding to the key */
+ mbedtls_pk_context *pk; /*!< Private key */
+ unsigned delay; /*!< Number of resume steps to go through */
+ unsigned pk_owned : 1; /*!< Whether to free the pk object on exit */
+} ssl_async_key_slot_t;
+
+typedef enum {
+ SSL_ASYNC_INJECT_ERROR_NONE = 0, /*!< Let the callbacks succeed */
+ SSL_ASYNC_INJECT_ERROR_START, /*!< Inject error during start */
+ SSL_ASYNC_INJECT_ERROR_CANCEL, /*!< Close the connection after async start */
+ SSL_ASYNC_INJECT_ERROR_RESUME, /*!< Inject error during resume */
+#define SSL_ASYNC_INJECT_ERROR_MAX SSL_ASYNC_INJECT_ERROR_RESUME
+} ssl_async_inject_error_t;
+
+typedef struct
+{
+ ssl_async_key_slot_t slots[4]; /* key, key2, sni1, sni2 */
+ size_t slots_used;
+ ssl_async_inject_error_t inject_error;
+ int (*f_rng)(void *, unsigned char *, size_t);
+ void *p_rng;
+} ssl_async_key_context_t;
+
+int ssl_async_set_key( ssl_async_key_context_t *ctx,
+ mbedtls_x509_crt *cert,
+ mbedtls_pk_context *pk,
+ int pk_take_ownership,
+ unsigned delay )
+{
+ if( ctx->slots_used >= sizeof( ctx->slots ) / sizeof( *ctx->slots ) )
+ return( -1 );
+ ctx->slots[ctx->slots_used].cert = cert;
+ ctx->slots[ctx->slots_used].pk = pk;
+ ctx->slots[ctx->slots_used].delay = delay;
+ ctx->slots[ctx->slots_used].pk_owned = pk_take_ownership;
+ ++ctx->slots_used;
+ return( 0 );
+}
+
+#define SSL_ASYNC_INPUT_MAX_SIZE 512
+
+typedef enum
+{
+ ASYNC_OP_SIGN,
+ ASYNC_OP_DECRYPT,
+} ssl_async_operation_type_t;
+/* Note that the enum above and the array below need to be kept in sync!
+ * `ssl_async_operation_names[op]` is the name of op for each value `op`
+ * of type `ssl_async_operation_type_t`. */
+static const char *const ssl_async_operation_names[] =
+{
+ "sign",
+ "decrypt",
+};
+
+typedef struct
+{
+ unsigned slot;
+ ssl_async_operation_type_t operation_type;
+ mbedtls_md_type_t md_alg;
+ unsigned char input[SSL_ASYNC_INPUT_MAX_SIZE];
+ size_t input_len;
+ unsigned remaining_delay;
+} ssl_async_operation_context_t;
+
+static int ssl_async_start( mbedtls_ssl_context *ssl,
+ mbedtls_x509_crt *cert,
+ ssl_async_operation_type_t op_type,
+ mbedtls_md_type_t md_alg,
+ const unsigned char *input,
+ size_t input_len )
+{
+ ssl_async_key_context_t *config_data =
+ mbedtls_ssl_conf_get_async_config_data( ssl->conf );
+ unsigned slot;
+ ssl_async_operation_context_t *ctx = NULL;
+ const char *op_name = ssl_async_operation_names[op_type];
+
+ {
+ char dn[100];
+ if( mbedtls_x509_dn_gets( dn, sizeof( dn ), &cert->subject ) > 0 )
+ mbedtls_printf( "Async %s callback: looking for DN=%s\n",
+ op_name, dn );
+ }
+
+ /* Look for a private key that matches the public key in cert.
+ * Since this test code has the private key inside Mbed TLS,
+ * we call mbedtls_pk_check_pair to match a private key with the
+ * public key. */
+ for( slot = 0; slot < config_data->slots_used; slot++ )
+ {
+ if( mbedtls_pk_check_pair( &cert->pk,
+ config_data->slots[slot].pk ) == 0 )
+ break;
+ }
+ if( slot == config_data->slots_used )
+ {
+ mbedtls_printf( "Async %s callback: no key matches this certificate.\n",
+ op_name );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH );
+ }
+ mbedtls_printf( "Async %s callback: using key slot %u, delay=%u.\n",
+ op_name, slot, config_data->slots[slot].delay );
+
+ if( config_data->inject_error == SSL_ASYNC_INJECT_ERROR_START )
+ {
+ mbedtls_printf( "Async %s callback: injected error\n", op_name );
+ return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+ }
+
+ if( input_len > SSL_ASYNC_INPUT_MAX_SIZE )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ ctx = mbedtls_calloc( 1, sizeof( *ctx ) );
+ if( ctx == NULL )
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+ ctx->slot = slot;
+ ctx->operation_type = op_type;
+ ctx->md_alg = md_alg;
+ memcpy( ctx->input, input, input_len );
+ ctx->input_len = input_len;
+ ctx->remaining_delay = config_data->slots[slot].delay;
+ mbedtls_ssl_set_async_operation_data( ssl, ctx );
+
+ if( ctx->remaining_delay == 0 )
+ return( 0 );
+ else
+ return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS );
+}
+
+static int ssl_async_sign( mbedtls_ssl_context *ssl,
+ mbedtls_x509_crt *cert,
+ mbedtls_md_type_t md_alg,
+ const unsigned char *hash,
+ size_t hash_len )
+{
+ return( ssl_async_start( ssl, cert,
+ ASYNC_OP_SIGN, md_alg,
+ hash, hash_len ) );
+}
+
+static int ssl_async_decrypt( mbedtls_ssl_context *ssl,
+ mbedtls_x509_crt *cert,
+ const unsigned char *input,
+ size_t input_len )
+{
+ return( ssl_async_start( ssl, cert,
+ ASYNC_OP_DECRYPT, MBEDTLS_MD_NONE,
+ input, input_len ) );
+}
+
+static int ssl_async_resume( mbedtls_ssl_context *ssl,
+ unsigned char *output,
+ size_t *output_len,
+ size_t output_size )
+{
+ ssl_async_operation_context_t *ctx = mbedtls_ssl_get_async_operation_data( ssl );
+ ssl_async_key_context_t *config_data =
+ mbedtls_ssl_conf_get_async_config_data( ssl->conf );
+ ssl_async_key_slot_t *key_slot = &config_data->slots[ctx->slot];
+ int ret;
+ const char *op_name;
+
+ if( ctx->remaining_delay > 0 )
+ {
+ --ctx->remaining_delay;
+ mbedtls_printf( "Async resume (slot %u): call %u more times.\n",
+ ctx->slot, ctx->remaining_delay );
+ return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS );
+ }
+
+ switch( ctx->operation_type )
+ {
+ case ASYNC_OP_DECRYPT:
+ ret = mbedtls_pk_decrypt( key_slot->pk,
+ ctx->input, ctx->input_len,
+ output, output_len, output_size,
+ config_data->f_rng, config_data->p_rng );
+ break;
+ case ASYNC_OP_SIGN:
+ ret = mbedtls_pk_sign( key_slot->pk,
+ ctx->md_alg,
+ ctx->input, ctx->input_len,
+ output, output_len,
+ config_data->f_rng, config_data->p_rng );
+ break;
+ default:
+ mbedtls_printf( "Async resume (slot %u): unknown operation type %ld. This shouldn't happen.\n",
+ ctx->slot, (long) ctx->operation_type );
+ mbedtls_free( ctx );
+ return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+ break;
+ }
+
+ op_name = ssl_async_operation_names[ctx->operation_type];
+
+ if( config_data->inject_error == SSL_ASYNC_INJECT_ERROR_RESUME )
+ {
+ mbedtls_printf( "Async resume callback: %s done but injected error\n",
+ op_name );
+ mbedtls_free( ctx );
+ return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+ }
+
+ mbedtls_printf( "Async resume (slot %u): %s done, status=%d.\n",
+ ctx->slot, op_name, ret );
+ mbedtls_free( ctx );
+ return( ret );
+}
+
+static void ssl_async_cancel( mbedtls_ssl_context *ssl )
+{
+ ssl_async_operation_context_t *ctx = mbedtls_ssl_get_async_operation_data( ssl );
+ mbedtls_printf( "Async cancel callback.\n" );
+ mbedtls_free( ctx );
+}
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
/*
* Wait for an event from the underlying transport or the timer
* (Used in event-driven IO mode).
@@ -929,7 +1188,10 @@ int main( int argc, char *argv[] )
mbedtls_x509_crt srvcert2;
mbedtls_pk_context pkey2;
int key_cert_init = 0, key_cert_init2 = 0;
-#endif
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ ssl_async_key_context_t ssl_async_keys;
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
mbedtls_dhm_context dhm;
#endif
@@ -975,6 +1237,9 @@ int main( int argc, char *argv[] )
mbedtls_pk_init( &pkey );
mbedtls_x509_crt_init( &srvcert2 );
mbedtls_pk_init( &pkey2 );
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ memset( &ssl_async_keys, 0, sizeof( ssl_async_keys ) );
+#endif
#endif
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
mbedtls_dhm_init( &dhm );
@@ -1032,6 +1297,10 @@ int main( int argc, char *argv[] )
opt.key_file = DFL_KEY_FILE;
opt.crt_file2 = DFL_CRT_FILE2;
opt.key_file2 = DFL_KEY_FILE2;
+ opt.async_operations = DFL_ASYNC_OPERATIONS;
+ opt.async_private_delay1 = DFL_ASYNC_PRIVATE_DELAY1;
+ opt.async_private_delay2 = DFL_ASYNC_PRIVATE_DELAY2;
+ opt.async_private_error = DFL_ASYNC_PRIVATE_ERROR;
opt.psk = DFL_PSK;
opt.psk_identity = DFL_PSK_IDENTITY;
opt.psk_list = DFL_PSK_LIST;
@@ -1124,6 +1393,25 @@ int main( int argc, char *argv[] )
opt.key_file2 = q;
else if( strcmp( p, "dhm_file" ) == 0 )
opt.dhm_file = q;
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ else if( strcmp( p, "async_operations" ) == 0 )
+ opt.async_operations = q;
+ else if( strcmp( p, "async_private_delay1" ) == 0 )
+ opt.async_private_delay1 = atoi( q );
+ else if( strcmp( p, "async_private_delay2" ) == 0 )
+ opt.async_private_delay2 = atoi( q );
+ else if( strcmp( p, "async_private_error" ) == 0 )
+ {
+ int n = atoi( q );
+ if( n < -SSL_ASYNC_INJECT_ERROR_MAX ||
+ n > SSL_ASYNC_INJECT_ERROR_MAX )
+ {
+ ret = 2;
+ goto usage;
+ }
+ opt.async_private_error = n;
+ }
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
else if( strcmp( p, "psk" ) == 0 )
opt.psk = q;
else if( strcmp( p, "psk_identity" ) == 0 )
@@ -2018,22 +2306,109 @@ int main( int argc, char *argv[] )
mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
}
if( key_cert_init )
- if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 )
+ {
+ mbedtls_pk_context *pk = &pkey;
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ if( opt.async_private_delay1 >= 0 )
+ {
+ ret = ssl_async_set_key( &ssl_async_keys, &srvcert, pk, 0,
+ opt.async_private_delay1 );
+ if( ret < 0 )
+ {
+ mbedtls_printf( " Test error: ssl_async_set_key failed (%d)\n",
+ ret );
+ goto exit;
+ }
+ pk = NULL;
+ }
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+ if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, pk ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
goto exit;
}
+ }
if( key_cert_init2 )
- if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert2, &pkey2 ) ) != 0 )
+ {
+ mbedtls_pk_context *pk = &pkey2;
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ if( opt.async_private_delay2 >= 0 )
+ {
+ ret = ssl_async_set_key( &ssl_async_keys, &srvcert2, pk, 0,
+ opt.async_private_delay2 );
+ if( ret < 0 )
+ {
+ mbedtls_printf( " Test error: ssl_async_set_key failed (%d)\n",
+ ret );
+ goto exit;
+ }
+ pk = NULL;
+ }
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+ if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert2, pk ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
goto exit;
}
-#endif
+ }
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ if( opt.async_operations[0] != '-' )
+ {
+ mbedtls_ssl_async_sign_t *sign = NULL;
+ mbedtls_ssl_async_decrypt_t *decrypt = NULL;
+ const char *r;
+ for( r = opt.async_operations; *r; r++ )
+ {
+ switch( *r )
+ {
+ case 'd':
+ decrypt = ssl_async_decrypt;
+ break;
+ case 's':
+ sign = ssl_async_sign;
+ break;
+ }
+ }
+ ssl_async_keys.inject_error = ( opt.async_private_error < 0 ?
+ - opt.async_private_error :
+ opt.async_private_error );
+ ssl_async_keys.f_rng = mbedtls_ctr_drbg_random;
+ ssl_async_keys.p_rng = &ctr_drbg;
+ mbedtls_ssl_conf_async_private_cb( &conf,
+ sign,
+ decrypt,
+ ssl_async_resume,
+ ssl_async_cancel,
+ &ssl_async_keys );
+ }
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(SNI_OPTION)
if( opt.sni != NULL )
+ {
mbedtls_ssl_conf_sni( &conf, sni_callback, sni_info );
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ if( opt.async_private_delay2 >= 0 )
+ {
+ sni_entry *cur;
+ for( cur = sni_info; cur != NULL; cur = cur->next )
+ {
+ ret = ssl_async_set_key( &ssl_async_keys,
+ cur->cert, cur->key, 1,
+ opt.async_private_delay2 );
+ if( ret < 0 )
+ {
+ mbedtls_printf( " Test error: ssl_async_set_key failed (%d)\n",
+ ret );
+ goto exit;
+ }
+ cur->key = NULL;
+ }
+ }
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+ }
#endif
#if defined(MBEDTLS_ECP_C)
@@ -2205,8 +2580,16 @@ handshake:
while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
{
- if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
- ret != MBEDTLS_ERR_SSL_WANT_WRITE )
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ if( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS &&
+ ssl_async_keys.inject_error == SSL_ASYNC_INJECT_ERROR_CANCEL )
+ {
+ mbedtls_printf( " cancelling on injected error\n" );
+ break;
+ }
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+ if( ! mbedtls_status_is_ssl_in_progress( ret ) )
break;
/* For event-driven IO, wait for socket to become available */
@@ -2244,6 +2627,11 @@ handshake:
}
#endif
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ if( opt.async_private_error < 0 )
+ /* Injected error only the first time round, to test reset */
+ ssl_async_keys.inject_error = SSL_ASYNC_INJECT_ERROR_NONE;
+#endif
goto reset;
}
else /* ret == 0 */
@@ -2324,8 +2712,7 @@ data_exchange:
memset( buf, 0, sizeof( buf ) );
ret = mbedtls_ssl_read( &ssl, buf, len );
- if( ret == MBEDTLS_ERR_SSL_WANT_READ ||
- ret == MBEDTLS_ERR_SSL_WANT_WRITE )
+ if( mbedtls_status_is_ssl_in_progress( ret ) )
{
if( opt.event == 1 /* level triggered IO */ )
{
@@ -2425,7 +2812,7 @@ data_exchange:
len = sizeof( buf ) - 1;
memset( buf, 0, sizeof( buf ) );
- while( 1 )
+ do
{
/* Without the call to `mbedtls_ssl_check_pending`, it might
* happen that the client sends application data in the same
@@ -2455,10 +2842,8 @@ data_exchange:
* it can happen that the subsequent call to `mbedtls_ssl_read`
* returns `MBEDTLS_ERR_SSL_WANT_READ`, because the pending messages
* might be discarded (e.g. because they are retransmissions). */
- if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
- ret != MBEDTLS_ERR_SSL_WANT_WRITE )
- break;
}
+ while( mbedtls_status_is_ssl_in_progress( ret ) );
if( ret <= 0 )
{
@@ -2493,8 +2878,7 @@ data_exchange:
while( ( ret = mbedtls_ssl_renegotiate( &ssl ) ) != 0 )
{
- if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
- ret != MBEDTLS_ERR_SSL_WANT_WRITE )
+ if( ! mbedtls_status_is_ssl_in_progress( ret ) )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_renegotiate returned %d\n\n", ret );
goto reset;
@@ -2537,8 +2921,7 @@ data_exchange:
goto reset;
}
- if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
- ret != MBEDTLS_ERR_SSL_WANT_WRITE )
+ if( ! mbedtls_status_is_ssl_in_progress( ret ) )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_write returned %d\n\n", ret );
goto reset;
@@ -2562,8 +2945,7 @@ data_exchange:
{
ret = mbedtls_ssl_write( &ssl, buf, len );
- if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
- ret != MBEDTLS_ERR_SSL_WANT_WRITE )
+ if( ! mbedtls_status_is_ssl_in_progress( ret ) )
break;
/* For event-driven IO, wait for socket to become available */
@@ -2641,6 +3023,17 @@ exit:
mbedtls_x509_crt_free( &srvcert2 );
mbedtls_pk_free( &pkey2 );
#endif
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ for( i = 0; (size_t) i < ssl_async_keys.slots_used; i++ )
+ {
+ if( ssl_async_keys.slots[i].pk_owned )
+ {
+ mbedtls_pk_free( ssl_async_keys.slots[i].pk );
+ mbedtls_free( ssl_async_keys.slots[i].pk );
+ ssl_async_keys.slots[i].pk = NULL;
+ }
+ }
+#endif
#if defined(SNI_OPTION)
sni_free( sni_info );
#endif
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index 07298c1c46..89fdb84772 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -99,8 +99,8 @@ int main( void )
#define OPTIONS \
"md4, md5, ripemd160, sha1, sha256, sha512,\n" \
"arc4, des3, des, camellia, blowfish,\n" \
- "aes_cbc, aes_gcm, aes_ccm, aes_cmac, des3_cmac,\n" \
- "havege, ctr_drbg, hmac_drbg\n" \
+ "aes_cbc, aes_gcm, aes_ccm, aes_cmac, aes_xts,\n" \
+ "des3_cmac, havege, ctr_drbg, hmac_drbg,\n" \
"rsa, dhm, ecdsa, ecdh.\n"
#if defined(MBEDTLS_ERROR_C)
@@ -233,8 +233,8 @@ unsigned char buf[BUFSIZE];
typedef struct {
char md4, md5, ripemd160, sha1, sha256, sha512,
arc4, des3, des,
- aes_cbc, aes_gcm, aes_ccm, aes_cmac, des3_cmac,
- aria, camellia, blowfish,
+ aes_cbc, aes_gcm, aes_ccm, aes_cmac, aes_xts,
+ des3_cmac, aria, camellia, blowfish,
havege, ctr_drbg, hmac_drbg,
rsa, dhm, ecdsa, ecdh;
} todo_list;
@@ -279,6 +279,8 @@ int main( int argc, char *argv[] )
todo.des = 1;
else if( strcmp( argv[i], "aes_cbc" ) == 0 )
todo.aes_cbc = 1;
+ else if( strcmp( argv[i], "aes_xts" ) == 0 )
+ todo.aes_xts = 1;
else if( strcmp( argv[i], "aes_gcm" ) == 0 )
todo.aes_gcm = 1;
else if( strcmp( argv[i], "aes_ccm" ) == 0 )
@@ -426,6 +428,29 @@ int main( int argc, char *argv[] )
mbedtls_aes_free( &aes );
}
#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ if( todo.aes_xts )
+ {
+ int keysize;
+ mbedtls_aes_xts_context ctx;
+
+ mbedtls_aes_xts_init( &ctx );
+ for( keysize = 128; keysize <= 256; keysize += 128 )
+ {
+ mbedtls_snprintf( title, sizeof( title ), "AES-XTS-%d", keysize );
+
+ memset( buf, 0, sizeof( buf ) );
+ memset( tmp, 0, sizeof( tmp ) );
+ mbedtls_aes_xts_setkey_enc( &ctx, tmp, keysize * 2 );
+
+ TIME_AND_TSC( title,
+ mbedtls_aes_crypt_xts( &ctx, MBEDTLS_AES_ENCRYPT, BUFSIZE,
+ tmp, buf, buf ) );
+
+ mbedtls_aes_xts_free( &ctx );
+ }
+ }
+#endif
#if defined(MBEDTLS_GCM_C)
if( todo.aes_gcm )
{
diff --git a/programs/test/zeroize.c b/programs/test/zeroize.c
index 252438bcf0..29cc0ac3c1 100644
--- a/programs/test/zeroize.c
+++ b/programs/test/zeroize.c
@@ -66,7 +66,7 @@ int main( int argc, char** argv )
char buf[BUFFER_LEN];
char *p = buf;
char *end = p + BUFFER_LEN;
- char c;
+ int c;
if( argc != 2 )
{
@@ -83,7 +83,7 @@ int main( int argc, char** argv )
}
while( ( c = fgetc( fp ) ) != EOF && p < end - 1 )
- *p++ = c;
+ *p++ = (char)c;
*p = '\0';
if( p - buf != 0 )
diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c
index 9cc582d610..12baf720cd 100644
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -607,11 +607,7 @@ int main( int argc, char *argv[] )
//
if( strlen( opt.issuer_crt ) )
{
- if( !mbedtls_pk_can_do( &issuer_crt.pk, MBEDTLS_PK_RSA ) ||
- mbedtls_mpi_cmp_mpi( &mbedtls_pk_rsa( issuer_crt.pk )->N,
- &mbedtls_pk_rsa( *issuer_key )->N ) != 0 ||
- mbedtls_mpi_cmp_mpi( &mbedtls_pk_rsa( issuer_crt.pk )->E,
- &mbedtls_pk_rsa( *issuer_key )->E ) != 0 )
+ if( mbedtls_pk_check_pair( &issuer_crt.pk, issuer_key ) != 0 )
{
mbedtls_printf( " failed\n ! issuer_key does not match "
"issuer certificate\n\n" );
diff --git a/scripts/generate_errors.pl b/scripts/generate_errors.pl
index 8fe60793fd..60e52333a7 100755
--- a/scripts/generate_errors.pl
+++ b/scripts/generate_errors.pl
@@ -31,7 +31,7 @@ my $error_format_file = $data_dir.'/error.fmt';
my @low_level_modules = qw( AES ARC4 ARIA ASN1 BASE64 BIGNUM BLOWFISH
CAMELLIA CCM CMAC CTR_DRBG DES
- ENTROPY GCM HMAC_DRBG MD2 MD4 MD5
+ ENTROPY GCM HKDF HMAC_DRBG MD2 MD4 MD5
NET OID PADLOCK PBKDF2 RIPEMD160
SHA1 SHA256 SHA512 THREADING XTEA );
my @high_level_modules = qw( CIPHER DHM ECP MD
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index fa7ee01a8e..f630edb838 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -48,6 +48,7 @@ add_test_suite(aes aes.ecb)
add_test_suite(aes aes.cbc)
add_test_suite(aes aes.cfb)
add_test_suite(aes aes.rest)
+add_test_suite(aes aes.xts)
add_test_suite(arc4)
add_test_suite(aria)
add_test_suite(asn1write)
@@ -82,6 +83,7 @@ add_test_suite(gcm gcm.aes128_de)
add_test_suite(gcm gcm.aes192_de)
add_test_suite(gcm gcm.aes256_de)
add_test_suite(gcm gcm.camellia)
+add_test_suite(hkdf)
add_test_suite(hmac_drbg hmac_drbg.misc)
add_test_suite(hmac_drbg hmac_drbg.no_reseed)
add_test_suite(hmac_drbg hmac_drbg.nopr)
diff --git a/tests/Makefile b/tests/Makefile
index 8efecf3520..d65cd93a25 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -46,7 +46,9 @@ LOCAL_LDFLAGS += -lz
endif
APPS = test_suite_aes.ecb$(EXEXT) test_suite_aes.cbc$(EXEXT) \
- test_suite_aes.cfb$(EXEXT) test_suite_aes.rest$(EXEXT) \
+ test_suite_aes.cfb$(EXEXT) test_suite_aes.ofb$(EXEXT) \
+ test_suite_aes.xts$(EXEXT) \
+ test_suite_aes.rest$(EXEXT) \
test_suite_arc4$(EXEXT) test_suite_asn1write$(EXEXT) \
test_suite_base64$(EXEXT) test_suite_blowfish$(EXEXT) \
test_suite_camellia$(EXEXT) test_suite_ccm$(EXEXT) \
@@ -71,6 +73,7 @@ APPS = test_suite_aes.ecb$(EXEXT) test_suite_aes.cbc$(EXEXT) \
test_suite_gcm.aes192_en$(EXEXT) \
test_suite_gcm.aes256_en$(EXEXT) \
test_suite_gcm.camellia$(EXEXT) \
+ test_suite_hkdf$(EXEXT) \
test_suite_hmac_drbg.misc$(EXEXT) \
test_suite_hmac_drbg.no_reseed$(EXEXT) \
test_suite_hmac_drbg.nopr$(EXEXT) \
@@ -110,10 +113,18 @@ test_suite_aes.cfb.c : suites/test_suite_aes.function suites/test_suite_aes.cfb.
echo " Gen $@"
perl scripts/generate_code.pl suites test_suite_aes test_suite_aes.cfb
+test_suite_aes.ofb.c : suites/test_suite_aes.function suites/test_suite_aes.ofb.data scripts/generate_code.pl suites/helpers.function suites/main_test.function
+ echo " Gen $@"
+ perl scripts/generate_code.pl suites test_suite_aes test_suite_aes.ofb
+
test_suite_aes.rest.c : suites/test_suite_aes.function suites/test_suite_aes.rest.data scripts/generate_code.pl suites/helpers.function suites/main_test.function
echo " Gen $@"
perl scripts/generate_code.pl suites test_suite_aes test_suite_aes.rest
+test_suite_aes.xts.c : suites/test_suite_aes.function suites/test_suite_aes.xts.data scripts/generate_code.pl suites/helpers.function suites/main_test.function
+ echo " Gen $@"
+ perl scripts/generate_code.pl suites test_suite_aes test_suite_aes.xts
+
test_suite_cipher.aes.c : suites/test_suite_cipher.function suites/test_suite_cipher.aes.data scripts/generate_code.pl suites/helpers.function suites/main_test.function
echo " Gen $@"
perl scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.aes
@@ -178,6 +189,10 @@ test_suite_gcm.camellia.c : suites/test_suite_gcm.function suites/test_suite_gcm
echo " Gen $@"
perl scripts/generate_code.pl suites test_suite_gcm test_suite_gcm.camellia
+test_suite_hkdf.c : suites/test_suite_hkdf.function suites/test_suite_hkdf.data scripts/generate_code.pl suites/helpers.function suites/main_test.function
+ echo " Gen $@"
+ perl scripts/generate_code.pl suites test_suite_hkdf test_suite_hkdf
+
test_suite_hmac_drbg.misc.c : suites/test_suite_hmac_drbg.function suites/test_suite_hmac_drbg.misc.data scripts/generate_code.pl suites/helpers.function suites/main_test.function
echo " Gen $@"
perl scripts/generate_code.pl suites test_suite_hmac_drbg test_suite_hmac_drbg.misc
@@ -210,10 +225,18 @@ test_suite_aes.cfb$(EXEXT): test_suite_aes.cfb.c $(DEP)
echo " CC $<"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+test_suite_aes.ofb$(EXEXT): test_suite_aes.ofb.c $(DEP)
+ echo " CC $<"
+ $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
test_suite_aes.rest$(EXEXT): test_suite_aes.rest.c $(DEP)
echo " CC $<"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+test_suite_aes.xts$(EXEXT): test_suite_aes.xts.c $(DEP)
+ echo " CC $<"
+ $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
test_suite_arc4$(EXEXT): test_suite_arc4.c $(DEP)
echo " CC $<"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
@@ -342,6 +365,10 @@ test_suite_gcm.camellia$(EXEXT): test_suite_gcm.camellia.c $(DEP)
echo " CC $<"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+test_suite_hkdf$(EXEXT): test_suite_hkdf.c $(DEP)
+ echo " CC $<"
+ $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
test_suite_hmac_drbg.misc$(EXEXT): test_suite_hmac_drbg.misc.c $(DEP)
echo " CC $<"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 4894ad9b56..8ae720e817 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -531,8 +531,8 @@ make
msg "test: main suites (full config)" # ~ 5s
make test
-msg "test: ssl-opt.sh default (full config)" # ~ 1s
-if_build_succeeded tests/ssl-opt.sh -f Default
+msg "test: ssl-opt.sh default, ECJPAKE, SSL async (full config)" # ~ 1s
+if_build_succeeded tests/ssl-opt.sh -f 'Default\|ECJPAKE\|SSL async private'
msg "test: compat.sh RC4, DES & NULL (full config)" # ~ 2 min
if_build_succeeded env OPENSSL_CMD="$OPENSSL_LEGACY" GNUTLS_CLI="$GNUTLS_LEGACY_CLI" GNUTLS_SERV="$GNUTLS_LEGACY_SERV" tests/compat.sh -e '3DES\|DES-CBC3' -f 'NULL\|DES\|RC4\|ARCFOUR'
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index d45be5a6f5..fb99be3a6b 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -2652,6 +2652,142 @@ run_test "SNI: CA override with CRL" \
-S "! The certificate is not correctly signed by the trusted CA" \
-s "The certificate has been revoked (is on a CRL)"
+# Tests for SNI and DTLS
+
+run_test "SNI: DTLS, no SNI callback" \
+ "$P_SRV debug_level=3 dtls=1 \
+ crt_file=data_files/server5.crt key_file=data_files/server5.key" \
+ "$P_CLI server_name=localhost dtls=1" \
+ 0 \
+ -S "parse ServerName extension" \
+ -c "issuer name *: C=NL, O=PolarSSL, CN=Polarssl Test EC CA" \
+ -c "subject name *: C=NL, O=PolarSSL, CN=localhost"
+
+run_test "SNI: DTLS, matching cert 1" \
+ "$P_SRV debug_level=3 dtls=1 \
+ crt_file=data_files/server5.crt key_file=data_files/server5.key \
+ sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \
+ "$P_CLI server_name=localhost dtls=1" \
+ 0 \
+ -s "parse ServerName extension" \
+ -c "issuer name *: C=NL, O=PolarSSL, CN=PolarSSL Test CA" \
+ -c "subject name *: C=NL, O=PolarSSL, CN=localhost"
+
+run_test "SNI: DTLS, matching cert 2" \
+ "$P_SRV debug_level=3 dtls=1 \
+ crt_file=data_files/server5.crt key_file=data_files/server5.key \
+ sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \
+ "$P_CLI server_name=polarssl.example dtls=1" \
+ 0 \
+ -s "parse ServerName extension" \
+ -c "issuer name *: C=NL, O=PolarSSL, CN=PolarSSL Test CA" \
+ -c "subject name *: C=NL, O=PolarSSL, CN=polarssl.example"
+
+run_test "SNI: DTLS, no matching cert" \
+ "$P_SRV debug_level=3 dtls=1 \
+ crt_file=data_files/server5.crt key_file=data_files/server5.key \
+ sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \
+ "$P_CLI server_name=nonesuch.example dtls=1" \
+ 1 \
+ -s "parse ServerName extension" \
+ -s "ssl_sni_wrapper() returned" \
+ -s "mbedtls_ssl_handshake returned" \
+ -c "mbedtls_ssl_handshake returned" \
+ -c "SSL - A fatal alert message was received from our peer"
+
+run_test "SNI: DTLS, client auth no override: optional" \
+ "$P_SRV debug_level=3 auth_mode=optional dtls=1 \
+ crt_file=data_files/server5.crt key_file=data_files/server5.key \
+ sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-" \
+ "$P_CLI debug_level=3 server_name=localhost dtls=1" \
+ 0 \
+ -S "skip write certificate request" \
+ -C "skip parse certificate request" \
+ -c "got a certificate request" \
+ -C "skip write certificate" \
+ -C "skip write certificate verify" \
+ -S "skip parse certificate verify"
+
+run_test "SNI: DTLS, client auth override: none -> optional" \
+ "$P_SRV debug_level=3 auth_mode=none dtls=1 \
+ crt_file=data_files/server5.crt key_file=data_files/server5.key \
+ sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,optional" \
+ "$P_CLI debug_level=3 server_name=localhost dtls=1" \
+ 0 \
+ -S "skip write certificate request" \
+ -C "skip parse certificate request" \
+ -c "got a certificate request" \
+ -C "skip write certificate" \
+ -C "skip write certificate verify" \
+ -S "skip parse certificate verify"
+
+run_test "SNI: DTLS, client auth override: optional -> none" \
+ "$P_SRV debug_level=3 auth_mode=optional dtls=1 \
+ crt_file=data_files/server5.crt key_file=data_files/server5.key \
+ sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,none" \
+ "$P_CLI debug_level=3 server_name=localhost dtls=1" \
+ 0 \
+ -s "skip write certificate request" \
+ -C "skip parse certificate request" \
+ -c "got no certificate request" \
+ -c "skip write certificate" \
+ -c "skip write certificate verify" \
+ -s "skip parse certificate verify"
+
+run_test "SNI: DTLS, CA no override" \
+ "$P_SRV debug_level=3 auth_mode=optional dtls=1 \
+ crt_file=data_files/server5.crt key_file=data_files/server5.key \
+ ca_file=data_files/test-ca.crt \
+ sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,required" \
+ "$P_CLI debug_level=3 server_name=localhost dtls=1 \
+ crt_file=data_files/server6.crt key_file=data_files/server6.key" \
+ 1 \
+ -S "skip write certificate request" \
+ -C "skip parse certificate request" \
+ -c "got a certificate request" \
+ -C "skip write certificate" \
+ -C "skip write certificate verify" \
+ -S "skip parse certificate verify" \
+ -s "x509_verify_cert() returned" \
+ -s "! The certificate is not correctly signed by the trusted CA" \
+ -S "The certificate has been revoked (is on a CRL)"
+
+run_test "SNI: DTLS, CA override" \
+ "$P_SRV debug_level=3 auth_mode=optional dtls=1 \
+ crt_file=data_files/server5.crt key_file=data_files/server5.key \
+ ca_file=data_files/test-ca.crt \
+ sni=localhost,data_files/server2.crt,data_files/server2.key,data_files/test-ca2.crt,-,required" \
+ "$P_CLI debug_level=3 server_name=localhost dtls=1 \
+ crt_file=data_files/server6.crt key_file=data_files/server6.key" \
+ 0 \
+ -S "skip write certificate request" \
+ -C "skip parse certificate request" \
+ -c "got a certificate request" \
+ -C "skip write certificate" \
+ -C "skip write certificate verify" \
+ -S "skip parse certificate verify" \
+ -S "x509_verify_cert() returned" \
+ -S "! The certificate is not correctly signed by the trusted CA" \
+ -S "The certificate has been revoked (is on a CRL)"
+
+run_test "SNI: DTLS, CA override with CRL" \
+ "$P_SRV debug_level=3 auth_mode=optional \
+ crt_file=data_files/server5.crt key_file=data_files/server5.key dtls=1 \
+ ca_file=data_files/test-ca.crt \
+ sni=localhost,data_files/server2.crt,data_files/server2.key,data_files/test-ca2.crt,data_files/crl-ec-sha256.pem,required" \
+ "$P_CLI debug_level=3 server_name=localhost dtls=1 \
+ crt_file=data_files/server6.crt key_file=data_files/server6.key" \
+ 1 \
+ -S "skip write certificate request" \
+ -C "skip parse certificate request" \
+ -c "got a certificate request" \
+ -C "skip write certificate" \
+ -C "skip write certificate verify" \
+ -S "skip parse certificate verify" \
+ -s "x509_verify_cert() returned" \
+ -S "! The certificate is not correctly signed by the trusted CA" \
+ -s "The certificate has been revoked (is on a CRL)"
+
# Tests for non-blocking I/O: exercise a variety of handshake flows
run_test "Non-blocking I/O: basic handshake" \
@@ -4202,6 +4338,354 @@ run_test "EC restart: TLS, max_ops=1000, ECDHE-PSK" \
-C "mbedtls_ecdh_make_public.*4b00" \
-C "mbedtls_pk_sign.*4b00"
+# Tests of asynchronous private key support in SSL
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: sign, delay=0" \
+ "$P_SRV \
+ async_operations=s async_private_delay1=0 async_private_delay2=0" \
+ "$P_CLI" \
+ 0 \
+ -s "Async sign callback: using key slot " \
+ -s "Async resume (slot [0-9]): sign done, status=0"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: sign, delay=1" \
+ "$P_SRV \
+ async_operations=s async_private_delay1=1 async_private_delay2=1" \
+ "$P_CLI" \
+ 0 \
+ -s "Async sign callback: using key slot " \
+ -s "Async resume (slot [0-9]): call 0 more times." \
+ -s "Async resume (slot [0-9]): sign done, status=0"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: sign, delay=2" \
+ "$P_SRV \
+ async_operations=s async_private_delay1=2 async_private_delay2=2" \
+ "$P_CLI" \
+ 0 \
+ -s "Async sign callback: using key slot " \
+ -U "Async sign callback: using key slot " \
+ -s "Async resume (slot [0-9]): call 1 more times." \
+ -s "Async resume (slot [0-9]): call 0 more times." \
+ -s "Async resume (slot [0-9]): sign done, status=0"
+
+# Test that the async callback correctly signs the 36-byte hash of TLS 1.0/1.1
+# with RSA PKCS#1v1.5 as used in TLS 1.0/1.1.
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_1
+run_test "SSL async private: sign, RSA, TLS 1.1" \
+ "$P_SRV key_file=data_files/server2.key crt_file=data_files/server2.crt \
+ async_operations=s async_private_delay1=0 async_private_delay2=0" \
+ "$P_CLI force_version=tls1_1" \
+ 0 \
+ -s "Async sign callback: using key slot " \
+ -s "Async resume (slot [0-9]): sign done, status=0"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: sign, SNI" \
+ "$P_SRV debug_level=3 \
+ async_operations=s async_private_delay1=0 async_private_delay2=0 \
+ crt_file=data_files/server5.crt key_file=data_files/server5.key \
+ sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \
+ "$P_CLI server_name=polarssl.example" \
+ 0 \
+ -s "Async sign callback: using key slot " \
+ -s "Async resume (slot [0-9]): sign done, status=0" \
+ -s "parse ServerName extension" \
+ -c "issuer name *: C=NL, O=PolarSSL, CN=PolarSSL Test CA" \
+ -c "subject name *: C=NL, O=PolarSSL, CN=polarssl.example"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: decrypt, delay=0" \
+ "$P_SRV \
+ async_operations=d async_private_delay1=0 async_private_delay2=0" \
+ "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
+ 0 \
+ -s "Async decrypt callback: using key slot " \
+ -s "Async resume (slot [0-9]): decrypt done, status=0"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: decrypt, delay=1" \
+ "$P_SRV \
+ async_operations=d async_private_delay1=1 async_private_delay2=1" \
+ "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
+ 0 \
+ -s "Async decrypt callback: using key slot " \
+ -s "Async resume (slot [0-9]): call 0 more times." \
+ -s "Async resume (slot [0-9]): decrypt done, status=0"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: decrypt RSA-PSK, delay=0" \
+ "$P_SRV psk=abc123 \
+ async_operations=d async_private_delay1=0 async_private_delay2=0" \
+ "$P_CLI psk=abc123 \
+ force_ciphersuite=TLS-RSA-PSK-WITH-AES-128-CBC-SHA256" \
+ 0 \
+ -s "Async decrypt callback: using key slot " \
+ -s "Async resume (slot [0-9]): decrypt done, status=0"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: decrypt RSA-PSK, delay=1" \
+ "$P_SRV psk=abc123 \
+ async_operations=d async_private_delay1=1 async_private_delay2=1" \
+ "$P_CLI psk=abc123 \
+ force_ciphersuite=TLS-RSA-PSK-WITH-AES-128-CBC-SHA256" \
+ 0 \
+ -s "Async decrypt callback: using key slot " \
+ -s "Async resume (slot [0-9]): call 0 more times." \
+ -s "Async resume (slot [0-9]): decrypt done, status=0"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: sign callback not present" \
+ "$P_SRV \
+ async_operations=d async_private_delay1=1 async_private_delay2=1" \
+ "$P_CLI; [ \$? -eq 1 ] &&
+ $P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
+ 0 \
+ -S "Async sign callback" \
+ -s "! mbedtls_ssl_handshake returned" \
+ -s "The own private key or pre-shared key is not set, but needed" \
+ -s "Async resume (slot [0-9]): decrypt done, status=0" \
+ -s "Successful connection"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: decrypt callback not present" \
+ "$P_SRV debug_level=1 \
+ async_operations=s async_private_delay1=1 async_private_delay2=1" \
+ "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA;
+ [ \$? -eq 1 ] && $P_CLI" \
+ 0 \
+ -S "Async decrypt callback" \
+ -s "! mbedtls_ssl_handshake returned" \
+ -s "got no RSA private key" \
+ -s "Async resume (slot [0-9]): sign done, status=0" \
+ -s "Successful connection"
+
+# key1: ECDSA, key2: RSA; use key1 from slot 0
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: slot 0 used with key1" \
+ "$P_SRV \
+ async_operations=s async_private_delay1=1 \
+ key_file=data_files/server5.key crt_file=data_files/server5.crt \
+ key_file2=data_files/server2.key crt_file2=data_files/server2.crt" \
+ "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256" \
+ 0 \
+ -s "Async sign callback: using key slot 0," \
+ -s "Async resume (slot 0): call 0 more times." \
+ -s "Async resume (slot 0): sign done, status=0"
+
+# key1: ECDSA, key2: RSA; use key2 from slot 0
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: slot 0 used with key2" \
+ "$P_SRV \
+ async_operations=s async_private_delay2=1 \
+ key_file=data_files/server5.key crt_file=data_files/server5.crt \
+ key_file2=data_files/server2.key crt_file2=data_files/server2.crt" \
+ "$P_CLI force_ciphersuite=TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256" \
+ 0 \
+ -s "Async sign callback: using key slot 0," \
+ -s "Async resume (slot 0): call 0 more times." \
+ -s "Async resume (slot 0): sign done, status=0"
+
+# key1: ECDSA, key2: RSA; use key2 from slot 1
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: slot 1 used with key2" \
+ "$P_SRV \
+ async_operations=s async_private_delay1=1 async_private_delay2=1 \
+ key_file=data_files/server5.key crt_file=data_files/server5.crt \
+ key_file2=data_files/server2.key crt_file2=data_files/server2.crt" \
+ "$P_CLI force_ciphersuite=TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256" \
+ 0 \
+ -s "Async sign callback: using key slot 1," \
+ -s "Async resume (slot 1): call 0 more times." \
+ -s "Async resume (slot 1): sign done, status=0"
+
+# key1: ECDSA, key2: RSA; use key2 directly
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: fall back to transparent key" \
+ "$P_SRV \
+ async_operations=s async_private_delay1=1 \
+ key_file=data_files/server5.key crt_file=data_files/server5.crt \
+ key_file2=data_files/server2.key crt_file2=data_files/server2.crt " \
+ "$P_CLI force_ciphersuite=TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256" \
+ 0 \
+ -s "Async sign callback: no key matches this certificate."
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: sign, error in start" \
+ "$P_SRV \
+ async_operations=s async_private_delay1=1 async_private_delay2=1 \
+ async_private_error=1" \
+ "$P_CLI" \
+ 1 \
+ -s "Async sign callback: injected error" \
+ -S "Async resume" \
+ -S "Async cancel" \
+ -s "! mbedtls_ssl_handshake returned"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: sign, cancel after start" \
+ "$P_SRV \
+ async_operations=s async_private_delay1=1 async_private_delay2=1 \
+ async_private_error=2" \
+ "$P_CLI" \
+ 1 \
+ -s "Async sign callback: using key slot " \
+ -S "Async resume" \
+ -s "Async cancel"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: sign, error in resume" \
+ "$P_SRV \
+ async_operations=s async_private_delay1=1 async_private_delay2=1 \
+ async_private_error=3" \
+ "$P_CLI" \
+ 1 \
+ -s "Async sign callback: using key slot " \
+ -s "Async resume callback: sign done but injected error" \
+ -S "Async cancel" \
+ -s "! mbedtls_ssl_handshake returned"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: decrypt, error in start" \
+ "$P_SRV \
+ async_operations=d async_private_delay1=1 async_private_delay2=1 \
+ async_private_error=1" \
+ "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
+ 1 \
+ -s "Async decrypt callback: injected error" \
+ -S "Async resume" \
+ -S "Async cancel" \
+ -s "! mbedtls_ssl_handshake returned"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: decrypt, cancel after start" \
+ "$P_SRV \
+ async_operations=d async_private_delay1=1 async_private_delay2=1 \
+ async_private_error=2" \
+ "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
+ 1 \
+ -s "Async decrypt callback: using key slot " \
+ -S "Async resume" \
+ -s "Async cancel"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: decrypt, error in resume" \
+ "$P_SRV \
+ async_operations=d async_private_delay1=1 async_private_delay2=1 \
+ async_private_error=3" \
+ "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
+ 1 \
+ -s "Async decrypt callback: using key slot " \
+ -s "Async resume callback: decrypt done but injected error" \
+ -S "Async cancel" \
+ -s "! mbedtls_ssl_handshake returned"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: cancel after start then operate correctly" \
+ "$P_SRV \
+ async_operations=s async_private_delay1=1 async_private_delay2=1 \
+ async_private_error=-2" \
+ "$P_CLI; [ \$? -eq 1 ] && $P_CLI" \
+ 0 \
+ -s "Async cancel" \
+ -s "! mbedtls_ssl_handshake returned" \
+ -s "Async resume" \
+ -s "Successful connection"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: error in resume then operate correctly" \
+ "$P_SRV \
+ async_operations=s async_private_delay1=1 async_private_delay2=1 \
+ async_private_error=-3" \
+ "$P_CLI; [ \$? -eq 1 ] && $P_CLI" \
+ 0 \
+ -s "! mbedtls_ssl_handshake returned" \
+ -s "Async resume" \
+ -s "Successful connection"
+
+# key1: ECDSA, key2: RSA; use key1 through async, then key2 directly
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: cancel after start then fall back to transparent key" \
+ "$P_SRV \
+ async_operations=s async_private_delay1=1 async_private_error=-2 \
+ key_file=data_files/server5.key crt_file=data_files/server5.crt \
+ key_file2=data_files/server2.key crt_file2=data_files/server2.crt" \
+ "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256;
+ [ \$? -eq 1 ] &&
+ $P_CLI force_ciphersuite=TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256" \
+ 0 \
+ -s "Async sign callback: using key slot 0" \
+ -S "Async resume" \
+ -s "Async cancel" \
+ -s "! mbedtls_ssl_handshake returned" \
+ -s "Async sign callback: no key matches this certificate." \
+ -s "Successful connection"
+
+# key1: ECDSA, key2: RSA; use key1 through async, then key2 directly
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+run_test "SSL async private: sign, error in resume then fall back to transparent key" \
+ "$P_SRV \
+ async_operations=s async_private_delay1=1 async_private_error=-3 \
+ key_file=data_files/server5.key crt_file=data_files/server5.crt \
+ key_file2=data_files/server2.key crt_file2=data_files/server2.crt" \
+ "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256;
+ [ \$? -eq 1 ] &&
+ $P_CLI force_ciphersuite=TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256" \
+ 0 \
+ -s "Async resume" \
+ -s "! mbedtls_ssl_handshake returned" \
+ -s "Async sign callback: no key matches this certificate." \
+ -s "Successful connection"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+run_test "SSL async private: renegotiation: client-initiated; sign" \
+ "$P_SRV \
+ async_operations=s async_private_delay1=1 async_private_delay2=1 \
+ exchanges=2 renegotiation=1" \
+ "$P_CLI exchanges=2 renegotiation=1 renegotiate=1" \
+ 0 \
+ -s "Async sign callback: using key slot " \
+ -s "Async resume (slot [0-9]): sign done, status=0"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+run_test "SSL async private: renegotiation: server-initiated; sign" \
+ "$P_SRV \
+ async_operations=s async_private_delay1=1 async_private_delay2=1 \
+ exchanges=2 renegotiation=1 renegotiate=1" \
+ "$P_CLI exchanges=2 renegotiation=1" \
+ 0 \
+ -s "Async sign callback: using key slot " \
+ -s "Async resume (slot [0-9]): sign done, status=0"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+run_test "SSL async private: renegotiation: client-initiated; decrypt" \
+ "$P_SRV \
+ async_operations=d async_private_delay1=1 async_private_delay2=1 \
+ exchanges=2 renegotiation=1" \
+ "$P_CLI exchanges=2 renegotiation=1 renegotiate=1 \
+ force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
+ 0 \
+ -s "Async decrypt callback: using key slot " \
+ -s "Async resume (slot [0-9]): decrypt done, status=0"
+
+requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+run_test "SSL async private: renegotiation: server-initiated; decrypt" \
+ "$P_SRV \
+ async_operations=d async_private_delay1=1 async_private_delay2=1 \
+ exchanges=2 renegotiation=1 renegotiate=1" \
+ "$P_CLI exchanges=2 renegotiation=1 \
+ force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
+ 0 \
+ -s "Async decrypt callback: using key slot " \
+ -s "Async resume (slot [0-9]): decrypt done, status=0"
+
# Tests for DTLS HelloVerifyRequest
run_test "DTLS cookie: enabled" \
diff --git a/tests/suites/test_suite_aes.function b/tests/suites/test_suite_aes.function
index c5f0eaac97..e346dc7c32 100644
--- a/tests/suites/test_suite_aes.function
+++ b/tests/suites/test_suite_aes.function
@@ -151,6 +151,130 @@ exit:
}
/* END_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_XTS */
+void aes_encrypt_xts( char *hex_key_string, char *hex_data_unit_string,
+ char *hex_src_string, char *hex_dst_string )
+{
+ enum { AES_BLOCK_SIZE = 16 };
+ unsigned char *data_unit = NULL;
+ unsigned char *key = NULL;
+ unsigned char *src = NULL;
+ unsigned char *dst = NULL;
+ unsigned char *output = NULL;
+ mbedtls_aes_xts_context ctx;
+ size_t key_len, src_len, dst_len, data_unit_len;
+
+ mbedtls_aes_xts_init( &ctx );
+
+ data_unit = unhexify_alloc( hex_data_unit_string, &data_unit_len );
+ TEST_ASSERT( data_unit_len == AES_BLOCK_SIZE );
+
+ key = unhexify_alloc( hex_key_string, &key_len );
+ TEST_ASSERT( key_len % 2 == 0 );
+
+ src = unhexify_alloc( hex_src_string, &src_len );
+ dst = unhexify_alloc( hex_dst_string, &dst_len );
+ TEST_ASSERT( src_len == dst_len );
+
+ output = zero_alloc( dst_len );
+
+ TEST_ASSERT( mbedtls_aes_xts_setkey_enc( &ctx, key, key_len * 8 ) == 0 );
+ TEST_ASSERT( mbedtls_aes_crypt_xts( &ctx, MBEDTLS_AES_ENCRYPT, src_len,
+ data_unit, src, output ) == 0 );
+
+ TEST_ASSERT( memcmp( output, dst, dst_len ) == 0 );
+
+exit:
+ mbedtls_aes_xts_free( &ctx );
+ mbedtls_free( data_unit );
+ mbedtls_free( key );
+ mbedtls_free( src );
+ mbedtls_free( dst );
+ mbedtls_free( output );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_XTS */
+void aes_decrypt_xts( char *hex_key_string, char *hex_data_unit_string,
+ char *hex_dst_string, char *hex_src_string )
+{
+ enum { AES_BLOCK_SIZE = 16 };
+ unsigned char *data_unit = NULL;
+ unsigned char *key = NULL;
+ unsigned char *src = NULL;
+ unsigned char *dst = NULL;
+ unsigned char *output = NULL;
+ mbedtls_aes_xts_context ctx;
+ size_t key_len, src_len, dst_len, data_unit_len;
+
+ mbedtls_aes_xts_init( &ctx );
+
+ data_unit = unhexify_alloc( hex_data_unit_string, &data_unit_len );
+ TEST_ASSERT( data_unit_len == AES_BLOCK_SIZE );
+
+ key = unhexify_alloc( hex_key_string, &key_len );
+ TEST_ASSERT( key_len % 2 == 0 );
+
+ src = unhexify_alloc( hex_src_string, &src_len );
+ dst = unhexify_alloc( hex_dst_string, &dst_len );
+ TEST_ASSERT( src_len == dst_len );
+
+ output = zero_alloc( dst_len );
+
+ TEST_ASSERT( mbedtls_aes_xts_setkey_dec( &ctx, key, key_len * 8 ) == 0 );
+ TEST_ASSERT( mbedtls_aes_crypt_xts( &ctx, MBEDTLS_AES_DECRYPT, src_len,
+ data_unit, src, output ) == 0 );
+
+ TEST_ASSERT( memcmp( output, dst, dst_len ) == 0 );
+
+exit:
+ mbedtls_aes_xts_free( &ctx );
+ mbedtls_free( data_unit );
+ mbedtls_free( key );
+ mbedtls_free( src );
+ mbedtls_free( dst );
+ mbedtls_free( output );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_XTS */
+void aes_crypt_xts_size( int size, int retval )
+{
+ mbedtls_aes_xts_context ctx;
+ const unsigned char *src = NULL;
+ unsigned char *output = NULL;
+ unsigned char data_unit[16];
+ size_t length = size;
+
+ mbedtls_aes_xts_init( &ctx );
+ memset( data_unit, 0x00, sizeof( data_unit ) );
+
+
+ /* Note that this function will most likely crash on failure, as NULL
+ * parameters will be used. In the passing case, the length check in
+ * mbedtls_aes_crypt_xts() will prevent any accesses to parameters by
+ * exiting the function early. */
+ TEST_ASSERT( mbedtls_aes_crypt_xts( &ctx, MBEDTLS_AES_ENCRYPT, length, data_unit, src, output ) == retval );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_XTS */
+void aes_crypt_xts_keysize( int size, int retval )
+{
+ mbedtls_aes_xts_context ctx;
+ const unsigned char *key = NULL;
+ size_t key_len = size;
+
+ mbedtls_aes_xts_init( &ctx );
+
+ TEST_ASSERT( mbedtls_aes_xts_setkey_enc( &ctx, key, key_len * 8 ) == retval );
+ TEST_ASSERT( mbedtls_aes_xts_setkey_dec( &ctx, key, key_len * 8 ) == retval );
+exit:
+ mbedtls_aes_xts_free( &ctx );
+}
+/* END_CASE */
+
+
/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
void aes_encrypt_cfb128( char *hex_key_string, char *hex_iv_string,
char *hex_src_string, char *hex_dst_string )
@@ -289,6 +413,63 @@ exit:
}
/* END_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_OFB */
+void aes_encrypt_ofb( int fragment_size, char *hex_key_string,
+ char *hex_iv_string, char *hex_src_string,
+ char *hex_dst_string )
+{
+ unsigned char key_str[32];
+ unsigned char iv_str[16];
+ unsigned char src_str[64];
+ unsigned char dst_str[64];
+ unsigned char output[32];
+ mbedtls_aes_context ctx;
+ size_t iv_offset = 0;
+ int in_buffer_len;
+ unsigned char* src_str_next;
+ int key_len;
+
+ memset( key_str, 0x00, sizeof( key_str ) );
+ memset( iv_str, 0x00, sizeof( iv_str ) );
+ memset( src_str, 0x00, sizeof( src_str ) );
+ memset( dst_str, 0x00, sizeof( dst_str ) );
+ memset( output, 0x00, sizeof( output ) );
+ mbedtls_aes_init( &ctx );
+
+ TEST_ASSERT( strlen( hex_key_string ) <= ( 32 * 2 ) );
+ TEST_ASSERT( strlen( hex_iv_string ) <= ( 16 * 2 ) );
+ TEST_ASSERT( strlen( hex_src_string ) <= ( 64 * 2 ) );
+ TEST_ASSERT( strlen( hex_dst_string ) <= ( 64 * 2 ) );
+
+ key_len = unhexify( key_str, hex_key_string );
+ unhexify( iv_str, hex_iv_string );
+ in_buffer_len = unhexify( src_str, hex_src_string );
+
+ TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str, key_len * 8 ) == 0 );
+ src_str_next = src_str;
+
+ while( in_buffer_len > 0 )
+ {
+ TEST_ASSERT( mbedtls_aes_crypt_ofb( &ctx, fragment_size, &iv_offset,
+ iv_str, src_str_next, output ) == 0 );
+
+ hexify( dst_str, output, fragment_size );
+ TEST_ASSERT( strncmp( (char *) dst_str, hex_dst_string,
+ ( 2 * fragment_size ) ) == 0 );
+
+ in_buffer_len -= fragment_size;
+ hex_dst_string += ( fragment_size * 2 );
+ src_str_next += fragment_size;
+
+ if( in_buffer_len < fragment_size )
+ fragment_size = in_buffer_len;
+ }
+
+exit:
+ mbedtls_aes_free( &ctx );
+}
+/* END_CASE */
+
/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
void aes_selftest()
{
diff --git a/tests/suites/test_suite_aes.ofb.data b/tests/suites/test_suite_aes.ofb.data
new file mode 100644
index 0000000000..4b9d80e8d9
--- /dev/null
+++ b/tests/suites/test_suite_aes.ofb.data
@@ -0,0 +1,35 @@
+# NIST Special Publication 800-38A
+# Recommendation for Block Cipher Modes of Operation
+# Test Vectors - Appendix F, Section F.4
+OFB-AES128.Encrypt - Single block
+depends_on:MBEDTLS_CIPHER_MODE_OFB
+aes_encrypt_ofb:16:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090a0b0c0d0e0f":"6bc1bee22e409f96e93d7e117393172a":"3b3fd92eb72dad20333449f8e83cfb4a"
+
+OFB-AES128.Encrypt - Partial blocks - 7 bytes
+depends_on:MBEDTLS_CIPHER_MODE_OFB
+aes_encrypt_ofb:5:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090a0b0c0d0e0f":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"3b3fd92eb72dad20333449f8e83cfb4a7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e"
+
+OFB-AES128.Encrypt - Test NIST SP800-38A - F.4.1
+depends_on:MBEDTLS_CIPHER_MODE_OFB
+aes_encrypt_ofb:16:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090a0b0c0d0e0f":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"3b3fd92eb72dad20333449f8e83cfb4a7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e"
+
+OFB-AES128.Decrypt - Test NIST SP800-38A - F.4.2
+depends_on:MBEDTLS_CIPHER_MODE_OFB
+aes_encrypt_ofb:16:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090a0b0c0d0e0f":"3b3fd92eb72dad20333449f8e83cfb4a7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"
+
+OFB-AES192.Encrypt - Test NIST SP800-38A - F.4.3
+depends_on:MBEDTLS_CIPHER_MODE_OFB
+aes_encrypt_ofb:16:"8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b":"000102030405060708090a0b0c0d0e0f":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"cdc80d6fddf18cab34c25909c99a4174fcc28b8d4c63837c09e81700c11004018d9a9aeac0f6596f559c6d4daf59a5f26d9f200857ca6c3e9cac524bd9acc92a"
+
+OFB-AES192.Decrypt - Test NIST SP800-38A - F.4.4
+depends_on:MBEDTLS_CIPHER_MODE_OFB
+aes_encrypt_ofb:16:"8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b":"000102030405060708090a0b0c0d0e0f":"cdc80d6fddf18cab34c25909c99a4174fcc28b8d4c63837c09e81700c11004018d9a9aeac0f6596f559c6d4daf59a5f26d9f200857ca6c3e9cac524bd9acc92a":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"
+
+OFB-AES256.Encrypt - Test NIST SP800-38A - F.4.5
+depends_on:MBEDTLS_CIPHER_MODE_OFB
+aes_encrypt_ofb:16:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"000102030405060708090a0b0c0d0e0f":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"dc7e84bfda79164b7ecd8486985d38604febdc6740d20b3ac88f6ad82a4fb08d71ab47a086e86eedf39d1c5bba97c4080126141d67f37be8538f5a8be740e484"
+
+OFB-AES256.Decrypt - Test NIST SP800-38A - F.4.6
+depends_on:MBEDTLS_CIPHER_MODE_OFB
+aes_encrypt_ofb:16:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"000102030405060708090a0b0c0d0e0f":"dc7e84bfda79164b7ecd8486985d38604febdc6740d20b3ac88f6ad82a4fb08d71ab47a086e86eedf39d1c5bba97c4080126141d67f37be8538f5a8be740e484":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"
+
diff --git a/tests/suites/test_suite_aes.xts.data b/tests/suites/test_suite_aes.xts.data
new file mode 100644
index 0000000000..647819e0de
--- /dev/null
+++ b/tests/suites/test_suite_aes.xts.data
@@ -0,0 +1,158 @@
+#
+# Tests for expected errors (negative tests)
+#
+AES-128-XTS Encrypt Fail Sector Too Small (by 16 bytes)
+aes_crypt_xts_size:0:MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
+
+AES-128-XTS Encrypt Fail Sector Too Small (by 1 byte)
+aes_crypt_xts_size:15:MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
+
+AES-128-XTS Encrypt Fail Sector Too Large (by 1 byte)
+aes_crypt_xts_size:16777217:MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
+
+AES-128-XTS Encrypt Fail Sector Too Large (by 1 block)
+aes_crypt_xts_size:16777232:MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
+
+AES-0-XTS Setkey Fail Invalid Key Length
+aes_crypt_xts_keysize:0:MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
+
+AES-4-XTS Setkey Fail Invalid Key Length
+aes_crypt_xts_keysize:1:MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
+
+AES-64-XTS Setkey Fail Invalid Key Length
+aes_crypt_xts_keysize:16:MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
+
+AES-192-XTS Setkey Fail Invalid Key Length
+aes_crypt_xts_keysize:48:MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
+
+AES-384-XTS Setkey Fail Invalid Key Length
+aes_crypt_xts_keysize:96:MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
+
+#
+# IEEE P1619/D16 Annex B Test Vectors
+# http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
+#
+# 128-bit keys with 32 byte sector
+#
+AES-128-XTS Encrypt IEEE P1619/D16 Vector 1
+aes_encrypt_xts:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"0000000000000000000000000000000000000000000000000000000000000000":"917cf69ebd68b2ec9b9fe9a3eadda692cd43d2f59598ed858c02c2652fbf922e"
+
+AES-128-XTS Encrypt IEEE P1619/D16 Vector 2
+aes_encrypt_xts:"1111111111111111111111111111111122222222222222222222222222222222":"33333333330000000000000000000000":"4444444444444444444444444444444444444444444444444444444444444444":"c454185e6a16936e39334038acef838bfb186fff7480adc4289382ecd6d394f0"
+
+AES-128-XTS Encrypt IEEE P1619/D16 Vector 3
+aes_encrypt_xts:"fffefdfcfbfaf9f8f7f6f5f4f3f2f1f022222222222222222222222222222222":"33333333330000000000000000000000":"4444444444444444444444444444444444444444444444444444444444444444":"af85336b597afc1a900b2eb21ec949d292df4c047e0b21532186a5971a227a89"
+
+#
+# 128-bit keys with 512 byte sector
+#
+AES-128-XTS Encrypt IEEE P1619/D16 Vector 4
+aes_encrypt_xts:"2718281828459045235360287471352631415926535897932384626433832795":"00000000000000000000000000000000":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"27a7479befa1d476489f308cd4cfa6e2a96e4bbe3208ff25287dd3819616e89cc78cf7f5e543445f8333d8fa7f56000005279fa5d8b5e4ad40e736ddb4d35412328063fd2aab53e5ea1e0a9f332500a5df9487d07a5c92cc512c8866c7e860ce93fdf166a24912b422976146ae20ce846bb7dc9ba94a767aaef20c0d61ad02655ea92dc4c4e41a8952c651d33174be51a10c421110e6d81588ede82103a252d8a750e8768defffed9122810aaeb99f9172af82b604dc4b8e51bcb08235a6f4341332e4ca60482a4ba1a03b3e65008fc5da76b70bf1690db4eae29c5f1badd03c5ccf2a55d705ddcd86d449511ceb7ec30bf12b1fa35b913f9f747a8afd1b130e94bff94effd01a91735ca1726acd0b197c4e5b03393697e126826fb6bbde8ecc1e08298516e2c9ed03ff3c1b7860f6de76d4cecd94c8119855ef5297ca67e9f3e7ff72b1e99785ca0a7e7720c5b36dc6d72cac9574c8cbbc2f801e23e56fd344b07f22154beba0f08ce8891e643ed995c94d9a69c9f1b5f499027a78572aeebd74d20cc39881c213ee770b1010e4bea718846977ae119f7a023ab58cca0ad752afe656bb3c17256a9f6e9bf19fdd5a38fc82bbe872c5539edb609ef4f79c203ebb140f2e583cb2ad15b4aa5b655016a8449277dbd477ef2c8d6c017db738b18deb4a427d1923ce3ff262735779a418f20a282df920147beabe421ee5319d0568"
+
+AES-128-XTS Encrypt IEEE P1619/D16 Vector 5
+aes_encrypt_xts:"2718281828459045235360287471352631415926535897932384626433832795":"01000000000000000000000000000000":"27a7479befa1d476489f308cd4cfa6e2a96e4bbe3208ff25287dd3819616e89cc78cf7f5e543445f8333d8fa7f56000005279fa5d8b5e4ad40e736ddb4d35412328063fd2aab53e5ea1e0a9f332500a5df9487d07a5c92cc512c8866c7e860ce93fdf166a24912b422976146ae20ce846bb7dc9ba94a767aaef20c0d61ad02655ea92dc4c4e41a8952c651d33174be51a10c421110e6d81588ede82103a252d8a750e8768defffed9122810aaeb99f9172af82b604dc4b8e51bcb08235a6f4341332e4ca60482a4ba1a03b3e65008fc5da76b70bf1690db4eae29c5f1badd03c5ccf2a55d705ddcd86d449511ceb7ec30bf12b1fa35b913f9f747a8afd1b130e94bff94effd01a91735ca1726acd0b197c4e5b03393697e126826fb6bbde8ecc1e08298516e2c9ed03ff3c1b7860f6de76d4cecd94c8119855ef5297ca67e9f3e7ff72b1e99785ca0a7e7720c5b36dc6d72cac9574c8cbbc2f801e23e56fd344b07f22154beba0f08ce8891e643ed995c94d9a69c9f1b5f499027a78572aeebd74d20cc39881c213ee770b1010e4bea718846977ae119f7a023ab58cca0ad752afe656bb3c17256a9f6e9bf19fdd5a38fc82bbe872c5539edb609ef4f79c203ebb140f2e583cb2ad15b4aa5b655016a8449277dbd477ef2c8d6c017db738b18deb4a427d1923ce3ff262735779a418f20a282df920147beabe421ee5319d0568":"264d3ca8512194fec312c8c9891f279fefdd608d0c027b60483a3fa811d65ee59d52d9e40ec5672d81532b38b6b089ce951f0f9c35590b8b978d175213f329bb1c2fd30f2f7f30492a61a532a79f51d36f5e31a7c9a12c286082ff7d2394d18f783e1a8e72c722caaaa52d8f065657d2631fd25bfd8e5baad6e527d763517501c68c5edc3cdd55435c532d7125c8614deed9adaa3acade5888b87bef641c4c994c8091b5bcd387f3963fb5bc37aa922fbfe3df4e5b915e6eb514717bdd2a74079a5073f5c4bfd46adf7d282e7a393a52579d11a028da4d9cd9c77124f9648ee383b1ac763930e7162a8d37f350b2f74b8472cf09902063c6b32e8c2d9290cefbd7346d1c779a0df50edcde4531da07b099c638e83a755944df2aef1aa31752fd323dcb710fb4bfbb9d22b925bc3577e1b8949e729a90bbafeacf7f7879e7b1147e28ba0bae940db795a61b15ecf4df8db07b824bb062802cc98a9545bb2aaeed77cb3fc6db15dcd7d80d7d5bc406c4970a3478ada8899b329198eb61c193fb6275aa8ca340344a75a862aebe92eee1ce032fd950b47d7704a3876923b4ad62844bf4a09c4dbe8b4397184b7471360c9564880aedddb9baa4af2e75394b08cd32ff479c57a07d3eab5d54de5f9738b8d27f27a9f0ab11799d7b7ffefb2704c95c6ad12c39f1e867a4b7b1d7818a4b753dfd2a89ccb45e001a03a867b187f225dd"
+
+AES-128-XTS Encrypt IEEE P1619/D16 Vector 6
+aes_encrypt_xts:"2718281828459045235360287471352631415926535897932384626433832795":"02000000000000000000000000000000":"264d3ca8512194fec312c8c9891f279fefdd608d0c027b60483a3fa811d65ee59d52d9e40ec5672d81532b38b6b089ce951f0f9c35590b8b978d175213f329bb1c2fd30f2f7f30492a61a532a79f51d36f5e31a7c9a12c286082ff7d2394d18f783e1a8e72c722caaaa52d8f065657d2631fd25bfd8e5baad6e527d763517501c68c5edc3cdd55435c532d7125c8614deed9adaa3acade5888b87bef641c4c994c8091b5bcd387f3963fb5bc37aa922fbfe3df4e5b915e6eb514717bdd2a74079a5073f5c4bfd46adf7d282e7a393a52579d11a028da4d9cd9c77124f9648ee383b1ac763930e7162a8d37f350b2f74b8472cf09902063c6b32e8c2d9290cefbd7346d1c779a0df50edcde4531da07b099c638e83a755944df2aef1aa31752fd323dcb710fb4bfbb9d22b925bc3577e1b8949e729a90bbafeacf7f7879e7b1147e28ba0bae940db795a61b15ecf4df8db07b824bb062802cc98a9545bb2aaeed77cb3fc6db15dcd7d80d7d5bc406c4970a3478ada8899b329198eb61c193fb6275aa8ca340344a75a862aebe92eee1ce032fd950b47d7704a3876923b4ad62844bf4a09c4dbe8b4397184b7471360c9564880aedddb9baa4af2e75394b08cd32ff479c57a07d3eab5d54de5f9738b8d27f27a9f0ab11799d7b7ffefb2704c95c6ad12c39f1e867a4b7b1d7818a4b753dfd2a89ccb45e001a03a867b187f225dd":"fa762a3680b76007928ed4a4f49a9456031b704782e65e16cecb54ed7d017b5e18abd67b338e81078f21edb7868d901ebe9c731a7c18b5e6dec1d6a72e078ac9a4262f860beefa14f4e821018272e411a951502b6e79066e84252c3346f3aa62344351a291d4bedc7a07618bdea2af63145cc7a4b8d4070691ae890cd65733e7946e9021a1dffc4c59f159425ee6d50ca9b135fa6162cea18a939838dc000fb386fad086acce5ac07cb2ece7fd580b00cfa5e98589631dc25e8e2a3daf2ffdec26531659912c9d8f7a15e5865ea8fb5816d6207052bd7128cd743c12c8118791a4736811935eb982a532349e31dd401e0b660a568cb1a4711f552f55ded59f1f15bf7196b3ca12a91e488ef59d64f3a02bf45239499ac6176ae321c4a211ec545365971c5d3f4f09d4eb139bfdf2073d33180b21002b65cc9865e76cb24cd92c874c24c18350399a936ab3637079295d76c417776b94efce3a0ef7206b15110519655c956cbd8b2489405ee2b09a6b6eebe0c53790a12a8998378b33a5b71159625f4ba49d2a2fdba59fbf0897bc7aabd8d707dc140a80f0f309f835d3da54ab584e501dfa0ee977fec543f74186a802b9a37adb3e8291eca04d66520d229e60401e7282bef486ae059aa70696e0e305d777140a7a883ecdcb69b9ff938e8a4231864c69ca2c2043bed007ff3e605e014bcf518138dc3a25c5e236171a2d01d6"
+
+AES-128-XTS Encrypt IEEE P1619/D16 Vector 7
+aes_encrypt_xts:"2718281828459045235360287471352631415926535897932384626433832795":"fd000000000000000000000000000000":"8e41b78c390b5af9d758bb214a67e9f6bf7727b09ac6124084c37611398fa45daad94868600ed391fb1acd4857a95b466e62ef9f4b377244d1c152e7b30d731aad30c716d214b707aed99eb5b5e580b3e887cf7497465651d4b60e6042051da3693c3b78c14489543be8b6ad0ba629565bba202313ba7b0d0c94a3252b676f46cc02ce0f8a7d34c0ed229129673c1f61aed579d08a9203a25aac3a77e9db60267996db38df637356d9dcd1632e369939f2a29d89345c66e05066f1a3677aef18dea4113faeb629e46721a66d0a7e785d3e29af2594eb67dfa982affe0aac058f6e15864269b135418261fc3afb089472cf68c45dd7f231c6249ba0255e1e033833fc4d00a3fe02132d7bc3873614b8aee34273581ea0325c81f0270affa13641d052d36f0757d484014354d02d6883ca15c24d8c3956b1bd027bcf41f151fd8023c5340e5606f37e90fdb87c86fb4fa634b3718a30bace06a66eaf8f63c4aa3b637826a87fe8cfa44282e92cb1615af3a28e53bc74c7cba1a0977be9065d0c1a5dec6c54ae38d37f37aa35283e048e5530a85c4e7a29d7b92ec0c3169cdf2a805c7604bce60049b9fb7b8eaac10f51ae23794ceba68bb58112e293b9b692ca721b37c662f8574ed4dba6f88e170881c82cddc1034a0ca7e284bf0962b6b26292d836fa9f73c1ac770eef0f2d3a1eaf61d3e03555fd424eedd67e18a18094f888":"d55f684f81f4426e9fde92a5ff02df2ac896af63962888a97910c1379e20b0a3b1db613fb7fe2e07004329ea5c22bfd33e3dbe4cf58cc608c2c26c19a2e2fe22f98732c2b5cb844cc6c0702d91e1d50fc4382a7eba5635cd602432a2306ac4ce82f8d70c8d9bc15f918fe71e74c622d5cf71178bf6e0b9cc9f2b41dd8dbe441c41cd0c73a6dc47a348f6702f9d0e9b1b1431e948e299b9ec2272ab2c5f0c7be86affa5dec87a0bee81d3d50007edaa2bcfccb35605155ff36ed8edd4a40dcd4b243acd11b2b987bdbfaf91a7cac27e9c5aea525ee53de7b2d3332c8644402b823e94a7db26276d2d23aa07180f76b4fd29b9c0823099c9d62c519880aee7e9697617c1497d47bf3e571950311421b6b734d38b0db91eb85331b91ea9f61530f54512a5a52a4bad589eb69781d537f23297bb459bdad2948a29e1550bf4787e0be95bb173cf5fab17dab7a13a052a63453d97ccec1a321954886b7a1299faaeecae35c6eaaca753b041b5e5f093bf83397fd21dd6b3012066fcc058cc32c3b09d7562dee29509b5839392c9ff05f51f3166aaac4ac5f238038a3045e6f72e48ef0fe8bc675e82c318a268e43970271bf119b81bf6a982746554f84e72b9f00280a320a08142923c23c883423ff949827f29bbacdc1ccdb04938ce6098c95ba6b32528f4ef78eed778b2e122ddfd1cbdd11d1c0a6783e011fc536d63d053260637"
+
+AES-128-XTS Encrypt IEEE P1619/D16 Vector 8
+aes_encrypt_xts:"2718281828459045235360287471352631415926535897932384626433832795":"fe000000000000000000000000000000":"d55f684f81f4426e9fde92a5ff02df2ac896af63962888a97910c1379e20b0a3b1db613fb7fe2e07004329ea5c22bfd33e3dbe4cf58cc608c2c26c19a2e2fe22f98732c2b5cb844cc6c0702d91e1d50fc4382a7eba5635cd602432a2306ac4ce82f8d70c8d9bc15f918fe71e74c622d5cf71178bf6e0b9cc9f2b41dd8dbe441c41cd0c73a6dc47a348f6702f9d0e9b1b1431e948e299b9ec2272ab2c5f0c7be86affa5dec87a0bee81d3d50007edaa2bcfccb35605155ff36ed8edd4a40dcd4b243acd11b2b987bdbfaf91a7cac27e9c5aea525ee53de7b2d3332c8644402b823e94a7db26276d2d23aa07180f76b4fd29b9c0823099c9d62c519880aee7e9697617c1497d47bf3e571950311421b6b734d38b0db91eb85331b91ea9f61530f54512a5a52a4bad589eb69781d537f23297bb459bdad2948a29e1550bf4787e0be95bb173cf5fab17dab7a13a052a63453d97ccec1a321954886b7a1299faaeecae35c6eaaca753b041b5e5f093bf83397fd21dd6b3012066fcc058cc32c3b09d7562dee29509b5839392c9ff05f51f3166aaac4ac5f238038a3045e6f72e48ef0fe8bc675e82c318a268e43970271bf119b81bf6a982746554f84e72b9f00280a320a08142923c23c883423ff949827f29bbacdc1ccdb04938ce6098c95ba6b32528f4ef78eed778b2e122ddfd1cbdd11d1c0a6783e011fc536d63d053260637":"72efc1ebfe1ee25975a6eb3aa8589dda2b261f1c85bdab442a9e5b2dd1d7c3957a16fc08e526d4b1223f1b1232a11af274c3d70dac57f83e0983c498f1a6f1aecb021c3e70085a1e527f1ce41ee5911a82020161529cd82773762daf5459de94a0a82adae7e1703c808543c29ed6fb32d9e004327c1355180c995a07741493a09c21ba01a387882da4f62534b87bb15d60d197201c0fd3bf30c1500a3ecfecdd66d8721f90bcc4c17ee925c61b0a03727a9c0d5f5ca462fbfa0af1c2513a9d9d4b5345bd27a5f6e653f751693e6b6a2b8ead57d511e00e58c45b7b8d005af79288f5c7c22fd4f1bf7a898b03a5634c6a1ae3f9fae5de4f296a2896b23e7ed43ed14fa5a2803f4d28f0d3ffcf24757677aebdb47bb388378708948a8d4126ed1839e0da29a537a8c198b3c66ab00712dd261674bf45a73d67f76914f830ca014b65596f27e4cf62de66125a5566df9975155628b400fbfb3a29040ed50faffdbb18aece7c5c44693260aab386c0a37b11b114f1c415aebb653be468179428d43a4d8bc3ec38813eca30a13cf1bb18d524f1992d44d8b1a42ea30b22e6c95b199d8d182f8840b09d059585c31ad691fa0619ff038aca2c39a943421157361717c49d322028a74648113bd8c9d7ec77cf3c89c1ec8718ceff8516d96b34c3c614f10699c9abc4ed0411506223bea16af35c883accdbe1104eef0cfdb54e12fb230a"
+
+AES-128-XTS Encrypt IEEE P1619/D16 Vector 9
+aes_encrypt_xts:"2718281828459045235360287471352631415926535897932384626433832795":"ff000000000000000000000000000000":"72efc1ebfe1ee25975a6eb3aa8589dda2b261f1c85bdab442a9e5b2dd1d7c3957a16fc08e526d4b1223f1b1232a11af274c3d70dac57f83e0983c498f1a6f1aecb021c3e70085a1e527f1ce41ee5911a82020161529cd82773762daf5459de94a0a82adae7e1703c808543c29ed6fb32d9e004327c1355180c995a07741493a09c21ba01a387882da4f62534b87bb15d60d197201c0fd3bf30c1500a3ecfecdd66d8721f90bcc4c17ee925c61b0a03727a9c0d5f5ca462fbfa0af1c2513a9d9d4b5345bd27a5f6e653f751693e6b6a2b8ead57d511e00e58c45b7b8d005af79288f5c7c22fd4f1bf7a898b03a5634c6a1ae3f9fae5de4f296a2896b23e7ed43ed14fa5a2803f4d28f0d3ffcf24757677aebdb47bb388378708948a8d4126ed1839e0da29a537a8c198b3c66ab00712dd261674bf45a73d67f76914f830ca014b65596f27e4cf62de66125a5566df9975155628b400fbfb3a29040ed50faffdbb18aece7c5c44693260aab386c0a37b11b114f1c415aebb653be468179428d43a4d8bc3ec38813eca30a13cf1bb18d524f1992d44d8b1a42ea30b22e6c95b199d8d182f8840b09d059585c31ad691fa0619ff038aca2c39a943421157361717c49d322028a74648113bd8c9d7ec77cf3c89c1ec8718ceff8516d96b34c3c614f10699c9abc4ed0411506223bea16af35c883accdbe1104eef0cfdb54e12fb230a":"3260ae8dad1f4a32c5cafe3ab0eb95549d461a67ceb9e5aa2d3afb62dece0553193ba50c75be251e08d1d08f1088576c7efdfaaf3f459559571e12511753b07af073f35da06af0ce0bbf6b8f5ccc5cea500ec1b211bd51f63b606bf6528796ca12173ba39b8935ee44ccce646f90a45bf9ccc567f0ace13dc2d53ebeedc81f58b2e41179dddf0d5a5c42f5d8506c1a5d2f8f59f3ea873cbcd0eec19acbf325423bd3dcb8c2b1bf1d1eaed0eba7f0698e4314fbeb2f1566d1b9253008cbccf45a2b0d9c5c9c21474f4076e02be26050b99dee4fd68a4cf890e496e4fcae7b70f94ea5a9062da0daeba1993d2ccd1dd3c244b8428801495a58b216547e7e847c46d1d756377b6242d2e5fb83bf752b54e0df71e889f3a2bb0f4c10805bf3c590376e3c24e22ff57f7fa965577375325cea5d920db94b9c336b455f6e894c01866fe9fbb8c8d3f70a2957285f6dfb5dcd8cbf54782f8fe7766d4723819913ac773421e3a31095866bad22c86a6036b2518b2059b4229d18c8c2ccbdf906c6cc6e82464ee57bddb0bebcb1dc645325bfb3e665ef7251082c88ebb1cf203bd779fdd38675713c8daadd17e1cabee432b09787b6ddf3304e38b731b45df5df51b78fcfb3d32466028d0ba36555e7e11ab0ee0666061d1645d962444bc47a38188930a84b4d561395c73c087021927ca638b7afc8a8679ccb84c26555440ec7f10445cd"
+
+#
+# 256-bit keys with 512 byte sector
+#
+AES-256-XTS Encrypt IEEE P1619/D16 Vector 10
+aes_encrypt_xts:"27182818284590452353602874713526624977572470936999595749669676273141592653589793238462643383279502884197169399375105820974944592":"ff000000000000000000000000000000":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"1c3b3a102f770386e4836c99e370cf9bea00803f5e482357a4ae12d414a3e63b5d31e276f8fe4a8d66b317f9ac683f44680a86ac35adfc3345befecb4bb188fd5776926c49a3095eb108fd1098baec70aaa66999a72a82f27d848b21d4a741b0c5cd4d5fff9dac89aeba122961d03a757123e9870f8acf1000020887891429ca2a3e7a7d7df7b10355165c8b9a6d0a7de8b062c4500dc4cd120c0f7418dae3d0b5781c34803fa75421c790dfe1de1834f280d7667b327f6c8cd7557e12ac3a0f93ec05c52e0493ef31a12d3d9260f79a289d6a379bc70c50841473d1a8cc81ec583e9645e07b8d9670655ba5bbcfecc6dc3966380ad8fecb17b6ba02469a020a84e18e8f84252070c13e9f1f289be54fbc481457778f616015e1327a02b140f1505eb309326d68378f8374595c849d84f4c333ec4423885143cb47bd71c5edae9be69a2ffeceb1bec9de244fbe15992b11b77c040f12bd8f6a975a44a0f90c29a9abc3d4d893927284c58754cce294529f8614dcd2aba991925fedc4ae74ffac6e333b93eb4aff0479da9a410e4450e0dd7ae4c6e2910900575da401fc07059f645e8b7e9bfdef33943054ff84011493c27b3429eaedb4ed5376441a77ed43851ad77f16f541dfd269d50d6a5f14fb0aab1cbb4c1550be97f7ab4066193c4caa773dad38014bd2092fa755c824bb5e54c4f36ffda9fcea70b9c6e693e148c151"
+
+AES-256-XTS Encrypt IEEE P1619/D16 Vector 11
+aes_encrypt_xts:"27182818284590452353602874713526624977572470936999595749669676273141592653589793238462643383279502884197169399375105820974944592":"ffff0000000000000000000000000000":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"77a31251618a15e6b92d1d66dffe7b50b50bad552305ba0217a610688eff7e11e1d0225438e093242d6db274fde801d4cae06f2092c728b2478559df58e837c2469ee4a4fa794e4bbc7f39bc026e3cb72c33b0888f25b4acf56a2a9804f1ce6d3d6e1dc6ca181d4b546179d55544aa7760c40d06741539c7e3cd9d2f6650b2013fd0eeb8c2b8e3d8d240ccae2d4c98320a7442e1c8d75a42d6e6cfa4c2eca1798d158c7aecdf82490f24bb9b38e108bcda12c3faf9a21141c3613b58367f922aaa26cd22f23d708dae699ad7cb40a8ad0b6e2784973dcb605684c08b8d6998c69aac049921871ebb65301a4619ca80ecb485a31d744223ce8ddc2394828d6a80470c092f5ba413c3378fa6054255c6f9df4495862bbb3287681f931b687c888abf844dfc8fc28331e579928cd12bd2390ae123cf03818d14dedde5c0c24c8ab018bfca75ca096f2d531f3d1619e785f1ada437cab92e980558b3dce1474afb75bfedbf8ff54cb2618e0244c9ac0d3c66fb51598cd2db11f9be39791abe447c63094f7c453b7ff87cb5bb36b7c79efb0872d17058b83b15ab0866ad8a58656c5a7e20dbdf308b2461d97c0ec0024a2715055249cf3b478ddd4740de654f75ca686e0d7345c69ed50cdc2a8b332b1f8824108ac937eb050585608ee734097fc09054fbff89eeaeea791f4a7ab1f9868294a4f9e27b42af8100cb9d59cef9645803"
+
+AES-256-XTS Encrypt IEEE P1619/D16 Vector 12
+aes_encrypt_xts:"27182818284590452353602874713526624977572470936999595749669676273141592653589793238462643383279502884197169399375105820974944592":"ffffff00000000000000000000000000":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"e387aaa58ba483afa7e8eb469778317ecf4cf573aa9d4eac23f2cdf914e4e200a8b490e42ee646802dc6ee2b471b278195d60918ececb44bf79966f83faba0499298ebc699c0c8634715a320bb4f075d622e74c8c932004f25b41e361025b5a87815391f6108fc4afa6a05d9303c6ba68a128a55705d415985832fdeaae6c8e19110e84d1b1f199a2692119edc96132658f09da7c623efcec712537a3d94c0bf5d7e352ec94ae5797fdb377dc1551150721adf15bd26a8efc2fcaad56881fa9e62462c28f30ae1ceaca93c345cf243b73f542e2074a705bd2643bb9f7cc79bb6e7091ea6e232df0f9ad0d6cf502327876d82207abf2115cdacf6d5a48f6c1879a65b115f0f8b3cb3c59d15dd8c769bc014795a1837f3901b5845eb491adfefe097b1fa30a12fc1f65ba22905031539971a10f2f36c321bb51331cdefb39e3964c7ef079994f5b69b2edd83a71ef549971ee93f44eac3938fcdd61d01fa71799da3a8091c4c48aa9ed263ff0749df95d44fef6a0bb578ec69456aa5408ae32c7af08ad7ba8921287e3bbee31b767be06a0e705c864a769137df28292283ea81a2480241b44d9921cdbec1bc28dc1fda114bd8e5217ac9d8ebafa720e9da4f9ace231cc949e5b96fe76ffc21063fddc83a6b8679c00d35e09576a875305bed5f36ed242c8900dd1fa965bc950dfce09b132263a1eef52dd6888c309f5a7d712826"
+
+AES-256-XTS Encrypt IEEE P1619/D16 Vector 13
+aes_encrypt_xts:"27182818284590452353602874713526624977572470936999595749669676273141592653589793238462643383279502884197169399375105820974944592":"ffffffff000000000000000000000000":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"bf53d2dade78e822a4d949a9bc6766b01b06a8ef70d26748c6a7fc36d80ae4c5520f7c4ab0ac8544424fa405162fef5a6b7f229498063618d39f0003cb5fb8d1c86b643497da1ff945c8d3bedeca4f479702a7a735f043ddb1d6aaade3c4a0ac7ca7f3fa5279bef56f82cd7a2f38672e824814e10700300a055e1630b8f1cb0e919f5e942010a416e2bf48cb46993d3cb6a51c19bacf864785a00bc2ecff15d350875b246ed53e68be6f55bd7e05cfc2b2ed6432198a6444b6d8c247fab941f569768b5c429366f1d3f00f0345b96123d56204c01c63b22ce78baf116e525ed90fdea39fa469494d3866c31e05f295ff21fea8d4e6e13d67e47ce722e9698a1c1048d68ebcde76b86fcf976eab8aa9790268b7068e017a8b9b749409514f1053027fd16c3786ea1bac5f15cb79711ee2abe82f5cf8b13ae73030ef5b9e4457e75d1304f988d62dd6fc4b94ed38ba831da4b7634971b6cd8ec325d9c61c00f1df73627ed3745a5e8489f3a95c69639c32cd6e1d537a85f75cc844726e8a72fc0077ad22000f1d5078f6b866318c668f1ad03d5a5fced5219f2eabbd0aa5c0f460d183f04404a0d6f469558e81fab24a167905ab4c7878502ad3e38fdbe62a41556cec37325759533ce8f25f367c87bb5578d667ae93f9e2fd99bcbc5f2fbba88cf6516139420fcff3b7361d86322c4bd84c82f335abb152c4a93411373aaa8220"
+
+AES-256-XTS Encrypt IEEE P1619/D16 Vector 14
+aes_encrypt_xts:"27182818284590452353602874713526624977572470936999595749669676273141592653589793238462643383279502884197169399375105820974944592":"ffffffffff0000000000000000000000":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"64497e5a831e4a932c09be3e5393376daa599548b816031d224bbf50a818ed2350eae7e96087c8a0db51ad290bd00c1ac1620857635bf246c176ab463be30b808da548081ac847b158e1264be25bb0910bbc92647108089415d45fab1b3d2604e8a8eff1ae4020cfa39936b66827b23f371b92200be90251e6d73c5f86de5fd4a950781933d79a28272b782a2ec313efdfcc0628f43d744c2dc2ff3dcb66999b50c7ca895b0c64791eeaa5f29499fb1c026f84ce5b5c72ba1083cddb5ce45434631665c333b60b11593fb253c5179a2c8db813782a004856a1653011e93fb6d876c18366dd8683f53412c0c180f9c848592d593f8609ca736317d356e13e2bff3a9f59cd9aeb19cd482593d8c46128bb32423b37a9adfb482b99453fbe25a41bf6feb4aa0bef5ed24bf73c762978025482c13115e4015aac992e5613a3b5c2f685b84795cb6e9b2656d8c88157e52c42f978d8634c43d06fea928f2822e465aa6576e9bf419384506cc3ce3c54ac1a6f67dc66f3b30191e698380bc999b05abce19dc0c6dcc2dd001ec535ba18deb2df1a101023108318c75dc98611a09dc48a0acdec676fabdf222f07e026f059b672b56e5cbc8e1d21bbd867dd927212054681d70ea737134cdfce93b6f82ae22423274e58a0821cc5502e2d0ab4585e94de6975be5e0b4efce51cd3e70c25a1fbbbd609d273ad5b0d59631c531f6a0a57b9"
+
+#
+# 128-bit keys with sector size not evenly divisible by 16 bytes
+#
+AES-128-XTS Encrypt IEEE P1619/D16 Vector 15
+aes_encrypt_xts:"fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0":"9a785634120000000000000000000000":"000102030405060708090a0b0c0d0e0f10":"6c1625db4671522d3d7599601de7ca09ed"
+
+AES-128-XTS Encrypt IEEE P1619/D16 Vector 16
+aes_encrypt_xts:"fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0":"9a785634120000000000000000000000":"000102030405060708090a0b0c0d0e0f1011":"d069444b7a7e0cab09e24447d24deb1fedbf"
+
+AES-128-XTS Encrypt IEEE P1619/D16 Vector 17
+aes_encrypt_xts:"fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0":"9a785634120000000000000000000000":"000102030405060708090a0b0c0d0e0f101112":"e5df1351c0544ba1350b3363cd8ef4beedbf9d"
+
+AES-128-XTS Encrypt IEEE P1619/D16 Vector 18
+aes_encrypt_xts:"fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0":"9a785634120000000000000000000000":"000102030405060708090a0b0c0d0e0f10111213":"9d84c813f719aa2c7be3f66171c7c5c2edbf9dac"
+
+AES-128-XTS Encrypt IEEE P1619/D16 Vector 19
+aes_encrypt_xts:"e0e1e2e3e4e5e6e7e8e9eaebecedeeefc0c1c2c3c4c5c6c7c8c9cacbcccdcecf":"21436587a90000000000000000000000":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"38b45812ef43a05bd957e545907e223b954ab4aaf088303ad910eadf14b42be68b2461149d8c8ba85f992be970bc621f1b06573f63e867bf5875acafa04e42ccbd7bd3c2a0fb1fff791ec5ec36c66ae4ac1e806d81fbf709dbe29e471fad38549c8e66f5345d7c1eb94f405d1ec785cc6f6a68f6254dd8339f9d84057e01a17741990482999516b5611a38f41bb6478e6f173f320805dd71b1932fc333cb9ee39936beea9ad96fa10fb4112b901734ddad40bc1878995f8e11aee7d141a2f5d48b7a4e1e7f0b2c04830e69a4fd1378411c2f287edf48c6c4e5c247a19680f7fe41cefbd49b582106e3616cbbe4dfb2344b2ae9519391f3e0fb4922254b1d6d2d19c6d4d537b3a26f3bcc51588b32f3eca0829b6a5ac72578fb814fb43cf80d64a233e3f997a3f02683342f2b33d25b492536b93becb2f5e1a8b82f5b883342729e8ae09d16938841a21a97fb543eea3bbff59f13c1a18449e398701c1ad51648346cbc04c27bb2da3b93a1372ccae548fb53bee476f9e9c91773b1bb19828394d55d3e1a20ed69113a860b6829ffa847224604435070221b257e8dff783615d2cae4803a93aa4334ab482a0afac9c0aeda70b45a481df5dec5df8cc0f423c77a5fd46cd312021d4b438862419a791be03bb4d97c0e59578542531ba466a83baf92cefc151b5cc1611a167893819b63fb8a6b18e86de60290fa72b797b0ce59f3"
+
+AES-128-XTS Decrypt IEEE P1619/D16 Vector 1
+aes_decrypt_xts:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"0000000000000000000000000000000000000000000000000000000000000000":"917cf69ebd68b2ec9b9fe9a3eadda692cd43d2f59598ed858c02c2652fbf922e"
+
+AES-128-XTS Decrypt IEEE P1619/D16 Vector 2
+aes_decrypt_xts:"1111111111111111111111111111111122222222222222222222222222222222":"33333333330000000000000000000000":"4444444444444444444444444444444444444444444444444444444444444444":"c454185e6a16936e39334038acef838bfb186fff7480adc4289382ecd6d394f0"
+
+AES-128-XTS Decrypt IEEE P1619/D16 Vector 3
+aes_decrypt_xts:"2718281828459045235360287471352631415926535897932384626433832795":"00000000000000000000000000000000":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"27a7479befa1d476489f308cd4cfa6e2a96e4bbe3208ff25287dd3819616e89cc78cf7f5e543445f8333d8fa7f56000005279fa5d8b5e4ad40e736ddb4d35412328063fd2aab53e5ea1e0a9f332500a5df9487d07a5c92cc512c8866c7e860ce93fdf166a24912b422976146ae20ce846bb7dc9ba94a767aaef20c0d61ad02655ea92dc4c4e41a8952c651d33174be51a10c421110e6d81588ede82103a252d8a750e8768defffed9122810aaeb99f9172af82b604dc4b8e51bcb08235a6f4341332e4ca60482a4ba1a03b3e65008fc5da76b70bf1690db4eae29c5f1badd03c5ccf2a55d705ddcd86d449511ceb7ec30bf12b1fa35b913f9f747a8afd1b130e94bff94effd01a91735ca1726acd0b197c4e5b03393697e126826fb6bbde8ecc1e08298516e2c9ed03ff3c1b7860f6de76d4cecd94c8119855ef5297ca67e9f3e7ff72b1e99785ca0a7e7720c5b36dc6d72cac9574c8cbbc2f801e23e56fd344b07f22154beba0f08ce8891e643ed995c94d9a69c9f1b5f499027a78572aeebd74d20cc39881c213ee770b1010e4bea718846977ae119f7a023ab58cca0ad752afe656bb3c17256a9f6e9bf19fdd5a38fc82bbe872c5539edb609ef4f79c203ebb140f2e583cb2ad15b4aa5b655016a8449277dbd477ef2c8d6c017db738b18deb4a427d1923ce3ff262735779a418f20a282df920147beabe421ee5319d0568"
+
+AES-128-XTS Decrypt IEEE P1619/D16 Vector 4
+aes_decrypt_xts:"2718281828459045235360287471352631415926535897932384626433832795":"00000000000000000000000000000000":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"27a7479befa1d476489f308cd4cfa6e2a96e4bbe3208ff25287dd3819616e89cc78cf7f5e543445f8333d8fa7f56000005279fa5d8b5e4ad40e736ddb4d35412328063fd2aab53e5ea1e0a9f332500a5df9487d07a5c92cc512c8866c7e860ce93fdf166a24912b422976146ae20ce846bb7dc9ba94a767aaef20c0d61ad02655ea92dc4c4e41a8952c651d33174be51a10c421110e6d81588ede82103a252d8a750e8768defffed9122810aaeb99f9172af82b604dc4b8e51bcb08235a6f4341332e4ca60482a4ba1a03b3e65008fc5da76b70bf1690db4eae29c5f1badd03c5ccf2a55d705ddcd86d449511ceb7ec30bf12b1fa35b913f9f747a8afd1b130e94bff94effd01a91735ca1726acd0b197c4e5b03393697e126826fb6bbde8ecc1e08298516e2c9ed03ff3c1b7860f6de76d4cecd94c8119855ef5297ca67e9f3e7ff72b1e99785ca0a7e7720c5b36dc6d72cac9574c8cbbc2f801e23e56fd344b07f22154beba0f08ce8891e643ed995c94d9a69c9f1b5f499027a78572aeebd74d20cc39881c213ee770b1010e4bea718846977ae119f7a023ab58cca0ad752afe656bb3c17256a9f6e9bf19fdd5a38fc82bbe872c5539edb609ef4f79c203ebb140f2e583cb2ad15b4aa5b655016a8449277dbd477ef2c8d6c017db738b18deb4a427d1923ce3ff262735779a418f20a282df920147beabe421ee5319d0568"
+
+AES-128-XTS Decrypt IEEE P1619/D16 Vector 5
+aes_decrypt_xts:"2718281828459045235360287471352631415926535897932384626433832795":"01000000000000000000000000000000":"27a7479befa1d476489f308cd4cfa6e2a96e4bbe3208ff25287dd3819616e89cc78cf7f5e543445f8333d8fa7f56000005279fa5d8b5e4ad40e736ddb4d35412328063fd2aab53e5ea1e0a9f332500a5df9487d07a5c92cc512c8866c7e860ce93fdf166a24912b422976146ae20ce846bb7dc9ba94a767aaef20c0d61ad02655ea92dc4c4e41a8952c651d33174be51a10c421110e6d81588ede82103a252d8a750e8768defffed9122810aaeb99f9172af82b604dc4b8e51bcb08235a6f4341332e4ca60482a4ba1a03b3e65008fc5da76b70bf1690db4eae29c5f1badd03c5ccf2a55d705ddcd86d449511ceb7ec30bf12b1fa35b913f9f747a8afd1b130e94bff94effd01a91735ca1726acd0b197c4e5b03393697e126826fb6bbde8ecc1e08298516e2c9ed03ff3c1b7860f6de76d4cecd94c8119855ef5297ca67e9f3e7ff72b1e99785ca0a7e7720c5b36dc6d72cac9574c8cbbc2f801e23e56fd344b07f22154beba0f08ce8891e643ed995c94d9a69c9f1b5f499027a78572aeebd74d20cc39881c213ee770b1010e4bea718846977ae119f7a023ab58cca0ad752afe656bb3c17256a9f6e9bf19fdd5a38fc82bbe872c5539edb609ef4f79c203ebb140f2e583cb2ad15b4aa5b655016a8449277dbd477ef2c8d6c017db738b18deb4a427d1923ce3ff262735779a418f20a282df920147beabe421ee5319d0568":"264d3ca8512194fec312c8c9891f279fefdd608d0c027b60483a3fa811d65ee59d52d9e40ec5672d81532b38b6b089ce951f0f9c35590b8b978d175213f329bb1c2fd30f2f7f30492a61a532a79f51d36f5e31a7c9a12c286082ff7d2394d18f783e1a8e72c722caaaa52d8f065657d2631fd25bfd8e5baad6e527d763517501c68c5edc3cdd55435c532d7125c8614deed9adaa3acade5888b87bef641c4c994c8091b5bcd387f3963fb5bc37aa922fbfe3df4e5b915e6eb514717bdd2a74079a5073f5c4bfd46adf7d282e7a393a52579d11a028da4d9cd9c77124f9648ee383b1ac763930e7162a8d37f350b2f74b8472cf09902063c6b32e8c2d9290cefbd7346d1c779a0df50edcde4531da07b099c638e83a755944df2aef1aa31752fd323dcb710fb4bfbb9d22b925bc3577e1b8949e729a90bbafeacf7f7879e7b1147e28ba0bae940db795a61b15ecf4df8db07b824bb062802cc98a9545bb2aaeed77cb3fc6db15dcd7d80d7d5bc406c4970a3478ada8899b329198eb61c193fb6275aa8ca340344a75a862aebe92eee1ce032fd950b47d7704a3876923b4ad62844bf4a09c4dbe8b4397184b7471360c9564880aedddb9baa4af2e75394b08cd32ff479c57a07d3eab5d54de5f9738b8d27f27a9f0ab11799d7b7ffefb2704c95c6ad12c39f1e867a4b7b1d7818a4b753dfd2a89ccb45e001a03a867b187f225dd"
+
+AES-128-XTS Decrypt IEEE P1619/D16 Vector 6
+aes_decrypt_xts:"2718281828459045235360287471352631415926535897932384626433832795":"02000000000000000000000000000000":"264d3ca8512194fec312c8c9891f279fefdd608d0c027b60483a3fa811d65ee59d52d9e40ec5672d81532b38b6b089ce951f0f9c35590b8b978d175213f329bb1c2fd30f2f7f30492a61a532a79f51d36f5e31a7c9a12c286082ff7d2394d18f783e1a8e72c722caaaa52d8f065657d2631fd25bfd8e5baad6e527d763517501c68c5edc3cdd55435c532d7125c8614deed9adaa3acade5888b87bef641c4c994c8091b5bcd387f3963fb5bc37aa922fbfe3df4e5b915e6eb514717bdd2a74079a5073f5c4bfd46adf7d282e7a393a52579d11a028da4d9cd9c77124f9648ee383b1ac763930e7162a8d37f350b2f74b8472cf09902063c6b32e8c2d9290cefbd7346d1c779a0df50edcde4531da07b099c638e83a755944df2aef1aa31752fd323dcb710fb4bfbb9d22b925bc3577e1b8949e729a90bbafeacf7f7879e7b1147e28ba0bae940db795a61b15ecf4df8db07b824bb062802cc98a9545bb2aaeed77cb3fc6db15dcd7d80d7d5bc406c4970a3478ada8899b329198eb61c193fb6275aa8ca340344a75a862aebe92eee1ce032fd950b47d7704a3876923b4ad62844bf4a09c4dbe8b4397184b7471360c9564880aedddb9baa4af2e75394b08cd32ff479c57a07d3eab5d54de5f9738b8d27f27a9f0ab11799d7b7ffefb2704c95c6ad12c39f1e867a4b7b1d7818a4b753dfd2a89ccb45e001a03a867b187f225dd":"fa762a3680b76007928ed4a4f49a9456031b704782e65e16cecb54ed7d017b5e18abd67b338e81078f21edb7868d901ebe9c731a7c18b5e6dec1d6a72e078ac9a4262f860beefa14f4e821018272e411a951502b6e79066e84252c3346f3aa62344351a291d4bedc7a07618bdea2af63145cc7a4b8d4070691ae890cd65733e7946e9021a1dffc4c59f159425ee6d50ca9b135fa6162cea18a939838dc000fb386fad086acce5ac07cb2ece7fd580b00cfa5e98589631dc25e8e2a3daf2ffdec26531659912c9d8f7a15e5865ea8fb5816d6207052bd7128cd743c12c8118791a4736811935eb982a532349e31dd401e0b660a568cb1a4711f552f55ded59f1f15bf7196b3ca12a91e488ef59d64f3a02bf45239499ac6176ae321c4a211ec545365971c5d3f4f09d4eb139bfdf2073d33180b21002b65cc9865e76cb24cd92c874c24c18350399a936ab3637079295d76c417776b94efce3a0ef7206b15110519655c956cbd8b2489405ee2b09a6b6eebe0c53790a12a8998378b33a5b71159625f4ba49d2a2fdba59fbf0897bc7aabd8d707dc140a80f0f309f835d3da54ab584e501dfa0ee977fec543f74186a802b9a37adb3e8291eca04d66520d229e60401e7282bef486ae059aa70696e0e305d777140a7a883ecdcb69b9ff938e8a4231864c69ca2c2043bed007ff3e605e014bcf518138dc3a25c5e236171a2d01d6"
+
+AES-128-XTS Decrypt IEEE P1619/D16 Vector 7
+aes_decrypt_xts:"2718281828459045235360287471352631415926535897932384626433832795":"fd000000000000000000000000000000":"8e41b78c390b5af9d758bb214a67e9f6bf7727b09ac6124084c37611398fa45daad94868600ed391fb1acd4857a95b466e62ef9f4b377244d1c152e7b30d731aad30c716d214b707aed99eb5b5e580b3e887cf7497465651d4b60e6042051da3693c3b78c14489543be8b6ad0ba629565bba202313ba7b0d0c94a3252b676f46cc02ce0f8a7d34c0ed229129673c1f61aed579d08a9203a25aac3a77e9db60267996db38df637356d9dcd1632e369939f2a29d89345c66e05066f1a3677aef18dea4113faeb629e46721a66d0a7e785d3e29af2594eb67dfa982affe0aac058f6e15864269b135418261fc3afb089472cf68c45dd7f231c6249ba0255e1e033833fc4d00a3fe02132d7bc3873614b8aee34273581ea0325c81f0270affa13641d052d36f0757d484014354d02d6883ca15c24d8c3956b1bd027bcf41f151fd8023c5340e5606f37e90fdb87c86fb4fa634b3718a30bace06a66eaf8f63c4aa3b637826a87fe8cfa44282e92cb1615af3a28e53bc74c7cba1a0977be9065d0c1a5dec6c54ae38d37f37aa35283e048e5530a85c4e7a29d7b92ec0c3169cdf2a805c7604bce60049b9fb7b8eaac10f51ae23794ceba68bb58112e293b9b692ca721b37c662f8574ed4dba6f88e170881c82cddc1034a0ca7e284bf0962b6b26292d836fa9f73c1ac770eef0f2d3a1eaf61d3e03555fd424eedd67e18a18094f888":"d55f684f81f4426e9fde92a5ff02df2ac896af63962888a97910c1379e20b0a3b1db613fb7fe2e07004329ea5c22bfd33e3dbe4cf58cc608c2c26c19a2e2fe22f98732c2b5cb844cc6c0702d91e1d50fc4382a7eba5635cd602432a2306ac4ce82f8d70c8d9bc15f918fe71e74c622d5cf71178bf6e0b9cc9f2b41dd8dbe441c41cd0c73a6dc47a348f6702f9d0e9b1b1431e948e299b9ec2272ab2c5f0c7be86affa5dec87a0bee81d3d50007edaa2bcfccb35605155ff36ed8edd4a40dcd4b243acd11b2b987bdbfaf91a7cac27e9c5aea525ee53de7b2d3332c8644402b823e94a7db26276d2d23aa07180f76b4fd29b9c0823099c9d62c519880aee7e9697617c1497d47bf3e571950311421b6b734d38b0db91eb85331b91ea9f61530f54512a5a52a4bad589eb69781d537f23297bb459bdad2948a29e1550bf4787e0be95bb173cf5fab17dab7a13a052a63453d97ccec1a321954886b7a1299faaeecae35c6eaaca753b041b5e5f093bf83397fd21dd6b3012066fcc058cc32c3b09d7562dee29509b5839392c9ff05f51f3166aaac4ac5f238038a3045e6f72e48ef0fe8bc675e82c318a268e43970271bf119b81bf6a982746554f84e72b9f00280a320a08142923c23c883423ff949827f29bbacdc1ccdb04938ce6098c95ba6b32528f4ef78eed778b2e122ddfd1cbdd11d1c0a6783e011fc536d63d053260637"
+
+AES-128-XTS Decrypt IEEE P1619/D16 Vector 8
+aes_decrypt_xts:"2718281828459045235360287471352631415926535897932384626433832795":"fe000000000000000000000000000000":"d55f684f81f4426e9fde92a5ff02df2ac896af63962888a97910c1379e20b0a3b1db613fb7fe2e07004329ea5c22bfd33e3dbe4cf58cc608c2c26c19a2e2fe22f98732c2b5cb844cc6c0702d91e1d50fc4382a7eba5635cd602432a2306ac4ce82f8d70c8d9bc15f918fe71e74c622d5cf71178bf6e0b9cc9f2b41dd8dbe441c41cd0c73a6dc47a348f6702f9d0e9b1b1431e948e299b9ec2272ab2c5f0c7be86affa5dec87a0bee81d3d50007edaa2bcfccb35605155ff36ed8edd4a40dcd4b243acd11b2b987bdbfaf91a7cac27e9c5aea525ee53de7b2d3332c8644402b823e94a7db26276d2d23aa07180f76b4fd29b9c0823099c9d62c519880aee7e9697617c1497d47bf3e571950311421b6b734d38b0db91eb85331b91ea9f61530f54512a5a52a4bad589eb69781d537f23297bb459bdad2948a29e1550bf4787e0be95bb173cf5fab17dab7a13a052a63453d97ccec1a321954886b7a1299faaeecae35c6eaaca753b041b5e5f093bf83397fd21dd6b3012066fcc058cc32c3b09d7562dee29509b5839392c9ff05f51f3166aaac4ac5f238038a3045e6f72e48ef0fe8bc675e82c318a268e43970271bf119b81bf6a982746554f84e72b9f00280a320a08142923c23c883423ff949827f29bbacdc1ccdb04938ce6098c95ba6b32528f4ef78eed778b2e122ddfd1cbdd11d1c0a6783e011fc536d63d053260637":"72efc1ebfe1ee25975a6eb3aa8589dda2b261f1c85bdab442a9e5b2dd1d7c3957a16fc08e526d4b1223f1b1232a11af274c3d70dac57f83e0983c498f1a6f1aecb021c3e70085a1e527f1ce41ee5911a82020161529cd82773762daf5459de94a0a82adae7e1703c808543c29ed6fb32d9e004327c1355180c995a07741493a09c21ba01a387882da4f62534b87bb15d60d197201c0fd3bf30c1500a3ecfecdd66d8721f90bcc4c17ee925c61b0a03727a9c0d5f5ca462fbfa0af1c2513a9d9d4b5345bd27a5f6e653f751693e6b6a2b8ead57d511e00e58c45b7b8d005af79288f5c7c22fd4f1bf7a898b03a5634c6a1ae3f9fae5de4f296a2896b23e7ed43ed14fa5a2803f4d28f0d3ffcf24757677aebdb47bb388378708948a8d4126ed1839e0da29a537a8c198b3c66ab00712dd261674bf45a73d67f76914f830ca014b65596f27e4cf62de66125a5566df9975155628b400fbfb3a29040ed50faffdbb18aece7c5c44693260aab386c0a37b11b114f1c415aebb653be468179428d43a4d8bc3ec38813eca30a13cf1bb18d524f1992d44d8b1a42ea30b22e6c95b199d8d182f8840b09d059585c31ad691fa0619ff038aca2c39a943421157361717c49d322028a74648113bd8c9d7ec77cf3c89c1ec8718ceff8516d96b34c3c614f10699c9abc4ed0411506223bea16af35c883accdbe1104eef0cfdb54e12fb230a"
+
+AES-128-XTS Decrypt IEEE P1619/D16 Vector 9
+aes_decrypt_xts:"2718281828459045235360287471352631415926535897932384626433832795":"ff000000000000000000000000000000":"72efc1ebfe1ee25975a6eb3aa8589dda2b261f1c85bdab442a9e5b2dd1d7c3957a16fc08e526d4b1223f1b1232a11af274c3d70dac57f83e0983c498f1a6f1aecb021c3e70085a1e527f1ce41ee5911a82020161529cd82773762daf5459de94a0a82adae7e1703c808543c29ed6fb32d9e004327c1355180c995a07741493a09c21ba01a387882da4f62534b87bb15d60d197201c0fd3bf30c1500a3ecfecdd66d8721f90bcc4c17ee925c61b0a03727a9c0d5f5ca462fbfa0af1c2513a9d9d4b5345bd27a5f6e653f751693e6b6a2b8ead57d511e00e58c45b7b8d005af79288f5c7c22fd4f1bf7a898b03a5634c6a1ae3f9fae5de4f296a2896b23e7ed43ed14fa5a2803f4d28f0d3ffcf24757677aebdb47bb388378708948a8d4126ed1839e0da29a537a8c198b3c66ab00712dd261674bf45a73d67f76914f830ca014b65596f27e4cf62de66125a5566df9975155628b400fbfb3a29040ed50faffdbb18aece7c5c44693260aab386c0a37b11b114f1c415aebb653be468179428d43a4d8bc3ec38813eca30a13cf1bb18d524f1992d44d8b1a42ea30b22e6c95b199d8d182f8840b09d059585c31ad691fa0619ff038aca2c39a943421157361717c49d322028a74648113bd8c9d7ec77cf3c89c1ec8718ceff8516d96b34c3c614f10699c9abc4ed0411506223bea16af35c883accdbe1104eef0cfdb54e12fb230a":"3260ae8dad1f4a32c5cafe3ab0eb95549d461a67ceb9e5aa2d3afb62dece0553193ba50c75be251e08d1d08f1088576c7efdfaaf3f459559571e12511753b07af073f35da06af0ce0bbf6b8f5ccc5cea500ec1b211bd51f63b606bf6528796ca12173ba39b8935ee44ccce646f90a45bf9ccc567f0ace13dc2d53ebeedc81f58b2e41179dddf0d5a5c42f5d8506c1a5d2f8f59f3ea873cbcd0eec19acbf325423bd3dcb8c2b1bf1d1eaed0eba7f0698e4314fbeb2f1566d1b9253008cbccf45a2b0d9c5c9c21474f4076e02be26050b99dee4fd68a4cf890e496e4fcae7b70f94ea5a9062da0daeba1993d2ccd1dd3c244b8428801495a58b216547e7e847c46d1d756377b6242d2e5fb83bf752b54e0df71e889f3a2bb0f4c10805bf3c590376e3c24e22ff57f7fa965577375325cea5d920db94b9c336b455f6e894c01866fe9fbb8c8d3f70a2957285f6dfb5dcd8cbf54782f8fe7766d4723819913ac773421e3a31095866bad22c86a6036b2518b2059b4229d18c8c2ccbdf906c6cc6e82464ee57bddb0bebcb1dc645325bfb3e665ef7251082c88ebb1cf203bd779fdd38675713c8daadd17e1cabee432b09787b6ddf3304e38b731b45df5df51b78fcfb3d32466028d0ba36555e7e11ab0ee0666061d1645d962444bc47a38188930a84b4d561395c73c087021927ca638b7afc8a8679ccb84c26555440ec7f10445cd"
+
+AES-256-XTS Decrypt IEEE P1619/D16 Vector 10
+aes_decrypt_xts:"27182818284590452353602874713526624977572470936999595749669676273141592653589793238462643383279502884197169399375105820974944592":"ff000000000000000000000000000000":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"1c3b3a102f770386e4836c99e370cf9bea00803f5e482357a4ae12d414a3e63b5d31e276f8fe4a8d66b317f9ac683f44680a86ac35adfc3345befecb4bb188fd5776926c49a3095eb108fd1098baec70aaa66999a72a82f27d848b21d4a741b0c5cd4d5fff9dac89aeba122961d03a757123e9870f8acf1000020887891429ca2a3e7a7d7df7b10355165c8b9a6d0a7de8b062c4500dc4cd120c0f7418dae3d0b5781c34803fa75421c790dfe1de1834f280d7667b327f6c8cd7557e12ac3a0f93ec05c52e0493ef31a12d3d9260f79a289d6a379bc70c50841473d1a8cc81ec583e9645e07b8d9670655ba5bbcfecc6dc3966380ad8fecb17b6ba02469a020a84e18e8f84252070c13e9f1f289be54fbc481457778f616015e1327a02b140f1505eb309326d68378f8374595c849d84f4c333ec4423885143cb47bd71c5edae9be69a2ffeceb1bec9de244fbe15992b11b77c040f12bd8f6a975a44a0f90c29a9abc3d4d893927284c58754cce294529f8614dcd2aba991925fedc4ae74ffac6e333b93eb4aff0479da9a410e4450e0dd7ae4c6e2910900575da401fc07059f645e8b7e9bfdef33943054ff84011493c27b3429eaedb4ed5376441a77ed43851ad77f16f541dfd269d50d6a5f14fb0aab1cbb4c1550be97f7ab4066193c4caa773dad38014bd2092fa755c824bb5e54c4f36ffda9fcea70b9c6e693e148c151"
+
+AES-256-XTS Decrypt IEEE P1619/D16 Vector 11
+aes_decrypt_xts:"27182818284590452353602874713526624977572470936999595749669676273141592653589793238462643383279502884197169399375105820974944592":"ffff0000000000000000000000000000":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"77a31251618a15e6b92d1d66dffe7b50b50bad552305ba0217a610688eff7e11e1d0225438e093242d6db274fde801d4cae06f2092c728b2478559df58e837c2469ee4a4fa794e4bbc7f39bc026e3cb72c33b0888f25b4acf56a2a9804f1ce6d3d6e1dc6ca181d4b546179d55544aa7760c40d06741539c7e3cd9d2f6650b2013fd0eeb8c2b8e3d8d240ccae2d4c98320a7442e1c8d75a42d6e6cfa4c2eca1798d158c7aecdf82490f24bb9b38e108bcda12c3faf9a21141c3613b58367f922aaa26cd22f23d708dae699ad7cb40a8ad0b6e2784973dcb605684c08b8d6998c69aac049921871ebb65301a4619ca80ecb485a31d744223ce8ddc2394828d6a80470c092f5ba413c3378fa6054255c6f9df4495862bbb3287681f931b687c888abf844dfc8fc28331e579928cd12bd2390ae123cf03818d14dedde5c0c24c8ab018bfca75ca096f2d531f3d1619e785f1ada437cab92e980558b3dce1474afb75bfedbf8ff54cb2618e0244c9ac0d3c66fb51598cd2db11f9be39791abe447c63094f7c453b7ff87cb5bb36b7c79efb0872d17058b83b15ab0866ad8a58656c5a7e20dbdf308b2461d97c0ec0024a2715055249cf3b478ddd4740de654f75ca686e0d7345c69ed50cdc2a8b332b1f8824108ac937eb050585608ee734097fc09054fbff89eeaeea791f4a7ab1f9868294a4f9e27b42af8100cb9d59cef9645803"
+
+AES-256-XTS Decrypt IEEE P1619/D16 Vector 12
+aes_decrypt_xts:"27182818284590452353602874713526624977572470936999595749669676273141592653589793238462643383279502884197169399375105820974944592":"ffffff00000000000000000000000000":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"e387aaa58ba483afa7e8eb469778317ecf4cf573aa9d4eac23f2cdf914e4e200a8b490e42ee646802dc6ee2b471b278195d60918ececb44bf79966f83faba0499298ebc699c0c8634715a320bb4f075d622e74c8c932004f25b41e361025b5a87815391f6108fc4afa6a05d9303c6ba68a128a55705d415985832fdeaae6c8e19110e84d1b1f199a2692119edc96132658f09da7c623efcec712537a3d94c0bf5d7e352ec94ae5797fdb377dc1551150721adf15bd26a8efc2fcaad56881fa9e62462c28f30ae1ceaca93c345cf243b73f542e2074a705bd2643bb9f7cc79bb6e7091ea6e232df0f9ad0d6cf502327876d82207abf2115cdacf6d5a48f6c1879a65b115f0f8b3cb3c59d15dd8c769bc014795a1837f3901b5845eb491adfefe097b1fa30a12fc1f65ba22905031539971a10f2f36c321bb51331cdefb39e3964c7ef079994f5b69b2edd83a71ef549971ee93f44eac3938fcdd61d01fa71799da3a8091c4c48aa9ed263ff0749df95d44fef6a0bb578ec69456aa5408ae32c7af08ad7ba8921287e3bbee31b767be06a0e705c864a769137df28292283ea81a2480241b44d9921cdbec1bc28dc1fda114bd8e5217ac9d8ebafa720e9da4f9ace231cc949e5b96fe76ffc21063fddc83a6b8679c00d35e09576a875305bed5f36ed242c8900dd1fa965bc950dfce09b132263a1eef52dd6888c309f5a7d712826"
+
+AES-256-XTS Decrypt IEEE P1619/D16 Vector 13
+aes_decrypt_xts:"27182818284590452353602874713526624977572470936999595749669676273141592653589793238462643383279502884197169399375105820974944592":"ffffffff000000000000000000000000":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"bf53d2dade78e822a4d949a9bc6766b01b06a8ef70d26748c6a7fc36d80ae4c5520f7c4ab0ac8544424fa405162fef5a6b7f229498063618d39f0003cb5fb8d1c86b643497da1ff945c8d3bedeca4f479702a7a735f043ddb1d6aaade3c4a0ac7ca7f3fa5279bef56f82cd7a2f38672e824814e10700300a055e1630b8f1cb0e919f5e942010a416e2bf48cb46993d3cb6a51c19bacf864785a00bc2ecff15d350875b246ed53e68be6f55bd7e05cfc2b2ed6432198a6444b6d8c247fab941f569768b5c429366f1d3f00f0345b96123d56204c01c63b22ce78baf116e525ed90fdea39fa469494d3866c31e05f295ff21fea8d4e6e13d67e47ce722e9698a1c1048d68ebcde76b86fcf976eab8aa9790268b7068e017a8b9b749409514f1053027fd16c3786ea1bac5f15cb79711ee2abe82f5cf8b13ae73030ef5b9e4457e75d1304f988d62dd6fc4b94ed38ba831da4b7634971b6cd8ec325d9c61c00f1df73627ed3745a5e8489f3a95c69639c32cd6e1d537a85f75cc844726e8a72fc0077ad22000f1d5078f6b866318c668f1ad03d5a5fced5219f2eabbd0aa5c0f460d183f04404a0d6f469558e81fab24a167905ab4c7878502ad3e38fdbe62a41556cec37325759533ce8f25f367c87bb5578d667ae93f9e2fd99bcbc5f2fbba88cf6516139420fcff3b7361d86322c4bd84c82f335abb152c4a93411373aaa8220"
+
+AES-256-XTS Decrypt IEEE P1619/D16 Vector 14
+aes_decrypt_xts:"27182818284590452353602874713526624977572470936999595749669676273141592653589793238462643383279502884197169399375105820974944592":"ffffffffff0000000000000000000000":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"64497e5a831e4a932c09be3e5393376daa599548b816031d224bbf50a818ed2350eae7e96087c8a0db51ad290bd00c1ac1620857635bf246c176ab463be30b808da548081ac847b158e1264be25bb0910bbc92647108089415d45fab1b3d2604e8a8eff1ae4020cfa39936b66827b23f371b92200be90251e6d73c5f86de5fd4a950781933d79a28272b782a2ec313efdfcc0628f43d744c2dc2ff3dcb66999b50c7ca895b0c64791eeaa5f29499fb1c026f84ce5b5c72ba1083cddb5ce45434631665c333b60b11593fb253c5179a2c8db813782a004856a1653011e93fb6d876c18366dd8683f53412c0c180f9c848592d593f8609ca736317d356e13e2bff3a9f59cd9aeb19cd482593d8c46128bb32423b37a9adfb482b99453fbe25a41bf6feb4aa0bef5ed24bf73c762978025482c13115e4015aac992e5613a3b5c2f685b84795cb6e9b2656d8c88157e52c42f978d8634c43d06fea928f2822e465aa6576e9bf419384506cc3ce3c54ac1a6f67dc66f3b30191e698380bc999b05abce19dc0c6dcc2dd001ec535ba18deb2df1a101023108318c75dc98611a09dc48a0acdec676fabdf222f07e026f059b672b56e5cbc8e1d21bbd867dd927212054681d70ea737134cdfce93b6f82ae22423274e58a0821cc5502e2d0ab4585e94de6975be5e0b4efce51cd3e70c25a1fbbbd609d273ad5b0d59631c531f6a0a57b9"
+
+AES-128-XTS Decrypt IEEE P1619/D16 Vector 15
+aes_decrypt_xts:"fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0":"9a785634120000000000000000000000":"000102030405060708090a0b0c0d0e0f10":"6c1625db4671522d3d7599601de7ca09ed"
+
+AES-128-XTS Decrypt IEEE P1619/D16 Vector 16
+aes_decrypt_xts:"fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0":"9a785634120000000000000000000000":"000102030405060708090a0b0c0d0e0f1011":"d069444b7a7e0cab09e24447d24deb1fedbf"
+
+AES-128-XTS Decrypt IEEE P1619/D16 Vector 17
+aes_decrypt_xts:"fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0":"9a785634120000000000000000000000":"000102030405060708090a0b0c0d0e0f101112":"e5df1351c0544ba1350b3363cd8ef4beedbf9d"
+
+AES-128-XTS Decrypt IEEE P1619/D16 Vector 18
+aes_decrypt_xts:"fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0":"9a785634120000000000000000000000":"000102030405060708090a0b0c0d0e0f10111213":"9d84c813f719aa2c7be3f66171c7c5c2edbf9dac"
+
+AES-128-XTS Decrypt IEEE P1619/D16 Vector 19
+aes_decrypt_xts:"e0e1e2e3e4e5e6e7e8e9eaebecedeeefc0c1c2c3c4c5c6c7c8c9cacbcccdcecf":"21436587a90000000000000000000000":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"38b45812ef43a05bd957e545907e223b954ab4aaf088303ad910eadf14b42be68b2461149d8c8ba85f992be970bc621f1b06573f63e867bf5875acafa04e42ccbd7bd3c2a0fb1fff791ec5ec36c66ae4ac1e806d81fbf709dbe29e471fad38549c8e66f5345d7c1eb94f405d1ec785cc6f6a68f6254dd8339f9d84057e01a17741990482999516b5611a38f41bb6478e6f173f320805dd71b1932fc333cb9ee39936beea9ad96fa10fb4112b901734ddad40bc1878995f8e11aee7d141a2f5d48b7a4e1e7f0b2c04830e69a4fd1378411c2f287edf48c6c4e5c247a19680f7fe41cefbd49b582106e3616cbbe4dfb2344b2ae9519391f3e0fb4922254b1d6d2d19c6d4d537b3a26f3bcc51588b32f3eca0829b6a5ac72578fb814fb43cf80d64a233e3f997a3f02683342f2b33d25b492536b93becb2f5e1a8b82f5b883342729e8ae09d16938841a21a97fb543eea3bbff59f13c1a18449e398701c1ad51648346cbc04c27bb2da3b93a1372ccae548fb53bee476f9e9c91773b1bb19828394d55d3e1a20ed69113a860b6829ffa847224604435070221b257e8dff783615d2cae4803a93aa4334ab482a0afac9c0aeda70b45a481df5dec5df8cc0f423c77a5fd46cd312021d4b438862419a791be03bb4d97c0e59578542531ba466a83baf92cefc151b5cc1611a167893819b63fb8a6b18e86de60290fa72b797b0ce59f3"
diff --git a/tests/suites/test_suite_ccm.data b/tests/suites/test_suite_ccm.data
index 90ba42d83c..cad40d59c8 100644
--- a/tests/suites/test_suite_ccm.data
+++ b/tests/suites/test_suite_ccm.data
@@ -41,6 +41,39 @@ ccm_lengths:5:10:65281:8:MBEDTLS_ERR_CCM_BAD_INPUT
CCM lengths #8 msg too long for this IV length (2^16, q = 2)
ccm_lengths:65536:13:5:8:MBEDTLS_ERR_CCM_BAD_INPUT
+CCM lengths #9 tag length 0
+ccm_lengths:5:10:5:0:MBEDTLS_ERR_CCM_BAD_INPUT
+
+CCM* fixed tag lengths #1 all OK
+ccm_star_lengths:5:10:5:8:0
+
+CCM* fixed tag lengths #2 all OK - tag length 0
+ccm_star_lengths:5:10:5:0:0
+
+CCM* encrypt and tag #1
+depends_on:MBEDTLS_AES_C
+mbedtls_ccm_star_encrypt_and_tag:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"":"ACDE480000000001":"00000005":2:"08D0842143010000000048DEAC020500000055CF000051525354":"223BC1EC841AB553":0
+
+CCM* encrypt and tag #2
+depends_on:MBEDTLS_AES_C
+mbedtls_ccm_star_encrypt_and_tag:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"61626364":"ACDE480000000001":"00000005":4:"69DC842143020000000048DEAC010000000048DEAC0405000000":"D43E022B":0
+
+CCM* encrypt and tag #3
+depends_on:MBEDTLS_AES_C
+mbedtls_ccm_star_encrypt_and_tag:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"CE":"ACDE480000000001":"00000005":6:"2BDC842143020000000048DEACFFFF010000000048DEAC060500000001":"D84FDE529061F9C6F1":0
+
+CCM* auth decrypt tag #1
+depends_on:MBEDTLS_AES_C
+mbedtls_ccm_star_auth_decrypt:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"223BC1EC841AB553":"ACDE480000000001":"00000005":2:"08D0842143010000000048DEAC020500000055CF000051525354":"":0
+
+CCM* auth decrypt tag #2
+depends_on:MBEDTLS_AES_C
+mbedtls_ccm_star_auth_decrypt:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"D43E022B":"ACDE480000000001":"00000005":4:"69DC842143020000000048DEAC010000000048DEAC0405000000":"61626364":0
+
+CCM* auth decrypt tag #3
+depends_on:MBEDTLS_AES_C
+mbedtls_ccm_star_auth_decrypt:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"D84FDE529061F9C6F1":"ACDE480000000001":"00000005":6:"2BDC842143020000000048DEACFFFF010000000048DEAC060500000001":"CE":0
+
CCM encrypt and tag RFC 3610 #1
depends_on:MBEDTLS_AES_C
mbedtls_ccm_encrypt_and_tag:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"08090A0B0C0D0E0F101112131415161718191A1B1C1D1E":"00000003020100A0A1A2A3A4A5":"0001020304050607":"588C979A61C663D2F066D0C2C0F989806D5F6B61DAC38417E8D12CFDF926E0"
diff --git a/tests/suites/test_suite_ccm.function b/tests/suites/test_suite_ccm.function
index 2f5c77c2c7..58c8569850 100644
--- a/tests/suites/test_suite_ccm.function
+++ b/tests/suites/test_suite_ccm.function
@@ -74,6 +74,47 @@ exit:
}
/* END_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_AES_C */
+void ccm_star_lengths( int msg_len, int iv_len, int add_len, int tag_len,
+ int res )
+{
+ mbedtls_ccm_context ctx;
+ unsigned char key[16];
+ unsigned char msg[10];
+ unsigned char iv[14];
+ unsigned char add[10];
+ unsigned char out[10];
+ unsigned char tag[18];
+ int decrypt_ret;
+
+ mbedtls_ccm_init( &ctx );
+
+ memset( key, 0, sizeof( key ) );
+ memset( msg, 0, sizeof( msg ) );
+ memset( iv, 0, sizeof( iv ) );
+ memset( add, 0, sizeof( add ) );
+ memset( out, 0, sizeof( out ) );
+ memset( tag, 0, sizeof( tag ) );
+
+ TEST_ASSERT( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
+ key, 8 * sizeof( key ) ) == 0 );
+
+ TEST_ASSERT( mbedtls_ccm_star_encrypt_and_tag( &ctx, msg_len, iv, iv_len,
+ add, add_len, msg, out, tag, tag_len ) == res );
+
+ decrypt_ret = mbedtls_ccm_star_auth_decrypt( &ctx, msg_len, iv, iv_len, add,
+ add_len, msg, out, tag, tag_len );
+
+ if( res == 0 && tag_len != 0 )
+ TEST_ASSERT( decrypt_ret == MBEDTLS_ERR_CCM_AUTH_FAILED );
+ else
+ TEST_ASSERT( decrypt_ret == res );
+
+exit:
+ mbedtls_ccm_free( &ctx );
+}
+/* END_CASE */
+
/* BEGIN_CASE */
void mbedtls_ccm_encrypt_and_tag( int cipher_id,
char *key_hex, char *msg_hex,
@@ -187,3 +228,140 @@ exit:
mbedtls_ccm_free( &ctx );
}
/* END_CASE */
+
+/* BEGIN_CASE */
+void mbedtls_ccm_star_encrypt_and_tag( int cipher_id,
+ char *key_hex, char *msg_hex,
+ char *source_address_hex, char *frame_counter_hex,
+ int sec_level, char *add_hex,
+ char *result_hex, int output_ret )
+{
+ unsigned char key[32];
+ unsigned char msg[50];
+ unsigned char iv[13];
+ unsigned char add[32];
+ unsigned char result[50];
+ unsigned char source_address[8];
+ unsigned char frame_counter[4];
+ mbedtls_ccm_context ctx;
+ size_t i, key_len, msg_len, iv_len, add_len, result_len, source_address_len, frame_counter_len, tag_len;
+ int ret;
+
+ mbedtls_ccm_init( &ctx );
+
+ memset( key, 0x00, sizeof( key ) );
+ memset( msg, 0x00, sizeof( msg ) );
+ memset( iv, 0x00, sizeof( iv ) );
+ memset( add, 0x00, sizeof( add ) );
+ memset( result, 0x00, sizeof( result ) );
+ memset( source_address, 0x00, sizeof( source_address ) );
+ memset( frame_counter, 0x00, sizeof( frame_counter ) );
+
+ key_len = unhexify( key, key_hex );
+ msg_len = unhexify( msg, msg_hex );
+ add_len = unhexify( add, add_hex );
+ result_len = unhexify( result, result_hex );
+ source_address_len = unhexify( source_address, source_address_hex );
+ frame_counter_len = unhexify( frame_counter, frame_counter_hex );
+
+ if( sec_level % 4 == 0)
+ tag_len = 0;
+ else
+ tag_len = 1 << ( sec_level % 4 + 1);
+
+ for( i = 0; i < source_address_len; i++ )
+ iv[i] = source_address[i];
+
+ for( i = 0; i < frame_counter_len; i++ )
+ iv[source_address_len + i] = frame_counter[i];
+
+ iv[source_address_len + frame_counter_len] = sec_level;
+ iv_len = sizeof( iv );
+
+ TEST_ASSERT( mbedtls_ccm_setkey( &ctx, cipher_id, key, key_len * 8 ) == 0 );
+
+ ret = mbedtls_ccm_star_encrypt_and_tag( &ctx, msg_len, iv, iv_len,
+ add, add_len, msg, msg, msg + msg_len, tag_len );
+
+ TEST_ASSERT( ret == output_ret );
+
+ TEST_ASSERT( memcmp( msg, result, result_len ) == 0 );
+
+ /* Check we didn't write past the end */
+ TEST_ASSERT( msg[result_len] == 0 && msg[result_len + 1] == 0 );
+
+exit:
+ mbedtls_ccm_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mbedtls_ccm_star_auth_decrypt( int cipher_id,
+ char *key_hex, char *msg_hex,
+ char *source_address_hex, char *frame_counter_hex,
+ int sec_level, char *add_hex,
+ char *result_hex, int output_ret )
+{
+ unsigned char key[32];
+ unsigned char msg[50];
+ unsigned char iv[13];
+ unsigned char add[32];
+ unsigned char tag[16];
+ unsigned char result[50];
+ unsigned char source_address[8];
+ unsigned char frame_counter[4];
+ mbedtls_ccm_context ctx;
+ size_t i, key_len, msg_len, iv_len, add_len, tag_len, result_len, source_address_len, frame_counter_len;
+ int ret;
+
+ mbedtls_ccm_init( &ctx );
+
+ memset( key, 0x00, sizeof( key ) );
+ memset( msg, 0x00, sizeof( msg ) );
+ memset( iv, 0x00, sizeof( iv ) );
+ memset( add, 0x00, sizeof( add ) );
+ memset( result, 0x00, sizeof( result ) );
+ memset( source_address, 0x00, sizeof( source_address ) );
+ memset( frame_counter, 0x00, sizeof( frame_counter ) );
+ memset( tag, 0x00, sizeof( tag ) );
+
+ key_len = unhexify( key, key_hex );
+ msg_len = unhexify( msg, msg_hex );
+ add_len = unhexify( add, add_hex );
+ result_len = unhexify( result, result_hex );
+ source_address_len = unhexify( source_address, source_address_hex );
+ frame_counter_len = unhexify( frame_counter, frame_counter_hex );
+
+ if( sec_level % 4 == 0)
+ tag_len = 0;
+ else
+ tag_len = 1 << ( sec_level % 4 + 1);
+
+ for( i = 0; i < source_address_len; i++ )
+ iv[i] = source_address[i];
+
+ for( i = 0; i < frame_counter_len; i++ )
+ iv[source_address_len + i] = frame_counter[i];
+
+ iv[source_address_len + frame_counter_len] = sec_level;
+ iv_len = sizeof( iv );
+
+ msg_len -= tag_len;
+ memcpy( tag, msg + msg_len, tag_len );
+
+ TEST_ASSERT( mbedtls_ccm_setkey( &ctx, cipher_id, key, key_len * 8 ) == 0 );
+
+ ret = mbedtls_ccm_star_auth_decrypt( &ctx, msg_len, iv, iv_len,
+ add, add_len, msg, msg, msg + msg_len, tag_len );
+
+ TEST_ASSERT( ret == output_ret );
+
+ TEST_ASSERT( memcmp( msg, result, result_len ) == 0 );
+
+ /* Check we didn't write past the end (where the original tag is) */
+ TEST_ASSERT( memcmp( msg + msg_len, tag, tag_len ) == 0 );
+
+exit:
+ mbedtls_ccm_free( &ctx );
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_cipher.aes.data b/tests/suites/test_suite_cipher.aes.data
index e8e9a155c2..baab3586bd 100644
--- a/tests/suites/test_suite_cipher.aes.data
+++ b/tests/suites/test_suite_cipher.aes.data
@@ -414,7 +414,7 @@ AES-128 CFB - Encrypt and decrypt 32 bytes
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CFB
enc_dec_buf:MBEDTLS_CIPHER_AES_128_CFB128:"AES-128-CFB128":128:32:-1
-AES-128 CFB - Encrypt and decrypt 32 bytes
+AES-128 CFB - Encrypt and decrypt 33 bytes
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CFB
enc_dec_buf:MBEDTLS_CIPHER_AES_128_CFB128:"AES-128-CFB128":128:33:-1
@@ -474,6 +474,382 @@ AES-128 CFB - Encrypt and decrypt 32 bytes in multiple parts 1
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CFB
enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_CFB128:128:16:16:-1:16:16:16:16
+AES-128 OFB - Encrypt and decrypt 0 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:0:-1
+
+AES-128 OFB - Encrypt and decrypt 1 byte
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:1:-1
+
+AES-128 OFB - Encrypt and decrypt 2 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:2:-1
+
+AES-128 OFB - Encrypt and decrypt 7 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:7:-1
+
+AES-128 OFB - Encrypt and decrypt 8 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:8:-1
+
+AES-128 OFB - Encrypt and decrypt 9 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:9:-1
+
+AES-128 OFB - Encrypt and decrypt 15 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:15:-1
+
+AES-128 OFB - Encrypt and decrypt 16 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:16:-1
+
+AES-128 OFB - Encrypt and decrypt 17 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:17:-1
+
+AES-128 OFB - Encrypt and decrypt 31 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:31:-1
+
+AES-128 OFB - Encrypt and decrypt 32 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:32:-1
+
+AES-128 OFB - Encrypt and decrypt 33 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:33:-1
+
+AES-128 OFB - Encrypt and decrypt 47 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:47:-1
+
+AES-128 OFB - Encrypt and decrypt 48 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:48:-1
+
+AES-128 OFB - Encrypt and decrypt 49 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:49:-1
+
+AES-128 OFB - Encrypt and decrypt 0 bytes in multiple parts
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:0:0:-1:0:0:0:0
+
+AES-128 OFB - Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:1:0:-1:1:0:1:0
+
+AES-128 OFB - Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:0:1:-1:0:1:0:1
+
+AES-128 OFB - Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:16:0:-1:16:0:16:0
+
+AES-128 OFB - Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:0:16:-1:0:16:0:16
+
+AES-128 OFB - Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:1:15:-1:1:15:1:15
+
+AES-128 OFB - Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:15:1:-1:15:1:15:1
+
+AES-128 OFB - Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:15:7:-1:15:7:15:7
+
+AES-128 OFB - Encrypt and decrypt 22 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:16:6:-1:16:6:16:6
+
+AES-128 OFB - Encrypt and decrypt 23 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:17:6:-1:17:6:17:6
+
+AES-128 OFB - Encrypt and decrypt 32 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:16:16:-1:16:16:16:16
+
+AES-192 OFB - Encrypt and decrypt 0 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:0:-1
+
+AES-192 OFB - Encrypt and decrypt 1 byte
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:1:-1
+
+AES-192 OFB - Encrypt and decrypt 2 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:2:-1
+
+AES-192 OFB - Encrypt and decrypt 7 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:7:-1
+
+AES-192 OFB - Encrypt and decrypt 8 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:8:-1
+
+AES-192 OFB - Encrypt and decrypt 9 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:9:-1
+
+AES-192 OFB - Encrypt and decrypt 15 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:15:-1
+
+AES-192 OFB - Encrypt and decrypt 16 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:16:-1
+
+AES-192 OFB - Encrypt and decrypt 17 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:17:-1
+
+AES-192 OFB - Encrypt and decrypt 31 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:31:-1
+
+AES-192 OFB - Encrypt and decrypt 32 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:32:-1
+
+AES-192 OFB - Encrypt and decrypt 33 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:33:-1
+
+AES-192 OFB - Encrypt and decrypt 47 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:47:-1
+
+AES-192 OFB - Encrypt and decrypt 48 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:48:-1
+
+AES-192 OFB - Encrypt and decrypt 49 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:49:-1
+
+AES-192 OFB - Encrypt and decrypt 0 bytes in multiple parts
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:0:0:-1:0:0:0:0
+
+AES-192 OFB - Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:1:0:-1:1:0:1:0
+
+AES-192 OFB - Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:0:1:-1:0:1:0:1
+
+AES-192 OFB - Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:16:0:-1:16:0:16:0
+
+AES-192 OFB - Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:0:16:-1:0:16:0:16
+
+AES-192 OFB - Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:1:15:-1:1:15:1:15
+
+AES-192 OFB - Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:15:1:-1:15:1:15:1
+
+AES-192 OFB - Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:15:7:-1:15:7:15:7
+
+AES-192 OFB - Encrypt and decrypt 22 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:16:6:-1:16:6:16:6
+
+AES-192 OFB - Encrypt and decrypt 23 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:17:6:-1:17:6:17:6
+
+AES-192 OFB - Encrypt and decrypt 32 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:16:16:-1:16:16:16:16
+
+AES-256 OFB - Encrypt and decrypt 0 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:0:-1
+
+AES-256 OFB - Encrypt and decrypt 1 byte
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:1:-1
+
+AES-256 OFB - Encrypt and decrypt 2 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:2:-1
+
+AES-256 OFB - Encrypt and decrypt 7 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:7:-1
+
+AES-256 OFB - Encrypt and decrypt 8 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:8:-1
+
+AES-256 OFB - Encrypt and decrypt 9 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:9:-1
+
+AES-256 OFB - Encrypt and decrypt 15 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:15:-1
+
+AES-256 OFB - Encrypt and decrypt 16 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:16:-1
+
+AES-256 OFB - Encrypt and decrypt 17 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:17:-1
+
+AES-256 OFB - Encrypt and decrypt 31 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:31:-1
+
+AES-256 OFB - Encrypt and decrypt 32 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:32:-1
+
+AES-256 OFB - Encrypt and decrypt 33 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:33:-1
+
+AES-256 OFB - Encrypt and decrypt 47 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:47:-1
+
+AES-256 OFB - Encrypt and decrypt 48 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:48:-1
+
+AES-256 OFB - Encrypt and decrypt 49 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:49:-1
+
+AES-256 OFB - Encrypt and decrypt 0 bytes in multiple parts
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:0:0:-1:0:0:0:0
+
+AES-256 OFB - Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:1:0:-1:1:0:1:0
+
+AES-256 OFB - Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:0:1:-1:0:1:0:1
+
+AES-256 OFB - Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:16:0:-1:16:0:16:0
+
+AES-256 OFB - Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:0:16:-1:0:16:0:16
+
+AES-256 OFB - Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:1:15:-1:1:15:1:15
+
+AES-256 OFB - Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:15:1:-1:15:1:15:1
+
+AES-256 OFB - Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:15:7:-1:15:7:15:7
+
+AES-256 OFB - Encrypt and decrypt 22 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:16:6:-1:16:6:16:6
+
+AES-256 OFB - Encrypt and decrypt 23 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:17:6:-1:17:6:17:6
+
+AES-256 OFB - Encrypt and decrypt 32 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:16:16:-1:16:16:16:16
+
+AES-128 XTS - Encrypt and decrypt 16 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_XTS:"AES-128-XTS":256:16:-1
+
+AES-128 XTS - Encrypt and decrypt 17 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_XTS:"AES-128-XTS":256:17:-1
+
+AES-128 XTS - Encrypt and decrypt 31 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_XTS:"AES-128-XTS":256:31:-1
+
+AES-128 XTS - Encrypt and decrypt 32 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_XTS:"AES-128-XTS":256:32:-1
+
+AES-128 XTS - Encrypt and decrypt 33 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_XTS:"AES-128-XTS":256:33:-1
+
+AES-128 XTS - Encrypt and decrypt 47 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_XTS:"AES-128-XTS":256:47:-1
+
+AES-128 XTS - Encrypt and decrypt 48 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_XTS:"AES-128-XTS":256:48:-1
+
+AES-128 XTS - Encrypt and decrypt 49 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_XTS:"AES-128-XTS":256:49:-1
+
+AES-256 XTS - Encrypt and decrypt 16 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_XTS:"AES-256-XTS":512:16:-1
+
+AES-256 XTS - Encrypt and decrypt 17 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_XTS:"AES-256-XTS":512:17:-1
+
+AES-256 XTS - Encrypt and decrypt 31 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_XTS:"AES-256-XTS":512:31:-1
+
+AES-256 XTS - Encrypt and decrypt 32 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_XTS:"AES-256-XTS":512:32:-1
+
+AES-256 XTS - Encrypt and decrypt 33 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_XTS:"AES-256-XTS":512:33:-1
+
+AES-256 XTS - Encrypt and decrypt 47 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_XTS:"AES-256-XTS":512:47:-1
+
+AES-256 XTS - Encrypt and decrypt 48 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_XTS:"AES-256-XTS":512:48:-1
+
+AES-256 XTS - Encrypt and decrypt 49 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_XTS:"AES-256-XTS":512:49:-1
+
AES-128 CTR - Encrypt and decrypt 0 bytes
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
enc_dec_buf:MBEDTLS_CIPHER_AES_128_CTR:"AES-128-CTR":128:0:-1
@@ -518,7 +894,7 @@ AES-128 CTR - Encrypt and decrypt 32 bytes
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
enc_dec_buf:MBEDTLS_CIPHER_AES_128_CTR:"AES-128-CTR":128:32:-1
-AES-128 CTR - Encrypt and decrypt 32 bytes
+AES-128 CTR - Encrypt and decrypt 33 bytes
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
enc_dec_buf:MBEDTLS_CIPHER_AES_128_CTR:"AES-128-CTR":128:33:-1
@@ -814,6 +1190,18 @@ AES Decrypt test vector #6
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CFB
decrypt_test_vec:MBEDTLS_CIPHER_AES_256_CFB128:-1:"ffffffffff800000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"be66cfea2fecd6bf0ec7b4352c99bcaa":"00000000000000000000000000000000":"":"":0:0
+AES Decrypt test vector #7
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+decrypt_test_vec:MBEDTLS_CIPHER_AES_128_OFB:-1:"2B7E151628AED2A6ABF7158809CF4F3C":"000102030405060708090A0B0C0D0E0F":"3B3FD92EB72DAD20333449F8E83CFB4A7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"":"":0:0:
+
+AES Decrypt test vector #8
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+decrypt_test_vec:MBEDTLS_CIPHER_AES_192_OFB:-1:"8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B":"000102030405060708090A0B0C0D0E0F":"CDC80D6FDDF18CAB34C25909C99A4174fcc28b8d4c63837c09e81700c11004018d9a9aeac0f6596f559c6d4daf59a5f26d9f200857ca6c3e9cac524bd9acc92a":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"":"":0:0:
+
+AES Decrypt test vector #9
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+decrypt_test_vec:MBEDTLS_CIPHER_AES_256_OFB:-1:"603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4":"000102030405060708090A0B0C0D0E0F":"DC7E84BFDA79164B7ECD8486985D38604febdc6740d20b3ac88f6ad82a4fb08d71ab47a086e86eedf39d1c5bba97c4080126141d67f37be8538f5a8be740e484":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"":"":0:0:
+
AES-128-ECB Encrypt NIST KAT #1
depends_on:MBEDTLS_AES_C
test_vec_ecb:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_ENCRYPT:"00000000000000000000000000000000":"f34481ec3cc627bacd5dc3fb08f273e6":"0336763e966d92595a567cc9ce537f5e":0
diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function
index 8f1109ee84..9899289f00 100644
--- a/tests/suites/test_suite_cipher.function
+++ b/tests/suites/test_suite_cipher.function
@@ -134,7 +134,7 @@ void enc_dec_buf( int cipher_id, char *cipher_string, int key_len,
int length_val, int pad_mode )
{
size_t length = length_val, outlen, total_len, i, block_size;
- unsigned char key[32];
+ unsigned char key[64];
unsigned char iv[16];
unsigned char ad[13];
unsigned char tag[16];
diff --git a/tests/suites/test_suite_hkdf.data b/tests/suites/test_suite_hkdf.data
new file mode 100644
index 0000000000..15837365fe
--- /dev/null
+++ b/tests/suites/test_suite_hkdf.data
@@ -0,0 +1,98 @@
+HKDF extract fails with hash_len of 0
+test_hkdf_extract_ret:0:MBEDTLS_ERR_HKDF_BAD_INPUT_DATA
+
+HKDF expand fails with NULL okm
+test_hkdf_expand_ret:32:32:0:MBEDTLS_ERR_HKDF_BAD_INPUT_DATA
+
+HKDF expand fails with hash_len of 0
+test_hkdf_expand_ret:0:32:32:MBEDTLS_ERR_HKDF_BAD_INPUT_DATA
+
+HKDF expand fails with prk_len < hash_len
+test_hkdf_expand_ret:32:16:32:MBEDTLS_ERR_HKDF_BAD_INPUT_DATA
+
+HKDF expand fails with okm_len / hash_len > 255
+test_hkdf_expand_ret:32:32:8192:MBEDTLS_ERR_HKDF_BAD_INPUT_DATA
+
+HKDF RFC5869 Test Vector #1
+depends_on:MBEDTLS_SHA256_C
+test_hkdf:6:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"
+
+HKDF RFC5869 Test Vector #2
+depends_on:MBEDTLS_SHA256_C
+test_hkdf:6:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f":"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf":"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87"
+
+HKDF RFC5869 Test Vector #3
+depends_on:MBEDTLS_SHA256_C
+test_hkdf:6:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"":"":"8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8"
+
+HKDF RFC5869 Test Vector #4
+depends_on:MBEDTLS_SHA1_C
+test_hkdf:4:"0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":"085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896"
+
+HKDF RFC5869 Test Vector #5
+depends_on:MBEDTLS_SHA1_C
+test_hkdf:4:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f":"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf":"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4"
+
+HKDF RFC5869 Test Vector #6
+depends_on:MBEDTLS_SHA1_C
+test_hkdf:4:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"":"":"0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918"
+
+HKDF RFC5869 Test Vector #7
+depends_on:MBEDTLS_SHA1_C
+test_hkdf:4:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":"":"":"2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48"
+
+HKDF RFC5869 Test Vector #1 Extract
+depends_on:MBEDTLS_SHA256_C
+test_hkdf_extract:6:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5"
+
+HKDF RFC5869 Test Vector #2 Extract
+depends_on:MBEDTLS_SHA256_C
+test_hkdf_extract:6:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f":"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf":"06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244"
+
+HKDF RFC5869 Test Vector #3 Extract
+depends_on:MBEDTLS_SHA256_C
+test_hkdf_extract:6:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"":"19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04"
+
+HKDF RFC5869 Test Vector #4 Extract
+depends_on:MBEDTLS_SHA1_C
+test_hkdf_extract:4:"0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243"
+
+HKDF RFC5869 Test Vector #5 Extract
+depends_on:MBEDTLS_SHA1_C
+test_hkdf_extract:4:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f":"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf":"8adae09a2a307059478d309b26c4115a224cfaf6"
+
+HKDF RFC5869 Test Vector #6 Extract
+depends_on:MBEDTLS_SHA1_C
+test_hkdf_extract:4:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"":"da8c8a73c7fa77288ec6f5e7c297786aa0d32d01"
+
+HKDF RFC5869 Test Vector #7 Extract
+depends_on:MBEDTLS_SHA1_C
+test_hkdf_extract:4:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":"":"2adccada18779e7c2077ad2eb19d3f3e731385dd"
+
+HKDF RFC5869 Test Vector #1 Expand
+depends_on:MBEDTLS_SHA256_C
+test_hkdf_expand:6:"f0f1f2f3f4f5f6f7f8f9":"077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5":"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"
+
+HKDF RFC5869 Test Vector #2 Expand
+depends_on:MBEDTLS_SHA256_C
+test_hkdf_expand:6:"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244":"b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87"
+
+HKDF RFC5869 Test Vector #3 Expand
+depends_on:MBEDTLS_SHA256_C
+test_hkdf_expand:6:"":"19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04":"8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8"
+
+HKDF RFC5869 Test Vector #4 Expand
+depends_on:MBEDTLS_SHA1_C
+test_hkdf_expand:4:"f0f1f2f3f4f5f6f7f8f9":"9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243":"085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896"
+
+HKDF RFC5869 Test Vector #5 Expand
+depends_on:MBEDTLS_SHA1_C
+test_hkdf_expand:4:"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"8adae09a2a307059478d309b26c4115a224cfaf6":"0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4"
+
+HKDF RFC5869 Test Vector #6 Expand
+depends_on:MBEDTLS_SHA1_C
+test_hkdf_expand:4:"":"da8c8a73c7fa77288ec6f5e7c297786aa0d32d01":"0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918"
+
+HKDF RFC5869 Test Vector #7 Expand
+depends_on:MBEDTLS_SHA1_C
+test_hkdf_expand:4:"":"2adccada18779e7c2077ad2eb19d3f3e731385dd":"2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48"
diff --git a/tests/suites/test_suite_hkdf.function b/tests/suites/test_suite_hkdf.function
new file mode 100644
index 0000000000..c85a51a7a9
--- /dev/null
+++ b/tests/suites/test_suite_hkdf.function
@@ -0,0 +1,170 @@
+/* BEGIN_HEADER */
+#include "mbedtls/hkdf.h"
+#include "mbedtls/md_internal.h"
+/* END_HEADER */
+
+/* BEGIN_DEPENDENCIES
+ * depends_on:MBEDTLS_HKDF_C
+ * END_DEPENDENCIES
+ */
+
+/* BEGIN_CASE */
+void test_hkdf( int md_alg, char *hex_ikm_string, char *hex_salt_string,
+ char *hex_info_string, char *hex_okm_string )
+{
+ int ret;
+ size_t ikm_len, salt_len, info_len, okm_len;
+ unsigned char ikm[1024] = { '\0' };
+ unsigned char salt[1024] = { '\0' };
+ unsigned char info[1024] = { '\0' };
+ unsigned char expected_okm[1024] = { '\0' };
+ unsigned char okm[1024] = { '\0' };
+ unsigned char okm_string[1000] = { '\0' };
+
+ const mbedtls_md_info_t *md = mbedtls_md_info_from_type( md_alg );
+ TEST_ASSERT( md != NULL );
+
+ ikm_len = unhexify( ikm, hex_ikm_string );
+ salt_len = unhexify( salt, hex_salt_string );
+ info_len = unhexify( info, hex_info_string );
+ okm_len = unhexify( expected_okm, hex_okm_string );
+
+ ret = mbedtls_hkdf( md, salt, salt_len, ikm, ikm_len, info, info_len, okm,
+ okm_len);
+ TEST_ASSERT( ret == 0 );
+
+ // Run hexify on it so that it looks nicer if the assertion fails
+ hexify( okm_string, okm, okm_len );
+ TEST_ASSERT( !strcmp( (char *)okm_string, hex_okm_string ) );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void test_hkdf_extract( int md_alg, char *hex_ikm_string,
+ char *hex_salt_string, char *hex_prk_string )
+{
+ int ret;
+ unsigned char *ikm = NULL;
+ unsigned char *salt = NULL;
+ unsigned char *prk = NULL;
+ unsigned char *output_prk = NULL;
+ size_t ikm_len, salt_len, prk_len, output_prk_len;
+
+ const mbedtls_md_info_t *md = mbedtls_md_info_from_type( md_alg );
+ TEST_ASSERT( md != NULL );
+
+ output_prk_len = mbedtls_md_get_size( md );
+ output_prk = mbedtls_calloc( 1, output_prk_len );
+
+ ikm = unhexify_alloc( hex_ikm_string, &ikm_len );
+ salt = unhexify_alloc( hex_salt_string, &salt_len );
+ prk = unhexify_alloc( hex_prk_string, &prk_len );
+ TEST_ASSERT( prk_len == output_prk_len );
+
+ ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, output_prk );
+ TEST_ASSERT( ret == 0 );
+
+ TEST_ASSERT( !memcmp( output_prk, prk, prk_len ) );
+
+exit:
+ mbedtls_free(ikm);
+ mbedtls_free(salt);
+ mbedtls_free(prk);
+ mbedtls_free(output_prk);
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void test_hkdf_expand( int md_alg, char *hex_info_string,
+ char *hex_prk_string, char *hex_okm_string )
+{
+ enum { OKM_LEN = 1024 };
+ int ret;
+ unsigned char *info = NULL;
+ unsigned char *prk = NULL;
+ unsigned char *okm = NULL;
+ unsigned char *output_okm = NULL;
+ size_t info_len, prk_len, okm_len;
+
+ const mbedtls_md_info_t *md = mbedtls_md_info_from_type( md_alg );
+ TEST_ASSERT( md != NULL );
+
+ output_okm = mbedtls_calloc( OKM_LEN, 1 );
+
+ prk = unhexify_alloc( hex_prk_string, &prk_len );
+ info = unhexify_alloc( hex_info_string, &info_len );
+ okm = unhexify_alloc( hex_okm_string, &okm_len );
+ TEST_ASSERT( prk_len == mbedtls_md_get_size( md ) );
+ TEST_ASSERT( okm_len < OKM_LEN );
+
+ ret = mbedtls_hkdf_expand( md, prk, prk_len, info, info_len,
+ output_okm, OKM_LEN );
+ TEST_ASSERT( ret == 0 );
+ TEST_ASSERT( !memcmp( output_okm, okm, okm_len ) );
+
+exit:
+ mbedtls_free(info);
+ mbedtls_free(prk);
+ mbedtls_free(okm);
+ mbedtls_free(output_okm);
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void test_hkdf_extract_ret( int hash_len, int ret )
+{
+ int output_ret;
+ unsigned char *salt = NULL;
+ unsigned char *ikm = NULL;
+ unsigned char *prk = NULL;
+ size_t salt_len, ikm_len;
+ struct mbedtls_md_info_t fake_md_info;
+
+ memset( &fake_md_info, 0, sizeof( fake_md_info ) );
+ fake_md_info.type = MBEDTLS_MD_NONE;
+ fake_md_info.size = hash_len;
+
+ prk = mbedtls_calloc( MBEDTLS_MD_MAX_SIZE, 1 );
+ salt_len = 0;
+ ikm_len = 0;
+
+ output_ret = mbedtls_hkdf_extract( &fake_md_info, salt, salt_len,
+ ikm, ikm_len, prk );
+ TEST_ASSERT( output_ret == ret );
+
+exit:
+ mbedtls_free(prk);
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void test_hkdf_expand_ret( int hash_len, int prk_len, int okm_len, int ret )
+{
+ int output_ret;
+ unsigned char *info = NULL;
+ unsigned char *prk = NULL;
+ unsigned char *okm = NULL;
+ size_t info_len;
+ struct mbedtls_md_info_t fake_md_info;
+
+ memset( &fake_md_info, 0, sizeof( fake_md_info ) );
+ fake_md_info.type = MBEDTLS_MD_NONE;
+ fake_md_info.size = hash_len;
+
+ info_len = 0;
+
+ if (prk_len > 0)
+ prk = mbedtls_calloc( prk_len, 1 );
+
+ if (okm_len > 0)
+ okm = mbedtls_calloc( okm_len, 1 );
+
+ output_ret = mbedtls_hkdf_expand( &fake_md_info, prk, prk_len,
+ info, info_len, okm, okm_len );
+ TEST_ASSERT( output_ret == ret );
+
+exit:
+ mbedtls_free(prk);
+ mbedtls_free(okm);
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data
index 999a93365a..7631791293 100644
--- a/tests/suites/test_suite_version.data
+++ b/tests/suites/test_suite_version.data
@@ -1,8 +1,8 @@
Check compiletime library version
-check_compiletime_version:"2.10.0"
+check_compiletime_version:"2.11.0"
Check runtime library version
-check_runtime_version:"2.10.0"
+check_runtime_version:"2.11.0"
Check for MBEDTLS_VERSION_C
check_feature:"MBEDTLS_VERSION_C":0
diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj
index f93546f4a8..737556affa 100644
--- a/visualc/VS2010/mbedTLS.vcxproj
+++ b/visualc/VS2010/mbedTLS.vcxproj
@@ -179,6 +179,7 @@
+
@@ -250,6 +251,7 @@
+