Release Mbed Crypto 0.1.0a
diff --git a/include/mbedcrypto/aes.h b/include/mbedcrypto/aes.h
new file mode 100644
index 0000000..eecf76c
--- /dev/null
+++ b/include/mbedcrypto/aes.h
@@ -0,0 +1,415 @@
+/**
+ * \file aes.h
+ *
+ * \brief This file contains AES definitions and functions.
+ *
+ * The Advanced Encryption Standard (AES) specifies a FIPS-approved
+ * cryptographic algorithm that can be used to protect electronic
+ * data.
+ *
+ * The AES algorithm is a symmetric block cipher that can
+ * encrypt and decrypt information. For more information, see
+ * <em>FIPS Publication 197: Advanced Encryption Standard</em> and
+ * <em>ISO/IEC 18033-2:2006: Information technology -- Security
+ * techniques -- Encryption algorithms -- Part 2: Asymmetric
+ * ciphers</em>.
+ */
+
+/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+#ifndef MBEDCRYPTO_AES_H
+#define MBEDCRYPTO_AES_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* padlock.c and aesni.c rely on these values! */
+#define MBEDCRYPTO_AES_ENCRYPT 1 /**< AES encryption. */
+#define MBEDCRYPTO_AES_DECRYPT 0 /**< AES decryption. */
+
+/* Error codes in range 0x0020-0x0022 */
+#define MBEDCRYPTO_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
+#define MBEDCRYPTO_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
+
+/* Error codes in range 0x0023-0x0025 */
+#define MBEDCRYPTO_ERR_AES_FEATURE_UNAVAILABLE -0x0023 /**< Feature not available. For example, an unsupported AES key size. */
+#define MBEDCRYPTO_ERR_AES_HW_ACCEL_FAILED -0x0025 /**< AES hardware accelerator failed. */
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+ !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDCRYPTO_AES_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief The AES context-type definition.
+ */
+typedef struct
+{
+ int nr; /*!< The number of rounds. */
+ uint32_t *rk; /*!< AES round keys. */
+ uint32_t buf[68]; /*!< Unaligned data buffer. This buffer can
+ hold 32 extra Bytes, which can be used for
+ one of the following purposes:
+ <ul><li>Alignment if VIA padlock is
+ used.</li>
+ <li>Simplifying key expansion in the 256-bit
+ case by generating an extra round key.
+ </li></ul> */
+}
+mbedcrypto_aes_context;
+
+#else /* MBEDCRYPTO_AES_ALT */
+#include "aes_alt.h"
+#endif /* MBEDCRYPTO_AES_ALT */
+
+/**
+ * \brief This function initializes the specified AES context.
+ *
+ * It must be the first API called before using
+ * the context.
+ *
+ * \param ctx The AES context to initialize.
+ */
+void mbedcrypto_aes_init( mbedcrypto_aes_context *ctx );
+
+/**
+ * \brief This function releases and clears the specified AES context.
+ *
+ * \param ctx The AES context to clear.
+ */
+void mbedcrypto_aes_free( mbedcrypto_aes_context *ctx );
+
+/**
+ * \brief This function sets the encryption key.
+ *
+ * \param ctx The AES context to which the key should be bound.
+ * \param key The encryption key.
+ * \param keybits The size of data passed in bits. Valid options are:
+ * <ul><li>128 bits</li>
+ * <li>192 bits</li>
+ * <li>256 bits</li></ul>
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_AES_INVALID_KEY_LENGTH on failure.
+ */
+int mbedcrypto_aes_setkey_enc( mbedcrypto_aes_context *ctx, const unsigned char *key,
+ unsigned int keybits );
+
+/**
+ * \brief This function sets the decryption key.
+ *
+ * \param ctx The AES context to which the key should be bound.
+ * \param key The decryption key.
+ * \param keybits The size of data passed. Valid options are:
+ * <ul><li>128 bits</li>
+ * <li>192 bits</li>
+ * <li>256 bits</li></ul>
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_AES_INVALID_KEY_LENGTH on failure.
+ */
+int mbedcrypto_aes_setkey_dec( mbedcrypto_aes_context *ctx, const unsigned char *key,
+ unsigned int keybits );
+
+/**
+ * \brief This function performs an AES single-block encryption or
+ * decryption operation.
+ *
+ * It performs the operation defined in the \p mode parameter
+ * (encrypt or decrypt), on the input data buffer defined in
+ * the \p input parameter.
+ *
+ * mbedcrypto_aes_init(), and either mbedcrypto_aes_setkey_enc() or
+ * mbedcrypto_aes_setkey_dec() must be called before the first
+ * call to this API with the same context.
+ *
+ * \param ctx The AES context to use for encryption or decryption.
+ * \param mode The AES operation: #MBEDCRYPTO_AES_ENCRYPT or
+ * #MBEDCRYPTO_AES_DECRYPT.
+ * \param input The 16-Byte buffer holding the input data.
+ * \param output The 16-Byte buffer holding the output data.
+
+ * \return \c 0 on success.
+ */
+int mbedcrypto_aes_crypt_ecb( mbedcrypto_aes_context *ctx,
+ int mode,
+ const unsigned char input[16],
+ unsigned char output[16] );
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_CBC)
+/**
+ * \brief This function performs an AES-CBC encryption or decryption operation
+ * on full blocks.
+ *
+ * It performs the operation defined in the \p mode
+ * parameter (encrypt/decrypt), on the input data buffer defined in
+ * the \p input parameter.
+ *
+ * It can be called as many times as needed, until all the input
+ * data is processed. mbedcrypto_aes_init(), and either
+ * mbedcrypto_aes_setkey_enc() or mbedcrypto_aes_setkey_dec() must be called
+ * before the first call to this API with the same context.
+ *
+ * \note This function operates on aligned blocks, that is, the input size
+ * must be a multiple of the AES block size of 16 Bytes.
+ *
+ * \note Upon exit, the content of the IV is updated so that you can
+ * call the same function again on the next
+ * block(s) of data and get the same result as if it was
+ * encrypted in one call. This allows a "streaming" usage.
+ * If you need to retain the contents of the IV, you should
+ * either save it manually or use the cipher module instead.
+ *
+ *
+ * \param ctx The AES context to use for encryption or decryption.
+ * \param mode The AES operation: #MBEDCRYPTO_AES_ENCRYPT or
+ * #MBEDCRYPTO_AES_DECRYPT.
+ * \param length The length of the input data in Bytes. This must be a
+ * multiple of the block size (16 Bytes).
+ * \param iv 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.
+ * \return #MBEDCRYPTO_ERR_AES_INVALID_INPUT_LENGTH
+ * on failure.
+ */
+int mbedcrypto_aes_crypt_cbc( mbedcrypto_aes_context *ctx,
+ int mode,
+ size_t length,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output );
+#endif /* MBEDCRYPTO_CIPHER_MODE_CBC */
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_CFB)
+/**
+ * \brief This function performs an AES-CFB128 encryption or decryption
+ * operation.
+ *
+ * It performs the operation defined in the \p mode
+ * parameter (encrypt or decrypt), on the input data buffer
+ * defined in the \p input parameter.
+ *
+ * For CFB, you must set up the context with mbedcrypto_aes_setkey_enc(),
+ * regardless of whether you are performing an encryption or decryption
+ * operation, that is, regardless of the \p mode parameter. This is
+ * because CFB mode uses the same key schedule for encryption and
+ * decryption.
+ *
+ * \note Upon exit, the content of the IV is updated so that you can
+ * call the same function again on the next
+ * block(s) of data and get the same result as if it was
+ * encrypted in one call. This allows a "streaming" usage.
+ * If you need to retain the contents of the
+ * IV, you must either save it manually or use the cipher
+ * module instead.
+ *
+ *
+ * \param ctx The AES context to use for encryption or decryption.
+ * \param mode The AES operation: #MBEDCRYPTO_AES_ENCRYPT or
+ * #MBEDCRYPTO_AES_DECRYPT.
+ * \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 mbedcrypto_aes_crypt_cfb128( mbedcrypto_aes_context *ctx,
+ int mode,
+ size_t length,
+ size_t *iv_off,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief This function performs an AES-CFB8 encryption or decryption
+ * operation.
+ *
+ * It performs the operation defined in the \p mode
+ * parameter (encrypt/decrypt), on the input data buffer defined
+ * in the \p input parameter.
+ *
+ * Due to the nature of CFB, you must use the same key schedule for
+ * both encryption and decryption operations. Therefore, you must
+ * use the context initialized with mbedcrypto_aes_setkey_enc() for
+ * both #MBEDCRYPTO_AES_ENCRYPT and #MBEDCRYPTO_AES_DECRYPT.
+ *
+ * \note Upon exit, the content of the IV is updated so that you can
+ * call the same function again on the next
+ * block(s) of data and get the same result as if it was
+ * encrypted in one call. This allows a "streaming" usage.
+ * If you need to retain the contents of the
+ * IV, you should either save it manually or use the cipher
+ * module instead.
+ *
+ *
+ * \param ctx The AES context to use for encryption or decryption.
+ * \param mode The AES operation: #MBEDCRYPTO_AES_ENCRYPT or
+ * #MBEDCRYPTO_AES_DECRYPT
+ * \param length The length of the input data.
+ * \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 mbedcrypto_aes_crypt_cfb8( mbedcrypto_aes_context *ctx,
+ int mode,
+ size_t length,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output );
+#endif /*MBEDCRYPTO_CIPHER_MODE_CFB */
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_CTR)
+/**
+ * \brief This function performs an AES-CTR encryption or decryption
+ * operation.
+ *
+ * This function performs the operation defined in the \p mode
+ * parameter (encrypt/decrypt), on the input data buffer
+ * defined in the \p input parameter.
+ *
+ * Due to the nature of CTR, you must use the same key schedule
+ * for both encryption and decryption operations. Therefore, you
+ * must use the context initialized with mbedcrypto_aes_setkey_enc()
+ * for both #MBEDCRYPTO_AES_ENCRYPT and #MBEDCRYPTO_AES_DECRYPT.
+ *
+ * \warning You must keep the maximum use of your counter in mind.
+ *
+ * \param ctx The AES context to use for encryption or decryption.
+ * \param length The length of the input data.
+ * \param nc_off The offset in the current \p stream_block, for
+ * resuming within the current cipher stream. The
+ * offset pointer should be 0 at the start of a stream.
+ * \param nonce_counter The 128-bit nonce and counter.
+ * \param stream_block The saved stream block for resuming. This is
+ * overwritten by the function.
+ * \param input The buffer holding the input data.
+ * \param output The buffer holding the output data.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_aes_crypt_ctr( mbedcrypto_aes_context *ctx,
+ size_t length,
+ size_t *nc_off,
+ unsigned char nonce_counter[16],
+ unsigned char stream_block[16],
+ const unsigned char *input,
+ unsigned char *output );
+#endif /* MBEDCRYPTO_CIPHER_MODE_CTR */
+
+/**
+ * \brief Internal AES block encryption function. This is only
+ * exposed to allow overriding it using
+ * \c MBEDCRYPTO_AES_ENCRYPT_ALT.
+ *
+ * \param ctx The AES context to use for encryption.
+ * \param input The plaintext block.
+ * \param output The output (ciphertext) block.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_internal_aes_encrypt( mbedcrypto_aes_context *ctx,
+ const unsigned char input[16],
+ unsigned char output[16] );
+
+/**
+ * \brief Internal AES block decryption function. This is only
+ * exposed to allow overriding it using see
+ * \c MBEDCRYPTO_AES_DECRYPT_ALT.
+ *
+ * \param ctx The AES context to use for decryption.
+ * \param input The ciphertext block.
+ * \param output The output (plaintext) block.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_internal_aes_decrypt( mbedcrypto_aes_context *ctx,
+ const unsigned char input[16],
+ unsigned char output[16] );
+
+#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
+#if defined(MBEDCRYPTO_DEPRECATED_WARNING)
+#define MBEDCRYPTO_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDCRYPTO_DEPRECATED
+#endif
+/**
+ * \brief Deprecated internal AES block encryption function
+ * without return value.
+ *
+ * \deprecated Superseded by mbedcrypto_aes_encrypt_ext() in 2.5.0.
+ *
+ * \param ctx The AES context to use for encryption.
+ * \param input Plaintext block.
+ * \param output Output (ciphertext) block.
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_aes_encrypt( mbedcrypto_aes_context *ctx,
+ const unsigned char input[16],
+ unsigned char output[16] );
+
+/**
+ * \brief Deprecated internal AES block decryption function
+ * without return value.
+ *
+ * \deprecated Superseded by mbedcrypto_aes_decrypt_ext() in 2.5.0.
+ *
+ * \param ctx The AES context to use for decryption.
+ * \param input Ciphertext block.
+ * \param output Output (plaintext) block.
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_aes_decrypt( mbedcrypto_aes_context *ctx,
+ const unsigned char input[16],
+ unsigned char output[16] );
+
+#undef MBEDCRYPTO_DEPRECATED
+#endif /* !MBEDCRYPTO_DEPRECATED_REMOVED */
+
+/**
+ * \brief Checkup routine.
+ *
+ * \return \c 0 on success.
+ * \return \c 1 on failure.
+ */
+int mbedcrypto_aes_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* aes.h */
diff --git a/include/mbedcrypto/aesni.h b/include/mbedcrypto/aesni.h
new file mode 100644
index 0000000..c68e360
--- /dev/null
+++ b/include/mbedcrypto/aesni.h
@@ -0,0 +1,112 @@
+/**
+ * \file aesni.h
+ *
+ * \brief AES-NI for hardware AES acceleration on some Intel processors
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_AESNI_H
+#define MBEDCRYPTO_AESNI_H
+
+#include "aes.h"
+
+#define MBEDCRYPTO_AESNI_AES 0x02000000u
+#define MBEDCRYPTO_AESNI_CLMUL 0x00000002u
+
+#if defined(MBEDCRYPTO_HAVE_ASM) && defined(__GNUC__) && \
+ ( defined(__amd64__) || defined(__x86_64__) ) && \
+ ! defined(MBEDCRYPTO_HAVE_X86_64)
+#define MBEDCRYPTO_HAVE_X86_64
+#endif
+
+#if defined(MBEDCRYPTO_HAVE_X86_64)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief AES-NI features detection routine
+ *
+ * \param what The feature to detect
+ * (MBEDCRYPTO_AESNI_AES or MBEDCRYPTO_AESNI_CLMUL)
+ *
+ * \return 1 if CPU has support for the feature, 0 otherwise
+ */
+int mbedcrypto_aesni_has_support( unsigned int what );
+
+/**
+ * \brief AES-NI AES-ECB block en(de)cryption
+ *
+ * \param ctx AES context
+ * \param mode MBEDCRYPTO_AES_ENCRYPT or MBEDCRYPTO_AES_DECRYPT
+ * \param input 16-byte input block
+ * \param output 16-byte output block
+ *
+ * \return 0 on success (cannot fail)
+ */
+int mbedcrypto_aesni_crypt_ecb( mbedcrypto_aes_context *ctx,
+ int mode,
+ const unsigned char input[16],
+ unsigned char output[16] );
+
+/**
+ * \brief GCM multiplication: c = a * b in GF(2^128)
+ *
+ * \param c Result
+ * \param a First operand
+ * \param b Second operand
+ *
+ * \note Both operands and result are bit strings interpreted as
+ * elements of GF(2^128) as per the GCM spec.
+ */
+void mbedcrypto_aesni_gcm_mult( unsigned char c[16],
+ const unsigned char a[16],
+ const unsigned char b[16] );
+
+/**
+ * \brief Compute decryption round keys from encryption round keys
+ *
+ * \param invkey Round keys for the equivalent inverse cipher
+ * \param fwdkey Original round keys (for encryption)
+ * \param nr Number of rounds (that is, number of round keys minus one)
+ */
+void mbedcrypto_aesni_inverse_key( unsigned char *invkey,
+ const unsigned char *fwdkey, int nr );
+
+/**
+ * \brief Perform key expansion (for encryption)
+ *
+ * \param rk Destination buffer where the round keys are written
+ * \param key Encryption key
+ * \param bits Key size in bits (must be 128, 192 or 256)
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_AES_INVALID_KEY_LENGTH
+ */
+int mbedcrypto_aesni_setkey_enc( unsigned char *rk,
+ const unsigned char *key,
+ size_t bits );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDCRYPTO_HAVE_X86_64 */
+
+#endif /* MBEDCRYPTO_AESNI_H */
diff --git a/include/mbedcrypto/arc4.h b/include/mbedcrypto/arc4.h
new file mode 100644
index 0000000..32c3abb
--- /dev/null
+++ b/include/mbedcrypto/arc4.h
@@ -0,0 +1,141 @@
+/**
+ * \file arc4.h
+ *
+ * \brief The ARCFOUR stream cipher
+ *
+ * \warning ARC4 is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers instead.
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ *
+ */
+#ifndef MBEDCRYPTO_ARC4_H
+#define MBEDCRYPTO_ARC4_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+
+#define MBEDCRYPTO_ERR_ARC4_HW_ACCEL_FAILED -0x0019 /**< ARC4 hardware accelerator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDCRYPTO_ARC4_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief ARC4 context structure
+ *
+ * \warning ARC4 is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers instead.
+ *
+ */
+typedef struct
+{
+ int x; /*!< permutation index */
+ int y; /*!< permutation index */
+ unsigned char m[256]; /*!< permutation table */
+}
+mbedcrypto_arc4_context;
+
+#else /* MBEDCRYPTO_ARC4_ALT */
+#include "arc4_alt.h"
+#endif /* MBEDCRYPTO_ARC4_ALT */
+
+/**
+ * \brief Initialize ARC4 context
+ *
+ * \param ctx ARC4 context to be initialized
+ *
+ * \warning ARC4 is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers
+ * instead.
+ *
+ */
+void mbedcrypto_arc4_init( mbedcrypto_arc4_context *ctx );
+
+/**
+ * \brief Clear ARC4 context
+ *
+ * \param ctx ARC4 context to be cleared
+ *
+ * \warning ARC4 is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers
+ * instead.
+ *
+ */
+void mbedcrypto_arc4_free( mbedcrypto_arc4_context *ctx );
+
+/**
+ * \brief ARC4 key schedule
+ *
+ * \param ctx ARC4 context to be setup
+ * \param key the secret key
+ * \param keylen length of the key, in bytes
+ *
+ * \warning ARC4 is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers
+ * instead.
+ *
+ */
+void mbedcrypto_arc4_setup( mbedcrypto_arc4_context *ctx, const unsigned char *key,
+ unsigned int keylen );
+
+/**
+ * \brief ARC4 cipher function
+ *
+ * \param ctx ARC4 context
+ * \param length length of the input data
+ * \param input buffer holding the input data
+ * \param output buffer for the output data
+ *
+ * \return 0 if successful
+ *
+ * \warning ARC4 is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers
+ * instead.
+ *
+ */
+int mbedcrypto_arc4_crypt( mbedcrypto_arc4_context *ctx, size_t length, const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ *
+ * \warning ARC4 is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers
+ * instead.
+ *
+ */
+int mbedcrypto_arc4_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* arc4.h */
diff --git a/include/mbedcrypto/asn1.h b/include/mbedcrypto/asn1.h
new file mode 100644
index 0000000..d815c4d
--- /dev/null
+++ b/include/mbedcrypto/asn1.h
@@ -0,0 +1,358 @@
+/**
+ * \file asn1.h
+ *
+ * \brief Generic ASN.1 parsing
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_ASN1_H
+#define MBEDCRYPTO_ASN1_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+
+#if defined(MBEDCRYPTO_BIGNUM_C)
+#include "bignum.h"
+#endif
+
+/**
+ * \addtogroup asn1_module
+ * \{
+ */
+
+/**
+ * \name ASN1 Error codes
+ * These error codes are OR'ed to X509 error codes for
+ * higher error granularity.
+ * ASN1 is a standard to specify data structures.
+ * \{
+ */
+#define MBEDCRYPTO_ERR_ASN1_OUT_OF_DATA -0x0060 /**< Out of data when parsing an ASN1 data structure. */
+#define MBEDCRYPTO_ERR_ASN1_UNEXPECTED_TAG -0x0062 /**< ASN1 tag was of an unexpected value. */
+#define MBEDCRYPTO_ERR_ASN1_INVALID_LENGTH -0x0064 /**< Error when trying to determine the length or invalid length. */
+#define MBEDCRYPTO_ERR_ASN1_LENGTH_MISMATCH -0x0066 /**< Actual length differs from expected length. */
+#define MBEDCRYPTO_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. (not used) */
+#define MBEDCRYPTO_ERR_ASN1_ALLOC_FAILED -0x006A /**< Memory allocation failed */
+#define MBEDCRYPTO_ERR_ASN1_BUF_TOO_SMALL -0x006C /**< Buffer too small when writing ASN.1 data structure. */
+
+/* \} name */
+
+/**
+ * \name DER constants
+ * These constants comply with the DER encoded ASN.1 type tags.
+ * DER encoding uses hexadecimal representation.
+ * An example DER sequence is:\n
+ * - 0x02 -- tag indicating INTEGER
+ * - 0x01 -- length in octets
+ * - 0x05 -- value
+ * Such sequences are typically read into \c ::mbedcrypto_x509_buf.
+ * \{
+ */
+#define MBEDCRYPTO_ASN1_BOOLEAN 0x01
+#define MBEDCRYPTO_ASN1_INTEGER 0x02
+#define MBEDCRYPTO_ASN1_BIT_STRING 0x03
+#define MBEDCRYPTO_ASN1_OCTET_STRING 0x04
+#define MBEDCRYPTO_ASN1_NULL 0x05
+#define MBEDCRYPTO_ASN1_OID 0x06
+#define MBEDCRYPTO_ASN1_UTF8_STRING 0x0C
+#define MBEDCRYPTO_ASN1_SEQUENCE 0x10
+#define MBEDCRYPTO_ASN1_SET 0x11
+#define MBEDCRYPTO_ASN1_PRINTABLE_STRING 0x13
+#define MBEDCRYPTO_ASN1_T61_STRING 0x14
+#define MBEDCRYPTO_ASN1_IA5_STRING 0x16
+#define MBEDCRYPTO_ASN1_UTC_TIME 0x17
+#define MBEDCRYPTO_ASN1_GENERALIZED_TIME 0x18
+#define MBEDCRYPTO_ASN1_UNIVERSAL_STRING 0x1C
+#define MBEDCRYPTO_ASN1_BMP_STRING 0x1E
+#define MBEDCRYPTO_ASN1_PRIMITIVE 0x00
+#define MBEDCRYPTO_ASN1_CONSTRUCTED 0x20
+#define MBEDCRYPTO_ASN1_CONTEXT_SPECIFIC 0x80
+
+/*
+ * Bit masks for each of the components of an ASN.1 tag as specified in
+ * ITU X.690 (08/2015), section 8.1 "General rules for encoding",
+ * paragraph 8.1.2.2:
+ *
+ * Bit 8 7 6 5 1
+ * +-------+-----+------------+
+ * | Class | P/C | Tag number |
+ * +-------+-----+------------+
+ */
+#define MBEDCRYPTO_ASN1_TAG_CLASS_MASK 0xC0
+#define MBEDCRYPTO_ASN1_TAG_PC_MASK 0x20
+#define MBEDCRYPTO_ASN1_TAG_VALUE_MASK 0x1F
+
+/* \} name */
+/* \} addtogroup asn1_module */
+
+/** Returns the size of the binary string, without the trailing \\0 */
+#define MBEDCRYPTO_OID_SIZE(x) (sizeof(x) - 1)
+
+/**
+ * Compares an mbedcrypto_asn1_buf structure to a reference OID.
+ *
+ * Only works for 'defined' oid_str values (MBEDCRYPTO_OID_HMAC_SHA1), you cannot use a
+ * 'unsigned char *oid' here!
+ */
+#define MBEDCRYPTO_OID_CMP(oid_str, oid_buf) \
+ ( ( MBEDCRYPTO_OID_SIZE(oid_str) != (oid_buf)->len ) || \
+ memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 )
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \name Functions to parse ASN.1 data structures
+ * \{
+ */
+
+/**
+ * Type-length-value structure that allows for ASN1 using DER.
+ */
+typedef struct mbedcrypto_asn1_buf
+{
+ int tag; /**< ASN1 type, e.g. MBEDCRYPTO_ASN1_UTF8_STRING. */
+ size_t len; /**< ASN1 length, in octets. */
+ unsigned char *p; /**< ASN1 data, e.g. in ASCII. */
+}
+mbedcrypto_asn1_buf;
+
+/**
+ * Container for ASN1 bit strings.
+ */
+typedef struct mbedcrypto_asn1_bitstring
+{
+ size_t len; /**< ASN1 length, in octets. */
+ unsigned char unused_bits; /**< Number of unused bits at the end of the string */
+ unsigned char *p; /**< Raw ASN1 data for the bit string */
+}
+mbedcrypto_asn1_bitstring;
+
+/**
+ * Container for a sequence of ASN.1 items
+ */
+typedef struct mbedcrypto_asn1_sequence
+{
+ mbedcrypto_asn1_buf buf; /**< Buffer containing the given ASN.1 item. */
+ struct mbedcrypto_asn1_sequence *next; /**< The next entry in the sequence. */
+}
+mbedcrypto_asn1_sequence;
+
+/**
+ * Container for a sequence or list of 'named' ASN.1 data items
+ */
+typedef struct mbedcrypto_asn1_named_data
+{
+ mbedcrypto_asn1_buf oid; /**< The object identifier. */
+ mbedcrypto_asn1_buf val; /**< The named value. */
+ struct mbedcrypto_asn1_named_data *next; /**< The next entry in the sequence. */
+ unsigned char next_merged; /**< Merge next item into the current one? */
+}
+mbedcrypto_asn1_named_data;
+
+/**
+ * \brief Get the length of an ASN.1 element.
+ * Updates the pointer to immediately behind the length.
+ *
+ * \param p The position in the ASN.1 data
+ * \param end End of data
+ * \param len The variable that will receive the value
+ *
+ * \return 0 if successful, MBEDCRYPTO_ERR_ASN1_OUT_OF_DATA on reaching
+ * end of data, MBEDCRYPTO_ERR_ASN1_INVALID_LENGTH if length is
+ * unparseable.
+ */
+int mbedcrypto_asn1_get_len( unsigned char **p,
+ const unsigned char *end,
+ size_t *len );
+
+/**
+ * \brief Get the tag and length of the tag. Check for the requested tag.
+ * Updates the pointer to immediately behind the tag and length.
+ *
+ * \param p The position in the ASN.1 data
+ * \param end End of data
+ * \param len The variable that will receive the length
+ * \param tag The expected tag
+ *
+ * \return 0 if successful, MBEDCRYPTO_ERR_ASN1_UNEXPECTED_TAG if tag did
+ * not match requested tag, or another specific ASN.1 error code.
+ */
+int mbedcrypto_asn1_get_tag( unsigned char **p,
+ const unsigned char *end,
+ size_t *len, int tag );
+
+/**
+ * \brief Retrieve a boolean ASN.1 tag and its value.
+ * Updates the pointer to immediately behind the full tag.
+ *
+ * \param p The position in the ASN.1 data
+ * \param end End of data
+ * \param val The variable that will receive the value
+ *
+ * \return 0 if successful or a specific ASN.1 error code.
+ */
+int mbedcrypto_asn1_get_bool( unsigned char **p,
+ const unsigned char *end,
+ int *val );
+
+/**
+ * \brief Retrieve an integer ASN.1 tag and its value.
+ * Updates the pointer to immediately behind the full tag.
+ *
+ * \param p The position in the ASN.1 data
+ * \param end End of data
+ * \param val The variable that will receive the value
+ *
+ * \return 0 if successful or a specific ASN.1 error code.
+ */
+int mbedcrypto_asn1_get_int( unsigned char **p,
+ const unsigned char *end,
+ int *val );
+
+/**
+ * \brief Retrieve a bitstring ASN.1 tag and its value.
+ * Updates the pointer to immediately behind the full tag.
+ *
+ * \param p The position in the ASN.1 data
+ * \param end End of data
+ * \param bs The variable that will receive the value
+ *
+ * \return 0 if successful or a specific ASN.1 error code.
+ */
+int mbedcrypto_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
+ mbedcrypto_asn1_bitstring *bs);
+
+/**
+ * \brief Retrieve a bitstring ASN.1 tag without unused bits and its
+ * value.
+ * Updates the pointer to the beginning of the bit/octet string.
+ *
+ * \param p The position in the ASN.1 data
+ * \param end End of data
+ * \param len Length of the actual bit/octect string in bytes
+ *
+ * \return 0 if successful or a specific ASN.1 error code.
+ */
+int mbedcrypto_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
+ size_t *len );
+
+/**
+ * \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>"
+ * Updated the pointer to immediately behind the full sequence tag.
+ *
+ * \param p The position in the ASN.1 data
+ * \param end End of data
+ * \param cur First variable in the chain to fill
+ * \param tag Type of sequence
+ *
+ * \return 0 if successful or a specific ASN.1 error code.
+ */
+int mbedcrypto_asn1_get_sequence_of( unsigned char **p,
+ const unsigned char *end,
+ mbedcrypto_asn1_sequence *cur,
+ int tag);
+
+#if defined(MBEDCRYPTO_BIGNUM_C)
+/**
+ * \brief Retrieve a MPI value from an integer ASN.1 tag.
+ * Updates the pointer to immediately behind the full tag.
+ *
+ * \param p The position in the ASN.1 data
+ * \param end End of data
+ * \param X The MPI that will receive the value
+ *
+ * \return 0 if successful or a specific ASN.1 or MPI error code.
+ */
+int mbedcrypto_asn1_get_mpi( unsigned char **p,
+ const unsigned char *end,
+ mbedcrypto_mpi *X );
+#endif /* MBEDCRYPTO_BIGNUM_C */
+
+/**
+ * \brief Retrieve an AlgorithmIdentifier ASN.1 sequence.
+ * Updates the pointer to immediately behind the full
+ * AlgorithmIdentifier.
+ *
+ * \param p The position in the ASN.1 data
+ * \param end End of data
+ * \param alg The buffer to receive the OID
+ * \param params The buffer to receive the params (if any)
+ *
+ * \return 0 if successful or a specific ASN.1 or MPI error code.
+ */
+int mbedcrypto_asn1_get_alg( unsigned char **p,
+ const unsigned char *end,
+ mbedcrypto_asn1_buf *alg, mbedcrypto_asn1_buf *params );
+
+/**
+ * \brief Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no
+ * params.
+ * Updates the pointer to immediately behind the full
+ * AlgorithmIdentifier.
+ *
+ * \param p The position in the ASN.1 data
+ * \param end End of data
+ * \param alg The buffer to receive the OID
+ *
+ * \return 0 if successful or a specific ASN.1 or MPI error code.
+ */
+int mbedcrypto_asn1_get_alg_null( unsigned char **p,
+ const unsigned char *end,
+ mbedcrypto_asn1_buf *alg );
+
+/**
+ * \brief Find a specific named_data entry in a sequence or list based on
+ * the OID.
+ *
+ * \param list The list to seek through
+ * \param oid The OID to look for
+ * \param len Size of the OID
+ *
+ * \return NULL if not found, or a pointer to the existing entry.
+ */
+mbedcrypto_asn1_named_data *mbedcrypto_asn1_find_named_data( mbedcrypto_asn1_named_data *list,
+ const char *oid, size_t len );
+
+/**
+ * \brief Free a mbedcrypto_asn1_named_data entry
+ *
+ * \param entry The named data entry to free
+ */
+void mbedcrypto_asn1_free_named_data( mbedcrypto_asn1_named_data *entry );
+
+/**
+ * \brief Free all entries in a mbedcrypto_asn1_named_data list
+ * Head will be set to NULL
+ *
+ * \param head Pointer to the head of the list of named data entries to free
+ */
+void mbedcrypto_asn1_free_named_data_list( mbedcrypto_asn1_named_data **head );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* asn1.h */
diff --git a/include/mbedcrypto/asn1write.h b/include/mbedcrypto/asn1write.h
new file mode 100644
index 0000000..cc134ce
--- /dev/null
+++ b/include/mbedcrypto/asn1write.h
@@ -0,0 +1,240 @@
+/**
+ * \file asn1write.h
+ *
+ * \brief ASN.1 buffer writing functionality
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_ASN1_WRITE_H
+#define MBEDCRYPTO_ASN1_WRITE_H
+
+#include "asn1.h"
+
+#define MBEDCRYPTO_ASN1_CHK_ADD(g, f) do { if( ( ret = f ) < 0 ) return( ret ); else \
+ g += ret; } while( 0 )
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Write a length field in ASN.1 format
+ * Note: function works backwards in data buffer
+ *
+ * \param p reference to current position pointer
+ * \param start start of the buffer (for bounds-checking)
+ * \param len the length to write
+ *
+ * \return the length written or a negative error code
+ */
+int mbedcrypto_asn1_write_len( unsigned char **p, unsigned char *start, size_t len );
+
+/**
+ * \brief Write a ASN.1 tag in ASN.1 format
+ * Note: function works backwards in data buffer
+ *
+ * \param p reference to current position pointer
+ * \param start start of the buffer (for bounds-checking)
+ * \param tag the tag to write
+ *
+ * \return the length written or a negative error code
+ */
+int mbedcrypto_asn1_write_tag( unsigned char **p, unsigned char *start,
+ unsigned char tag );
+
+/**
+ * \brief Write raw buffer data
+ * Note: function works backwards in data buffer
+ *
+ * \param p reference to current position pointer
+ * \param start start of the buffer (for bounds-checking)
+ * \param buf data buffer to write
+ * \param size length of the data buffer
+ *
+ * \return the length written or a negative error code
+ */
+int mbedcrypto_asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
+ const unsigned char *buf, size_t size );
+
+#if defined(MBEDCRYPTO_BIGNUM_C)
+/**
+ * \brief Write a big number (MBEDCRYPTO_ASN1_INTEGER) in ASN.1 format
+ * Note: function works backwards in data buffer
+ *
+ * \param p reference to current position pointer
+ * \param start start of the buffer (for bounds-checking)
+ * \param X the MPI to write
+ *
+ * \return the length written or a negative error code
+ */
+int mbedcrypto_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedcrypto_mpi *X );
+#endif /* MBEDCRYPTO_BIGNUM_C */
+
+/**
+ * \brief Write a NULL tag (MBEDCRYPTO_ASN1_NULL) with zero data in ASN.1 format
+ * Note: function works backwards in data buffer
+ *
+ * \param p reference to current position pointer
+ * \param start start of the buffer (for bounds-checking)
+ *
+ * \return the length written or a negative error code
+ */
+int mbedcrypto_asn1_write_null( unsigned char **p, unsigned char *start );
+
+/**
+ * \brief Write an OID tag (MBEDCRYPTO_ASN1_OID) and data in ASN.1 format
+ * Note: function works backwards in data buffer
+ *
+ * \param p reference to current position pointer
+ * \param start start of the buffer (for bounds-checking)
+ * \param oid the OID to write
+ * \param oid_len length of the OID
+ *
+ * \return the length written or a negative error code
+ */
+int mbedcrypto_asn1_write_oid( unsigned char **p, unsigned char *start,
+ const char *oid, size_t oid_len );
+
+/**
+ * \brief Write an AlgorithmIdentifier sequence in ASN.1 format
+ * Note: function works backwards in data buffer
+ *
+ * \param p reference to current position pointer
+ * \param start start of the buffer (for bounds-checking)
+ * \param oid the OID of the algorithm
+ * \param oid_len length of the OID
+ * \param par_len length of parameters, which must be already written.
+ * If 0, NULL parameters are added
+ *
+ * \return the length written or a negative error code
+ */
+int mbedcrypto_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
+ const char *oid, size_t oid_len,
+ size_t par_len );
+
+/**
+ * \brief Write a boolean tag (MBEDCRYPTO_ASN1_BOOLEAN) and value in ASN.1 format
+ * Note: function works backwards in data buffer
+ *
+ * \param p reference to current position pointer
+ * \param start start of the buffer (for bounds-checking)
+ * \param boolean 0 or 1
+ *
+ * \return the length written or a negative error code
+ */
+int mbedcrypto_asn1_write_bool( unsigned char **p, unsigned char *start, int boolean );
+
+/**
+ * \brief Write an int tag (MBEDCRYPTO_ASN1_INTEGER) and value in ASN.1 format
+ * Note: function works backwards in data buffer
+ *
+ * \param p reference to current position pointer
+ * \param start start of the buffer (for bounds-checking)
+ * \param val the integer value
+ *
+ * \return the length written or a negative error code
+ */
+int mbedcrypto_asn1_write_int( unsigned char **p, unsigned char *start, int val );
+
+/**
+ * \brief Write a printable string tag (MBEDCRYPTO_ASN1_PRINTABLE_STRING) and
+ * value in ASN.1 format
+ * Note: function works backwards in data buffer
+ *
+ * \param p reference to current position pointer
+ * \param start start of the buffer (for bounds-checking)
+ * \param text the text to write
+ * \param text_len length of the text
+ *
+ * \return the length written or a negative error code
+ */
+int mbedcrypto_asn1_write_printable_string( unsigned char **p, unsigned char *start,
+ const char *text, size_t text_len );
+
+/**
+ * \brief Write an IA5 string tag (MBEDCRYPTO_ASN1_IA5_STRING) and
+ * value in ASN.1 format
+ * Note: function works backwards in data buffer
+ *
+ * \param p reference to current position pointer
+ * \param start start of the buffer (for bounds-checking)
+ * \param text the text to write
+ * \param text_len length of the text
+ *
+ * \return the length written or a negative error code
+ */
+int mbedcrypto_asn1_write_ia5_string( unsigned char **p, unsigned char *start,
+ const char *text, size_t text_len );
+
+/**
+ * \brief Write a bitstring tag (MBEDCRYPTO_ASN1_BIT_STRING) and
+ * value in ASN.1 format
+ * Note: function works backwards in data buffer
+ *
+ * \param p reference to current position pointer
+ * \param start start of the buffer (for bounds-checking)
+ * \param buf the bitstring
+ * \param bits the total number of bits in the bitstring
+ *
+ * \return the length written or a negative error code
+ */
+int mbedcrypto_asn1_write_bitstring( unsigned char **p, unsigned char *start,
+ const unsigned char *buf, size_t bits );
+
+/**
+ * \brief Write an octet string tag (MBEDCRYPTO_ASN1_OCTET_STRING) and
+ * value in ASN.1 format
+ * Note: function works backwards in data buffer
+ *
+ * \param p reference to current position pointer
+ * \param start start of the buffer (for bounds-checking)
+ * \param buf data buffer to write
+ * \param size length of the data buffer
+ *
+ * \return the length written or a negative error code
+ */
+int mbedcrypto_asn1_write_octet_string( unsigned char **p, unsigned char *start,
+ const unsigned char *buf, size_t size );
+
+/**
+ * \brief Create or find a specific named_data entry for writing in a
+ * sequence or list based on the OID. If not already in there,
+ * a new entry is added to the head of the list.
+ * Warning: Destructive behaviour for the val data!
+ *
+ * \param list Pointer to the location of the head of the list to seek
+ * through (will be updated in case of a new entry)
+ * \param oid The OID to look for
+ * \param oid_len Size of the OID
+ * \param val Data to store (can be NULL if you want to fill it by hand)
+ * \param val_len Minimum length of the data buffer needed
+ *
+ * \return NULL if if there was a memory allocation error, or a pointer
+ * to the new / existing entry.
+ */
+mbedcrypto_asn1_named_data *mbedcrypto_asn1_store_named_data( mbedcrypto_asn1_named_data **list,
+ const char *oid, size_t oid_len,
+ const unsigned char *val,
+ size_t val_len );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDCRYPTO_ASN1_WRITE_H */
diff --git a/include/mbedcrypto/base64.h b/include/mbedcrypto/base64.h
new file mode 100644
index 0000000..21b4622
--- /dev/null
+++ b/include/mbedcrypto/base64.h
@@ -0,0 +1,89 @@
+/**
+ * \file base64.h
+ *
+ * \brief RFC 1521 base64 encoding/decoding
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_BASE64_H
+#define MBEDCRYPTO_BASE64_H
+
+#include <stddef.h>
+
+#define MBEDCRYPTO_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */
+#define MBEDCRYPTO_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Encode a buffer into base64 format
+ *
+ * \param dst destination buffer
+ * \param dlen size of the destination buffer
+ * \param olen number of bytes written
+ * \param src source buffer
+ * \param slen amount of data to be encoded
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_BASE64_BUFFER_TOO_SMALL.
+ * *olen is always updated to reflect the amount
+ * of data that has (or would have) been written.
+ * If that length cannot be represented, then no data is
+ * written to the buffer and *olen is set to the maximum
+ * length representable as a size_t.
+ *
+ * \note Call this function with dlen = 0 to obtain the
+ * required buffer size in *olen
+ */
+int mbedcrypto_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
+ const unsigned char *src, size_t slen );
+
+/**
+ * \brief Decode a base64-formatted buffer
+ *
+ * \param dst destination buffer (can be NULL for checking size)
+ * \param dlen size of the destination buffer
+ * \param olen number of bytes written
+ * \param src source buffer
+ * \param slen amount of data to be decoded
+ *
+ * \return 0 if successful, MBEDCRYPTO_ERR_BASE64_BUFFER_TOO_SMALL, or
+ * MBEDCRYPTO_ERR_BASE64_INVALID_CHARACTER if the input data is
+ * not correct. *olen is always updated to reflect the amount
+ * of data that has (or would have) been written.
+ *
+ * \note Call this function with *dst = NULL or dlen = 0 to obtain
+ * the required buffer size in *olen
+ */
+int mbedcrypto_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
+ const unsigned char *src, size_t slen );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int mbedcrypto_base64_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* base64.h */
diff --git a/include/mbedcrypto/bignum.h b/include/mbedcrypto/bignum.h
new file mode 100644
index 0000000..ad989bb
--- /dev/null
+++ b/include/mbedcrypto/bignum.h
@@ -0,0 +1,772 @@
+/**
+ * \file bignum.h
+ *
+ * \brief Multi-precision integer library
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_BIGNUM_H
+#define MBEDCRYPTO_BIGNUM_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#if defined(MBEDCRYPTO_FS_IO)
+#include <stdio.h>
+#endif
+
+#define MBEDCRYPTO_ERR_MPI_FILE_IO_ERROR -0x0002 /**< An error occurred while reading from or writing to a file. */
+#define MBEDCRYPTO_ERR_MPI_BAD_INPUT_DATA -0x0004 /**< Bad input parameters to function. */
+#define MBEDCRYPTO_ERR_MPI_INVALID_CHARACTER -0x0006 /**< There is an invalid character in the digit string. */
+#define MBEDCRYPTO_ERR_MPI_BUFFER_TOO_SMALL -0x0008 /**< The buffer is too small to write to. */
+#define MBEDCRYPTO_ERR_MPI_NEGATIVE_VALUE -0x000A /**< The input arguments are negative or result in illegal output. */
+#define MBEDCRYPTO_ERR_MPI_DIVISION_BY_ZERO -0x000C /**< The input argument for division is zero, which is not allowed. */
+#define MBEDCRYPTO_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */
+#define MBEDCRYPTO_ERR_MPI_ALLOC_FAILED -0x0010 /**< Memory allocation failed. */
+
+#define MBEDCRYPTO_MPI_CHK(f) do { if( ( ret = f ) != 0 ) goto cleanup; } while( 0 )
+
+/*
+ * Maximum size MPIs are allowed to grow to in number of limbs.
+ */
+#define MBEDCRYPTO_MPI_MAX_LIMBS 10000
+
+#if !defined(MBEDCRYPTO_MPI_WINDOW_SIZE)
+/*
+ * Maximum window size used for modular exponentiation. Default: 6
+ * Minimum value: 1. Maximum value: 6.
+ *
+ * Result is an array of ( 2 << MBEDCRYPTO_MPI_WINDOW_SIZE ) MPIs used
+ * for the sliding window calculation. (So 64 by default)
+ *
+ * Reduction in size, reduces speed.
+ */
+#define MBEDCRYPTO_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */
+#endif /* !MBEDCRYPTO_MPI_WINDOW_SIZE */
+
+#if !defined(MBEDCRYPTO_MPI_MAX_SIZE)
+/*
+ * Maximum size of MPIs allowed in bits and bytes for user-MPIs.
+ * ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits )
+ *
+ * Note: Calculations can temporarily result in larger MPIs. So the number
+ * of limbs required (MBEDCRYPTO_MPI_MAX_LIMBS) is higher.
+ */
+#define MBEDCRYPTO_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */
+#endif /* !MBEDCRYPTO_MPI_MAX_SIZE */
+
+#define MBEDCRYPTO_MPI_MAX_BITS ( 8 * MBEDCRYPTO_MPI_MAX_SIZE ) /**< Maximum number of bits for usable MPIs. */
+
+/*
+ * When reading from files with mbedcrypto_mpi_read_file() and writing to files with
+ * mbedcrypto_mpi_write_file() the buffer should have space
+ * for a (short) label, the MPI (in the provided radix), the newline
+ * characters and the '\0'.
+ *
+ * By default we assume at least a 10 char label, a minimum radix of 10
+ * (decimal) and a maximum of 4096 bit numbers (1234 decimal chars).
+ * Autosized at compile time for at least a 10 char label, a minimum radix
+ * of 10 (decimal) for a number of MBEDCRYPTO_MPI_MAX_BITS size.
+ *
+ * This used to be statically sized to 1250 for a maximum of 4096 bit
+ * numbers (1234 decimal chars).
+ *
+ * Calculate using the formula:
+ * MBEDCRYPTO_MPI_RW_BUFFER_SIZE = ceil(MBEDCRYPTO_MPI_MAX_BITS / ln(10) * ln(2)) +
+ * LabelSize + 6
+ */
+#define MBEDCRYPTO_MPI_MAX_BITS_SCALE100 ( 100 * MBEDCRYPTO_MPI_MAX_BITS )
+#define MBEDCRYPTO_LN_2_DIV_LN_10_SCALE100 332
+#define MBEDCRYPTO_MPI_RW_BUFFER_SIZE ( ((MBEDCRYPTO_MPI_MAX_BITS_SCALE100 + MBEDCRYPTO_LN_2_DIV_LN_10_SCALE100 - 1) / MBEDCRYPTO_LN_2_DIV_LN_10_SCALE100) + 10 + 6 )
+
+/*
+ * Define the base integer type, architecture-wise.
+ *
+ * 32 or 64-bit integer types can be forced regardless of the underlying
+ * architecture by defining MBEDCRYPTO_HAVE_INT32 or MBEDCRYPTO_HAVE_INT64
+ * respectively and undefining MBEDCRYPTO_HAVE_ASM.
+ *
+ * Double-width integers (e.g. 128-bit in 64-bit architectures) can be
+ * disabled by defining MBEDCRYPTO_NO_UDBL_DIVISION.
+ */
+#if !defined(MBEDCRYPTO_HAVE_INT32)
+ #if defined(_MSC_VER) && defined(_M_AMD64)
+ /* Always choose 64-bit when using MSC */
+ #if !defined(MBEDCRYPTO_HAVE_INT64)
+ #define MBEDCRYPTO_HAVE_INT64
+ #endif /* !MBEDCRYPTO_HAVE_INT64 */
+ typedef int64_t mbedcrypto_mpi_sint;
+ typedef uint64_t mbedcrypto_mpi_uint;
+ #elif defined(__GNUC__) && ( \
+ defined(__amd64__) || defined(__x86_64__) || \
+ defined(__ppc64__) || defined(__powerpc64__) || \
+ defined(__ia64__) || defined(__alpha__) || \
+ ( defined(__sparc__) && defined(__arch64__) ) || \
+ defined(__s390x__) || defined(__mips64) )
+ #if !defined(MBEDCRYPTO_HAVE_INT64)
+ #define MBEDCRYPTO_HAVE_INT64
+ #endif /* MBEDCRYPTO_HAVE_INT64 */
+ typedef int64_t mbedcrypto_mpi_sint;
+ typedef uint64_t mbedcrypto_mpi_uint;
+ #if !defined(MBEDCRYPTO_NO_UDBL_DIVISION)
+ /* mbedcrypto_t_udbl defined as 128-bit unsigned int */
+ typedef unsigned int mbedcrypto_t_udbl __attribute__((mode(TI)));
+ #define MBEDCRYPTO_HAVE_UDBL
+ #endif /* !MBEDCRYPTO_NO_UDBL_DIVISION */
+ #elif defined(__ARMCC_VERSION) && defined(__aarch64__)
+ /*
+ * __ARMCC_VERSION is defined for both armcc and armclang and
+ * __aarch64__ is only defined by armclang when compiling 64-bit code
+ */
+ #if !defined(MBEDCRYPTO_HAVE_INT64)
+ #define MBEDCRYPTO_HAVE_INT64
+ #endif /* !MBEDCRYPTO_HAVE_INT64 */
+ typedef int64_t mbedcrypto_mpi_sint;
+ typedef uint64_t mbedcrypto_mpi_uint;
+ #if !defined(MBEDCRYPTO_NO_UDBL_DIVISION)
+ /* mbedcrypto_t_udbl defined as 128-bit unsigned int */
+ typedef __uint128_t mbedcrypto_t_udbl;
+ #define MBEDCRYPTO_HAVE_UDBL
+ #endif /* !MBEDCRYPTO_NO_UDBL_DIVISION */
+ #elif defined(MBEDCRYPTO_HAVE_INT64)
+ /* Force 64-bit integers with unknown compiler */
+ typedef int64_t mbedcrypto_mpi_sint;
+ typedef uint64_t mbedcrypto_mpi_uint;
+ #endif
+#endif /* !MBEDCRYPTO_HAVE_INT32 */
+
+#if !defined(MBEDCRYPTO_HAVE_INT64)
+ /* Default to 32-bit compilation */
+ #if !defined(MBEDCRYPTO_HAVE_INT32)
+ #define MBEDCRYPTO_HAVE_INT32
+ #endif /* !MBEDCRYPTO_HAVE_INT32 */
+ typedef int32_t mbedcrypto_mpi_sint;
+ typedef uint32_t mbedcrypto_mpi_uint;
+ #if !defined(MBEDCRYPTO_NO_UDBL_DIVISION)
+ typedef uint64_t mbedcrypto_t_udbl;
+ #define MBEDCRYPTO_HAVE_UDBL
+ #endif /* !MBEDCRYPTO_NO_UDBL_DIVISION */
+#endif /* !MBEDCRYPTO_HAVE_INT64 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief MPI structure
+ */
+typedef struct
+{
+ int s; /*!< integer sign */
+ size_t n; /*!< total # of limbs */
+ mbedcrypto_mpi_uint *p; /*!< pointer to limbs */
+}
+mbedcrypto_mpi;
+
+/**
+ * \brief Initialize one MPI (make internal references valid)
+ * This just makes it ready to be set or freed,
+ * but does not define a value for the MPI.
+ *
+ * \param X One MPI to initialize.
+ */
+void mbedcrypto_mpi_init( mbedcrypto_mpi *X );
+
+/**
+ * \brief Unallocate one MPI
+ *
+ * \param X One MPI to unallocate.
+ */
+void mbedcrypto_mpi_free( mbedcrypto_mpi *X );
+
+/**
+ * \brief Enlarge to the specified number of limbs
+ *
+ * This function does nothing if the MPI is already large enough.
+ *
+ * \param X MPI to grow
+ * \param nblimbs The target number of limbs
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ */
+int mbedcrypto_mpi_grow( mbedcrypto_mpi *X, size_t nblimbs );
+
+/**
+ * \brief Resize down, keeping at least the specified number of limbs
+ *
+ * If \c X is smaller than \c nblimbs, it is resized up
+ * instead.
+ *
+ * \param X MPI to shrink
+ * \param nblimbs The minimum number of limbs to keep
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * (this can only happen when resizing up).
+ */
+int mbedcrypto_mpi_shrink( mbedcrypto_mpi *X, size_t nblimbs );
+
+/**
+ * \brief Copy the contents of Y into X
+ *
+ * \param X Destination MPI. It is enlarged if necessary.
+ * \param Y Source MPI.
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ */
+int mbedcrypto_mpi_copy( mbedcrypto_mpi *X, const mbedcrypto_mpi *Y );
+
+/**
+ * \brief Swap the contents of X and Y
+ *
+ * \param X First MPI value
+ * \param Y Second MPI value
+ */
+void mbedcrypto_mpi_swap( mbedcrypto_mpi *X, mbedcrypto_mpi *Y );
+
+/**
+ * \brief Safe conditional assignement X = Y if assign is 1
+ *
+ * \param X MPI to conditionally assign to
+ * \param Y Value to be assigned
+ * \param assign 1: perform the assignment, 0: keep X's original value
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed,
+ *
+ * \note This function is equivalent to
+ * if( assign ) mbedcrypto_mpi_copy( X, Y );
+ * except that it avoids leaking any information about whether
+ * the assignment was done or not (the above code may leak
+ * information through branch prediction and/or memory access
+ * patterns analysis).
+ */
+int mbedcrypto_mpi_safe_cond_assign( mbedcrypto_mpi *X, const mbedcrypto_mpi *Y, unsigned char assign );
+
+/**
+ * \brief Safe conditional swap X <-> Y if swap is 1
+ *
+ * \param X First mbedcrypto_mpi value
+ * \param Y Second mbedcrypto_mpi value
+ * \param assign 1: perform the swap, 0: keep X and Y's original values
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed,
+ *
+ * \note This function is equivalent to
+ * if( assign ) mbedcrypto_mpi_swap( X, Y );
+ * except that it avoids leaking any information about whether
+ * the assignment was done or not (the above code may leak
+ * information through branch prediction and/or memory access
+ * patterns analysis).
+ */
+int mbedcrypto_mpi_safe_cond_swap( mbedcrypto_mpi *X, mbedcrypto_mpi *Y, unsigned char assign );
+
+/**
+ * \brief Set value from integer
+ *
+ * \param X MPI to set
+ * \param z Value to use
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ */
+int mbedcrypto_mpi_lset( mbedcrypto_mpi *X, mbedcrypto_mpi_sint z );
+
+/**
+ * \brief Get a specific bit from X
+ *
+ * \param X MPI to use
+ * \param pos Zero-based index of the bit in X
+ *
+ * \return Either a 0 or a 1
+ */
+int mbedcrypto_mpi_get_bit( const mbedcrypto_mpi *X, size_t pos );
+
+/**
+ * \brief Set a bit of X to a specific value of 0 or 1
+ *
+ * \note Will grow X if necessary to set a bit to 1 in a not yet
+ * existing limb. Will not grow if bit should be set to 0
+ *
+ * \param X MPI to use
+ * \param pos Zero-based index of the bit in X
+ * \param val The value to set the bit to (0 or 1)
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed,
+ * MBEDCRYPTO_ERR_MPI_BAD_INPUT_DATA if val is not 0 or 1
+ */
+int mbedcrypto_mpi_set_bit( mbedcrypto_mpi *X, size_t pos, unsigned char val );
+
+/**
+ * \brief Return the number of zero-bits before the least significant
+ * '1' bit
+ *
+ * Note: Thus also the zero-based index of the least significant '1' bit
+ *
+ * \param X MPI to use
+ */
+size_t mbedcrypto_mpi_lsb( const mbedcrypto_mpi *X );
+
+/**
+ * \brief Return the number of bits up to and including the most
+ * significant '1' bit'
+ *
+ * Note: Thus also the one-based index of the most significant '1' bit
+ *
+ * \param X MPI to use
+ */
+size_t mbedcrypto_mpi_bitlen( const mbedcrypto_mpi *X );
+
+/**
+ * \brief Return the total size in bytes
+ *
+ * \param X MPI to use
+ */
+size_t mbedcrypto_mpi_size( const mbedcrypto_mpi *X );
+
+/**
+ * \brief Import from an ASCII string
+ *
+ * \param X Destination MPI
+ * \param radix Input numeric base
+ * \param s Null-terminated string buffer
+ *
+ * \return 0 if successful, or a MBEDCRYPTO_ERR_MPI_XXX error code
+ */
+int mbedcrypto_mpi_read_string( mbedcrypto_mpi *X, int radix, const char *s );
+
+/**
+ * \brief Export into an ASCII string
+ *
+ * \param X Source MPI
+ * \param radix Output numeric base
+ * \param buf Buffer to write the string to
+ * \param buflen Length of buf
+ * \param olen Length of the string written, including final NUL byte
+ *
+ * \return 0 if successful, or a MBEDCRYPTO_ERR_MPI_XXX error code.
+ * *olen is always updated to reflect the amount
+ * of data that has (or would have) been written.
+ *
+ * \note Call this function with buflen = 0 to obtain the
+ * minimum required buffer size in *olen.
+ */
+int mbedcrypto_mpi_write_string( const mbedcrypto_mpi *X, int radix,
+ char *buf, size_t buflen, size_t *olen );
+
+#if defined(MBEDCRYPTO_FS_IO)
+/**
+ * \brief Read MPI from a line in an opened file
+ *
+ * \param X Destination MPI
+ * \param radix Input numeric base
+ * \param fin Input file handle
+ *
+ * \return 0 if successful, MBEDCRYPTO_ERR_MPI_BUFFER_TOO_SMALL if
+ * the file read buffer is too small or a
+ * MBEDCRYPTO_ERR_MPI_XXX error code
+ *
+ * \note On success, this function advances the file stream
+ * to the end of the current line or to EOF.
+ *
+ * The function returns 0 on an empty line.
+ *
+ * Leading whitespaces are ignored, as is a
+ * '0x' prefix for radix 16.
+ *
+ */
+int mbedcrypto_mpi_read_file( mbedcrypto_mpi *X, int radix, FILE *fin );
+
+/**
+ * \brief Write X into an opened file, or stdout if fout is NULL
+ *
+ * \param p Prefix, can be NULL
+ * \param X Source MPI
+ * \param radix Output numeric base
+ * \param fout Output file handle (can be NULL)
+ *
+ * \return 0 if successful, or a MBEDCRYPTO_ERR_MPI_XXX error code
+ *
+ * \note Set fout == NULL to print X on the console.
+ */
+int mbedcrypto_mpi_write_file( const char *p, const mbedcrypto_mpi *X, int radix, FILE *fout );
+#endif /* MBEDCRYPTO_FS_IO */
+
+/**
+ * \brief Import X from unsigned binary data, big endian
+ *
+ * \param X Destination MPI
+ * \param buf Input buffer
+ * \param buflen Input buffer size
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ */
+int mbedcrypto_mpi_read_binary( mbedcrypto_mpi *X, const unsigned char *buf, size_t buflen );
+
+/**
+ * \brief Export X into unsigned binary data, big endian.
+ * Always fills the whole buffer, which will start with zeros
+ * if the number is smaller.
+ *
+ * \param X Source MPI
+ * \param buf Output buffer
+ * \param buflen Output buffer size
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
+ */
+int mbedcrypto_mpi_write_binary( const mbedcrypto_mpi *X, unsigned char *buf, size_t buflen );
+
+/**
+ * \brief Left-shift: X <<= count
+ *
+ * \param X MPI to shift
+ * \param count Amount to shift
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ */
+int mbedcrypto_mpi_shift_l( mbedcrypto_mpi *X, size_t count );
+
+/**
+ * \brief Right-shift: X >>= count
+ *
+ * \param X MPI to shift
+ * \param count Amount to shift
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ */
+int mbedcrypto_mpi_shift_r( mbedcrypto_mpi *X, size_t count );
+
+/**
+ * \brief Compare unsigned values
+ *
+ * \param X Left-hand MPI
+ * \param Y Right-hand MPI
+ *
+ * \return 1 if |X| is greater than |Y|,
+ * -1 if |X| is lesser than |Y| or
+ * 0 if |X| is equal to |Y|
+ */
+int mbedcrypto_mpi_cmp_abs( const mbedcrypto_mpi *X, const mbedcrypto_mpi *Y );
+
+/**
+ * \brief Compare signed values
+ *
+ * \param X Left-hand MPI
+ * \param Y Right-hand MPI
+ *
+ * \return 1 if X is greater than Y,
+ * -1 if X is lesser than Y or
+ * 0 if X is equal to Y
+ */
+int mbedcrypto_mpi_cmp_mpi( const mbedcrypto_mpi *X, const mbedcrypto_mpi *Y );
+
+/**
+ * \brief Compare signed values
+ *
+ * \param X Left-hand MPI
+ * \param z The integer value to compare to
+ *
+ * \return 1 if X is greater than z,
+ * -1 if X is lesser than z or
+ * 0 if X is equal to z
+ */
+int mbedcrypto_mpi_cmp_int( const mbedcrypto_mpi *X, mbedcrypto_mpi_sint z );
+
+/**
+ * \brief Unsigned addition: X = |A| + |B|
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ */
+int mbedcrypto_mpi_add_abs( mbedcrypto_mpi *X, const mbedcrypto_mpi *A, const mbedcrypto_mpi *B );
+
+/**
+ * \brief Unsigned subtraction: X = |A| - |B|
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_NEGATIVE_VALUE if B is greater than A
+ */
+int mbedcrypto_mpi_sub_abs( mbedcrypto_mpi *X, const mbedcrypto_mpi *A, const mbedcrypto_mpi *B );
+
+/**
+ * \brief Signed addition: X = A + B
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ */
+int mbedcrypto_mpi_add_mpi( mbedcrypto_mpi *X, const mbedcrypto_mpi *A, const mbedcrypto_mpi *B );
+
+/**
+ * \brief Signed subtraction: X = A - B
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ */
+int mbedcrypto_mpi_sub_mpi( mbedcrypto_mpi *X, const mbedcrypto_mpi *A, const mbedcrypto_mpi *B );
+
+/**
+ * \brief Signed addition: X = A + b
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param b The integer value to add
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ */
+int mbedcrypto_mpi_add_int( mbedcrypto_mpi *X, const mbedcrypto_mpi *A, mbedcrypto_mpi_sint b );
+
+/**
+ * \brief Signed subtraction: X = A - b
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param b The integer value to subtract
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ */
+int mbedcrypto_mpi_sub_int( mbedcrypto_mpi *X, const mbedcrypto_mpi *A, mbedcrypto_mpi_sint b );
+
+/**
+ * \brief Baseline multiplication: X = A * B
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ */
+int mbedcrypto_mpi_mul_mpi( mbedcrypto_mpi *X, const mbedcrypto_mpi *A, const mbedcrypto_mpi *B );
+
+/**
+ * \brief Baseline multiplication: X = A * b
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param b The unsigned integer value to multiply with
+ *
+ * \note b is unsigned
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ */
+int mbedcrypto_mpi_mul_int( mbedcrypto_mpi *X, const mbedcrypto_mpi *A, mbedcrypto_mpi_uint b );
+
+/**
+ * \brief Division by mbedcrypto_mpi: A = Q * B + R
+ *
+ * \param Q Destination MPI for the quotient
+ * \param R Destination MPI for the rest value
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed,
+ * MBEDCRYPTO_ERR_MPI_DIVISION_BY_ZERO if B == 0
+ *
+ * \note Either Q or R can be NULL.
+ */
+int mbedcrypto_mpi_div_mpi( mbedcrypto_mpi *Q, mbedcrypto_mpi *R, const mbedcrypto_mpi *A, const mbedcrypto_mpi *B );
+
+/**
+ * \brief Division by int: A = Q * b + R
+ *
+ * \param Q Destination MPI for the quotient
+ * \param R Destination MPI for the rest value
+ * \param A Left-hand MPI
+ * \param b Integer to divide by
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed,
+ * MBEDCRYPTO_ERR_MPI_DIVISION_BY_ZERO if b == 0
+ *
+ * \note Either Q or R can be NULL.
+ */
+int mbedcrypto_mpi_div_int( mbedcrypto_mpi *Q, mbedcrypto_mpi *R, const mbedcrypto_mpi *A, mbedcrypto_mpi_sint b );
+
+/**
+ * \brief Modulo: R = A mod B
+ *
+ * \param R Destination MPI for the rest value
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed,
+ * MBEDCRYPTO_ERR_MPI_DIVISION_BY_ZERO if B == 0,
+ * MBEDCRYPTO_ERR_MPI_NEGATIVE_VALUE if B < 0
+ */
+int mbedcrypto_mpi_mod_mpi( mbedcrypto_mpi *R, const mbedcrypto_mpi *A, const mbedcrypto_mpi *B );
+
+/**
+ * \brief Modulo: r = A mod b
+ *
+ * \param r Destination mbedcrypto_mpi_uint
+ * \param A Left-hand MPI
+ * \param b Integer to divide by
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed,
+ * MBEDCRYPTO_ERR_MPI_DIVISION_BY_ZERO if b == 0,
+ * MBEDCRYPTO_ERR_MPI_NEGATIVE_VALUE if b < 0
+ */
+int mbedcrypto_mpi_mod_int( mbedcrypto_mpi_uint *r, const mbedcrypto_mpi *A, mbedcrypto_mpi_sint b );
+
+/**
+ * \brief Sliding-window exponentiation: X = A^E mod N
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param E Exponent MPI
+ * \param N Modular MPI
+ * \param _RR Speed-up MPI used for recalculations
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed,
+ * MBEDCRYPTO_ERR_MPI_BAD_INPUT_DATA if N is negative or even or
+ * if E is negative
+ *
+ * \note _RR is used to avoid re-computing R*R mod N across
+ * multiple calls, which speeds up things a bit. It can
+ * be set to NULL if the extra performance is unneeded.
+ */
+int mbedcrypto_mpi_exp_mod( mbedcrypto_mpi *X, const mbedcrypto_mpi *A, const mbedcrypto_mpi *E, const mbedcrypto_mpi *N, mbedcrypto_mpi *_RR );
+
+/**
+ * \brief Fill an MPI X with size bytes of random
+ *
+ * \param X Destination MPI
+ * \param size Size in bytes
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ *
+ * \note The bytes obtained from the PRNG are interpreted
+ * as a big-endian representation of an MPI; this can
+ * be relevant in applications like deterministic ECDSA.
+ */
+int mbedcrypto_mpi_fill_random( mbedcrypto_mpi *X, size_t size,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
+/**
+ * \brief Greatest common divisor: G = gcd(A, B)
+ *
+ * \param G Destination MPI
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ */
+int mbedcrypto_mpi_gcd( mbedcrypto_mpi *G, const mbedcrypto_mpi *A, const mbedcrypto_mpi *B );
+
+/**
+ * \brief Modular inverse: X = A^-1 mod N
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param N Right-hand MPI
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed,
+ * MBEDCRYPTO_ERR_MPI_BAD_INPUT_DATA if N is <= 1,
+ MBEDCRYPTO_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N.
+ */
+int mbedcrypto_mpi_inv_mod( mbedcrypto_mpi *X, const mbedcrypto_mpi *A, const mbedcrypto_mpi *N );
+
+/**
+ * \brief Miller-Rabin primality test
+ *
+ * \param X MPI to check
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
+ *
+ * \return 0 if successful (probably prime),
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed,
+ * MBEDCRYPTO_ERR_MPI_NOT_ACCEPTABLE if X is not prime
+ */
+int mbedcrypto_mpi_is_prime( const mbedcrypto_mpi *X,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
+/**
+ * \brief Prime number generation
+ *
+ * \param X Destination MPI
+ * \param nbits Required size of X in bits
+ * ( 3 <= nbits <= MBEDCRYPTO_MPI_MAX_BITS )
+ * \param dh_flag If 1, then (X-1)/2 will be prime too
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
+ *
+ * \return 0 if successful (probably prime),
+ * MBEDCRYPTO_ERR_MPI_ALLOC_FAILED if memory allocation failed,
+ * MBEDCRYPTO_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
+ */
+int mbedcrypto_mpi_gen_prime( mbedcrypto_mpi *X, size_t nbits, int dh_flag,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int mbedcrypto_mpi_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* bignum.h */
diff --git a/include/mbedcrypto/blowfish.h b/include/mbedcrypto/blowfish.h
new file mode 100644
index 0000000..b11c2e8
--- /dev/null
+++ b/include/mbedcrypto/blowfish.h
@@ -0,0 +1,205 @@
+/**
+ * \file blowfish.h
+ *
+ * \brief Blowfish block cipher
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_BLOWFISH_H
+#define MBEDCRYPTO_BLOWFISH_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MBEDCRYPTO_BLOWFISH_ENCRYPT 1
+#define MBEDCRYPTO_BLOWFISH_DECRYPT 0
+#define MBEDCRYPTO_BLOWFISH_MAX_KEY_BITS 448
+#define MBEDCRYPTO_BLOWFISH_MIN_KEY_BITS 32
+#define MBEDCRYPTO_BLOWFISH_ROUNDS 16 /**< Rounds to use. When increasing this value, make sure to extend the initialisation vectors */
+#define MBEDCRYPTO_BLOWFISH_BLOCKSIZE 8 /* Blowfish uses 64 bit blocks */
+
+#define MBEDCRYPTO_ERR_BLOWFISH_INVALID_KEY_LENGTH -0x0016 /**< Invalid key length. */
+#define MBEDCRYPTO_ERR_BLOWFISH_HW_ACCEL_FAILED -0x0017 /**< Blowfish hardware accelerator failed. */
+#define MBEDCRYPTO_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDCRYPTO_BLOWFISH_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief Blowfish context structure
+ */
+typedef struct
+{
+ uint32_t P[MBEDCRYPTO_BLOWFISH_ROUNDS + 2]; /*!< Blowfish round keys */
+ uint32_t S[4][256]; /*!< key dependent S-boxes */
+}
+mbedcrypto_blowfish_context;
+
+#else /* MBEDCRYPTO_BLOWFISH_ALT */
+#include "blowfish_alt.h"
+#endif /* MBEDCRYPTO_BLOWFISH_ALT */
+
+/**
+ * \brief Initialize Blowfish context
+ *
+ * \param ctx Blowfish context to be initialized
+ */
+void mbedcrypto_blowfish_init( mbedcrypto_blowfish_context *ctx );
+
+/**
+ * \brief Clear Blowfish context
+ *
+ * \param ctx Blowfish context to be cleared
+ */
+void mbedcrypto_blowfish_free( mbedcrypto_blowfish_context *ctx );
+
+/**
+ * \brief Blowfish key schedule
+ *
+ * \param ctx Blowfish context to be initialized
+ * \param key encryption key
+ * \param keybits must be between 32 and 448 bits
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_BLOWFISH_INVALID_KEY_LENGTH
+ */
+int mbedcrypto_blowfish_setkey( mbedcrypto_blowfish_context *ctx, const unsigned char *key,
+ unsigned int keybits );
+
+/**
+ * \brief Blowfish-ECB block encryption/decryption
+ *
+ * \param ctx Blowfish context
+ * \param mode MBEDCRYPTO_BLOWFISH_ENCRYPT or MBEDCRYPTO_BLOWFISH_DECRYPT
+ * \param input 8-byte input block
+ * \param output 8-byte output block
+ *
+ * \return 0 if successful
+ */
+int mbedcrypto_blowfish_crypt_ecb( mbedcrypto_blowfish_context *ctx,
+ int mode,
+ const unsigned char input[MBEDCRYPTO_BLOWFISH_BLOCKSIZE],
+ unsigned char output[MBEDCRYPTO_BLOWFISH_BLOCKSIZE] );
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_CBC)
+/**
+ * \brief Blowfish-CBC buffer encryption/decryption
+ * Length should be a multiple of the block
+ * size (8 bytes)
+ *
+ * \note Upon exit, the content of the IV is updated so that you can
+ * call the function same function again on the following
+ * block(s) of data and get the same result as if it was
+ * encrypted in one call. This allows a "streaming" usage.
+ * If on the other hand you need to retain the contents of the
+ * IV, you should either save it manually or use the cipher
+ * module instead.
+ *
+ * \param ctx Blowfish context
+ * \param mode MBEDCRYPTO_BLOWFISH_ENCRYPT or MBEDCRYPTO_BLOWFISH_DECRYPT
+ * \param length length of the input data
+ * \param iv initialization vector (updated after use)
+ * \param input buffer holding the input data
+ * \param output buffer holding the output data
+ *
+ * \return 0 if successful, or
+ * MBEDCRYPTO_ERR_BLOWFISH_INVALID_INPUT_LENGTH
+ */
+int mbedcrypto_blowfish_crypt_cbc( mbedcrypto_blowfish_context *ctx,
+ int mode,
+ size_t length,
+ unsigned char iv[MBEDCRYPTO_BLOWFISH_BLOCKSIZE],
+ const unsigned char *input,
+ unsigned char *output );
+#endif /* MBEDCRYPTO_CIPHER_MODE_CBC */
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_CFB)
+/**
+ * \brief Blowfish CFB buffer encryption/decryption.
+ *
+ * \note Upon exit, the content of the IV is updated so that you can
+ * call the function same function again on the following
+ * block(s) of data and get the same result as if it was
+ * encrypted in one call. This allows a "streaming" usage.
+ * If on the other hand you need to retain the contents of the
+ * IV, you should either save it manually or use the cipher
+ * module instead.
+ *
+ * \param ctx Blowfish context
+ * \param mode MBEDCRYPTO_BLOWFISH_ENCRYPT or MBEDCRYPTO_BLOWFISH_DECRYPT
+ * \param length length of the input data
+ * \param iv_off offset in IV (updated after use)
+ * \param iv initialization vector (updated after use)
+ * \param input buffer holding the input data
+ * \param output buffer holding the output data
+ *
+ * \return 0 if successful
+ */
+int mbedcrypto_blowfish_crypt_cfb64( mbedcrypto_blowfish_context *ctx,
+ int mode,
+ size_t length,
+ size_t *iv_off,
+ unsigned char iv[MBEDCRYPTO_BLOWFISH_BLOCKSIZE],
+ const unsigned char *input,
+ unsigned char *output );
+#endif /*MBEDCRYPTO_CIPHER_MODE_CFB */
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_CTR)
+/**
+ * \brief Blowfish-CTR buffer encryption/decryption
+ *
+ * Warning: You have to keep the maximum use of your counter in mind!
+ *
+ * \param ctx Blowfish context
+ * \param length The length of the data
+ * \param nc_off The offset in the current stream_block (for resuming
+ * within current cipher stream). The offset pointer to
+ * should be 0 at the start of a stream.
+ * \param nonce_counter The 64-bit nonce and counter.
+ * \param stream_block The saved stream-block for resuming. Is overwritten
+ * by the function.
+ * \param input The input data stream
+ * \param output The output data stream
+ *
+ * \return 0 if successful
+ */
+int mbedcrypto_blowfish_crypt_ctr( mbedcrypto_blowfish_context *ctx,
+ size_t length,
+ size_t *nc_off,
+ unsigned char nonce_counter[MBEDCRYPTO_BLOWFISH_BLOCKSIZE],
+ unsigned char stream_block[MBEDCRYPTO_BLOWFISH_BLOCKSIZE],
+ const unsigned char *input,
+ unsigned char *output );
+#endif /* MBEDCRYPTO_CIPHER_MODE_CTR */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* blowfish.h */
diff --git a/include/mbedcrypto/bn_mul.h b/include/mbedcrypto/bn_mul.h
new file mode 100644
index 0000000..7d70c2e
--- /dev/null
+++ b/include/mbedcrypto/bn_mul.h
@@ -0,0 +1,886 @@
+/**
+ * \file bn_mul.h
+ *
+ * \brief Multi-precision integer library
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+/*
+ * Multiply source vector [s] with b, add result
+ * to destination vector [d] and set carry c.
+ *
+ * Currently supports:
+ *
+ * . IA-32 (386+) . AMD64 / EM64T
+ * . IA-32 (SSE2) . Motorola 68000
+ * . PowerPC, 32-bit . MicroBlaze
+ * . PowerPC, 64-bit . TriCore
+ * . SPARC v8 . ARM v3+
+ * . Alpha . MIPS32
+ * . C, longlong . C, generic
+ */
+#ifndef MBEDCRYPTO_BN_MUL_H
+#define MBEDCRYPTO_BN_MUL_H
+
+#include "bignum.h"
+
+#if defined(MBEDCRYPTO_HAVE_ASM)
+
+#ifndef asm
+#define asm __asm
+#endif
+
+/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
+#if defined(__GNUC__) && \
+ ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 )
+#if defined(__i386__)
+
+#define MULADDC_INIT \
+ asm( \
+ "movl %%ebx, %0 \n\t" \
+ "movl %5, %%esi \n\t" \
+ "movl %6, %%edi \n\t" \
+ "movl %7, %%ecx \n\t" \
+ "movl %8, %%ebx \n\t"
+
+#define MULADDC_CORE \
+ "lodsl \n\t" \
+ "mull %%ebx \n\t" \
+ "addl %%ecx, %%eax \n\t" \
+ "adcl $0, %%edx \n\t" \
+ "addl (%%edi), %%eax \n\t" \
+ "adcl $0, %%edx \n\t" \
+ "movl %%edx, %%ecx \n\t" \
+ "stosl \n\t"
+
+#if defined(MBEDCRYPTO_HAVE_SSE2)
+
+#define MULADDC_HUIT \
+ "movd %%ecx, %%mm1 \n\t" \
+ "movd %%ebx, %%mm0 \n\t" \
+ "movd (%%edi), %%mm3 \n\t" \
+ "paddq %%mm3, %%mm1 \n\t" \
+ "movd (%%esi), %%mm2 \n\t" \
+ "pmuludq %%mm0, %%mm2 \n\t" \
+ "movd 4(%%esi), %%mm4 \n\t" \
+ "pmuludq %%mm0, %%mm4 \n\t" \
+ "movd 8(%%esi), %%mm6 \n\t" \
+ "pmuludq %%mm0, %%mm6 \n\t" \
+ "movd 12(%%esi), %%mm7 \n\t" \
+ "pmuludq %%mm0, %%mm7 \n\t" \
+ "paddq %%mm2, %%mm1 \n\t" \
+ "movd 4(%%edi), %%mm3 \n\t" \
+ "paddq %%mm4, %%mm3 \n\t" \
+ "movd 8(%%edi), %%mm5 \n\t" \
+ "paddq %%mm6, %%mm5 \n\t" \
+ "movd 12(%%edi), %%mm4 \n\t" \
+ "paddq %%mm4, %%mm7 \n\t" \
+ "movd %%mm1, (%%edi) \n\t" \
+ "movd 16(%%esi), %%mm2 \n\t" \
+ "pmuludq %%mm0, %%mm2 \n\t" \
+ "psrlq $32, %%mm1 \n\t" \
+ "movd 20(%%esi), %%mm4 \n\t" \
+ "pmuludq %%mm0, %%mm4 \n\t" \
+ "paddq %%mm3, %%mm1 \n\t" \
+ "movd 24(%%esi), %%mm6 \n\t" \
+ "pmuludq %%mm0, %%mm6 \n\t" \
+ "movd %%mm1, 4(%%edi) \n\t" \
+ "psrlq $32, %%mm1 \n\t" \
+ "movd 28(%%esi), %%mm3 \n\t" \
+ "pmuludq %%mm0, %%mm3 \n\t" \
+ "paddq %%mm5, %%mm1 \n\t" \
+ "movd 16(%%edi), %%mm5 \n\t" \
+ "paddq %%mm5, %%mm2 \n\t" \
+ "movd %%mm1, 8(%%edi) \n\t" \
+ "psrlq $32, %%mm1 \n\t" \
+ "paddq %%mm7, %%mm1 \n\t" \
+ "movd 20(%%edi), %%mm5 \n\t" \
+ "paddq %%mm5, %%mm4 \n\t" \
+ "movd %%mm1, 12(%%edi) \n\t" \
+ "psrlq $32, %%mm1 \n\t" \
+ "paddq %%mm2, %%mm1 \n\t" \
+ "movd 24(%%edi), %%mm5 \n\t" \
+ "paddq %%mm5, %%mm6 \n\t" \
+ "movd %%mm1, 16(%%edi) \n\t" \
+ "psrlq $32, %%mm1 \n\t" \
+ "paddq %%mm4, %%mm1 \n\t" \
+ "movd 28(%%edi), %%mm5 \n\t" \
+ "paddq %%mm5, %%mm3 \n\t" \
+ "movd %%mm1, 20(%%edi) \n\t" \
+ "psrlq $32, %%mm1 \n\t" \
+ "paddq %%mm6, %%mm1 \n\t" \
+ "movd %%mm1, 24(%%edi) \n\t" \
+ "psrlq $32, %%mm1 \n\t" \
+ "paddq %%mm3, %%mm1 \n\t" \
+ "movd %%mm1, 28(%%edi) \n\t" \
+ "addl $32, %%edi \n\t" \
+ "addl $32, %%esi \n\t" \
+ "psrlq $32, %%mm1 \n\t" \
+ "movd %%mm1, %%ecx \n\t"
+
+#define MULADDC_STOP \
+ "emms \n\t" \
+ "movl %4, %%ebx \n\t" \
+ "movl %%ecx, %1 \n\t" \
+ "movl %%edi, %2 \n\t" \
+ "movl %%esi, %3 \n\t" \
+ : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "eax", "ecx", "edx", "esi", "edi" \
+ );
+
+#else
+
+#define MULADDC_STOP \
+ "movl %4, %%ebx \n\t" \
+ "movl %%ecx, %1 \n\t" \
+ "movl %%edi, %2 \n\t" \
+ "movl %%esi, %3 \n\t" \
+ : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "eax", "ecx", "edx", "esi", "edi" \
+ );
+#endif /* SSE2 */
+#endif /* i386 */
+
+#if defined(__amd64__) || defined (__x86_64__)
+
+#define MULADDC_INIT \
+ asm( \
+ "xorq %%r8, %%r8 \n\t"
+
+#define MULADDC_CORE \
+ "movq (%%rsi), %%rax \n\t" \
+ "mulq %%rbx \n\t" \
+ "addq $8, %%rsi \n\t" \
+ "addq %%rcx, %%rax \n\t" \
+ "movq %%r8, %%rcx \n\t" \
+ "adcq $0, %%rdx \n\t" \
+ "nop \n\t" \
+ "addq %%rax, (%%rdi) \n\t" \
+ "adcq %%rdx, %%rcx \n\t" \
+ "addq $8, %%rdi \n\t"
+
+#define MULADDC_STOP \
+ : "+c" (c), "+D" (d), "+S" (s) \
+ : "b" (b) \
+ : "rax", "rdx", "r8" \
+ );
+
+#endif /* AMD64 */
+
+#if defined(__mc68020__) || defined(__mcpu32__)
+
+#define MULADDC_INIT \
+ asm( \
+ "movl %3, %%a2 \n\t" \
+ "movl %4, %%a3 \n\t" \
+ "movl %5, %%d3 \n\t" \
+ "movl %6, %%d2 \n\t" \
+ "moveq #0, %%d0 \n\t"
+
+#define MULADDC_CORE \
+ "movel %%a2@+, %%d1 \n\t" \
+ "mulul %%d2, %%d4:%%d1 \n\t" \
+ "addl %%d3, %%d1 \n\t" \
+ "addxl %%d0, %%d4 \n\t" \
+ "moveq #0, %%d3 \n\t" \
+ "addl %%d1, %%a3@+ \n\t" \
+ "addxl %%d4, %%d3 \n\t"
+
+#define MULADDC_STOP \
+ "movl %%d3, %0 \n\t" \
+ "movl %%a3, %1 \n\t" \
+ "movl %%a2, %2 \n\t" \
+ : "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "d0", "d1", "d2", "d3", "d4", "a2", "a3" \
+ );
+
+#define MULADDC_HUIT \
+ "movel %%a2@+, %%d1 \n\t" \
+ "mulul %%d2, %%d4:%%d1 \n\t" \
+ "addxl %%d3, %%d1 \n\t" \
+ "addxl %%d0, %%d4 \n\t" \
+ "addl %%d1, %%a3@+ \n\t" \
+ "movel %%a2@+, %%d1 \n\t" \
+ "mulul %%d2, %%d3:%%d1 \n\t" \
+ "addxl %%d4, %%d1 \n\t" \
+ "addxl %%d0, %%d3 \n\t" \
+ "addl %%d1, %%a3@+ \n\t" \
+ "movel %%a2@+, %%d1 \n\t" \
+ "mulul %%d2, %%d4:%%d1 \n\t" \
+ "addxl %%d3, %%d1 \n\t" \
+ "addxl %%d0, %%d4 \n\t" \
+ "addl %%d1, %%a3@+ \n\t" \
+ "movel %%a2@+, %%d1 \n\t" \
+ "mulul %%d2, %%d3:%%d1 \n\t" \
+ "addxl %%d4, %%d1 \n\t" \
+ "addxl %%d0, %%d3 \n\t" \
+ "addl %%d1, %%a3@+ \n\t" \
+ "movel %%a2@+, %%d1 \n\t" \
+ "mulul %%d2, %%d4:%%d1 \n\t" \
+ "addxl %%d3, %%d1 \n\t" \
+ "addxl %%d0, %%d4 \n\t" \
+ "addl %%d1, %%a3@+ \n\t" \
+ "movel %%a2@+, %%d1 \n\t" \
+ "mulul %%d2, %%d3:%%d1 \n\t" \
+ "addxl %%d4, %%d1 \n\t" \
+ "addxl %%d0, %%d3 \n\t" \
+ "addl %%d1, %%a3@+ \n\t" \
+ "movel %%a2@+, %%d1 \n\t" \
+ "mulul %%d2, %%d4:%%d1 \n\t" \
+ "addxl %%d3, %%d1 \n\t" \
+ "addxl %%d0, %%d4 \n\t" \
+ "addl %%d1, %%a3@+ \n\t" \
+ "movel %%a2@+, %%d1 \n\t" \
+ "mulul %%d2, %%d3:%%d1 \n\t" \
+ "addxl %%d4, %%d1 \n\t" \
+ "addxl %%d0, %%d3 \n\t" \
+ "addl %%d1, %%a3@+ \n\t" \
+ "addxl %%d0, %%d3 \n\t"
+
+#endif /* MC68000 */
+
+#if defined(__powerpc64__) || defined(__ppc64__)
+
+#if defined(__MACH__) && defined(__APPLE__)
+
+#define MULADDC_INIT \
+ asm( \
+ "ld r3, %3 \n\t" \
+ "ld r4, %4 \n\t" \
+ "ld r5, %5 \n\t" \
+ "ld r6, %6 \n\t" \
+ "addi r3, r3, -8 \n\t" \
+ "addi r4, r4, -8 \n\t" \
+ "addic r5, r5, 0 \n\t"
+
+#define MULADDC_CORE \
+ "ldu r7, 8(r3) \n\t" \
+ "mulld r8, r7, r6 \n\t" \
+ "mulhdu r9, r7, r6 \n\t" \
+ "adde r8, r8, r5 \n\t" \
+ "ld r7, 8(r4) \n\t" \
+ "addze r5, r9 \n\t" \
+ "addc r8, r8, r7 \n\t" \
+ "stdu r8, 8(r4) \n\t"
+
+#define MULADDC_STOP \
+ "addze r5, r5 \n\t" \
+ "addi r4, r4, 8 \n\t" \
+ "addi r3, r3, 8 \n\t" \
+ "std r5, %0 \n\t" \
+ "std r4, %1 \n\t" \
+ "std r3, %2 \n\t" \
+ : "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
+ );
+
+
+#else /* __MACH__ && __APPLE__ */
+
+#define MULADDC_INIT \
+ asm( \
+ "ld %%r3, %3 \n\t" \
+ "ld %%r4, %4 \n\t" \
+ "ld %%r5, %5 \n\t" \
+ "ld %%r6, %6 \n\t" \
+ "addi %%r3, %%r3, -8 \n\t" \
+ "addi %%r4, %%r4, -8 \n\t" \
+ "addic %%r5, %%r5, 0 \n\t"
+
+#define MULADDC_CORE \
+ "ldu %%r7, 8(%%r3) \n\t" \
+ "mulld %%r8, %%r7, %%r6 \n\t" \
+ "mulhdu %%r9, %%r7, %%r6 \n\t" \
+ "adde %%r8, %%r8, %%r5 \n\t" \
+ "ld %%r7, 8(%%r4) \n\t" \
+ "addze %%r5, %%r9 \n\t" \
+ "addc %%r8, %%r8, %%r7 \n\t" \
+ "stdu %%r8, 8(%%r4) \n\t"
+
+#define MULADDC_STOP \
+ "addze %%r5, %%r5 \n\t" \
+ "addi %%r4, %%r4, 8 \n\t" \
+ "addi %%r3, %%r3, 8 \n\t" \
+ "std %%r5, %0 \n\t" \
+ "std %%r4, %1 \n\t" \
+ "std %%r3, %2 \n\t" \
+ : "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
+ );
+
+#endif /* __MACH__ && __APPLE__ */
+
+#elif defined(__powerpc__) || defined(__ppc__) /* end PPC64/begin PPC32 */
+
+#if defined(__MACH__) && defined(__APPLE__)
+
+#define MULADDC_INIT \
+ asm( \
+ "lwz r3, %3 \n\t" \
+ "lwz r4, %4 \n\t" \
+ "lwz r5, %5 \n\t" \
+ "lwz r6, %6 \n\t" \
+ "addi r3, r3, -4 \n\t" \
+ "addi r4, r4, -4 \n\t" \
+ "addic r5, r5, 0 \n\t"
+
+#define MULADDC_CORE \
+ "lwzu r7, 4(r3) \n\t" \
+ "mullw r8, r7, r6 \n\t" \
+ "mulhwu r9, r7, r6 \n\t" \
+ "adde r8, r8, r5 \n\t" \
+ "lwz r7, 4(r4) \n\t" \
+ "addze r5, r9 \n\t" \
+ "addc r8, r8, r7 \n\t" \
+ "stwu r8, 4(r4) \n\t"
+
+#define MULADDC_STOP \
+ "addze r5, r5 \n\t" \
+ "addi r4, r4, 4 \n\t" \
+ "addi r3, r3, 4 \n\t" \
+ "stw r5, %0 \n\t" \
+ "stw r4, %1 \n\t" \
+ "stw r3, %2 \n\t" \
+ : "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
+ );
+
+#else /* __MACH__ && __APPLE__ */
+
+#define MULADDC_INIT \
+ asm( \
+ "lwz %%r3, %3 \n\t" \
+ "lwz %%r4, %4 \n\t" \
+ "lwz %%r5, %5 \n\t" \
+ "lwz %%r6, %6 \n\t" \
+ "addi %%r3, %%r3, -4 \n\t" \
+ "addi %%r4, %%r4, -4 \n\t" \
+ "addic %%r5, %%r5, 0 \n\t"
+
+#define MULADDC_CORE \
+ "lwzu %%r7, 4(%%r3) \n\t" \
+ "mullw %%r8, %%r7, %%r6 \n\t" \
+ "mulhwu %%r9, %%r7, %%r6 \n\t" \
+ "adde %%r8, %%r8, %%r5 \n\t" \
+ "lwz %%r7, 4(%%r4) \n\t" \
+ "addze %%r5, %%r9 \n\t" \
+ "addc %%r8, %%r8, %%r7 \n\t" \
+ "stwu %%r8, 4(%%r4) \n\t"
+
+#define MULADDC_STOP \
+ "addze %%r5, %%r5 \n\t" \
+ "addi %%r4, %%r4, 4 \n\t" \
+ "addi %%r3, %%r3, 4 \n\t" \
+ "stw %%r5, %0 \n\t" \
+ "stw %%r4, %1 \n\t" \
+ "stw %%r3, %2 \n\t" \
+ : "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
+ );
+
+#endif /* __MACH__ && __APPLE__ */
+
+#endif /* PPC32 */
+
+/*
+ * The Sparc(64) assembly is reported to be broken.
+ * Disable it for now, until we're able to fix it.
+ */
+#if 0 && defined(__sparc__)
+#if defined(__sparc64__)
+
+#define MULADDC_INIT \
+ asm( \
+ "ldx %3, %%o0 \n\t" \
+ "ldx %4, %%o1 \n\t" \
+ "ld %5, %%o2 \n\t" \
+ "ld %6, %%o3 \n\t"
+
+#define MULADDC_CORE \
+ "ld [%%o0], %%o4 \n\t" \
+ "inc 4, %%o0 \n\t" \
+ "ld [%%o1], %%o5 \n\t" \
+ "umul %%o3, %%o4, %%o4 \n\t" \
+ "addcc %%o4, %%o2, %%o4 \n\t" \
+ "rd %%y, %%g1 \n\t" \
+ "addx %%g1, 0, %%g1 \n\t" \
+ "addcc %%o4, %%o5, %%o4 \n\t" \
+ "st %%o4, [%%o1] \n\t" \
+ "addx %%g1, 0, %%o2 \n\t" \
+ "inc 4, %%o1 \n\t"
+
+ #define MULADDC_STOP \
+ "st %%o2, %0 \n\t" \
+ "stx %%o1, %1 \n\t" \
+ "stx %%o0, %2 \n\t" \
+ : "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "g1", "o0", "o1", "o2", "o3", "o4", \
+ "o5" \
+ );
+
+#else /* __sparc64__ */
+
+#define MULADDC_INIT \
+ asm( \
+ "ld %3, %%o0 \n\t" \
+ "ld %4, %%o1 \n\t" \
+ "ld %5, %%o2 \n\t" \
+ "ld %6, %%o3 \n\t"
+
+#define MULADDC_CORE \
+ "ld [%%o0], %%o4 \n\t" \
+ "inc 4, %%o0 \n\t" \
+ "ld [%%o1], %%o5 \n\t" \
+ "umul %%o3, %%o4, %%o4 \n\t" \
+ "addcc %%o4, %%o2, %%o4 \n\t" \
+ "rd %%y, %%g1 \n\t" \
+ "addx %%g1, 0, %%g1 \n\t" \
+ "addcc %%o4, %%o5, %%o4 \n\t" \
+ "st %%o4, [%%o1] \n\t" \
+ "addx %%g1, 0, %%o2 \n\t" \
+ "inc 4, %%o1 \n\t"
+
+#define MULADDC_STOP \
+ "st %%o2, %0 \n\t" \
+ "st %%o1, %1 \n\t" \
+ "st %%o0, %2 \n\t" \
+ : "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "g1", "o0", "o1", "o2", "o3", "o4", \
+ "o5" \
+ );
+
+#endif /* __sparc64__ */
+#endif /* __sparc__ */
+
+#if defined(__microblaze__) || defined(microblaze)
+
+#define MULADDC_INIT \
+ asm( \
+ "lwi r3, %3 \n\t" \
+ "lwi r4, %4 \n\t" \
+ "lwi r5, %5 \n\t" \
+ "lwi r6, %6 \n\t" \
+ "andi r7, r6, 0xffff \n\t" \
+ "bsrli r6, r6, 16 \n\t"
+
+#define MULADDC_CORE \
+ "lhui r8, r3, 0 \n\t" \
+ "addi r3, r3, 2 \n\t" \
+ "lhui r9, r3, 0 \n\t" \
+ "addi r3, r3, 2 \n\t" \
+ "mul r10, r9, r6 \n\t" \
+ "mul r11, r8, r7 \n\t" \
+ "mul r12, r9, r7 \n\t" \
+ "mul r13, r8, r6 \n\t" \
+ "bsrli r8, r10, 16 \n\t" \
+ "bsrli r9, r11, 16 \n\t" \
+ "add r13, r13, r8 \n\t" \
+ "add r13, r13, r9 \n\t" \
+ "bslli r10, r10, 16 \n\t" \
+ "bslli r11, r11, 16 \n\t" \
+ "add r12, r12, r10 \n\t" \
+ "addc r13, r13, r0 \n\t" \
+ "add r12, r12, r11 \n\t" \
+ "addc r13, r13, r0 \n\t" \
+ "lwi r10, r4, 0 \n\t" \
+ "add r12, r12, r10 \n\t" \
+ "addc r13, r13, r0 \n\t" \
+ "add r12, r12, r5 \n\t" \
+ "addc r5, r13, r0 \n\t" \
+ "swi r12, r4, 0 \n\t" \
+ "addi r4, r4, 4 \n\t"
+
+#define MULADDC_STOP \
+ "swi r5, %0 \n\t" \
+ "swi r4, %1 \n\t" \
+ "swi r3, %2 \n\t" \
+ : "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "r3", "r4" "r5", "r6", "r7", "r8", \
+ "r9", "r10", "r11", "r12", "r13" \
+ );
+
+#endif /* MicroBlaze */
+
+#if defined(__tricore__)
+
+#define MULADDC_INIT \
+ asm( \
+ "ld.a %%a2, %3 \n\t" \
+ "ld.a %%a3, %4 \n\t" \
+ "ld.w %%d4, %5 \n\t" \
+ "ld.w %%d1, %6 \n\t" \
+ "xor %%d5, %%d5 \n\t"
+
+#define MULADDC_CORE \
+ "ld.w %%d0, [%%a2+] \n\t" \
+ "madd.u %%e2, %%e4, %%d0, %%d1 \n\t" \
+ "ld.w %%d0, [%%a3] \n\t" \
+ "addx %%d2, %%d2, %%d0 \n\t" \
+ "addc %%d3, %%d3, 0 \n\t" \
+ "mov %%d4, %%d3 \n\t" \
+ "st.w [%%a3+], %%d2 \n\t"
+
+#define MULADDC_STOP \
+ "st.w %0, %%d4 \n\t" \
+ "st.a %1, %%a3 \n\t" \
+ "st.a %2, %%a2 \n\t" \
+ : "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "d0", "d1", "e2", "d4", "a2", "a3" \
+ );
+
+#endif /* TriCore */
+
+/*
+ * gcc -O0 by default uses r7 for the frame pointer, so it complains about our
+ * use of r7 below, unless -fomit-frame-pointer is passed. Unfortunately,
+ * passing that option is not easy when building with yotta.
+ *
+ * On the other hand, -fomit-frame-pointer is implied by any -Ox options with
+ * x !=0, which we can detect using __OPTIMIZE__ (which is also defined by
+ * clang and armcc5 under the same conditions).
+ *
+ * So, only use the optimized assembly below for optimized build, which avoids
+ * the build error and is pretty reasonable anyway.
+ */
+#if defined(__GNUC__) && !defined(__OPTIMIZE__)
+#define MULADDC_CANNOT_USE_R7
+#endif
+
+#if defined(__arm__) && !defined(MULADDC_CANNOT_USE_R7)
+
+#if defined(__thumb__) && !defined(__thumb2__)
+
+#define MULADDC_INIT \
+ asm( \
+ "ldr r0, %3 \n\t" \
+ "ldr r1, %4 \n\t" \
+ "ldr r2, %5 \n\t" \
+ "ldr r3, %6 \n\t" \
+ "lsr r7, r3, #16 \n\t" \
+ "mov r9, r7 \n\t" \
+ "lsl r7, r3, #16 \n\t" \
+ "lsr r7, r7, #16 \n\t" \
+ "mov r8, r7 \n\t"
+
+#define MULADDC_CORE \
+ "ldmia r0!, {r6} \n\t" \
+ "lsr r7, r6, #16 \n\t" \
+ "lsl r6, r6, #16 \n\t" \
+ "lsr r6, r6, #16 \n\t" \
+ "mov r4, r8 \n\t" \
+ "mul r4, r6 \n\t" \
+ "mov r3, r9 \n\t" \
+ "mul r6, r3 \n\t" \
+ "mov r5, r9 \n\t" \
+ "mul r5, r7 \n\t" \
+ "mov r3, r8 \n\t" \
+ "mul r7, r3 \n\t" \
+ "lsr r3, r6, #16 \n\t" \
+ "add r5, r5, r3 \n\t" \
+ "lsr r3, r7, #16 \n\t" \
+ "add r5, r5, r3 \n\t" \
+ "add r4, r4, r2 \n\t" \
+ "mov r2, #0 \n\t" \
+ "adc r5, r2 \n\t" \
+ "lsl r3, r6, #16 \n\t" \
+ "add r4, r4, r3 \n\t" \
+ "adc r5, r2 \n\t" \
+ "lsl r3, r7, #16 \n\t" \
+ "add r4, r4, r3 \n\t" \
+ "adc r5, r2 \n\t" \
+ "ldr r3, [r1] \n\t" \
+ "add r4, r4, r3 \n\t" \
+ "adc r2, r5 \n\t" \
+ "stmia r1!, {r4} \n\t"
+
+#define MULADDC_STOP \
+ "str r2, %0 \n\t" \
+ "str r1, %1 \n\t" \
+ "str r0, %2 \n\t" \
+ : "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "r0", "r1", "r2", "r3", "r4", "r5", \
+ "r6", "r7", "r8", "r9", "cc" \
+ );
+
+#else
+
+#define MULADDC_INIT \
+ asm( \
+ "ldr r0, %3 \n\t" \
+ "ldr r1, %4 \n\t" \
+ "ldr r2, %5 \n\t" \
+ "ldr r3, %6 \n\t"
+
+#define MULADDC_CORE \
+ "ldr r4, [r0], #4 \n\t" \
+ "mov r5, #0 \n\t" \
+ "ldr r6, [r1] \n\t" \
+ "umlal r2, r5, r3, r4 \n\t" \
+ "adds r7, r6, r2 \n\t" \
+ "adc r2, r5, #0 \n\t" \
+ "str r7, [r1], #4 \n\t"
+
+#define MULADDC_STOP \
+ "str r2, %0 \n\t" \
+ "str r1, %1 \n\t" \
+ "str r0, %2 \n\t" \
+ : "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "r0", "r1", "r2", "r3", "r4", "r5", \
+ "r6", "r7", "cc" \
+ );
+
+#endif /* Thumb */
+
+#endif /* ARMv3 */
+
+#if defined(__alpha__)
+
+#define MULADDC_INIT \
+ asm( \
+ "ldq $1, %3 \n\t" \
+ "ldq $2, %4 \n\t" \
+ "ldq $3, %5 \n\t" \
+ "ldq $4, %6 \n\t"
+
+#define MULADDC_CORE \
+ "ldq $6, 0($1) \n\t" \
+ "addq $1, 8, $1 \n\t" \
+ "mulq $6, $4, $7 \n\t" \
+ "umulh $6, $4, $6 \n\t" \
+ "addq $7, $3, $7 \n\t" \
+ "cmpult $7, $3, $3 \n\t" \
+ "ldq $5, 0($2) \n\t" \
+ "addq $7, $5, $7 \n\t" \
+ "cmpult $7, $5, $5 \n\t" \
+ "stq $7, 0($2) \n\t" \
+ "addq $2, 8, $2 \n\t" \
+ "addq $6, $3, $3 \n\t" \
+ "addq $5, $3, $3 \n\t"
+
+#define MULADDC_STOP \
+ "stq $3, %0 \n\t" \
+ "stq $2, %1 \n\t" \
+ "stq $1, %2 \n\t" \
+ : "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "$1", "$2", "$3", "$4", "$5", "$6", "$7" \
+ );
+#endif /* Alpha */
+
+#if defined(__mips__) && !defined(__mips64)
+
+#define MULADDC_INIT \
+ asm( \
+ "lw $10, %3 \n\t" \
+ "lw $11, %4 \n\t" \
+ "lw $12, %5 \n\t" \
+ "lw $13, %6 \n\t"
+
+#define MULADDC_CORE \
+ "lw $14, 0($10) \n\t" \
+ "multu $13, $14 \n\t" \
+ "addi $10, $10, 4 \n\t" \
+ "mflo $14 \n\t" \
+ "mfhi $9 \n\t" \
+ "addu $14, $12, $14 \n\t" \
+ "lw $15, 0($11) \n\t" \
+ "sltu $12, $14, $12 \n\t" \
+ "addu $15, $14, $15 \n\t" \
+ "sltu $14, $15, $14 \n\t" \
+ "addu $12, $12, $9 \n\t" \
+ "sw $15, 0($11) \n\t" \
+ "addu $12, $12, $14 \n\t" \
+ "addi $11, $11, 4 \n\t"
+
+#define MULADDC_STOP \
+ "sw $12, %0 \n\t" \
+ "sw $11, %1 \n\t" \
+ "sw $10, %2 \n\t" \
+ : "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "$9", "$10", "$11", "$12", "$13", "$14", "$15" \
+ );
+
+#endif /* MIPS */
+#endif /* GNUC */
+
+#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
+
+#define MULADDC_INIT \
+ __asm mov esi, s \
+ __asm mov edi, d \
+ __asm mov ecx, c \
+ __asm mov ebx, b
+
+#define MULADDC_CORE \
+ __asm lodsd \
+ __asm mul ebx \
+ __asm add eax, ecx \
+ __asm adc edx, 0 \
+ __asm add eax, [edi] \
+ __asm adc edx, 0 \
+ __asm mov ecx, edx \
+ __asm stosd
+
+#if defined(MBEDCRYPTO_HAVE_SSE2)
+
+#define EMIT __asm _emit
+
+#define MULADDC_HUIT \
+ EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
+ EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x1F \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
+ EMIT 0x0F EMIT 0x6E EMIT 0x16 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
+ EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
+ EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
+ EMIT 0x0F EMIT 0x7E EMIT 0x0F \
+ EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
+ EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
+ EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
+ EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x7E EMIT 0xC9
+
+#define MULADDC_STOP \
+ EMIT 0x0F EMIT 0x77 \
+ __asm mov c, ecx \
+ __asm mov d, edi \
+ __asm mov s, esi \
+
+#else
+
+#define MULADDC_STOP \
+ __asm mov c, ecx \
+ __asm mov d, edi \
+ __asm mov s, esi \
+
+#endif /* SSE2 */
+#endif /* MSVC */
+
+#endif /* MBEDCRYPTO_HAVE_ASM */
+
+#if !defined(MULADDC_CORE)
+#if defined(MBEDCRYPTO_HAVE_UDBL)
+
+#define MULADDC_INIT \
+{ \
+ mbedcrypto_t_udbl r; \
+ mbedcrypto_mpi_uint r0, r1;
+
+#define MULADDC_CORE \
+ r = *(s++) * (mbedcrypto_t_udbl) b; \
+ r0 = (mbedcrypto_mpi_uint) r; \
+ r1 = (mbedcrypto_mpi_uint)( r >> biL ); \
+ r0 += c; r1 += (r0 < c); \
+ r0 += *d; r1 += (r0 < *d); \
+ c = r1; *(d++) = r0;
+
+#define MULADDC_STOP \
+}
+
+#else
+#define MULADDC_INIT \
+{ \
+ mbedcrypto_mpi_uint s0, s1, b0, b1; \
+ mbedcrypto_mpi_uint r0, r1, rx, ry; \
+ b0 = ( b << biH ) >> biH; \
+ b1 = ( b >> biH );
+
+#define MULADDC_CORE \
+ s0 = ( *s << biH ) >> biH; \
+ s1 = ( *s >> biH ); s++; \
+ rx = s0 * b1; r0 = s0 * b0; \
+ ry = s1 * b0; r1 = s1 * b1; \
+ r1 += ( rx >> biH ); \
+ r1 += ( ry >> biH ); \
+ rx <<= biH; ry <<= biH; \
+ r0 += rx; r1 += (r0 < rx); \
+ r0 += ry; r1 += (r0 < ry); \
+ r0 += c; r1 += (r0 < c); \
+ r0 += *d; r1 += (r0 < *d); \
+ c = r1; *(d++) = r0;
+
+#define MULADDC_STOP \
+}
+
+#endif /* C (generic) */
+#endif /* C (longlong) */
+
+#endif /* bn_mul.h */
diff --git a/include/mbedcrypto/camellia.h b/include/mbedcrypto/camellia.h
new file mode 100644
index 0000000..21607e2
--- /dev/null
+++ b/include/mbedcrypto/camellia.h
@@ -0,0 +1,229 @@
+/**
+ * \file camellia.h
+ *
+ * \brief Camellia block cipher
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_CAMELLIA_H
+#define MBEDCRYPTO_CAMELLIA_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MBEDCRYPTO_CAMELLIA_ENCRYPT 1
+#define MBEDCRYPTO_CAMELLIA_DECRYPT 0
+
+#define MBEDCRYPTO_ERR_CAMELLIA_INVALID_KEY_LENGTH -0x0024 /**< Invalid key length. */
+#define MBEDCRYPTO_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 /**< Invalid data input length. */
+#define MBEDCRYPTO_ERR_CAMELLIA_HW_ACCEL_FAILED -0x0027 /**< Camellia hardware accelerator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDCRYPTO_CAMELLIA_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief CAMELLIA context structure
+ */
+typedef struct
+{
+ int nr; /*!< number of rounds */
+ uint32_t rk[68]; /*!< CAMELLIA round keys */
+}
+mbedcrypto_camellia_context;
+
+#else /* MBEDCRYPTO_CAMELLIA_ALT */
+#include "camellia_alt.h"
+#endif /* MBEDCRYPTO_CAMELLIA_ALT */
+
+/**
+ * \brief Initialize CAMELLIA context
+ *
+ * \param ctx CAMELLIA context to be initialized
+ */
+void mbedcrypto_camellia_init( mbedcrypto_camellia_context *ctx );
+
+/**
+ * \brief Clear CAMELLIA context
+ *
+ * \param ctx CAMELLIA context to be cleared
+ */
+void mbedcrypto_camellia_free( mbedcrypto_camellia_context *ctx );
+
+/**
+ * \brief CAMELLIA key schedule (encryption)
+ *
+ * \param ctx CAMELLIA context to be initialized
+ * \param key encryption key
+ * \param keybits must be 128, 192 or 256
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_CAMELLIA_INVALID_KEY_LENGTH
+ */
+int mbedcrypto_camellia_setkey_enc( mbedcrypto_camellia_context *ctx, const unsigned char *key,
+ unsigned int keybits );
+
+/**
+ * \brief CAMELLIA key schedule (decryption)
+ *
+ * \param ctx CAMELLIA context to be initialized
+ * \param key decryption key
+ * \param keybits must be 128, 192 or 256
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_CAMELLIA_INVALID_KEY_LENGTH
+ */
+int mbedcrypto_camellia_setkey_dec( mbedcrypto_camellia_context *ctx, const unsigned char *key,
+ unsigned int keybits );
+
+/**
+ * \brief CAMELLIA-ECB block encryption/decryption
+ *
+ * \param ctx CAMELLIA context
+ * \param mode MBEDCRYPTO_CAMELLIA_ENCRYPT or MBEDCRYPTO_CAMELLIA_DECRYPT
+ * \param input 16-byte input block
+ * \param output 16-byte output block
+ *
+ * \return 0 if successful
+ */
+int mbedcrypto_camellia_crypt_ecb( mbedcrypto_camellia_context *ctx,
+ int mode,
+ const unsigned char input[16],
+ unsigned char output[16] );
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_CBC)
+/**
+ * \brief CAMELLIA-CBC buffer encryption/decryption
+ * Length should be a multiple of the block
+ * size (16 bytes)
+ *
+ * \note Upon exit, the content of the IV is updated so that you can
+ * call the function same function again on the following
+ * block(s) of data and get the same result as if it was
+ * encrypted in one call. This allows a "streaming" usage.
+ * If on the other hand you need to retain the contents of the
+ * IV, you should either save it manually or use the cipher
+ * module instead.
+ *
+ * \param ctx CAMELLIA context
+ * \param mode MBEDCRYPTO_CAMELLIA_ENCRYPT or MBEDCRYPTO_CAMELLIA_DECRYPT
+ * \param length length of the input data
+ * \param iv initialization vector (updated after use)
+ * \param input buffer holding the input data
+ * \param output buffer holding the output data
+ *
+ * \return 0 if successful, or
+ * MBEDCRYPTO_ERR_CAMELLIA_INVALID_INPUT_LENGTH
+ */
+int mbedcrypto_camellia_crypt_cbc( mbedcrypto_camellia_context *ctx,
+ int mode,
+ size_t length,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output );
+#endif /* MBEDCRYPTO_CIPHER_MODE_CBC */
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_CFB)
+/**
+ * \brief CAMELLIA-CFB128 buffer encryption/decryption
+ *
+ * Note: Due to the nature of CFB you should use the same key schedule for
+ * both encryption and decryption. So a context initialized with
+ * mbedcrypto_camellia_setkey_enc() for both MBEDCRYPTO_CAMELLIA_ENCRYPT and CAMELLIE_DECRYPT.
+ *
+ * \note Upon exit, the content of the IV is updated so that you can
+ * call the function same function again on the following
+ * block(s) of data and get the same result as if it was
+ * encrypted in one call. This allows a "streaming" usage.
+ * If on the other hand you need to retain the contents of the
+ * IV, you should either save it manually or use the cipher
+ * module instead.
+ *
+ * \param ctx CAMELLIA context
+ * \param mode MBEDCRYPTO_CAMELLIA_ENCRYPT or MBEDCRYPTO_CAMELLIA_DECRYPT
+ * \param length length of the input data
+ * \param iv_off offset in IV (updated after use)
+ * \param iv initialization vector (updated after use)
+ * \param input buffer holding the input data
+ * \param output buffer holding the output data
+ *
+ * \return 0 if successful, or
+ * MBEDCRYPTO_ERR_CAMELLIA_INVALID_INPUT_LENGTH
+ */
+int mbedcrypto_camellia_crypt_cfb128( mbedcrypto_camellia_context *ctx,
+ int mode,
+ size_t length,
+ size_t *iv_off,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output );
+#endif /* MBEDCRYPTO_CIPHER_MODE_CFB */
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_CTR)
+/**
+ * \brief CAMELLIA-CTR buffer encryption/decryption
+ *
+ * Warning: You have to keep the maximum use of your counter in mind!
+ *
+ * Note: Due to the nature of CTR you should use the same key schedule for
+ * both encryption and decryption. So a context initialized with
+ * mbedcrypto_camellia_setkey_enc() for both MBEDCRYPTO_CAMELLIA_ENCRYPT and MBEDCRYPTO_CAMELLIA_DECRYPT.
+ *
+ * \param ctx CAMELLIA context
+ * \param length The length of the data
+ * \param nc_off The offset in the current stream_block (for resuming
+ * within current cipher stream). The offset pointer to
+ * should be 0 at the start of a stream.
+ * \param nonce_counter The 128-bit nonce and counter.
+ * \param stream_block The saved stream-block for resuming. Is overwritten
+ * by the function.
+ * \param input The input data stream
+ * \param output The output data stream
+ *
+ * \return 0 if successful
+ */
+int mbedcrypto_camellia_crypt_ctr( mbedcrypto_camellia_context *ctx,
+ size_t length,
+ size_t *nc_off,
+ unsigned char nonce_counter[16],
+ unsigned char stream_block[16],
+ const unsigned char *input,
+ unsigned char *output );
+#endif /* MBEDCRYPTO_CIPHER_MODE_CTR */
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int mbedcrypto_camellia_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* camellia.h */
diff --git a/include/mbedcrypto/ccm.h b/include/mbedcrypto/ccm.h
new file mode 100644
index 0000000..14e178e
--- /dev/null
+++ b/include/mbedcrypto/ccm.h
@@ -0,0 +1,178 @@
+/**
+ * \file ccm.h
+ *
+ * \brief This file provides an API for the CCM authenticated encryption
+ * mode for block ciphers.
+ *
+ * CCM combines Counter mode encryption with CBC-MAC authentication
+ * for 128-bit block ciphers.
+ *
+ * Input to CCM includes the following elements:
+ * <ul><li>Payload - data that is both authenticated and encrypted.</li>
+ * <li>Associated data (Adata) - data that is authenticated but not
+ * encrypted, For example, a header.</li>
+ * <li>Nonce - A unique value that is assigned to the payload and the
+ * associated data.</li></ul>
+ *
+ */
+/*
+ * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+#ifndef MBEDCRYPTO_CCM_H
+#define MBEDCRYPTO_CCM_H
+
+#include "cipher.h"
+
+#define MBEDCRYPTO_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to the function. */
+#define MBEDCRYPTO_ERR_CCM_AUTH_FAILED -0x000F /**< Authenticated decryption failed. */
+#define MBEDCRYPTO_ERR_CCM_HW_ACCEL_FAILED -0x0011 /**< CCM hardware accelerator failed. */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDCRYPTO_CCM_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief The CCM context-type definition. The CCM context is passed
+ * to the APIs called.
+ */
+typedef struct {
+ mbedcrypto_cipher_context_t cipher_ctx; /*!< The cipher context used. */
+}
+mbedcrypto_ccm_context;
+
+#else /* MBEDCRYPTO_CCM_ALT */
+#include "ccm_alt.h"
+#endif /* MBEDCRYPTO_CCM_ALT */
+
+/**
+ * \brief This function initializes the specified CCM context,
+ * to make references valid, and prepare the context
+ * for mbedcrypto_ccm_setkey() or mbedcrypto_ccm_free().
+ *
+ * \param ctx The CCM context to initialize.
+ */
+void mbedcrypto_ccm_init( mbedcrypto_ccm_context *ctx );
+
+/**
+ * \brief This function initializes the CCM context set in the
+ * \p ctx parameter and sets the encryption key.
+ *
+ * \param ctx The CCM context to initialize.
+ * \param cipher The 128-bit block cipher to use.
+ * \param key The encryption key.
+ * \param keybits The key size in bits. This must be acceptable by the cipher.
+ *
+ * \return \c 0 on success.
+ * \return A CCM or cipher-specific error code on failure.
+ */
+int mbedcrypto_ccm_setkey( mbedcrypto_ccm_context *ctx,
+ mbedcrypto_cipher_id_t cipher,
+ const unsigned char *key,
+ unsigned int keybits );
+
+/**
+ * \brief This function releases and clears the specified CCM context
+ * and underlying cipher sub-context.
+ *
+ * \param ctx The CCM context to clear.
+ */
+void mbedcrypto_ccm_free( mbedcrypto_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 <em>RFC-3610:
+ * Counter with CBC-MAC (CCM)</em>, use
+ * \p tag = \p output + \p length, and make sure that the
+ * output buffer is at least \p length + \p tag_len wide.
+ *
+ * \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 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:
+ * 4, 6, 8, 10, 12, 14 or 16.
+ *
+ * \return \c 0 on success.
+ * \return A CCM or cipher-specific error code on failure.
+ */
+int mbedcrypto_ccm_encrypt_and_tag( mbedcrypto_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.
+ * \param iv_len The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13.
+ * \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.
+ * 4, 6, 8, 10, 12, 14 or 16.
+ *
+ * \return \c 0 on success. This indicates that the message is authentic.
+ * \return #MBEDCRYPTO_ERR_CCM_AUTH_FAILED if the tag does not match.
+ * \return A cipher-specific error code on calculation failure.
+ */
+int mbedcrypto_ccm_auth_decrypt( mbedcrypto_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(MBEDCRYPTO_SELF_TEST) && defined(MBEDCRYPTO_AES_C)
+/**
+ * \brief The CCM checkup routine.
+ *
+ * \return \c 0 on success.
+ * \return \c 1 on failure.
+ */
+int mbedcrypto_ccm_self_test( int verbose );
+#endif /* MBEDCRYPTO_SELF_TEST && MBEDCRYPTO_AES_C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDCRYPTO_CCM_H */
diff --git a/include/mbedcrypto/certs.h b/include/mbedcrypto/certs.h
new file mode 100644
index 0000000..c4d27e9
--- /dev/null
+++ b/include/mbedcrypto/certs.h
@@ -0,0 +1,100 @@
+/**
+ * \file certs.h
+ *
+ * \brief Sample certificates and DHM parameters for testing
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_CERTS_H
+#define MBEDCRYPTO_CERTS_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDCRYPTO_PEM_PARSE_C)
+/* Concatenation of all CA certificates in PEM format if available */
+extern const char mbedcrypto_test_cas_pem[];
+extern const size_t mbedcrypto_test_cas_pem_len;
+#endif
+
+/* List of all CA certificates, terminated by NULL */
+extern const char * mbedcrypto_test_cas[];
+extern const size_t mbedcrypto_test_cas_len[];
+
+/*
+ * Convenience for users who just want a certificate:
+ * RSA by default, or ECDSA if RSA is not available
+ */
+extern const char * mbedcrypto_test_ca_crt;
+extern const size_t mbedcrypto_test_ca_crt_len;
+extern const char * mbedcrypto_test_ca_key;
+extern const size_t mbedcrypto_test_ca_key_len;
+extern const char * mbedcrypto_test_ca_pwd;
+extern const size_t mbedcrypto_test_ca_pwd_len;
+extern const char * mbedcrypto_test_srv_crt;
+extern const size_t mbedcrypto_test_srv_crt_len;
+extern const char * mbedcrypto_test_srv_key;
+extern const size_t mbedcrypto_test_srv_key_len;
+extern const char * mbedcrypto_test_cli_crt;
+extern const size_t mbedcrypto_test_cli_crt_len;
+extern const char * mbedcrypto_test_cli_key;
+extern const size_t mbedcrypto_test_cli_key_len;
+
+#if defined(MBEDCRYPTO_ECDSA_C)
+extern const char mbedcrypto_test_ca_crt_ec[];
+extern const size_t mbedcrypto_test_ca_crt_ec_len;
+extern const char mbedcrypto_test_ca_key_ec[];
+extern const size_t mbedcrypto_test_ca_key_ec_len;
+extern const char mbedcrypto_test_ca_pwd_ec[];
+extern const size_t mbedcrypto_test_ca_pwd_ec_len;
+extern const char mbedcrypto_test_srv_crt_ec[];
+extern const size_t mbedcrypto_test_srv_crt_ec_len;
+extern const char mbedcrypto_test_srv_key_ec[];
+extern const size_t mbedcrypto_test_srv_key_ec_len;
+extern const char mbedcrypto_test_cli_crt_ec[];
+extern const size_t mbedcrypto_test_cli_crt_ec_len;
+extern const char mbedcrypto_test_cli_key_ec[];
+extern const size_t mbedcrypto_test_cli_key_ec_len;
+#endif
+
+#if defined(MBEDCRYPTO_RSA_C)
+extern const char mbedcrypto_test_ca_crt_rsa[];
+extern const size_t mbedcrypto_test_ca_crt_rsa_len;
+extern const char mbedcrypto_test_ca_key_rsa[];
+extern const size_t mbedcrypto_test_ca_key_rsa_len;
+extern const char mbedcrypto_test_ca_pwd_rsa[];
+extern const size_t mbedcrypto_test_ca_pwd_rsa_len;
+extern const char mbedcrypto_test_srv_crt_rsa[];
+extern const size_t mbedcrypto_test_srv_crt_rsa_len;
+extern const char mbedcrypto_test_srv_key_rsa[];
+extern const size_t mbedcrypto_test_srv_key_rsa_len;
+extern const char mbedcrypto_test_cli_crt_rsa[];
+extern const size_t mbedcrypto_test_cli_crt_rsa_len;
+extern const char mbedcrypto_test_cli_key_rsa[];
+extern const size_t mbedcrypto_test_cli_key_rsa_len;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* certs.h */
diff --git a/include/mbedcrypto/check_config.h b/include/mbedcrypto/check_config.h
new file mode 100644
index 0000000..9948f0e
--- /dev/null
+++ b/include/mbedcrypto/check_config.h
@@ -0,0 +1,684 @@
+/**
+ * \file check_config.h
+ *
+ * \brief Consistency checks for configuration options
+ */
+/*
+ * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+/*
+ * It is recommended to include this file from your config.h
+ * in order to catch dependency issues early.
+ */
+
+#ifndef MBEDCRYPTO_CHECK_CONFIG_H
+#define MBEDCRYPTO_CHECK_CONFIG_H
+
+/*
+ * We assume CHAR_BIT is 8 in many places. In practice, this is true on our
+ * target platforms, so not an issue, but let's just be extra sure.
+ */
+#include <limits.h>
+#if CHAR_BIT != 8
+#error "Mbed Crypto requires a platform with 8-bit chars"
+#endif
+
+#if defined(_WIN32)
+#if !defined(MBEDCRYPTO_PLATFORM_C)
+#error "MBEDCRYPTO_PLATFORM_C is required on Windows"
+#endif
+
+/* Fix the config here. Not convenient to put an #ifdef _WIN32 in config.h as
+ * it would confuse config.pl. */
+#if !defined(MBEDCRYPTO_PLATFORM_SNPRINTF_ALT) && \
+ !defined(MBEDCRYPTO_PLATFORM_SNPRINTF_MACRO)
+#define MBEDCRYPTO_PLATFORM_SNPRINTF_ALT
+#endif
+#endif /* _WIN32 */
+
+#if defined(TARGET_LIKE_MBED) && \
+ ( defined(MBEDCRYPTO_NET_C) || defined(MBEDCRYPTO_TIMING_C) )
+#error "The NET and TIMING modules are not available for mbed OS - please use the network and timing functions provided by mbed OS"
+#endif
+
+#if defined(MBEDCRYPTO_DEPRECATED_WARNING) && \
+ !defined(__GNUC__) && !defined(__clang__)
+#error "MBEDCRYPTO_DEPRECATED_WARNING only works with GCC and Clang"
+#endif
+
+#if defined(MBEDCRYPTO_HAVE_TIME_DATE) && !defined(MBEDCRYPTO_HAVE_TIME)
+#error "MBEDCRYPTO_HAVE_TIME_DATE without MBEDCRYPTO_HAVE_TIME does not make sense"
+#endif
+
+#if defined(MBEDCRYPTO_AESNI_C) && !defined(MBEDCRYPTO_HAVE_ASM)
+#error "MBEDCRYPTO_AESNI_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_CTR_DRBG_C) && !defined(MBEDCRYPTO_AES_C)
+#error "MBEDCRYPTO_CTR_DRBG_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_DHM_C) && !defined(MBEDCRYPTO_BIGNUM_C)
+#error "MBEDCRYPTO_DHM_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_TRUNCATED_HMAC_COMPAT) && !defined(MBEDCRYPTO_SSL_TRUNCATED_HMAC)
+#error "MBEDCRYPTO_SSL_TRUNCATED_HMAC_COMPAT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_CMAC_C) && \
+ !defined(MBEDCRYPTO_AES_C) && !defined(MBEDCRYPTO_DES_C)
+#error "MBEDCRYPTO_CMAC_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_ECDH_C) && !defined(MBEDCRYPTO_ECP_C)
+#error "MBEDCRYPTO_ECDH_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_ECDSA_C) && \
+ ( !defined(MBEDCRYPTO_ECP_C) || \
+ !defined(MBEDCRYPTO_ASN1_PARSE_C) || \
+ !defined(MBEDCRYPTO_ASN1_WRITE_C) )
+#error "MBEDCRYPTO_ECDSA_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_ECJPAKE_C) && \
+ ( !defined(MBEDCRYPTO_ECP_C) || !defined(MBEDCRYPTO_MD_C) )
+#error "MBEDCRYPTO_ECJPAKE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_ECDSA_DETERMINISTIC) && !defined(MBEDCRYPTO_HMAC_DRBG_C)
+#error "MBEDCRYPTO_ECDSA_DETERMINISTIC defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_ECP_C) && ( !defined(MBEDCRYPTO_BIGNUM_C) || ( \
+ !defined(MBEDCRYPTO_ECP_DP_SECP192R1_ENABLED) && \
+ !defined(MBEDCRYPTO_ECP_DP_SECP224R1_ENABLED) && \
+ !defined(MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED) && \
+ !defined(MBEDCRYPTO_ECP_DP_SECP384R1_ENABLED) && \
+ !defined(MBEDCRYPTO_ECP_DP_SECP521R1_ENABLED) && \
+ !defined(MBEDCRYPTO_ECP_DP_BP256R1_ENABLED) && \
+ !defined(MBEDCRYPTO_ECP_DP_BP384R1_ENABLED) && \
+ !defined(MBEDCRYPTO_ECP_DP_BP512R1_ENABLED) && \
+ !defined(MBEDCRYPTO_ECP_DP_SECP192K1_ENABLED) && \
+ !defined(MBEDCRYPTO_ECP_DP_SECP224K1_ENABLED) && \
+ !defined(MBEDCRYPTO_ECP_DP_SECP256K1_ENABLED) ) )
+#error "MBEDCRYPTO_ECP_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_ENTROPY_C) && (!defined(MBEDCRYPTO_SHA512_C) && \
+ !defined(MBEDCRYPTO_SHA256_C))
+#error "MBEDCRYPTO_ENTROPY_C defined, but not all prerequisites"
+#endif
+#if defined(MBEDCRYPTO_ENTROPY_C) && defined(MBEDCRYPTO_SHA512_C) && \
+ defined(MBEDCRYPTO_CTR_DRBG_ENTROPY_LEN) && (MBEDCRYPTO_CTR_DRBG_ENTROPY_LEN > 64)
+#error "MBEDCRYPTO_CTR_DRBG_ENTROPY_LEN value too high"
+#endif
+#if defined(MBEDCRYPTO_ENTROPY_C) && \
+ ( !defined(MBEDCRYPTO_SHA512_C) || defined(MBEDCRYPTO_ENTROPY_FORCE_SHA256) ) \
+ && defined(MBEDCRYPTO_CTR_DRBG_ENTROPY_LEN) && (MBEDCRYPTO_CTR_DRBG_ENTROPY_LEN > 32)
+#error "MBEDCRYPTO_CTR_DRBG_ENTROPY_LEN value too high"
+#endif
+#if defined(MBEDCRYPTO_ENTROPY_C) && \
+ defined(MBEDCRYPTO_ENTROPY_FORCE_SHA256) && !defined(MBEDCRYPTO_SHA256_C)
+#error "MBEDCRYPTO_ENTROPY_FORCE_SHA256 defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_TEST_NULL_ENTROPY) && \
+ ( !defined(MBEDCRYPTO_ENTROPY_C) || !defined(MBEDCRYPTO_NO_DEFAULT_ENTROPY_SOURCES) )
+#error "MBEDCRYPTO_TEST_NULL_ENTROPY defined, but not all prerequisites"
+#endif
+#if defined(MBEDCRYPTO_TEST_NULL_ENTROPY) && \
+ ( defined(MBEDCRYPTO_ENTROPY_NV_SEED) || defined(MBEDCRYPTO_ENTROPY_HARDWARE_ALT) || \
+ defined(MBEDCRYPTO_HAVEGE_C) )
+#error "MBEDCRYPTO_TEST_NULL_ENTROPY defined, but entropy sources too"
+#endif
+
+#if defined(MBEDCRYPTO_GCM_C) && ( \
+ !defined(MBEDCRYPTO_AES_C) && !defined(MBEDCRYPTO_CAMELLIA_C) )
+#error "MBEDCRYPTO_GCM_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_ECP_RANDOMIZE_JAC_ALT) && !defined(MBEDCRYPTO_ECP_INTERNAL_ALT)
+#error "MBEDCRYPTO_ECP_RANDOMIZE_JAC_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_ECP_ADD_MIXED_ALT) && !defined(MBEDCRYPTO_ECP_INTERNAL_ALT)
+#error "MBEDCRYPTO_ECP_ADD_MIXED_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_ECP_DOUBLE_JAC_ALT) && !defined(MBEDCRYPTO_ECP_INTERNAL_ALT)
+#error "MBEDCRYPTO_ECP_DOUBLE_JAC_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_ECP_NORMALIZE_JAC_MANY_ALT) && !defined(MBEDCRYPTO_ECP_INTERNAL_ALT)
+#error "MBEDCRYPTO_ECP_NORMALIZE_JAC_MANY_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_ECP_NORMALIZE_JAC_ALT) && !defined(MBEDCRYPTO_ECP_INTERNAL_ALT)
+#error "MBEDCRYPTO_ECP_NORMALIZE_JAC_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_ECP_DOUBLE_ADD_MXZ_ALT) && !defined(MBEDCRYPTO_ECP_INTERNAL_ALT)
+#error "MBEDCRYPTO_ECP_DOUBLE_ADD_MXZ_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_ECP_RANDOMIZE_MXZ_ALT) && !defined(MBEDCRYPTO_ECP_INTERNAL_ALT)
+#error "MBEDCRYPTO_ECP_RANDOMIZE_MXZ_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_ECP_NORMALIZE_MXZ_ALT) && !defined(MBEDCRYPTO_ECP_INTERNAL_ALT)
+#error "MBEDCRYPTO_ECP_NORMALIZE_MXZ_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_HAVEGE_C) && !defined(MBEDCRYPTO_TIMING_C)
+#error "MBEDCRYPTO_HAVEGE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_HMAC_DRBG_C) && !defined(MBEDCRYPTO_MD_C)
+#error "MBEDCRYPTO_HMAC_DRBG_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \
+ ( !defined(MBEDCRYPTO_ECDH_C) || !defined(MBEDCRYPTO_X509_CRT_PARSE_C) )
+#error "MBEDCRYPTO_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
+ ( !defined(MBEDCRYPTO_ECDH_C) || !defined(MBEDCRYPTO_X509_CRT_PARSE_C) )
+#error "MBEDCRYPTO_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(MBEDCRYPTO_DHM_C)
+#error "MBEDCRYPTO_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \
+ !defined(MBEDCRYPTO_ECDH_C)
+#error "MBEDCRYPTO_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
+ ( !defined(MBEDCRYPTO_DHM_C) || !defined(MBEDCRYPTO_RSA_C) || \
+ !defined(MBEDCRYPTO_X509_CRT_PARSE_C) || !defined(MBEDCRYPTO_PKCS1_V15) )
+#error "MBEDCRYPTO_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
+ ( !defined(MBEDCRYPTO_ECDH_C) || !defined(MBEDCRYPTO_RSA_C) || \
+ !defined(MBEDCRYPTO_X509_CRT_PARSE_C) || !defined(MBEDCRYPTO_PKCS1_V15) )
+#error "MBEDCRYPTO_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
+ ( !defined(MBEDCRYPTO_ECDH_C) || !defined(MBEDCRYPTO_ECDSA_C) || \
+ !defined(MBEDCRYPTO_X509_CRT_PARSE_C) )
+#error "MBEDCRYPTO_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_KEY_EXCHANGE_RSA_PSK_ENABLED) && \
+ ( !defined(MBEDCRYPTO_RSA_C) || !defined(MBEDCRYPTO_X509_CRT_PARSE_C) || \
+ !defined(MBEDCRYPTO_PKCS1_V15) )
+#error "MBEDCRYPTO_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_KEY_EXCHANGE_RSA_ENABLED) && \
+ ( !defined(MBEDCRYPTO_RSA_C) || !defined(MBEDCRYPTO_X509_CRT_PARSE_C) || \
+ !defined(MBEDCRYPTO_PKCS1_V15) )
+#error "MBEDCRYPTO_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
+ ( !defined(MBEDCRYPTO_ECJPAKE_C) || !defined(MBEDCRYPTO_SHA256_C) || \
+ !defined(MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED) )
+#error "MBEDCRYPTO_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_MEMORY_BUFFER_ALLOC_C) && \
+ ( !defined(MBEDCRYPTO_PLATFORM_C) || !defined(MBEDCRYPTO_PLATFORM_MEMORY) )
+#error "MBEDCRYPTO_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PADLOCK_C) && !defined(MBEDCRYPTO_HAVE_ASM)
+#error "MBEDCRYPTO_PADLOCK_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PEM_PARSE_C) && !defined(MBEDCRYPTO_BASE64_C)
+#error "MBEDCRYPTO_PEM_PARSE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PEM_WRITE_C) && !defined(MBEDCRYPTO_BASE64_C)
+#error "MBEDCRYPTO_PEM_WRITE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PK_C) && \
+ ( !defined(MBEDCRYPTO_RSA_C) && !defined(MBEDCRYPTO_ECP_C) )
+#error "MBEDCRYPTO_PK_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PK_PARSE_C) && !defined(MBEDCRYPTO_PK_C)
+#error "MBEDCRYPTO_PK_PARSE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PK_WRITE_C) && !defined(MBEDCRYPTO_PK_C)
+#error "MBEDCRYPTO_PK_WRITE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PKCS11_C) && !defined(MBEDCRYPTO_PK_C)
+#error "MBEDCRYPTO_PKCS11_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_EXIT_ALT) && !defined(MBEDCRYPTO_PLATFORM_C)
+#error "MBEDCRYPTO_PLATFORM_EXIT_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_EXIT_MACRO) && !defined(MBEDCRYPTO_PLATFORM_C)
+#error "MBEDCRYPTO_PLATFORM_EXIT_MACRO defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_EXIT_MACRO) &&\
+ ( defined(MBEDCRYPTO_PLATFORM_STD_EXIT) ||\
+ defined(MBEDCRYPTO_PLATFORM_EXIT_ALT) )
+#error "MBEDCRYPTO_PLATFORM_EXIT_MACRO and MBEDCRYPTO_PLATFORM_STD_EXIT/MBEDCRYPTO_PLATFORM_EXIT_ALT cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_TIME_ALT) &&\
+ ( !defined(MBEDCRYPTO_PLATFORM_C) ||\
+ !defined(MBEDCRYPTO_HAVE_TIME) )
+#error "MBEDCRYPTO_PLATFORM_TIME_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_TIME_MACRO) &&\
+ ( !defined(MBEDCRYPTO_PLATFORM_C) ||\
+ !defined(MBEDCRYPTO_HAVE_TIME) )
+#error "MBEDCRYPTO_PLATFORM_TIME_MACRO defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_TIME_TYPE_MACRO) &&\
+ ( !defined(MBEDCRYPTO_PLATFORM_C) ||\
+ !defined(MBEDCRYPTO_HAVE_TIME) )
+#error "MBEDCRYPTO_PLATFORM_TIME_TYPE_MACRO defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_TIME_MACRO) &&\
+ ( defined(MBEDCRYPTO_PLATFORM_STD_TIME) ||\
+ defined(MBEDCRYPTO_PLATFORM_TIME_ALT) )
+#error "MBEDCRYPTO_PLATFORM_TIME_MACRO and MBEDCRYPTO_PLATFORM_STD_TIME/MBEDCRYPTO_PLATFORM_TIME_ALT cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_TIME_TYPE_MACRO) &&\
+ ( defined(MBEDCRYPTO_PLATFORM_STD_TIME) ||\
+ defined(MBEDCRYPTO_PLATFORM_TIME_ALT) )
+#error "MBEDCRYPTO_PLATFORM_TIME_TYPE_MACRO and MBEDCRYPTO_PLATFORM_STD_TIME/MBEDCRYPTO_PLATFORM_TIME_ALT cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_FPRINTF_ALT) && !defined(MBEDCRYPTO_PLATFORM_C)
+#error "MBEDCRYPTO_PLATFORM_FPRINTF_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_FPRINTF_MACRO) && !defined(MBEDCRYPTO_PLATFORM_C)
+#error "MBEDCRYPTO_PLATFORM_FPRINTF_MACRO defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_FPRINTF_MACRO) &&\
+ ( defined(MBEDCRYPTO_PLATFORM_STD_FPRINTF) ||\
+ defined(MBEDCRYPTO_PLATFORM_FPRINTF_ALT) )
+#error "MBEDCRYPTO_PLATFORM_FPRINTF_MACRO and MBEDCRYPTO_PLATFORM_STD_FPRINTF/MBEDCRYPTO_PLATFORM_FPRINTF_ALT cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_FREE_MACRO) &&\
+ ( !defined(MBEDCRYPTO_PLATFORM_C) || !defined(MBEDCRYPTO_PLATFORM_MEMORY) )
+#error "MBEDCRYPTO_PLATFORM_FREE_MACRO defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_FREE_MACRO) &&\
+ defined(MBEDCRYPTO_PLATFORM_STD_FREE)
+#error "MBEDCRYPTO_PLATFORM_FREE_MACRO and MBEDCRYPTO_PLATFORM_STD_FREE cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_FREE_MACRO) && !defined(MBEDCRYPTO_PLATFORM_CALLOC_MACRO)
+#error "MBEDCRYPTO_PLATFORM_CALLOC_MACRO must be defined if MBEDCRYPTO_PLATFORM_FREE_MACRO is"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_CALLOC_MACRO) &&\
+ ( !defined(MBEDCRYPTO_PLATFORM_C) || !defined(MBEDCRYPTO_PLATFORM_MEMORY) )
+#error "MBEDCRYPTO_PLATFORM_CALLOC_MACRO defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_CALLOC_MACRO) &&\
+ defined(MBEDCRYPTO_PLATFORM_STD_CALLOC)
+#error "MBEDCRYPTO_PLATFORM_CALLOC_MACRO and MBEDCRYPTO_PLATFORM_STD_CALLOC cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_CALLOC_MACRO) && !defined(MBEDCRYPTO_PLATFORM_FREE_MACRO)
+#error "MBEDCRYPTO_PLATFORM_FREE_MACRO must be defined if MBEDCRYPTO_PLATFORM_CALLOC_MACRO is"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_MEMORY) && !defined(MBEDCRYPTO_PLATFORM_C)
+#error "MBEDCRYPTO_PLATFORM_MEMORY defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_PRINTF_ALT) && !defined(MBEDCRYPTO_PLATFORM_C)
+#error "MBEDCRYPTO_PLATFORM_PRINTF_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_PRINTF_MACRO) && !defined(MBEDCRYPTO_PLATFORM_C)
+#error "MBEDCRYPTO_PLATFORM_PRINTF_MACRO defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_PRINTF_MACRO) &&\
+ ( defined(MBEDCRYPTO_PLATFORM_STD_PRINTF) ||\
+ defined(MBEDCRYPTO_PLATFORM_PRINTF_ALT) )
+#error "MBEDCRYPTO_PLATFORM_PRINTF_MACRO and MBEDCRYPTO_PLATFORM_STD_PRINTF/MBEDCRYPTO_PLATFORM_PRINTF_ALT cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_SNPRINTF_ALT) && !defined(MBEDCRYPTO_PLATFORM_C)
+#error "MBEDCRYPTO_PLATFORM_SNPRINTF_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_SNPRINTF_MACRO) && !defined(MBEDCRYPTO_PLATFORM_C)
+#error "MBEDCRYPTO_PLATFORM_SNPRINTF_MACRO defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_SNPRINTF_MACRO) &&\
+ ( defined(MBEDCRYPTO_PLATFORM_STD_SNPRINTF) ||\
+ defined(MBEDCRYPTO_PLATFORM_SNPRINTF_ALT) )
+#error "MBEDCRYPTO_PLATFORM_SNPRINTF_MACRO and MBEDCRYPTO_PLATFORM_STD_SNPRINTF/MBEDCRYPTO_PLATFORM_SNPRINTF_ALT cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_STD_MEM_HDR) &&\
+ !defined(MBEDCRYPTO_PLATFORM_NO_STD_FUNCTIONS)
+#error "MBEDCRYPTO_PLATFORM_STD_MEM_HDR defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_STD_CALLOC) && !defined(MBEDCRYPTO_PLATFORM_MEMORY)
+#error "MBEDCRYPTO_PLATFORM_STD_CALLOC defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_STD_CALLOC) && !defined(MBEDCRYPTO_PLATFORM_MEMORY)
+#error "MBEDCRYPTO_PLATFORM_STD_CALLOC defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_STD_FREE) && !defined(MBEDCRYPTO_PLATFORM_MEMORY)
+#error "MBEDCRYPTO_PLATFORM_STD_FREE defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_STD_EXIT) &&\
+ !defined(MBEDCRYPTO_PLATFORM_EXIT_ALT)
+#error "MBEDCRYPTO_PLATFORM_STD_EXIT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_STD_TIME) &&\
+ ( !defined(MBEDCRYPTO_PLATFORM_TIME_ALT) ||\
+ !defined(MBEDCRYPTO_HAVE_TIME) )
+#error "MBEDCRYPTO_PLATFORM_STD_TIME defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_STD_FPRINTF) &&\
+ !defined(MBEDCRYPTO_PLATFORM_FPRINTF_ALT)
+#error "MBEDCRYPTO_PLATFORM_STD_FPRINTF defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_STD_PRINTF) &&\
+ !defined(MBEDCRYPTO_PLATFORM_PRINTF_ALT)
+#error "MBEDCRYPTO_PLATFORM_STD_PRINTF defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_STD_SNPRINTF) &&\
+ !defined(MBEDCRYPTO_PLATFORM_SNPRINTF_ALT)
+#error "MBEDCRYPTO_PLATFORM_STD_SNPRINTF defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_ENTROPY_NV_SEED) &&\
+ ( !defined(MBEDCRYPTO_PLATFORM_C) || !defined(MBEDCRYPTO_ENTROPY_C) )
+#error "MBEDCRYPTO_ENTROPY_NV_SEED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_NV_SEED_ALT) &&\
+ !defined(MBEDCRYPTO_ENTROPY_NV_SEED)
+#error "MBEDCRYPTO_PLATFORM_NV_SEED_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_STD_NV_SEED_READ) &&\
+ !defined(MBEDCRYPTO_PLATFORM_NV_SEED_ALT)
+#error "MBEDCRYPTO_PLATFORM_STD_NV_SEED_READ defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_STD_NV_SEED_WRITE) &&\
+ !defined(MBEDCRYPTO_PLATFORM_NV_SEED_ALT)
+#error "MBEDCRYPTO_PLATFORM_STD_NV_SEED_WRITE defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_NV_SEED_READ_MACRO) &&\
+ ( defined(MBEDCRYPTO_PLATFORM_STD_NV_SEED_READ) ||\
+ defined(MBEDCRYPTO_PLATFORM_NV_SEED_ALT) )
+#error "MBEDCRYPTO_PLATFORM_NV_SEED_READ_MACRO and MBEDCRYPTO_PLATFORM_STD_NV_SEED_READ cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_NV_SEED_WRITE_MACRO) &&\
+ ( defined(MBEDCRYPTO_PLATFORM_STD_NV_SEED_WRITE) ||\
+ defined(MBEDCRYPTO_PLATFORM_NV_SEED_ALT) )
+#error "MBEDCRYPTO_PLATFORM_NV_SEED_WRITE_MACRO and MBEDCRYPTO_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDCRYPTO_PSA_CRYPTO_C) && \
+ !( defined(MBEDCRYPTO_CTR_DRBG_C) && \
+ defined(MBEDCRYPTO_ENTROPY_C) )
+#error "MBEDCRYPTO_PSA_CRYPTO_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_PSA_CRYPTO_SPM) && !defined(MBEDCRYPTO_PSA_CRYPTO_C)
+#error "MBEDCRYPTO_PSA_CRYPTO_SPM defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_RSA_C) && ( !defined(MBEDCRYPTO_BIGNUM_C) || \
+ !defined(MBEDCRYPTO_OID_C) )
+#error "MBEDCRYPTO_RSA_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_RSA_C) && ( !defined(MBEDCRYPTO_PKCS1_V21) && \
+ !defined(MBEDCRYPTO_PKCS1_V15) )
+#error "MBEDCRYPTO_RSA_C defined, but none of the PKCS1 versions enabled"
+#endif
+
+#if defined(MBEDCRYPTO_X509_RSASSA_PSS_SUPPORT) && \
+ ( !defined(MBEDCRYPTO_RSA_C) || !defined(MBEDCRYPTO_PKCS1_V21) )
+#error "MBEDCRYPTO_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_PROTO_SSL3) && ( !defined(MBEDCRYPTO_MD5_C) || \
+ !defined(MBEDCRYPTO_SHA1_C) )
+#error "MBEDCRYPTO_SSL_PROTO_SSL3 defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_PROTO_TLS1) && ( !defined(MBEDCRYPTO_MD5_C) || \
+ !defined(MBEDCRYPTO_SHA1_C) )
+#error "MBEDCRYPTO_SSL_PROTO_TLS1 defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_PROTO_TLS1_1) && ( !defined(MBEDCRYPTO_MD5_C) || \
+ !defined(MBEDCRYPTO_SHA1_C) )
+#error "MBEDCRYPTO_SSL_PROTO_TLS1_1 defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_PROTO_TLS1_2) && ( !defined(MBEDCRYPTO_SHA1_C) && \
+ !defined(MBEDCRYPTO_SHA256_C) && !defined(MBEDCRYPTO_SHA512_C) )
+#error "MBEDCRYPTO_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_PROTO_DTLS) && \
+ !defined(MBEDCRYPTO_SSL_PROTO_TLS1_1) && \
+ !defined(MBEDCRYPTO_SSL_PROTO_TLS1_2)
+#error "MBEDCRYPTO_SSL_PROTO_DTLS defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_CLI_C) && !defined(MBEDCRYPTO_SSL_TLS_C)
+#error "MBEDCRYPTO_SSL_CLI_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_TLS_C) && ( !defined(MBEDCRYPTO_CIPHER_C) || \
+ !defined(MBEDCRYPTO_MD_C) )
+#error "MBEDCRYPTO_SSL_TLS_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_SRV_C) && !defined(MBEDCRYPTO_SSL_TLS_C)
+#error "MBEDCRYPTO_SSL_SRV_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_TLS_C) && (!defined(MBEDCRYPTO_SSL_PROTO_SSL3) && \
+ !defined(MBEDCRYPTO_SSL_PROTO_TLS1) && !defined(MBEDCRYPTO_SSL_PROTO_TLS1_1) && \
+ !defined(MBEDCRYPTO_SSL_PROTO_TLS1_2))
+#error "MBEDCRYPTO_SSL_TLS_C defined, but no protocols are active"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_TLS_C) && (defined(MBEDCRYPTO_SSL_PROTO_SSL3) && \
+ defined(MBEDCRYPTO_SSL_PROTO_TLS1_1) && !defined(MBEDCRYPTO_SSL_PROTO_TLS1))
+#error "Illegal protocol selection"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_TLS_C) && (defined(MBEDCRYPTO_SSL_PROTO_TLS1) && \
+ defined(MBEDCRYPTO_SSL_PROTO_TLS1_2) && !defined(MBEDCRYPTO_SSL_PROTO_TLS1_1))
+#error "Illegal protocol selection"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_TLS_C) && (defined(MBEDCRYPTO_SSL_PROTO_SSL3) && \
+ defined(MBEDCRYPTO_SSL_PROTO_TLS1_2) && (!defined(MBEDCRYPTO_SSL_PROTO_TLS1) || \
+ !defined(MBEDCRYPTO_SSL_PROTO_TLS1_1)))
+#error "Illegal protocol selection"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_DTLS_HELLO_VERIFY) && !defined(MBEDCRYPTO_SSL_PROTO_DTLS)
+#error "MBEDCRYPTO_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_DTLS_CLIENT_PORT_REUSE) && \
+ !defined(MBEDCRYPTO_SSL_DTLS_HELLO_VERIFY)
+#error "MBEDCRYPTO_SSL_DTLS_CLIENT_PORT_REUSE defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_DTLS_ANTI_REPLAY) && \
+ ( !defined(MBEDCRYPTO_SSL_TLS_C) || !defined(MBEDCRYPTO_SSL_PROTO_DTLS) )
+#error "MBEDCRYPTO_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_DTLS_BADMAC_LIMIT) && \
+ ( !defined(MBEDCRYPTO_SSL_TLS_C) || !defined(MBEDCRYPTO_SSL_PROTO_DTLS) )
+#error "MBEDCRYPTO_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_ENCRYPT_THEN_MAC) && \
+ !defined(MBEDCRYPTO_SSL_PROTO_TLS1) && \
+ !defined(MBEDCRYPTO_SSL_PROTO_TLS1_1) && \
+ !defined(MBEDCRYPTO_SSL_PROTO_TLS1_2)
+#error "MBEDCRYPTO_SSL_ENCRYPT_THEN_MAC defined, but not all prerequsites"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_EXTENDED_MASTER_SECRET) && \
+ !defined(MBEDCRYPTO_SSL_PROTO_TLS1) && \
+ !defined(MBEDCRYPTO_SSL_PROTO_TLS1_1) && \
+ !defined(MBEDCRYPTO_SSL_PROTO_TLS1_2)
+#error "MBEDCRYPTO_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_TICKET_C) && !defined(MBEDCRYPTO_CIPHER_C)
+#error "MBEDCRYPTO_SSL_TICKET_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_CBC_RECORD_SPLITTING) && \
+ !defined(MBEDCRYPTO_SSL_PROTO_SSL3) && !defined(MBEDCRYPTO_SSL_PROTO_TLS1)
+#error "MBEDCRYPTO_SSL_CBC_RECORD_SPLITTING defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_SSL_SERVER_NAME_INDICATION) && \
+ !defined(MBEDCRYPTO_X509_CRT_PARSE_C)
+#error "MBEDCRYPTO_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_THREADING_PTHREAD)
+#if !defined(MBEDCRYPTO_THREADING_C) || defined(MBEDCRYPTO_THREADING_IMPL)
+#error "MBEDCRYPTO_THREADING_PTHREAD defined, but not all prerequisites"
+#endif
+#define MBEDCRYPTO_THREADING_IMPL
+#endif
+
+#if defined(MBEDCRYPTO_THREADING_ALT)
+#if !defined(MBEDCRYPTO_THREADING_C) || defined(MBEDCRYPTO_THREADING_IMPL)
+#error "MBEDCRYPTO_THREADING_ALT defined, but not all prerequisites"
+#endif
+#define MBEDCRYPTO_THREADING_IMPL
+#endif
+
+#if defined(MBEDCRYPTO_THREADING_C) && !defined(MBEDCRYPTO_THREADING_IMPL)
+#error "MBEDCRYPTO_THREADING_C defined, single threading implementation required"
+#endif
+#undef MBEDCRYPTO_THREADING_IMPL
+
+#if defined(MBEDCRYPTO_VERSION_FEATURES) && !defined(MBEDCRYPTO_VERSION_C)
+#error "MBEDCRYPTO_VERSION_FEATURES defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_X509_USE_C) && ( !defined(MBEDCRYPTO_BIGNUM_C) || \
+ !defined(MBEDCRYPTO_OID_C) || !defined(MBEDCRYPTO_ASN1_PARSE_C) || \
+ !defined(MBEDCRYPTO_PK_PARSE_C) )
+#error "MBEDCRYPTO_X509_USE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_X509_CREATE_C) && ( !defined(MBEDCRYPTO_BIGNUM_C) || \
+ !defined(MBEDCRYPTO_OID_C) || !defined(MBEDCRYPTO_ASN1_WRITE_C) || \
+ !defined(MBEDCRYPTO_PK_WRITE_C) )
+#error "MBEDCRYPTO_X509_CREATE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_X509_CRT_PARSE_C) && ( !defined(MBEDCRYPTO_X509_USE_C) )
+#error "MBEDCRYPTO_X509_CRT_PARSE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_X509_CRL_PARSE_C) && ( !defined(MBEDCRYPTO_X509_USE_C) )
+#error "MBEDCRYPTO_X509_CRL_PARSE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_X509_CSR_PARSE_C) && ( !defined(MBEDCRYPTO_X509_USE_C) )
+#error "MBEDCRYPTO_X509_CSR_PARSE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_X509_CRT_WRITE_C) && ( !defined(MBEDCRYPTO_X509_CREATE_C) )
+#error "MBEDCRYPTO_X509_CRT_WRITE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_X509_CSR_WRITE_C) && ( !defined(MBEDCRYPTO_X509_CREATE_C) )
+#error "MBEDCRYPTO_X509_CSR_WRITE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDCRYPTO_HAVE_INT32) && defined(MBEDCRYPTO_HAVE_INT64)
+#error "MBEDCRYPTO_HAVE_INT32 and MBEDCRYPTO_HAVE_INT64 cannot be defined simultaneously"
+#endif /* MBEDCRYPTO_HAVE_INT32 && MBEDCRYPTO_HAVE_INT64 */
+
+#if ( defined(MBEDCRYPTO_HAVE_INT32) || defined(MBEDCRYPTO_HAVE_INT64) ) && \
+ defined(MBEDCRYPTO_HAVE_ASM)
+#error "MBEDCRYPTO_HAVE_INT32/MBEDCRYPTO_HAVE_INT64 and MBEDCRYPTO_HAVE_ASM cannot be defined simultaneously"
+#endif /* (MBEDCRYPTO_HAVE_INT32 || MBEDCRYPTO_HAVE_INT64) && MBEDCRYPTO_HAVE_ASM */
+
+/*
+ * Avoid warning from -pedantic. This is a convenient place for this
+ * workaround since this is included by every single file before the
+ * #if defined(MBEDCRYPTO_xxx_C) that results in emtpy translation units.
+ */
+typedef int mbedcrypto_iso_c_forbids_empty_translation_units;
+
+#endif /* MBEDCRYPTO_CHECK_CONFIG_H */
diff --git a/include/mbedcrypto/cipher.h b/include/mbedcrypto/cipher.h
new file mode 100644
index 0000000..43f8f68
--- /dev/null
+++ b/include/mbedcrypto/cipher.h
@@ -0,0 +1,773 @@
+/**
+ * \file cipher.h
+ *
+ * \brief This file contains an abstraction interface for use with the cipher
+ * primitives provided by the library. It provides a common interface to all of
+ * the available cipher operations.
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ */
+/*
+ * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+#ifndef MBEDCRYPTO_CIPHER_H
+#define MBEDCRYPTO_CIPHER_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+
+#if defined(MBEDCRYPTO_GCM_C) || defined(MBEDCRYPTO_CCM_C)
+#define MBEDCRYPTO_CIPHER_MODE_AEAD
+#endif
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_CBC)
+#define MBEDCRYPTO_CIPHER_MODE_WITH_PADDING
+#endif
+
+#if defined(MBEDCRYPTO_ARC4_C)
+#define MBEDCRYPTO_CIPHER_MODE_STREAM
+#endif
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+ !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+#define MBEDCRYPTO_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */
+#define MBEDCRYPTO_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters. */
+#define MBEDCRYPTO_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */
+#define MBEDCRYPTO_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */
+#define MBEDCRYPTO_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */
+#define MBEDCRYPTO_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */
+#define MBEDCRYPTO_ERR_CIPHER_INVALID_CONTEXT -0x6380 /**< The context is invalid. For example, because it was freed. */
+#define MBEDCRYPTO_ERR_CIPHER_HW_ACCEL_FAILED -0x6400 /**< Cipher hardware accelerator failed. */
+
+#define MBEDCRYPTO_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length. */
+#define MBEDCRYPTO_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Supported cipher types.
+ *
+ * \warning RC4 and DES are considered weak ciphers and their use
+ * constitutes a security risk. Arm recommends considering stronger
+ * ciphers instead.
+ */
+typedef enum {
+ MBEDCRYPTO_CIPHER_ID_NONE = 0, /**< Placeholder to mark the end of cipher ID lists. */
+ MBEDCRYPTO_CIPHER_ID_NULL, /**< The identity cipher, treated as a stream cipher. */
+ MBEDCRYPTO_CIPHER_ID_AES, /**< The AES cipher. */
+ MBEDCRYPTO_CIPHER_ID_DES, /**< The DES cipher. */
+ MBEDCRYPTO_CIPHER_ID_3DES, /**< The Triple DES cipher. */
+ MBEDCRYPTO_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */
+ MBEDCRYPTO_CIPHER_ID_BLOWFISH, /**< The Blowfish cipher. */
+ MBEDCRYPTO_CIPHER_ID_ARC4, /**< The RC4 cipher. */
+} mbedcrypto_cipher_id_t;
+
+/**
+ * \brief Supported {cipher type, cipher mode} pairs.
+ *
+ * \warning RC4 and DES are considered weak ciphers and their use
+ * constitutes a security risk. Arm recommends considering stronger
+ * ciphers instead.
+ */
+typedef enum {
+ MBEDCRYPTO_CIPHER_NONE = 0, /**< Placeholder to mark the end of cipher-pair lists. */
+ MBEDCRYPTO_CIPHER_NULL, /**< The identity stream cipher. */
+ MBEDCRYPTO_CIPHER_AES_128_ECB, /**< AES cipher with 128-bit ECB mode. */
+ MBEDCRYPTO_CIPHER_AES_192_ECB, /**< AES cipher with 192-bit ECB mode. */
+ MBEDCRYPTO_CIPHER_AES_256_ECB, /**< AES cipher with 256-bit ECB mode. */
+ MBEDCRYPTO_CIPHER_AES_128_CBC, /**< AES cipher with 128-bit CBC mode. */
+ MBEDCRYPTO_CIPHER_AES_192_CBC, /**< AES cipher with 192-bit CBC mode. */
+ MBEDCRYPTO_CIPHER_AES_256_CBC, /**< AES cipher with 256-bit CBC mode. */
+ MBEDCRYPTO_CIPHER_AES_128_CFB128, /**< AES cipher with 128-bit CFB128 mode. */
+ MBEDCRYPTO_CIPHER_AES_192_CFB128, /**< AES cipher with 192-bit CFB128 mode. */
+ MBEDCRYPTO_CIPHER_AES_256_CFB128, /**< AES cipher with 256-bit CFB128 mode. */
+ MBEDCRYPTO_CIPHER_AES_128_CTR, /**< AES cipher with 128-bit CTR mode. */
+ MBEDCRYPTO_CIPHER_AES_192_CTR, /**< AES cipher with 192-bit CTR mode. */
+ MBEDCRYPTO_CIPHER_AES_256_CTR, /**< AES cipher with 256-bit CTR mode. */
+ MBEDCRYPTO_CIPHER_AES_128_GCM, /**< AES cipher with 128-bit GCM mode. */
+ MBEDCRYPTO_CIPHER_AES_192_GCM, /**< AES cipher with 192-bit GCM mode. */
+ MBEDCRYPTO_CIPHER_AES_256_GCM, /**< AES cipher with 256-bit GCM mode. */
+ MBEDCRYPTO_CIPHER_CAMELLIA_128_ECB, /**< Camellia cipher with 128-bit ECB mode. */
+ MBEDCRYPTO_CIPHER_CAMELLIA_192_ECB, /**< Camellia cipher with 192-bit ECB mode. */
+ MBEDCRYPTO_CIPHER_CAMELLIA_256_ECB, /**< Camellia cipher with 256-bit ECB mode. */
+ MBEDCRYPTO_CIPHER_CAMELLIA_128_CBC, /**< Camellia cipher with 128-bit CBC mode. */
+ MBEDCRYPTO_CIPHER_CAMELLIA_192_CBC, /**< Camellia cipher with 192-bit CBC mode. */
+ MBEDCRYPTO_CIPHER_CAMELLIA_256_CBC, /**< Camellia cipher with 256-bit CBC mode. */
+ MBEDCRYPTO_CIPHER_CAMELLIA_128_CFB128, /**< Camellia cipher with 128-bit CFB128 mode. */
+ MBEDCRYPTO_CIPHER_CAMELLIA_192_CFB128, /**< Camellia cipher with 192-bit CFB128 mode. */
+ MBEDCRYPTO_CIPHER_CAMELLIA_256_CFB128, /**< Camellia cipher with 256-bit CFB128 mode. */
+ MBEDCRYPTO_CIPHER_CAMELLIA_128_CTR, /**< Camellia cipher with 128-bit CTR mode. */
+ MBEDCRYPTO_CIPHER_CAMELLIA_192_CTR, /**< Camellia cipher with 192-bit CTR mode. */
+ MBEDCRYPTO_CIPHER_CAMELLIA_256_CTR, /**< Camellia cipher with 256-bit CTR mode. */
+ MBEDCRYPTO_CIPHER_CAMELLIA_128_GCM, /**< Camellia cipher with 128-bit GCM mode. */
+ MBEDCRYPTO_CIPHER_CAMELLIA_192_GCM, /**< Camellia cipher with 192-bit GCM mode. */
+ MBEDCRYPTO_CIPHER_CAMELLIA_256_GCM, /**< Camellia cipher with 256-bit GCM mode. */
+ MBEDCRYPTO_CIPHER_DES_ECB, /**< DES cipher with ECB mode. */
+ MBEDCRYPTO_CIPHER_DES_CBC, /**< DES cipher with CBC mode. */
+ MBEDCRYPTO_CIPHER_DES_EDE_ECB, /**< DES cipher with EDE ECB mode. */
+ MBEDCRYPTO_CIPHER_DES_EDE_CBC, /**< DES cipher with EDE CBC mode. */
+ MBEDCRYPTO_CIPHER_DES_EDE3_ECB, /**< DES cipher with EDE3 ECB mode. */
+ MBEDCRYPTO_CIPHER_DES_EDE3_CBC, /**< DES cipher with EDE3 CBC mode. */
+ MBEDCRYPTO_CIPHER_BLOWFISH_ECB, /**< Blowfish cipher with ECB mode. */
+ MBEDCRYPTO_CIPHER_BLOWFISH_CBC, /**< Blowfish cipher with CBC mode. */
+ MBEDCRYPTO_CIPHER_BLOWFISH_CFB64, /**< Blowfish cipher with CFB64 mode. */
+ MBEDCRYPTO_CIPHER_BLOWFISH_CTR, /**< Blowfish cipher with CTR mode. */
+ MBEDCRYPTO_CIPHER_ARC4_128, /**< RC4 cipher with 128-bit mode. */
+ MBEDCRYPTO_CIPHER_AES_128_CCM, /**< AES cipher with 128-bit CCM mode. */
+ MBEDCRYPTO_CIPHER_AES_192_CCM, /**< AES cipher with 192-bit CCM mode. */
+ MBEDCRYPTO_CIPHER_AES_256_CCM, /**< AES cipher with 256-bit CCM mode. */
+ MBEDCRYPTO_CIPHER_CAMELLIA_128_CCM, /**< Camellia cipher with 128-bit CCM mode. */
+ MBEDCRYPTO_CIPHER_CAMELLIA_192_CCM, /**< Camellia cipher with 192-bit CCM mode. */
+ MBEDCRYPTO_CIPHER_CAMELLIA_256_CCM, /**< Camellia cipher with 256-bit CCM mode. */
+} mbedcrypto_cipher_type_t;
+
+/** Supported cipher modes. */
+typedef enum {
+ MBEDCRYPTO_MODE_NONE = 0, /**< None. */
+ MBEDCRYPTO_MODE_ECB, /**< The ECB cipher mode. */
+ MBEDCRYPTO_MODE_CBC, /**< The CBC cipher mode. */
+ MBEDCRYPTO_MODE_CFB, /**< The CFB cipher mode. */
+ MBEDCRYPTO_MODE_OFB, /**< The OFB cipher mode - unsupported. */
+ MBEDCRYPTO_MODE_CTR, /**< The CTR cipher mode. */
+ MBEDCRYPTO_MODE_GCM, /**< The GCM cipher mode. */
+ MBEDCRYPTO_MODE_STREAM, /**< The stream cipher mode. */
+ MBEDCRYPTO_MODE_CCM, /**< The CCM cipher mode. */
+} mbedcrypto_cipher_mode_t;
+
+/** Supported cipher padding types. */
+typedef enum {
+ MBEDCRYPTO_PADDING_PKCS7 = 0, /**< PKCS7 padding (default). */
+ MBEDCRYPTO_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding. */
+ MBEDCRYPTO_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding. */
+ MBEDCRYPTO_PADDING_ZEROS, /**< Zero padding (not reversible). */
+ MBEDCRYPTO_PADDING_NONE, /**< Never pad (full blocks only). */
+} mbedcrypto_cipher_padding_t;
+
+/** Type of operation. */
+typedef enum {
+ MBEDCRYPTO_OPERATION_NONE = -1,
+ MBEDCRYPTO_DECRYPT = 0,
+ MBEDCRYPTO_ENCRYPT,
+} mbedcrypto_operation_t;
+
+enum {
+ /** Undefined key length. */
+ MBEDCRYPTO_KEY_LENGTH_NONE = 0,
+ /** Key length, in bits (including parity), for DES keys. */
+ MBEDCRYPTO_KEY_LENGTH_DES = 64,
+ /** Key length in bits, including parity, for DES in two-key EDE. */
+ MBEDCRYPTO_KEY_LENGTH_DES_EDE = 128,
+ /** Key length in bits, including parity, for DES in three-key EDE. */
+ MBEDCRYPTO_KEY_LENGTH_DES_EDE3 = 192,
+};
+
+/** Maximum length of any IV, in Bytes. */
+#define MBEDCRYPTO_MAX_IV_LENGTH 16
+/** Maximum block size of any cipher, in Bytes. */
+#define MBEDCRYPTO_MAX_BLOCK_LENGTH 16
+
+/**
+ * Base cipher information (opaque struct).
+ */
+typedef struct mbedcrypto_cipher_base_t mbedcrypto_cipher_base_t;
+
+/**
+ * CMAC context (opaque struct).
+ */
+typedef struct mbedcrypto_cmac_context_t mbedcrypto_cmac_context_t;
+
+/**
+ * Cipher information. Allows calling cipher functions
+ * in a generic way.
+ */
+typedef struct {
+ /** Full cipher identifier. For example,
+ * MBEDCRYPTO_CIPHER_AES_256_CBC.
+ */
+ mbedcrypto_cipher_type_t type;
+
+ /** The cipher mode. For example, MBEDCRYPTO_MODE_CBC. */
+ mbedcrypto_cipher_mode_t mode;
+
+ /** The cipher key length, in bits. This is the
+ * default length for variable sized ciphers.
+ * Includes parity bits for ciphers like DES.
+ */
+ unsigned int key_bitlen;
+
+ /** Name of the cipher. */
+ const char * name;
+
+ /** IV or nonce size, in Bytes.
+ * For ciphers that accept variable IV sizes,
+ * this is the recommended size.
+ */
+ unsigned int iv_size;
+
+ /** Bitflag comprised of MBEDCRYPTO_CIPHER_VARIABLE_IV_LEN and
+ * MBEDCRYPTO_CIPHER_VARIABLE_KEY_LEN indicating whether the
+ * cipher supports variable IV or variable key sizes, respectively.
+ */
+ int flags;
+
+ /** The block size, in Bytes. */
+ unsigned int block_size;
+
+ /** Struct for base cipher information and functions. */
+ const mbedcrypto_cipher_base_t *base;
+
+} mbedcrypto_cipher_info_t;
+
+/**
+ * Generic cipher context.
+ */
+typedef struct {
+ /** Information about the associated cipher. */
+ const mbedcrypto_cipher_info_t *cipher_info;
+
+ /** Key length to use. */
+ int key_bitlen;
+
+ /** Operation that the key of the context has been
+ * initialized for.
+ */
+ mbedcrypto_operation_t operation;
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_WITH_PADDING)
+ /** Padding functions to use, if relevant for
+ * the specific cipher mode.
+ */
+ void (*add_padding)( unsigned char *output, size_t olen, size_t data_len );
+ int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len );
+#endif
+
+ /** Buffer for input that has not been processed yet. */
+ unsigned char unprocessed_data[MBEDCRYPTO_MAX_BLOCK_LENGTH];
+
+ /** Number of Bytes that have not been processed yet. */
+ size_t unprocessed_len;
+
+ /** Current IV or NONCE_COUNTER for CTR-mode. */
+ unsigned char iv[MBEDCRYPTO_MAX_IV_LENGTH];
+
+ /** IV size in Bytes, for ciphers with variable-length IVs. */
+ size_t iv_size;
+
+ /** The cipher-specific context. */
+ void *cipher_ctx;
+
+#if defined(MBEDCRYPTO_CMAC_C)
+ /** CMAC-specific context. */
+ mbedcrypto_cmac_context_t *cmac_ctx;
+#endif
+} mbedcrypto_cipher_context_t;
+
+/**
+ * \brief This function retrieves the list of ciphers supported by the generic
+ * cipher module.
+ *
+ * \return A statically-allocated array of ciphers. The last entry
+ * is zero.
+ */
+const int *mbedcrypto_cipher_list( void );
+
+/**
+ * \brief This function retrieves the cipher-information
+ * structure associated with the given cipher name.
+ *
+ * \param cipher_name Name of the cipher to search for.
+ *
+ * \return The cipher information structure associated with the
+ * given \p cipher_name.
+ * \return NULL if the associated cipher information is not found.
+ */
+const mbedcrypto_cipher_info_t *mbedcrypto_cipher_info_from_string( const char *cipher_name );
+
+/**
+ * \brief This function retrieves the cipher-information
+ * structure associated with the given cipher type.
+ *
+ * \param cipher_type Type of the cipher to search for.
+ *
+ * \return The cipher information structure associated with the
+ * given \p cipher_type.
+ * \return NULL if the associated cipher information is not found.
+ */
+const mbedcrypto_cipher_info_t *mbedcrypto_cipher_info_from_type( const mbedcrypto_cipher_type_t cipher_type );
+
+/**
+ * \brief This function retrieves the cipher-information
+ * structure associated with the given cipher ID,
+ * key size and mode.
+ *
+ * \param cipher_id The ID of the cipher to search for. For example,
+ * #MBEDCRYPTO_CIPHER_ID_AES.
+ * \param key_bitlen The length of the key in bits.
+ * \param mode The cipher mode. For example, #MBEDCRYPTO_MODE_CBC.
+ *
+ * \return The cipher information structure associated with the
+ * given \p cipher_id.
+ * \return NULL if the associated cipher information is not found.
+ */
+const mbedcrypto_cipher_info_t *mbedcrypto_cipher_info_from_values( const mbedcrypto_cipher_id_t cipher_id,
+ int key_bitlen,
+ const mbedcrypto_cipher_mode_t mode );
+
+/**
+ * \brief This function initializes a \p cipher_context as NONE.
+ */
+void mbedcrypto_cipher_init( mbedcrypto_cipher_context_t *ctx );
+
+/**
+ * \brief This function frees and clears the cipher-specific
+ * context of \p ctx. Freeing \p ctx itself remains the
+ * responsibility of the caller.
+ */
+void mbedcrypto_cipher_free( mbedcrypto_cipher_context_t *ctx );
+
+
+/**
+ * \brief This function initializes and fills the cipher-context
+ * structure with the appropriate values. It also clears
+ * the structure.
+ *
+ * \param ctx The context to initialize. May not be NULL.
+ * \param cipher_info The cipher to use.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return #MBEDCRYPTO_ERR_CIPHER_ALLOC_FAILED if allocation of the
+ * cipher-specific context fails.
+ *
+ * \internal Currently, the function also clears the structure.
+ * In future versions, the caller will be required to call
+ * mbedcrypto_cipher_init() on the structure first.
+ */
+int mbedcrypto_cipher_setup( mbedcrypto_cipher_context_t *ctx, const mbedcrypto_cipher_info_t *cipher_info );
+
+/**
+ * \brief This function returns the block size of the given cipher.
+ *
+ * \param ctx The context of the cipher. Must be initialized.
+ *
+ * \return The size of the blocks of the cipher.
+ * \return 0 if \p ctx has not been initialized.
+ */
+static inline unsigned int mbedcrypto_cipher_get_block_size( const mbedcrypto_cipher_context_t *ctx )
+{
+ if( NULL == ctx || NULL == ctx->cipher_info )
+ return 0;
+
+ return ctx->cipher_info->block_size;
+}
+
+/**
+ * \brief This function returns the mode of operation for
+ * the cipher. For example, MBEDCRYPTO_MODE_CBC.
+ *
+ * \param ctx The context of the cipher. Must be initialized.
+ *
+ * \return The mode of operation.
+ * \return #MBEDCRYPTO_MODE_NONE if \p ctx has not been initialized.
+ */
+static inline mbedcrypto_cipher_mode_t mbedcrypto_cipher_get_cipher_mode( const mbedcrypto_cipher_context_t *ctx )
+{
+ if( NULL == ctx || NULL == ctx->cipher_info )
+ return MBEDCRYPTO_MODE_NONE;
+
+ return ctx->cipher_info->mode;
+}
+
+/**
+ * \brief This function returns the size of the IV or nonce
+ * of the cipher, in Bytes.
+ *
+ * \param ctx The context of the cipher. Must be initialized.
+ *
+ * \return The recommended IV size if no IV has been set.
+ * \return \c 0 for ciphers not using an IV or a nonce.
+ * \return The actual size if an IV has been set.
+ */
+static inline int mbedcrypto_cipher_get_iv_size( const mbedcrypto_cipher_context_t *ctx )
+{
+ if( NULL == ctx || NULL == ctx->cipher_info )
+ return 0;
+
+ if( ctx->iv_size != 0 )
+ return (int) ctx->iv_size;
+
+ return (int) ctx->cipher_info->iv_size;
+}
+
+/**
+ * \brief This function returns the type of the given cipher.
+ *
+ * \param ctx The context of the cipher. Must be initialized.
+ *
+ * \return The type of the cipher.
+ * \return #MBEDCRYPTO_CIPHER_NONE if \p ctx has not been initialized.
+ */
+static inline mbedcrypto_cipher_type_t mbedcrypto_cipher_get_type( const mbedcrypto_cipher_context_t *ctx )
+{
+ if( NULL == ctx || NULL == ctx->cipher_info )
+ return MBEDCRYPTO_CIPHER_NONE;
+
+ return ctx->cipher_info->type;
+}
+
+/**
+ * \brief This function returns the name of the given cipher
+ * as a string.
+ *
+ * \param ctx The context of the cipher. Must be initialized.
+ *
+ * \return The name of the cipher.
+ * \return NULL if \p ctx has not been not initialized.
+ */
+static inline const char *mbedcrypto_cipher_get_name( const mbedcrypto_cipher_context_t *ctx )
+{
+ if( NULL == ctx || NULL == ctx->cipher_info )
+ return 0;
+
+ return ctx->cipher_info->name;
+}
+
+/**
+ * \brief This function returns the key length of the cipher.
+ *
+ * \param ctx The context of the cipher. Must be initialized.
+ *
+ * \return The key length of the cipher in bits.
+ * \return #MBEDCRYPTO_KEY_LENGTH_NONE if ctx \p has not been
+ * initialized.
+ */
+static inline int mbedcrypto_cipher_get_key_bitlen( const mbedcrypto_cipher_context_t *ctx )
+{
+ if( NULL == ctx || NULL == ctx->cipher_info )
+ return MBEDCRYPTO_KEY_LENGTH_NONE;
+
+ return (int) ctx->cipher_info->key_bitlen;
+}
+
+/**
+ * \brief This function returns the operation of the given cipher.
+ *
+ * \param ctx The context of the cipher. Must be initialized.
+ *
+ * \return The type of operation: #MBEDCRYPTO_ENCRYPT or #MBEDCRYPTO_DECRYPT.
+ * \return #MBEDCRYPTO_OPERATION_NONE if \p ctx has not been initialized.
+ */
+static inline mbedcrypto_operation_t mbedcrypto_cipher_get_operation( const mbedcrypto_cipher_context_t *ctx )
+{
+ if( NULL == ctx || NULL == ctx->cipher_info )
+ return MBEDCRYPTO_OPERATION_NONE;
+
+ return ctx->operation;
+}
+
+/**
+ * \brief This function sets the key to use with the given context.
+ *
+ * \param ctx The generic cipher context. May not be NULL. Must have
+ * been initialized using mbedcrypto_cipher_info_from_type()
+ * or mbedcrypto_cipher_info_from_string().
+ * \param key The key to use.
+ * \param key_bitlen The key length to use, in bits.
+ * \param operation The operation that the key will be used for:
+ * #MBEDCRYPTO_ENCRYPT or #MBEDCRYPTO_DECRYPT.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedcrypto_cipher_setkey( mbedcrypto_cipher_context_t *ctx, const unsigned char *key,
+ int key_bitlen, const mbedcrypto_operation_t operation );
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_WITH_PADDING)
+/**
+ * \brief This function sets the padding mode, for cipher modes
+ * that use padding.
+ *
+ * The default passing mode is PKCS7 padding.
+ *
+ * \param ctx The generic cipher context.
+ * \param mode The padding mode.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_CIPHER_FEATURE_UNAVAILABLE
+ * if the selected padding mode is not supported.
+ * \return #MBEDCRYPTO_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode
+ * does not support padding.
+ */
+int mbedcrypto_cipher_set_padding_mode( mbedcrypto_cipher_context_t *ctx, mbedcrypto_cipher_padding_t mode );
+#endif /* MBEDCRYPTO_CIPHER_MODE_WITH_PADDING */
+
+/**
+ * \brief This function sets the initialization vector (IV)
+ * or nonce.
+ *
+ * \note Some ciphers do not use IVs nor nonce. For these
+ * ciphers, this function has no effect.
+ *
+ * \param ctx The generic cipher context.
+ * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ * \param iv_len The IV length for ciphers with variable-size IV.
+ * This parameter is discarded by ciphers with fixed-size IV.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ */
+int mbedcrypto_cipher_set_iv( mbedcrypto_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len );
+
+/**
+ * \brief This function resets the cipher state.
+ *
+ * \param ctx The generic cipher context.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ */
+int mbedcrypto_cipher_reset( mbedcrypto_cipher_context_t *ctx );
+
+#if defined(MBEDCRYPTO_GCM_C)
+/**
+ * \brief This function adds additional data for AEAD ciphers.
+ * Only supported with GCM. Must be called
+ * exactly once, after mbedcrypto_cipher_reset().
+ *
+ * \param ctx The generic cipher context.
+ * \param ad The additional data to use.
+ * \param ad_len the Length of \p ad.
+ *
+ * \return \c 0 on success.
+ * \return A specific error code on failure.
+ */
+int mbedcrypto_cipher_update_ad( mbedcrypto_cipher_context_t *ctx,
+ const unsigned char *ad, size_t ad_len );
+#endif /* MBEDCRYPTO_GCM_C */
+
+/**
+ * \brief The generic cipher update function. It encrypts or
+ * decrypts using the given cipher context. Writes as
+ * many block-sized blocks of data as possible to output.
+ * Any data that cannot be written immediately is either
+ * added to the next block, or flushed when
+ * mbedcrypto_cipher_finish() is called.
+ * Exception: For MBEDCRYPTO_MODE_ECB, expects a single block
+ * in size. For example, 16 Bytes for AES.
+ *
+ * \note If the underlying cipher is used in GCM mode, all calls
+ * to this function, except for the last one before
+ * mbedcrypto_cipher_finish(), must have \p ilen as a
+ * multiple of the block size of the cipher.
+ *
+ * \param ctx The generic cipher context.
+ * \param input The buffer holding the input data.
+ * \param ilen The length of the input data.
+ * \param output The buffer for the output data. Must be able to hold at
+ * least \p ilen + block_size. Must not be the same buffer
+ * as input.
+ * \param olen The length of the output data, to be updated with the
+ * actual number of Bytes written.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return #MBEDCRYPTO_ERR_CIPHER_FEATURE_UNAVAILABLE on an
+ * unsupported mode for a cipher.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedcrypto_cipher_update( mbedcrypto_cipher_context_t *ctx, const unsigned char *input,
+ size_t ilen, unsigned char *output, size_t *olen );
+
+/**
+ * \brief The generic cipher finalization function. If data still
+ * needs to be flushed from an incomplete block, the data
+ * contained in it is padded to the size of
+ * the last block, and written to the \p output buffer.
+ *
+ * \param ctx The generic cipher context.
+ * \param output The buffer to write data to. Needs block_size available.
+ * \param olen The length of the data written to the \p output buffer.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return #MBEDCRYPTO_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
+ * expecting a full block but not receiving one.
+ * \return #MBEDCRYPTO_ERR_CIPHER_INVALID_PADDING on invalid padding
+ * while decrypting.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedcrypto_cipher_finish( mbedcrypto_cipher_context_t *ctx,
+ unsigned char *output, size_t *olen );
+
+#if defined(MBEDCRYPTO_GCM_C)
+/**
+ * \brief This function writes a tag for AEAD ciphers.
+ * Only supported with GCM.
+ * Must be called after mbedcrypto_cipher_finish().
+ *
+ * \param ctx The generic cipher context.
+ * \param tag The buffer to write the tag to.
+ * \param tag_len The length of the tag to write.
+ *
+ * \return \c 0 on success.
+ * \return A specific error code on failure.
+ */
+int mbedcrypto_cipher_write_tag( mbedcrypto_cipher_context_t *ctx,
+ unsigned char *tag, size_t tag_len );
+
+/**
+ * \brief This function checks the tag for AEAD ciphers.
+ * Only supported with GCM.
+ * Must be called after mbedcrypto_cipher_finish().
+ *
+ * \param ctx The generic cipher context.
+ * \param tag The buffer holding the tag.
+ * \param tag_len The length of the tag to check.
+ *
+ * \return \c 0 on success.
+ * \return A specific error code on failure.
+ */
+int mbedcrypto_cipher_check_tag( mbedcrypto_cipher_context_t *ctx,
+ const unsigned char *tag, size_t tag_len );
+#endif /* MBEDCRYPTO_GCM_C */
+
+/**
+ * \brief The generic all-in-one encryption/decryption function,
+ * for all ciphers except AEAD constructs.
+ *
+ * \param ctx The generic cipher context.
+ * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ * \param iv_len The IV length for ciphers with variable-size IV.
+ * This parameter is discarded by ciphers with fixed-size
+ * IV.
+ * \param input The buffer holding the input data.
+ * \param ilen The length of the input data.
+ * \param output The buffer for the output data. Must be able to hold at
+ * least \p ilen + block_size. Must not be the same buffer
+ * as input.
+ * \param olen The length of the output data, to be updated with the
+ * actual number of Bytes written.
+ *
+ * \note Some ciphers do not use IVs nor nonce. For these
+ * ciphers, use \p iv = NULL and \p iv_len = 0.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return #MBEDCRYPTO_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
+ * expecting a full block but not receiving one.
+ * \return #MBEDCRYPTO_ERR_CIPHER_INVALID_PADDING on invalid padding
+ * while decrypting.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedcrypto_cipher_crypt( mbedcrypto_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen );
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_AEAD)
+/**
+ * \brief The generic autenticated encryption (AEAD) function.
+ *
+ * \param ctx The generic cipher context.
+ * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ * \param iv_len The IV length for ciphers with variable-size IV.
+ * This parameter is discarded by ciphers with fixed-size IV.
+ * \param ad The additional data to authenticate.
+ * \param ad_len The length of \p ad.
+ * \param input The buffer holding the input data.
+ * \param ilen The length of the input data.
+ * \param output The buffer for the output data.
+ * Must be able to hold at least \p ilen.
+ * \param olen The length of the output data, to be updated with the
+ * actual number of Bytes written.
+ * \param tag The buffer for the authentication tag.
+ * \param tag_len The desired length of the authentication tag.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedcrypto_cipher_auth_encrypt( mbedcrypto_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen,
+ unsigned char *tag, size_t tag_len );
+
+/**
+ * \brief The generic autenticated decryption (AEAD) function.
+ *
+ * \note If the data is not authentic, then the output buffer
+ * is zeroed out to prevent the unauthentic plaintext being
+ * used, making this interface safer.
+ *
+ * \param ctx The generic cipher context.
+ * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ * \param iv_len The IV length for ciphers with variable-size IV.
+ * This parameter is discarded by ciphers with fixed-size IV.
+ * \param ad The additional data to be authenticated.
+ * \param ad_len The length of \p ad.
+ * \param input The buffer holding the input data.
+ * \param ilen The length of the input data.
+ * \param output The buffer for the output data.
+ * Must be able to hold at least \p ilen.
+ * \param olen The length of the output data, to be updated with the
+ * actual number of Bytes written.
+ * \param tag The buffer holding the authentication tag.
+ * \param tag_len The length of the authentication tag.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return #MBEDCRYPTO_ERR_CIPHER_AUTH_FAILED if data is not authentic.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedcrypto_cipher_auth_decrypt( mbedcrypto_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen,
+ const unsigned char *tag, size_t tag_len );
+#endif /* MBEDCRYPTO_CIPHER_MODE_AEAD */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDCRYPTO_CIPHER_H */
diff --git a/include/mbedcrypto/cipher_internal.h b/include/mbedcrypto/cipher_internal.h
new file mode 100644
index 0000000..3d4451b
--- /dev/null
+++ b/include/mbedcrypto/cipher_internal.h
@@ -0,0 +1,110 @@
+/**
+ * \file cipher_internal.h
+ *
+ * \brief Cipher wrappers.
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_CIPHER_WRAP_H
+#define MBEDCRYPTO_CIPHER_WRAP_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include "cipher.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Base cipher information. The non-mode specific functions and values.
+ */
+struct mbedcrypto_cipher_base_t
+{
+ /** Base Cipher type (e.g. MBEDCRYPTO_CIPHER_ID_AES) */
+ mbedcrypto_cipher_id_t cipher;
+
+ /** Encrypt using ECB */
+ int (*ecb_func)( void *ctx, mbedcrypto_operation_t mode,
+ const unsigned char *input, unsigned char *output );
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_CBC)
+ /** Encrypt using CBC */
+ int (*cbc_func)( void *ctx, mbedcrypto_operation_t mode, size_t length,
+ unsigned char *iv, const unsigned char *input,
+ unsigned char *output );
+#endif
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_CFB)
+ /** Encrypt using CFB (Full length) */
+ int (*cfb_func)( void *ctx, mbedcrypto_operation_t mode, size_t length, size_t *iv_off,
+ unsigned char *iv, const unsigned char *input,
+ unsigned char *output );
+#endif
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_CTR)
+ /** Encrypt using CTR */
+ int (*ctr_func)( void *ctx, size_t length, size_t *nc_off,
+ unsigned char *nonce_counter, unsigned char *stream_block,
+ const unsigned char *input, unsigned char *output );
+#endif
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_STREAM)
+ /** Encrypt using STREAM */
+ int (*stream_func)( void *ctx, size_t length,
+ const unsigned char *input, unsigned char *output );
+#endif
+
+ /** Set key for encryption purposes */
+ int (*setkey_enc_func)( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen );
+
+ /** Set key for decryption purposes */
+ int (*setkey_dec_func)( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen);
+
+ /** Allocate a new context */
+ void * (*ctx_alloc_func)( void );
+
+ /** Free the given context */
+ void (*ctx_free_func)( void *ctx );
+
+};
+
+typedef struct
+{
+ mbedcrypto_cipher_type_t type;
+ const mbedcrypto_cipher_info_t *info;
+} mbedcrypto_cipher_definition_t;
+
+extern const mbedcrypto_cipher_definition_t mbedcrypto_cipher_definitions[];
+
+extern int mbedcrypto_cipher_supported[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDCRYPTO_CIPHER_WRAP_H */
diff --git a/include/mbedcrypto/cmac.h b/include/mbedcrypto/cmac.h
new file mode 100644
index 0000000..4c697d1
--- /dev/null
+++ b/include/mbedcrypto/cmac.h
@@ -0,0 +1,206 @@
+/**
+ * \file cmac.h
+ *
+ * \brief This file contains CMAC definitions and functions.
+ *
+ * The Cipher-based Message Authentication Code (CMAC) Mode for
+ * Authentication is defined in <em>RFC-4493: The AES-CMAC Algorithm</em>.
+ */
+/*
+ * Copyright (C) 2015-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+#ifndef MBEDCRYPTO_CMAC_H
+#define MBEDCRYPTO_CMAC_H
+
+#include "mbedcrypto/cipher.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MBEDCRYPTO_ERR_CMAC_HW_ACCEL_FAILED -0x007A /**< CMAC hardware accelerator failed. */
+
+#define MBEDCRYPTO_AES_BLOCK_SIZE 16
+#define MBEDCRYPTO_DES3_BLOCK_SIZE 8
+
+#if defined(MBEDCRYPTO_AES_C)
+#define MBEDCRYPTO_CIPHER_BLKSIZE_MAX 16 /**< The longest block used by CMAC is that of AES. */
+#else
+#define MBEDCRYPTO_CIPHER_BLKSIZE_MAX 8 /**< The longest block used by CMAC is that of 3DES. */
+#endif
+
+#if !defined(MBEDCRYPTO_CMAC_ALT)
+
+/**
+ * The CMAC context structure.
+ */
+struct mbedcrypto_cmac_context_t
+{
+ /** The internal state of the CMAC algorithm. */
+ unsigned char state[MBEDCRYPTO_CIPHER_BLKSIZE_MAX];
+
+ /** Unprocessed data - either data that was not block aligned and is still
+ * pending processing, or the final block. */
+ unsigned char unprocessed_block[MBEDCRYPTO_CIPHER_BLKSIZE_MAX];
+
+ /** The length of data pending processing. */
+ size_t unprocessed_len;
+};
+
+#else /* !MBEDCRYPTO_CMAC_ALT */
+#include "cmac_alt.h"
+#endif /* !MBEDCRYPTO_CMAC_ALT */
+
+/**
+ * \brief This function sets the CMAC key, and prepares to authenticate
+ * the input data.
+ * Must be called with an initialized cipher context.
+ *
+ * \param ctx The cipher context used for the CMAC operation, initialized
+ * as one of the following types: MBEDCRYPTO_CIPHER_AES_128_ECB,
+ * MBEDCRYPTO_CIPHER_AES_192_ECB, MBEDCRYPTO_CIPHER_AES_256_ECB,
+ * or MBEDCRYPTO_CIPHER_DES_EDE3_ECB.
+ * \param key The CMAC key.
+ * \param keybits The length of the CMAC key in bits.
+ * Must be supported by the cipher.
+ *
+ * \return \c 0 on success.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedcrypto_cipher_cmac_starts( mbedcrypto_cipher_context_t *ctx,
+ const unsigned char *key, size_t keybits );
+
+/**
+ * \brief This function feeds an input buffer into an ongoing CMAC
+ * computation.
+ *
+ * It is called between mbedcrypto_cipher_cmac_starts() or
+ * mbedcrypto_cipher_cmac_reset(), and mbedcrypto_cipher_cmac_finish().
+ * Can be called repeatedly.
+ *
+ * \param ctx The cipher context used for the CMAC operation.
+ * \param input The buffer holding the input data.
+ * \param ilen The length of the input data.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA
+ * if parameter verification fails.
+ */
+int mbedcrypto_cipher_cmac_update( mbedcrypto_cipher_context_t *ctx,
+ const unsigned char *input, size_t ilen );
+
+/**
+ * \brief This function finishes the CMAC operation, and writes
+ * the result to the output buffer.
+ *
+ * It is called after mbedcrypto_cipher_cmac_update().
+ * It can be followed by mbedcrypto_cipher_cmac_reset() and
+ * mbedcrypto_cipher_cmac_update(), or mbedcrypto_cipher_free().
+ *
+ * \param ctx The cipher context used for the CMAC operation.
+ * \param output The output buffer for the CMAC checksum result.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA
+ * if parameter verification fails.
+ */
+int mbedcrypto_cipher_cmac_finish( mbedcrypto_cipher_context_t *ctx,
+ unsigned char *output );
+
+/**
+ * \brief This function prepares the authentication of another
+ * message with the same key as the previous CMAC
+ * operation.
+ *
+ * It is called after mbedcrypto_cipher_cmac_finish()
+ * and before mbedcrypto_cipher_cmac_update().
+ *
+ * \param ctx The cipher context used for the CMAC operation.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA
+ * if parameter verification fails.
+ */
+int mbedcrypto_cipher_cmac_reset( mbedcrypto_cipher_context_t *ctx );
+
+/**
+ * \brief This function calculates the full generic CMAC
+ * on the input buffer with the provided key.
+ *
+ * The function allocates the context, performs the
+ * calculation, and frees the context.
+ *
+ * The CMAC result is calculated as
+ * output = generic CMAC(cmac key, input buffer).
+ *
+ *
+ * \param cipher_info The cipher information.
+ * \param key The CMAC key.
+ * \param keylen The length of the CMAC key in bits.
+ * \param input The buffer holding the input data.
+ * \param ilen The length of the input data.
+ * \param output The buffer for the generic CMAC result.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA
+ * if parameter verification fails.
+ */
+int mbedcrypto_cipher_cmac( const mbedcrypto_cipher_info_t *cipher_info,
+ const unsigned char *key, size_t keylen,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output );
+
+#if defined(MBEDCRYPTO_AES_C)
+/**
+ * \brief This function implements the AES-CMAC-PRF-128 pseudorandom
+ * function, as defined in
+ * <em>RFC-4615: The Advanced Encryption Standard-Cipher-based
+ * Message Authentication Code-Pseudo-Random Function-128
+ * (AES-CMAC-PRF-128) Algorithm for the Internet Key
+ * Exchange Protocol (IKE).</em>
+ *
+ * \param key The key to use.
+ * \param key_len The key length in Bytes.
+ * \param input The buffer holding the input data.
+ * \param in_len The length of the input data in Bytes.
+ * \param output The buffer holding the generated 16 Bytes of
+ * pseudorandom output.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_aes_cmac_prf_128( const unsigned char *key, size_t key_len,
+ const unsigned char *input, size_t in_len,
+ unsigned char output[16] );
+#endif /* MBEDCRYPTO_AES_C */
+
+#if defined(MBEDCRYPTO_SELF_TEST) && ( defined(MBEDCRYPTO_AES_C) || defined(MBEDCRYPTO_DES_C) )
+/**
+ * \brief The CMAC checkup routine.
+ *
+ * \return \c 0 on success.
+ * \return \c 1 on failure.
+ */
+int mbedcrypto_cmac_self_test( int verbose );
+#endif /* MBEDCRYPTO_SELF_TEST && ( MBEDCRYPTO_AES_C || MBEDCRYPTO_DES_C ) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDCRYPTO_CMAC_H */
diff --git a/include/mbedcrypto/config.h b/include/mbedcrypto/config.h
new file mode 100644
index 0000000..502b42f
--- /dev/null
+++ b/include/mbedcrypto/config.h
@@ -0,0 +1,1753 @@
+/**
+ * \file config.h
+ *
+ * \brief Configuration with all cryptography features and no X.509 or TLS.
+ *
+ * This configuration is intended to prototype the PSA reference implementation.
+ */
+/*
+ * 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
+ * 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 Crypto (https://tls.mbed.org)
+ */
+
+#ifndef MBEDCRYPTO_CONFIG_H
+#define MBEDCRYPTO_CONFIG_H
+
+#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+
+/**
+ * \name SECTION: System support
+ *
+ * This section sets system specific settings.
+ * \{
+ */
+
+/**
+ * \def MBEDCRYPTO_HAVE_ASM
+ *
+ * The compiler has support for asm().
+ *
+ * Requires support for asm() in compiler.
+ *
+ * Used in:
+ * library/timing.c
+ * library/padlock.c
+ * include/mbedcrypto/bn_mul.h
+ *
+ * Comment to disable the use of assembly code.
+ */
+#define MBEDCRYPTO_HAVE_ASM
+
+/**
+ * \def MBEDCRYPTO_NO_UDBL_DIVISION
+ *
+ * The platform lacks support for double-width integer division (64-bit
+ * division on a 32-bit platform, 128-bit division on a 64-bit platform).
+ *
+ * Used in:
+ * include/mbedcrypto/bignum.h
+ * library/bignum.c
+ *
+ * The bignum code uses double-width division to speed up some operations.
+ * Double-width division is often implemented in software that needs to
+ * be linked with the program. The presence of a double-width integer
+ * type is usually detected automatically through preprocessor macros,
+ * but the automatic detection cannot know whether the code needs to
+ * and can be linked with an implementation of division for that type.
+ * By default division is assumed to be usable if the type is present.
+ * Uncomment this option to prevent the use of double-width division.
+ *
+ * Note that division for the native integer type is always required.
+ * Furthermore, a 64-bit type is always required even on a 32-bit
+ * platform, but it need not support multiplication or division. In some
+ * cases it is also desirable to disable some double-width operations. For
+ * example, if double-width division is implemented in software, disabling
+ * it can reduce code size in some embedded targets.
+ */
+//#define MBEDCRYPTO_NO_UDBL_DIVISION
+
+/**
+ * \def MBEDCRYPTO_HAVE_SSE2
+ *
+ * CPU supports SSE2 instruction set.
+ *
+ * Uncomment if the CPU supports SSE2 (IA-32 specific).
+ */
+//#define MBEDCRYPTO_HAVE_SSE2
+
+/**
+ * \def MBEDCRYPTO_PLATFORM_MEMORY
+ *
+ * Enable the memory allocation layer.
+ *
+ * By default Mbed Crypto uses the system-provided calloc() and free().
+ * This allows different allocators (self-implemented or provided) to be
+ * provided to the platform abstraction layer.
+ *
+ * Enabling MBEDCRYPTO_PLATFORM_MEMORY without the
+ * MBEDCRYPTO_PLATFORM_{FREE,CALLOC}_MACROs will provide
+ * "mbedcrypto_platform_set_calloc_free()" allowing you to set an alternative calloc() and
+ * free() function pointer at runtime.
+ *
+ * Enabling MBEDCRYPTO_PLATFORM_MEMORY and specifying
+ * MBEDCRYPTO_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the
+ * alternate function at compile time.
+ *
+ * Requires: MBEDCRYPTO_PLATFORM_C
+ *
+ * Enable this layer to allow use of alternative memory allocators.
+ */
+//#define MBEDCRYPTO_PLATFORM_MEMORY
+
+/**
+ * \def MBEDCRYPTO_PLATFORM_NO_STD_FUNCTIONS
+ *
+ * Do not assign standard functions in the platform layer (e.g. calloc() to
+ * MBEDCRYPTO_PLATFORM_STD_CALLOC and printf() to MBEDCRYPTO_PLATFORM_STD_PRINTF)
+ *
+ * This makes sure there are no linking errors on platforms that do not support
+ * these functions. You will HAVE to provide alternatives, either at runtime
+ * via the platform_set_xxx() functions or at compile time by setting
+ * the MBEDCRYPTO_PLATFORM_STD_XXX defines, or enabling a
+ * MBEDCRYPTO_PLATFORM_XXX_MACRO.
+ *
+ * Requires: MBEDCRYPTO_PLATFORM_C
+ *
+ * Uncomment to prevent default assignment of standard functions in the
+ * platform layer.
+ */
+//#define MBEDCRYPTO_PLATFORM_NO_STD_FUNCTIONS
+
+/**
+ * \def MBEDCRYPTO_PLATFORM_EXIT_ALT
+ *
+ * MBEDCRYPTO_PLATFORM_XXX_ALT: Uncomment a macro to let Mbed Crypto support the
+ * function in the platform abstraction layer.
+ *
+ * Example: In case you uncomment MBEDCRYPTO_PLATFORM_PRINTF_ALT, Mbed Crypto will
+ * provide a function "mbedcrypto_platform_set_printf()" that allows you to set an
+ * alternative printf function pointer.
+ *
+ * All these define require MBEDCRYPTO_PLATFORM_C to be defined!
+ *
+ * \note MBEDCRYPTO_PLATFORM_SNPRINTF_ALT is required on Windows;
+ * it will be enabled automatically by check_config.h
+ *
+ * \warning MBEDCRYPTO_PLATFORM_XXX_ALT cannot be defined at the same time as
+ * MBEDCRYPTO_PLATFORM_XXX_MACRO!
+ *
+ * Uncomment a macro to enable alternate implementation of specific base
+ * platform function
+ */
+//#define MBEDCRYPTO_PLATFORM_EXIT_ALT
+//#define MBEDCRYPTO_PLATFORM_FPRINTF_ALT
+//#define MBEDCRYPTO_PLATFORM_PRINTF_ALT
+//#define MBEDCRYPTO_PLATFORM_SNPRINTF_ALT
+//#define MBEDCRYPTO_PLATFORM_NV_SEED_ALT
+//#define MBEDCRYPTO_PLATFORM_SETUP_TEARDOWN_ALT
+
+/**
+ * \def MBEDCRYPTO_DEPRECATED_WARNING
+ *
+ * Mark deprecated functions so that they generate a warning if used.
+ * Functions deprecated in one version will usually be removed in the next
+ * version. You can enable this to help you prepare the transition to a new
+ * major version by making sure your code is not using these functions.
+ *
+ * This only works with GCC and Clang. With other compilers, you may want to
+ * use MBEDCRYPTO_DEPRECATED_REMOVED
+ *
+ * Uncomment to get warnings on using deprecated functions.
+ */
+//#define MBEDCRYPTO_DEPRECATED_WARNING
+
+/**
+ * \def MBEDCRYPTO_DEPRECATED_REMOVED
+ *
+ * Remove deprecated functions so that they generate an error if used.
+ * Functions deprecated in one version will usually be removed in the next
+ * version. You can enable this to help you prepare the transition to a new
+ * major version by making sure your code is not using these functions.
+ *
+ * Uncomment to get errors on using deprecated functions.
+ */
+//#define MBEDCRYPTO_DEPRECATED_REMOVED
+
+/* \} name SECTION: System support */
+
+/**
+ * \name SECTION: Mbed Crypto feature support
+ *
+ * This section sets support for features that are or are not needed
+ * within the modules that are enabled.
+ * \{
+ */
+
+/**
+ * \def MBEDCRYPTO_AES_ALT
+ *
+ * MBEDCRYPTO__MODULE_NAME__ALT: Uncomment a macro to let Mbed Crypto use your
+ * alternate core implementation of a symmetric crypto, an arithmetic or hash
+ * module (e.g. platform specific assembly optimized implementations). Keep
+ * in mind that the function prototypes should remain the same.
+ *
+ * This replaces the whole module. If you only want to replace one of the
+ * functions, use one of the MBEDCRYPTO__FUNCTION_NAME__ALT flags.
+ *
+ * Example: In case you uncomment MBEDCRYPTO_AES_ALT, Mbed Crypto will no longer
+ * provide the "struct mbedcrypto_aes_context" definition and omit the base
+ * function declarations and implementations. "aes_alt.h" will be included from
+ * "aes.h" to include the new function definitions.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * module.
+ *
+ * \warning MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their
+ * use constitutes a security risk. If possible, we recommend
+ * avoiding dependencies on them, and considering stronger message
+ * digests and ciphers instead.
+ *
+ */
+//#define MBEDCRYPTO_AES_ALT
+//#define MBEDCRYPTO_ARC4_ALT
+//#define MBEDCRYPTO_BLOWFISH_ALT
+//#define MBEDCRYPTO_CAMELLIA_ALT
+//#define MBEDCRYPTO_CCM_ALT
+//#define MBEDCRYPTO_CMAC_ALT
+//#define MBEDCRYPTO_DES_ALT
+//#define MBEDCRYPTO_DHM_ALT
+//#define MBEDCRYPTO_ECJPAKE_ALT
+//#define MBEDCRYPTO_GCM_ALT
+//#define MBEDCRYPTO_MD2_ALT
+//#define MBEDCRYPTO_MD4_ALT
+//#define MBEDCRYPTO_MD5_ALT
+//#define MBEDCRYPTO_RIPEMD160_ALT
+//#define MBEDCRYPTO_RSA_ALT
+//#define MBEDCRYPTO_SHA1_ALT
+//#define MBEDCRYPTO_SHA256_ALT
+//#define MBEDCRYPTO_SHA512_ALT
+//#define MBEDCRYPTO_XTEA_ALT
+/*
+ * When replacing the elliptic curve module, pleace consider, that it is
+ * implemented with two .c files:
+ * - ecp.c
+ * - ecp_curves.c
+ * You can replace them very much like all the other MBEDCRYPTO__MODULE_NAME__ALT
+ * macros as described above. The only difference is that you have to make sure
+ * that you provide functionality for both .c files.
+ */
+//#define MBEDCRYPTO_ECP_ALT
+
+/**
+ * \def MBEDCRYPTO_MD2_PROCESS_ALT
+ *
+ * MBEDCRYPTO__FUNCTION_NAME__ALT: Uncomment a macro to let Mbed Crypto use you
+ * alternate core implementation of symmetric crypto or hash function. Keep in
+ * mind that function prototypes should remain the same.
+ *
+ * This replaces only one function. The header file from Mbed Crypto is still
+ * used, in contrast to the MBEDCRYPTO__MODULE_NAME__ALT flags.
+ *
+ * Example: In case you uncomment MBEDCRYPTO_SHA256_PROCESS_ALT, Mbed Crypto will
+ * no longer provide the mbedcrypto_sha1_process() function, but it will still provide
+ * the other function (using your mbedcrypto_sha1_process() function) and the definition
+ * of mbedcrypto_sha1_context, so your implementation of mbedcrypto_sha1_process must be compatible
+ * with this definition.
+ *
+ * \note Because of a signature change, the core AES encryption and decryption routines are
+ * currently named mbedcrypto_aes_internal_encrypt and mbedcrypto_aes_internal_decrypt,
+ * respectively. When setting up alternative implementations, these functions should
+ * be overriden, but the wrapper functions mbedcrypto_aes_decrypt and mbedcrypto_aes_encrypt
+ * must stay untouched.
+ *
+ * \note If you use the AES_xxx_ALT macros, then is is recommended to also set
+ * MBEDCRYPTO_AES_ROM_TABLES in order to help the linker garbage-collect the AES
+ * tables.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * function.
+ *
+ * \warning MD2, MD4, MD5, DES and SHA-1 are considered weak and their use
+ * constitutes a security risk. If possible, we recommend avoiding
+ * dependencies on them, and considering stronger message digests
+ * and ciphers instead.
+ *
+ */
+//#define MBEDCRYPTO_MD2_PROCESS_ALT
+//#define MBEDCRYPTO_MD4_PROCESS_ALT
+//#define MBEDCRYPTO_MD5_PROCESS_ALT
+//#define MBEDCRYPTO_RIPEMD160_PROCESS_ALT
+//#define MBEDCRYPTO_SHA1_PROCESS_ALT
+//#define MBEDCRYPTO_SHA256_PROCESS_ALT
+//#define MBEDCRYPTO_SHA512_PROCESS_ALT
+//#define MBEDCRYPTO_DES_SETKEY_ALT
+//#define MBEDCRYPTO_DES_CRYPT_ECB_ALT
+//#define MBEDCRYPTO_DES3_CRYPT_ECB_ALT
+//#define MBEDCRYPTO_AES_SETKEY_ENC_ALT
+//#define MBEDCRYPTO_AES_SETKEY_DEC_ALT
+//#define MBEDCRYPTO_AES_ENCRYPT_ALT
+//#define MBEDCRYPTO_AES_DECRYPT_ALT
+//#define MBEDCRYPTO_ECDH_GEN_PUBLIC_ALT
+//#define MBEDCRYPTO_ECDH_COMPUTE_SHARED_ALT
+//#define MBEDCRYPTO_ECDSA_VERIFY_ALT
+//#define MBEDCRYPTO_ECDSA_SIGN_ALT
+//#define MBEDCRYPTO_ECDSA_GENKEY_ALT
+
+/**
+ * \def MBEDCRYPTO_ECP_INTERNAL_ALT
+ *
+ * Expose a part of the internal interface of the Elliptic Curve Point module.
+ *
+ * MBEDCRYPTO_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let Mbed Crypto use your
+ * alternative core implementation of elliptic curve arithmetic. Keep in mind
+ * that function prototypes should remain the same.
+ *
+ * This partially replaces one function. The header file from Mbed Crypto is still
+ * used, in contrast to the MBEDCRYPTO_ECP_ALT flag. The original implementation
+ * is still present and it is used for group structures not supported by the
+ * alternative.
+ *
+ * Any of these options become available by defining MBEDCRYPTO_ECP_INTERNAL_ALT
+ * and implementing the following functions:
+ * unsigned char mbedcrypto_internal_ecp_grp_capable(
+ * const mbedcrypto_ecp_group *grp )
+ * int mbedcrypto_internal_ecp_init( const mbedcrypto_ecp_group *grp )
+ * void mbedcrypto_internal_ecp_deinit( const mbedcrypto_ecp_group *grp )
+ * The mbedcrypto_internal_ecp_grp_capable function should return 1 if the
+ * replacement functions implement arithmetic for the given group and 0
+ * otherwise.
+ * The functions mbedcrypto_internal_ecp_init and mbedcrypto_internal_ecp_deinit are
+ * called before and after each point operation and provide an opportunity to
+ * implement optimized set up and tear down instructions.
+ *
+ * Example: In case you uncomment MBEDCRYPTO_ECP_INTERNAL_ALT and
+ * MBEDCRYPTO_ECP_DOUBLE_JAC_ALT, Mbed Crypto will still provide the ecp_double_jac
+ * function, but will use your mbedcrypto_internal_ecp_double_jac if the group is
+ * supported (your mbedcrypto_internal_ecp_grp_capable function returns 1 when
+ * receives it as an argument). If the group is not supported then the original
+ * implementation is used. The other functions and the definition of
+ * mbedcrypto_ecp_group and mbedcrypto_ecp_point will not change, so your
+ * implementation of mbedcrypto_internal_ecp_double_jac and
+ * mbedcrypto_internal_ecp_grp_capable must be compatible with this definition.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * function.
+ */
+/* Required for all the functions in this section */
+//#define MBEDCRYPTO_ECP_INTERNAL_ALT
+/* Support for Weierstrass curves with Jacobi representation */
+//#define MBEDCRYPTO_ECP_RANDOMIZE_JAC_ALT
+//#define MBEDCRYPTO_ECP_ADD_MIXED_ALT
+//#define MBEDCRYPTO_ECP_DOUBLE_JAC_ALT
+//#define MBEDCRYPTO_ECP_NORMALIZE_JAC_MANY_ALT
+//#define MBEDCRYPTO_ECP_NORMALIZE_JAC_ALT
+/* Support for curves with Montgomery arithmetic */
+//#define MBEDCRYPTO_ECP_DOUBLE_ADD_MXZ_ALT
+//#define MBEDCRYPTO_ECP_RANDOMIZE_MXZ_ALT
+//#define MBEDCRYPTO_ECP_NORMALIZE_MXZ_ALT
+
+/**
+ * \def MBEDCRYPTO_TEST_NULL_ENTROPY
+ *
+ * Enables testing and use of Mbed Crypto without any configured entropy sources.
+ * This permits use of the library on platforms before an entropy source has
+ * been integrated (see for example the MBEDCRYPTO_ENTROPY_HARDWARE_ALT or the
+ * MBEDCRYPTO_ENTROPY_NV_SEED switches).
+ *
+ * WARNING! This switch MUST be disabled in production builds, and is suitable
+ * only for development.
+ * Enabling the switch negates any security provided by the library.
+ *
+ * Requires MBEDCRYPTO_ENTROPY_C, MBEDCRYPTO_NO_DEFAULT_ENTROPY_SOURCES
+ *
+ */
+//#define MBEDCRYPTO_TEST_NULL_ENTROPY
+
+/**
+ * \def MBEDCRYPTO_ENTROPY_HARDWARE_ALT
+ *
+ * Uncomment this macro to let Mbed Crypto use your own implementation of a
+ * hardware entropy collector.
+ *
+ * Your function must be called \c mbedcrypto_hardware_poll(), have the same
+ * prototype as declared in entropy_poll.h, and accept NULL as first argument.
+ *
+ * Uncomment to use your own hardware entropy collector.
+ */
+//#define MBEDCRYPTO_ENTROPY_HARDWARE_ALT
+
+/**
+ * \def MBEDCRYPTO_AES_ROM_TABLES
+ *
+ * Use precomputed AES tables stored in ROM.
+ *
+ * Uncomment this macro to use precomputed AES tables stored in ROM.
+ * Comment this macro to generate AES tables in RAM at runtime.
+ *
+ * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb
+ * (or ~2kb if \c MBEDCRYPTO_AES_FEWER_TABLES is used) and reduces the
+ * initialization time before the first AES operation can be performed.
+ * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c
+ * MBEDCRYPTO_AES_FEWER_TABLES below is used), and potentially degraded
+ * performance if ROM access is slower than RAM access.
+ *
+ * This option is independent of \c MBEDCRYPTO_AES_FEWER_TABLES.
+ *
+ */
+//#define MBEDCRYPTO_AES_ROM_TABLES
+
+/**
+ * \def MBEDCRYPTO_AES_FEWER_TABLES
+ *
+ * Use less ROM/RAM for AES tables.
+ *
+ * Uncommenting this macro omits 75% of the AES tables from
+ * ROM / RAM (depending on the value of \c MBEDCRYPTO_AES_ROM_TABLES)
+ * by computing their values on the fly during operations
+ * (the tables are entry-wise rotations of one another).
+ *
+ * Tradeoff: Uncommenting this reduces the RAM / ROM footprint
+ * by ~6kb but at the cost of more arithmetic operations during
+ * runtime. Specifically, one has to compare 4 accesses within
+ * different tables to 4 accesses with additional arithmetic
+ * operations within the same table. The performance gain/loss
+ * depends on the system and memory details.
+ *
+ * This option is independent of \c MBEDCRYPTO_AES_ROM_TABLES.
+ *
+ */
+//#define MBEDCRYPTO_AES_FEWER_TABLES
+
+/**
+ * \def MBEDCRYPTO_CAMELLIA_SMALL_MEMORY
+ *
+ * Use less ROM for the Camellia implementation (saves about 768 bytes).
+ *
+ * Uncomment this macro to use less memory for Camellia.
+ */
+//#define MBEDCRYPTO_CAMELLIA_SMALL_MEMORY
+
+/**
+ * \def MBEDCRYPTO_CIPHER_MODE_CBC
+ *
+ * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
+ */
+#define MBEDCRYPTO_CIPHER_MODE_CBC
+
+/**
+ * \def MBEDCRYPTO_CIPHER_MODE_CFB
+ *
+ * Enable Cipher Feedback mode (CFB) for symmetric ciphers.
+ */
+#define MBEDCRYPTO_CIPHER_MODE_CFB
+
+/**
+ * \def MBEDCRYPTO_CIPHER_MODE_CTR
+ *
+ * Enable Counter Block Cipher mode (CTR) for symmetric ciphers.
+ */
+#define MBEDCRYPTO_CIPHER_MODE_CTR
+
+/**
+ * \def MBEDCRYPTO_CIPHER_PADDING_PKCS7
+ *
+ * MBEDCRYPTO_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for
+ * specific padding modes in the cipher layer with cipher modes that support
+ * padding (e.g. CBC)
+ *
+ * If you disable all padding modes, only full blocks can be used with CBC.
+ *
+ * Enable padding modes in the cipher layer.
+ */
+#define MBEDCRYPTO_CIPHER_PADDING_PKCS7
+#define MBEDCRYPTO_CIPHER_PADDING_ONE_AND_ZEROS
+#define MBEDCRYPTO_CIPHER_PADDING_ZEROS_AND_LEN
+#define MBEDCRYPTO_CIPHER_PADDING_ZEROS
+
+/**
+ * \def MBEDCRYPTO_ECP_DP_SECP192R1_ENABLED
+ *
+ * MBEDCRYPTO_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve
+ * module. By default all supported curves are enabled.
+ *
+ * Comment macros to disable the curve and functions for it
+ */
+#define MBEDCRYPTO_ECP_DP_SECP192R1_ENABLED
+#define MBEDCRYPTO_ECP_DP_SECP224R1_ENABLED
+#define MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED
+#define MBEDCRYPTO_ECP_DP_SECP384R1_ENABLED
+#define MBEDCRYPTO_ECP_DP_SECP521R1_ENABLED
+#define MBEDCRYPTO_ECP_DP_SECP192K1_ENABLED
+#define MBEDCRYPTO_ECP_DP_SECP224K1_ENABLED
+#define MBEDCRYPTO_ECP_DP_SECP256K1_ENABLED
+#define MBEDCRYPTO_ECP_DP_BP256R1_ENABLED
+#define MBEDCRYPTO_ECP_DP_BP384R1_ENABLED
+#define MBEDCRYPTO_ECP_DP_BP512R1_ENABLED
+#define MBEDCRYPTO_ECP_DP_CURVE25519_ENABLED
+#define MBEDCRYPTO_ECP_DP_CURVE448_ENABLED
+
+/**
+ * \def MBEDCRYPTO_ECP_NIST_OPTIM
+ *
+ * Enable specific 'modulo p' routines for each NIST prime.
+ * Depending on the prime and architecture, makes operations 4 to 8 times
+ * faster on the corresponding curve.
+ *
+ * Comment this macro to disable NIST curves optimisation.
+ */
+#define MBEDCRYPTO_ECP_NIST_OPTIM
+
+/**
+ * \def MBEDCRYPTO_ECDSA_DETERMINISTIC
+ *
+ * Enable deterministic ECDSA (RFC 6979).
+ * Standard ECDSA is "fragile" in the sense that lack of entropy when signing
+ * may result in a compromise of the long-term signing key. This is avoided by
+ * the deterministic variant.
+ *
+ * Requires: MBEDCRYPTO_HMAC_DRBG_C
+ *
+ * Comment this macro to disable deterministic ECDSA.
+ */
+#define MBEDCRYPTO_ECDSA_DETERMINISTIC
+
+/**
+ * \def MBEDCRYPTO_PK_PARSE_EC_EXTENDED
+ *
+ * Enhance support for reading EC keys using variants of SEC1 not allowed by
+ * RFC 5915 and RFC 5480.
+ *
+ * Currently this means parsing the SpecifiedECDomain choice of EC
+ * parameters (only known groups are supported, not arbitrary domains, to
+ * avoid validation issues).
+ *
+ * Disable if you only need to support RFC 5915 + 5480 key formats.
+ */
+#define MBEDCRYPTO_PK_PARSE_EC_EXTENDED
+
+/**
+ * \def MBEDCRYPTO_ERROR_STRERROR_DUMMY
+ *
+ * Enable a dummy error function to make use of mbedcrypto_strerror() in
+ * third party libraries easier when MBEDCRYPTO_ERROR_C is disabled
+ * (no effect when MBEDCRYPTO_ERROR_C is enabled).
+ *
+ * You can safely disable this if MBEDCRYPTO_ERROR_C is enabled, or if you're
+ * not using mbedcrypto_strerror() or error_strerror() in your application.
+ *
+ * Disable if you run into name conflicts and want to really remove the
+ * mbedcrypto_strerror()
+ */
+#define MBEDCRYPTO_ERROR_STRERROR_DUMMY
+
+/**
+ * \def MBEDCRYPTO_GENPRIME
+ *
+ * Enable the prime-number generation code.
+ *
+ * Requires: MBEDCRYPTO_BIGNUM_C
+ */
+#define MBEDCRYPTO_GENPRIME
+
+/**
+ * \def MBEDCRYPTO_FS_IO
+ *
+ * Enable functions that use the filesystem.
+ */
+#define MBEDCRYPTO_FS_IO
+
+/**
+ * \def MBEDCRYPTO_NO_DEFAULT_ENTROPY_SOURCES
+ *
+ * Do not add default entropy sources. These are the platform specific,
+ * mbedcrypto_timing_hardclock and HAVEGE based poll functions.
+ *
+ * This is useful to have more control over the added entropy sources in an
+ * application.
+ *
+ * Uncomment this macro to prevent loading of default entropy functions.
+ */
+//#define MBEDCRYPTO_NO_DEFAULT_ENTROPY_SOURCES
+
+/**
+ * \def MBEDCRYPTO_NO_PLATFORM_ENTROPY
+ *
+ * Do not use built-in platform entropy functions.
+ * This is useful if your platform does not support
+ * standards like the /dev/urandom or Windows CryptoAPI.
+ *
+ * Uncomment this macro to disable the built-in platform entropy functions.
+ */
+//#define MBEDCRYPTO_NO_PLATFORM_ENTROPY
+
+/**
+ * \def MBEDCRYPTO_ENTROPY_FORCE_SHA256
+ *
+ * Force the entropy accumulator to use a SHA-256 accumulator instead of the
+ * default SHA-512 based one (if both are available).
+ *
+ * Requires: MBEDCRYPTO_SHA256_C
+ *
+ * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option
+ * if you have performance concerns.
+ *
+ * This option is only useful if both MBEDCRYPTO_SHA256_C and
+ * MBEDCRYPTO_SHA512_C are defined. Otherwise the available hash module is used.
+ */
+//#define MBEDCRYPTO_ENTROPY_FORCE_SHA256
+
+/**
+ * \def MBEDCRYPTO_ENTROPY_NV_SEED
+ *
+ * Enable the non-volatile (NV) seed file-based entropy source.
+ * (Also enables the NV seed read/write functions in the platform layer)
+ *
+ * This is crucial (if not required) on systems that do not have a
+ * cryptographic entropy source (in hardware or kernel) available.
+ *
+ * Requires: MBEDCRYPTO_ENTROPY_C, MBEDCRYPTO_PLATFORM_C
+ *
+ * \note The read/write functions that are used by the entropy source are
+ * determined in the platform layer, and can be modified at runtime and/or
+ * compile-time depending on the flags (MBEDCRYPTO_PLATFORM_NV_SEED_*) used.
+ *
+ * \note If you use the default implementation functions that read a seedfile
+ * with regular fopen(), please make sure you make a seedfile with the
+ * proper name (defined in MBEDCRYPTO_PLATFORM_STD_NV_SEED_FILE) and at
+ * least MBEDCRYPTO_ENTROPY_BLOCK_SIZE bytes in size that can be read from
+ * and written to or you will get an entropy source error! The default
+ * implementation will only use the first MBEDCRYPTO_ENTROPY_BLOCK_SIZE
+ * bytes from the file.
+ *
+ * \note The entropy collector will write to the seed file before entropy is
+ * given to an external source, to update it.
+ */
+//#define MBEDCRYPTO_ENTROPY_NV_SEED
+
+/**
+ * \def MBEDCRYPTO_MEMORY_DEBUG
+ *
+ * Enable debugging of buffer allocator memory issues. Automatically prints
+ * (to stderr) all (fatal) messages on memory allocation issues. Enables
+ * function for 'debug output' of allocated memory.
+ *
+ * Requires: MBEDCRYPTO_MEMORY_BUFFER_ALLOC_C
+ *
+ * Uncomment this macro to let the buffer allocator print out error messages.
+ */
+//#define MBEDCRYPTO_MEMORY_DEBUG
+
+/**
+ * \def MBEDCRYPTO_MEMORY_BACKTRACE
+ *
+ * Include backtrace information with each allocated block.
+ *
+ * Requires: MBEDCRYPTO_MEMORY_BUFFER_ALLOC_C
+ * GLIBC-compatible backtrace() an backtrace_symbols() support
+ *
+ * Uncomment this macro to include backtrace information
+ */
+//#define MBEDCRYPTO_MEMORY_BACKTRACE
+
+/**
+ * \def MBEDCRYPTO_PK_RSA_ALT_SUPPORT
+ *
+ * Support external private RSA keys (eg from a HSM) in the PK layer.
+ *
+ * Comment this macro to disable support for external private RSA keys.
+ */
+#define MBEDCRYPTO_PK_RSA_ALT_SUPPORT
+
+/**
+ * \def MBEDCRYPTO_PKCS1_V15
+ *
+ * Enable support for PKCS#1 v1.5 encoding.
+ *
+ * Requires: MBEDCRYPTO_RSA_C
+ *
+ * This enables support for PKCS#1 v1.5 operations.
+ */
+#define MBEDCRYPTO_PKCS1_V15
+
+/**
+ * \def MBEDCRYPTO_PKCS1_V21
+ *
+ * Enable support for PKCS#1 v2.1 encoding.
+ *
+ * Requires: MBEDCRYPTO_MD_C, MBEDCRYPTO_RSA_C
+ *
+ * This enables support for RSAES-OAEP and RSASSA-PSS operations.
+ */
+#define MBEDCRYPTO_PKCS1_V21
+
+/**
+ * \def MBEDCRYPTO_PSA_CRYPTO_SPM
+ *
+ * When MBEDCRYPTO_PSA_CRYPTO_SPM is defined, the code is built for SPM (Secure
+ * Partition Manager) integration which separates the code into two parts: a
+ * NSPE (Non-Secure Process Environment) and an SPE (Secure Process
+ * Environment).
+ *
+ * Module: library/psa_crypto.c
+ * Requires: MBEDCRYPTO_PSA_CRYPTO_C
+ *
+ */
+//#define MBEDCRYPTO_PSA_CRYPTO_SPM
+
+/**
+ * \def MBEDCRYPTO_RSA_NO_CRT
+ *
+ * Do not use the Chinese Remainder Theorem for the RSA private operation.
+ *
+ * Uncomment this macro to disable the use of CRT in RSA.
+ *
+ */
+//#define MBEDCRYPTO_RSA_NO_CRT
+
+/**
+ * \def MBEDCRYPTO_SELF_TEST
+ *
+ * Enable the checkup functions (*_self_test).
+ */
+#define MBEDCRYPTO_SELF_TEST
+
+/**
+ * \def MBEDCRYPTO_SHA256_SMALLER
+ *
+ * Enable an implementation of SHA-256 that has lower ROM footprint but also
+ * lower performance.
+ *
+ * The default implementation is meant to be a reasonnable compromise between
+ * performance and size. This version optimizes more aggressively for size at
+ * the expense of performance. Eg on Cortex-M4 it reduces the size of
+ * mbedcrypto_sha256_process() from ~2KB to ~0.5KB for a performance hit of about
+ * 30%.
+ *
+ * Uncomment to enable the smaller implementation of SHA256.
+ */
+//#define MBEDCRYPTO_SHA256_SMALLER
+
+/**
+ * \def MBEDCRYPTO_THREADING_ALT
+ *
+ * Provide your own alternate threading implementation.
+ *
+ * Requires: MBEDCRYPTO_THREADING_C
+ *
+ * Uncomment this to allow your own alternate threading implementation.
+ */
+//#define MBEDCRYPTO_THREADING_ALT
+
+/**
+ * \def MBEDCRYPTO_THREADING_PTHREAD
+ *
+ * Enable the pthread wrapper layer for the threading layer.
+ *
+ * Requires: MBEDCRYPTO_THREADING_C
+ *
+ * Uncomment this to enable pthread mutexes.
+ */
+//#define MBEDCRYPTO_THREADING_PTHREAD
+
+/**
+ * \def MBEDCRYPTO_VERSION_FEATURES
+ *
+ * Allow run-time checking of compile-time enabled features. Thus allowing users
+ * to check at run-time if the library is for instance compiled with threading
+ * support via mbedcrypto_version_check_feature().
+ *
+ * Requires: MBEDCRYPTO_VERSION_C
+ *
+ * Comment this to disable run-time checking and save ROM space
+ */
+#define MBEDCRYPTO_VERSION_FEATURES
+
+/* \} name SECTION: Mbed Crypto feature support */
+
+/**
+ * \name SECTION: Mbed Crypto modules
+ *
+ * This section enables or disables entire modules in Mbed Crypto
+ * \{
+ */
+
+/**
+ * \def MBEDCRYPTO_AESNI_C
+ *
+ * Enable AES-NI support on x86-64.
+ *
+ * Module: library/aesni.c
+ * Caller: library/aes.c
+ *
+ * Requires: MBEDCRYPTO_HAVE_ASM
+ *
+ * This modules adds support for the AES-NI instructions on x86-64
+ */
+#define MBEDCRYPTO_AESNI_C
+
+/**
+ * \def MBEDCRYPTO_AES_C
+ *
+ * Enable the AES block cipher.
+ *
+ * Module: library/aes.c
+ * Caller: library/ssl_tls.c
+ * library/pem.c
+ * library/ctr_drbg.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDCRYPTO_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+ * MBEDCRYPTO_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ * MBEDCRYPTO_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ * MBEDCRYPTO_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+ * MBEDCRYPTO_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+ * MBEDCRYPTO_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+ * MBEDCRYPTO_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+ * MBEDCRYPTO_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+ * MBEDCRYPTO_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+ * MBEDCRYPTO_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+ * MBEDCRYPTO_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ * MBEDCRYPTO_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ * MBEDCRYPTO_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+ * MBEDCRYPTO_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+ * MBEDCRYPTO_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+ * MBEDCRYPTO_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+ * MBEDCRYPTO_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ * MBEDCRYPTO_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+ * MBEDCRYPTO_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ * MBEDCRYPTO_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ * MBEDCRYPTO_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ * MBEDCRYPTO_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+ * MBEDCRYPTO_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+ * MBEDCRYPTO_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+ * MBEDCRYPTO_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ * MBEDCRYPTO_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+ * MBEDCRYPTO_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384
+ * MBEDCRYPTO_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+ * MBEDCRYPTO_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
+ * MBEDCRYPTO_TLS_DHE_PSK_WITH_AES_256_CBC_SHA
+ * MBEDCRYPTO_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+ * MBEDCRYPTO_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
+ * MBEDCRYPTO_TLS_DHE_PSK_WITH_AES_128_CBC_SHA
+ * MBEDCRYPTO_TLS_RSA_WITH_AES_256_GCM_SHA384
+ * MBEDCRYPTO_TLS_RSA_WITH_AES_256_CBC_SHA256
+ * MBEDCRYPTO_TLS_RSA_WITH_AES_256_CBC_SHA
+ * MBEDCRYPTO_TLS_RSA_WITH_AES_128_GCM_SHA256
+ * MBEDCRYPTO_TLS_RSA_WITH_AES_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_RSA_WITH_AES_128_CBC_SHA
+ * MBEDCRYPTO_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
+ * MBEDCRYPTO_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
+ * MBEDCRYPTO_TLS_RSA_PSK_WITH_AES_256_CBC_SHA
+ * MBEDCRYPTO_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
+ * MBEDCRYPTO_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_RSA_PSK_WITH_AES_128_CBC_SHA
+ * MBEDCRYPTO_TLS_PSK_WITH_AES_256_GCM_SHA384
+ * MBEDCRYPTO_TLS_PSK_WITH_AES_256_CBC_SHA384
+ * MBEDCRYPTO_TLS_PSK_WITH_AES_256_CBC_SHA
+ * MBEDCRYPTO_TLS_PSK_WITH_AES_128_GCM_SHA256
+ * MBEDCRYPTO_TLS_PSK_WITH_AES_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_PSK_WITH_AES_128_CBC_SHA
+ *
+ * PEM_PARSE uses AES for decrypting encrypted keys.
+ */
+#define MBEDCRYPTO_AES_C
+
+/**
+ * \def MBEDCRYPTO_ARC4_C
+ *
+ * Enable the ARCFOUR stream cipher.
+ *
+ * Module: library/arc4.c
+ * Caller: library/ssl_tls.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDCRYPTO_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+ * MBEDCRYPTO_TLS_ECDH_RSA_WITH_RC4_128_SHA
+ * MBEDCRYPTO_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+ * MBEDCRYPTO_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+ * MBEDCRYPTO_TLS_ECDHE_PSK_WITH_RC4_128_SHA
+ * MBEDCRYPTO_TLS_DHE_PSK_WITH_RC4_128_SHA
+ * MBEDCRYPTO_TLS_RSA_WITH_RC4_128_SHA
+ * MBEDCRYPTO_TLS_RSA_WITH_RC4_128_MD5
+ * MBEDCRYPTO_TLS_RSA_PSK_WITH_RC4_128_SHA
+ * MBEDCRYPTO_TLS_PSK_WITH_RC4_128_SHA
+ *
+ * \warning ARC4 is considered a weak cipher and its use constitutes a
+ * security risk. If possible, we recommend avoidng dependencies on
+ * it, and considering stronger ciphers instead.
+ *
+ */
+#define MBEDCRYPTO_ARC4_C
+
+/**
+ * \def MBEDCRYPTO_ASN1_PARSE_C
+ *
+ * Enable the generic ASN1 parser.
+ *
+ * Module: library/asn1.c
+ * Caller: library/x509.c
+ * library/dhm.c
+ * library/pkcs12.c
+ * library/pkcs5.c
+ * library/pkparse.c
+ */
+#define MBEDCRYPTO_ASN1_PARSE_C
+
+/**
+ * \def MBEDCRYPTO_ASN1_WRITE_C
+ *
+ * Enable the generic ASN1 writer.
+ *
+ * Module: library/asn1write.c
+ * Caller: library/ecdsa.c
+ * library/pkwrite.c
+ * library/x509_create.c
+ * library/x509write_crt.c
+ * library/x509write_csr.c
+ */
+#define MBEDCRYPTO_ASN1_WRITE_C
+
+/**
+ * \def MBEDCRYPTO_BASE64_C
+ *
+ * Enable the Base64 module.
+ *
+ * Module: library/base64.c
+ * Caller: library/pem.c
+ *
+ * This module is required for PEM support (required by X.509).
+ */
+#define MBEDCRYPTO_BASE64_C
+
+/**
+ * \def MBEDCRYPTO_BIGNUM_C
+ *
+ * Enable the multi-precision integer library.
+ *
+ * Module: library/bignum.c
+ * Caller: library/dhm.c
+ * library/ecp.c
+ * library/ecdsa.c
+ * library/rsa.c
+ * library/rsa_internal.c
+ * library/ssl_tls.c
+ *
+ * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support.
+ */
+#define MBEDCRYPTO_BIGNUM_C
+
+/**
+ * \def MBEDCRYPTO_BLOWFISH_C
+ *
+ * Enable the Blowfish block cipher.
+ *
+ * Module: library/blowfish.c
+ */
+#define MBEDCRYPTO_BLOWFISH_C
+
+/**
+ * \def MBEDCRYPTO_CAMELLIA_C
+ *
+ * Enable the Camellia block cipher.
+ *
+ * Module: library/camellia.c
+ * Caller: library/ssl_tls.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDCRYPTO_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDCRYPTO_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDCRYPTO_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDCRYPTO_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDCRYPTO_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDCRYPTO_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDCRYPTO_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDCRYPTO_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDCRYPTO_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDCRYPTO_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDCRYPTO_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDCRYPTO_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ * MBEDCRYPTO_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+ * MBEDCRYPTO_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDCRYPTO_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDCRYPTO_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDCRYPTO_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+ * MBEDCRYPTO_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDCRYPTO_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDCRYPTO_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDCRYPTO_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDCRYPTO_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDCRYPTO_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ * MBEDCRYPTO_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+ * MBEDCRYPTO_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDCRYPTO_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+ * MBEDCRYPTO_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDCRYPTO_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDCRYPTO_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDCRYPTO_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDCRYPTO_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDCRYPTO_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDCRYPTO_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDCRYPTO_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ */
+#define MBEDCRYPTO_CAMELLIA_C
+
+/**
+ * \def MBEDCRYPTO_CCM_C
+ *
+ * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher.
+ *
+ * Module: library/ccm.c
+ *
+ * Requires: MBEDCRYPTO_AES_C or MBEDCRYPTO_CAMELLIA_C
+ *
+ * This module enables the AES-CCM ciphersuites, if other requisites are
+ * enabled as well.
+ */
+#define MBEDCRYPTO_CCM_C
+
+/**
+ * \def MBEDCRYPTO_CIPHER_C
+ *
+ * Enable the generic cipher layer.
+ *
+ * Module: library/cipher.c
+ * Caller: library/ssl_tls.c
+ *
+ * Uncomment to enable generic cipher wrappers.
+ */
+#define MBEDCRYPTO_CIPHER_C
+
+/**
+ * \def MBEDCRYPTO_CMAC_C
+ *
+ * Enable the CMAC (Cipher-based Message Authentication Code) mode for block
+ * ciphers.
+ *
+ * Module: library/cmac.c
+ *
+ * Requires: MBEDCRYPTO_AES_C or MBEDCRYPTO_DES_C
+ *
+ */
+#define MBEDCRYPTO_CMAC_C
+
+/**
+ * \def MBEDCRYPTO_CTR_DRBG_C
+ *
+ * Enable the CTR_DRBG AES-256-based random generator.
+ *
+ * Module: library/ctr_drbg.c
+ * Caller:
+ *
+ * Requires: MBEDCRYPTO_AES_C
+ *
+ * This module provides the CTR_DRBG AES-256 random number generator.
+ */
+#define MBEDCRYPTO_CTR_DRBG_C
+
+/**
+ * \def MBEDCRYPTO_DES_C
+ *
+ * Enable the DES block cipher.
+ *
+ * Module: library/des.c
+ * Caller: library/pem.c
+ * library/ssl_tls.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDCRYPTO_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+ * MBEDCRYPTO_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+ * MBEDCRYPTO_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+ * MBEDCRYPTO_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+ * MBEDCRYPTO_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ * MBEDCRYPTO_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA
+ * MBEDCRYPTO_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
+ * MBEDCRYPTO_TLS_RSA_WITH_3DES_EDE_CBC_SHA
+ * MBEDCRYPTO_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
+ * MBEDCRYPTO_TLS_PSK_WITH_3DES_EDE_CBC_SHA
+ *
+ * PEM_PARSE uses DES/3DES for decrypting encrypted keys.
+ *
+ * \warning DES is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers instead.
+ */
+#define MBEDCRYPTO_DES_C
+
+/**
+ * \def MBEDCRYPTO_DHM_C
+ *
+ * Enable the Diffie-Hellman-Merkle module.
+ *
+ * Module: library/dhm.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * This module is used by the following key exchanges:
+ * DHE-RSA, DHE-PSK
+ *
+ * \warning Using DHE constitutes a security risk as it
+ * is not possible to validate custom DH parameters.
+ * If possible, it is recommended users should consider
+ * preferring other methods of key exchange.
+ * See dhm.h for more details.
+ *
+ */
+#define MBEDCRYPTO_DHM_C
+
+/**
+ * \def MBEDCRYPTO_ECDH_C
+ *
+ * Enable the elliptic curve Diffie-Hellman library.
+ *
+ * Module: library/ecdh.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * This module is used by the following key exchanges:
+ * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK
+ *
+ * Requires: MBEDCRYPTO_ECP_C
+ */
+#define MBEDCRYPTO_ECDH_C
+
+/**
+ * \def MBEDCRYPTO_ECDSA_C
+ *
+ * Enable the elliptic curve DSA library.
+ *
+ * Module: library/ecdsa.c
+ * Caller:
+ *
+ * This module is used by the following key exchanges:
+ * ECDHE-ECDSA
+ *
+ * Requires: MBEDCRYPTO_ECP_C, MBEDCRYPTO_ASN1_WRITE_C, MBEDCRYPTO_ASN1_PARSE_C
+ */
+#define MBEDCRYPTO_ECDSA_C
+
+/**
+ * \def MBEDCRYPTO_ECJPAKE_C
+ *
+ * Enable the elliptic curve J-PAKE library.
+ *
+ * \warning This is currently experimental. EC J-PAKE support is based on the
+ * Thread v1.0.0 specification; incompatible changes to the specification
+ * might still happen. For this reason, this is disabled by default.
+ *
+ * Module: library/ecjpake.c
+ * Caller:
+ *
+ * This module is used by the following key exchanges:
+ * ECJPAKE
+ *
+ * Requires: MBEDCRYPTO_ECP_C, MBEDCRYPTO_MD_C
+ */
+#define MBEDCRYPTO_ECJPAKE_C
+
+/**
+ * \def MBEDCRYPTO_ECP_C
+ *
+ * Enable the elliptic curve over GF(p) library.
+ *
+ * Module: library/ecp.c
+ * Caller: library/ecdh.c
+ * library/ecdsa.c
+ * library/ecjpake.c
+ *
+ * Requires: MBEDCRYPTO_BIGNUM_C and at least one MBEDCRYPTO_ECP_DP_XXX_ENABLED
+ */
+#define MBEDCRYPTO_ECP_C
+
+/**
+ * \def MBEDCRYPTO_ENTROPY_C
+ *
+ * Enable the platform-specific entropy code.
+ *
+ * Module: library/entropy.c
+ * Caller:
+ *
+ * Requires: MBEDCRYPTO_SHA512_C or MBEDCRYPTO_SHA256_C
+ *
+ * This module provides a generic entropy pool
+ */
+#define MBEDCRYPTO_ENTROPY_C
+
+/**
+ * \def MBEDCRYPTO_ERROR_C
+ *
+ * Enable error code to error string conversion.
+ *
+ * Module: library/error.c
+ * Caller:
+ *
+ * This module enables mbedcrypto_strerror().
+ */
+#define MBEDCRYPTO_ERROR_C
+
+/**
+ * \def MBEDCRYPTO_GCM_C
+ *
+ * Enable the Galois/Counter Mode (GCM) for AES.
+ *
+ * Module: library/gcm.c
+ *
+ * Requires: MBEDCRYPTO_AES_C or MBEDCRYPTO_CAMELLIA_C
+ *
+ * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other
+ * requisites are enabled as well.
+ */
+#define MBEDCRYPTO_GCM_C
+
+/**
+ * \def MBEDCRYPTO_HMAC_DRBG_C
+ *
+ * Enable the HMAC_DRBG random generator.
+ *
+ * Module: library/hmac_drbg.c
+ * Caller:
+ *
+ * Requires: MBEDCRYPTO_MD_C
+ *
+ * Uncomment to enable the HMAC_DRBG random number geerator.
+ */
+#define MBEDCRYPTO_HMAC_DRBG_C
+
+/**
+ * \def MBEDCRYPTO_MD_C
+ *
+ * Enable the generic message digest layer.
+ *
+ * Module: library/md.c
+ * Caller:
+ *
+ * Uncomment to enable generic message digest wrappers.
+ */
+#define MBEDCRYPTO_MD_C
+
+/**
+ * \def MBEDCRYPTO_MD2_C
+ *
+ * Enable the MD2 hash algorithm.
+ *
+ * Module: library/md2.c
+ * Caller:
+ *
+ * Uncomment to enable support for (rare) MD2-signed X.509 certs.
+ *
+ * \warning MD2 is considered a weak message digest and its use constitutes a
+ * security risk. If possible, we recommend avoiding dependencies on
+ * it, and considering stronger message digests instead.
+ *
+ */
+#define MBEDCRYPTO_MD2_C
+
+/**
+ * \def MBEDCRYPTO_MD4_C
+ *
+ * Enable the MD4 hash algorithm.
+ *
+ * Module: library/md4.c
+ * Caller:
+ *
+ * Uncomment to enable support for (rare) MD4-signed X.509 certs.
+ *
+ * \warning MD4 is considered a weak message digest and its use constitutes a
+ * security risk. If possible, we recommend avoiding dependencies on
+ * it, and considering stronger message digests instead.
+ *
+ */
+#define MBEDCRYPTO_MD4_C
+
+/**
+ * \def MBEDCRYPTO_MD5_C
+ *
+ * Enable the MD5 hash algorithm.
+ *
+ * Module: library/md5.c
+ * Caller: library/md.c
+ * library/pem.c
+ * library/ssl_tls.c
+ *
+ * This module is required for SSL/TLS up to version 1.1, and for TLS 1.2
+ * depending on the handshake parameters. Further, it is used for checking
+ * MD5-signed certificates, and for PBKDF1 when decrypting PEM-encoded
+ * encrypted keys.
+ *
+ * \warning MD5 is considered a weak message digest and its use constitutes a
+ * security risk. If possible, we recommend avoiding dependencies on
+ * it, and considering stronger message digests instead.
+ *
+ */
+#define MBEDCRYPTO_MD5_C
+
+/**
+ * \def MBEDCRYPTO_MEMORY_BUFFER_ALLOC_C
+ *
+ * Enable the buffer allocator implementation that makes use of a (stack)
+ * based buffer to 'allocate' dynamic memory. (replaces calloc() and free()
+ * calls)
+ *
+ * Module: library/memory_buffer_alloc.c
+ *
+ * Requires: MBEDCRYPTO_PLATFORM_C
+ * MBEDCRYPTO_PLATFORM_MEMORY (to use it within Mbed Crypto)
+ *
+ * Enable this module to enable the buffer memory allocator.
+ */
+//#define MBEDCRYPTO_MEMORY_BUFFER_ALLOC_C
+
+/**
+ * \def MBEDCRYPTO_OID_C
+ *
+ * Enable the OID database.
+ *
+ * Module: library/oid.c
+ * Caller: library/asn1write.c
+ * library/pkcs5.c
+ * library/pkparse.c
+ * library/pkwrite.c
+ * library/rsa.c
+ * library/x509.c
+ * library/x509_create.c
+ * library/x509_crl.c
+ * library/x509_crt.c
+ * library/x509_csr.c
+ * library/x509write_crt.c
+ * library/x509write_csr.c
+ *
+ * This modules translates between OIDs and internal values.
+ */
+#define MBEDCRYPTO_OID_C
+
+/**
+ * \def MBEDCRYPTO_PADLOCK_C
+ *
+ * Enable VIA Padlock support on x86.
+ *
+ * Module: library/padlock.c
+ * Caller: library/aes.c
+ *
+ * Requires: MBEDCRYPTO_HAVE_ASM
+ *
+ * This modules adds support for the VIA PadLock on x86.
+ */
+//#define MBEDCRYPTO_PADLOCK_C
+
+/**
+ * \def MBEDCRYPTO_PEM_PARSE_C
+ *
+ * Enable PEM decoding / parsing.
+ *
+ * Module: library/pem.c
+ * Caller: library/dhm.c
+ * library/pkparse.c
+ * library/x509_crl.c
+ * library/x509_crt.c
+ * library/x509_csr.c
+ *
+ * Requires: MBEDCRYPTO_BASE64_C
+ *
+ * This modules adds support for decoding / parsing PEM files.
+ */
+#define MBEDCRYPTO_PEM_PARSE_C
+
+/**
+ * \def MBEDCRYPTO_PEM_WRITE_C
+ *
+ * Enable PEM encoding / writing.
+ *
+ * Module: library/pem.c
+ * Caller: library/pkwrite.c
+ * library/x509write_crt.c
+ * library/x509write_csr.c
+ *
+ * Requires: MBEDCRYPTO_BASE64_C
+ *
+ * This modules adds support for encoding / writing PEM files.
+ */
+#define MBEDCRYPTO_PEM_WRITE_C
+
+/**
+ * \def MBEDCRYPTO_PK_C
+ *
+ * Enable the generic public (asymetric) key layer.
+ *
+ * Module: library/pk.c
+ * Caller: library/ssl_tls.c
+ * library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * Requires: MBEDCRYPTO_RSA_C or MBEDCRYPTO_ECP_C
+ *
+ * Uncomment to enable generic public key wrappers.
+ */
+#define MBEDCRYPTO_PK_C
+
+/**
+ * \def MBEDCRYPTO_PK_PARSE_C
+ *
+ * Enable the generic public (asymetric) key parser.
+ *
+ * Module: library/pkparse.c
+ * Caller: library/x509_crt.c
+ * library/x509_csr.c
+ *
+ * Requires: MBEDCRYPTO_PK_C
+ *
+ * Uncomment to enable generic public key parse functions.
+ */
+#define MBEDCRYPTO_PK_PARSE_C
+
+/**
+ * \def MBEDCRYPTO_PK_WRITE_C
+ *
+ * Enable the generic public (asymetric) key writer.
+ *
+ * Module: library/pkwrite.c
+ * Caller: library/x509write.c
+ *
+ * Requires: MBEDCRYPTO_PK_C
+ *
+ * Uncomment to enable generic public key write functions.
+ */
+#define MBEDCRYPTO_PK_WRITE_C
+
+/**
+ * \def MBEDCRYPTO_PKCS5_C
+ *
+ * Enable PKCS#5 functions.
+ *
+ * Module: library/pkcs5.c
+ *
+ * Requires: MBEDCRYPTO_MD_C
+ *
+ * This module adds support for the PKCS#5 functions.
+ */
+#define MBEDCRYPTO_PKCS5_C
+
+/**
+ * \def MBEDCRYPTO_PKCS11_C
+ *
+ * Enable wrapper for PKCS#11 smartcard support.
+ *
+ * Module: library/pkcs11.c
+ * Caller: library/pk.c
+ *
+ * Requires: MBEDCRYPTO_PK_C
+ *
+ * This module enables SSL/TLS PKCS #11 smartcard support.
+ * Requires the presence of the PKCS#11 helper library (libpkcs11-helper)
+ */
+//#define MBEDCRYPTO_PKCS11_C
+
+/**
+ * \def MBEDCRYPTO_PKCS12_C
+ *
+ * Enable PKCS#12 PBE functions.
+ * Adds algorithms for parsing PKCS#8 encrypted private keys
+ *
+ * Module: library/pkcs12.c
+ * Caller: library/pkparse.c
+ *
+ * Requires: MBEDCRYPTO_ASN1_PARSE_C, MBEDCRYPTO_CIPHER_C, MBEDCRYPTO_MD_C
+ * Can use: MBEDCRYPTO_ARC4_C
+ *
+ * This module enables PKCS#12 functions.
+ */
+#define MBEDCRYPTO_PKCS12_C
+
+/**
+ * \def MBEDCRYPTO_PLATFORM_C
+ *
+ * Enable the platform abstraction layer that allows you to re-assign
+ * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit().
+ *
+ * Enabling MBEDCRYPTO_PLATFORM_C enables to use of MBEDCRYPTO_PLATFORM_XXX_ALT
+ * or MBEDCRYPTO_PLATFORM_XXX_MACRO directives, allowing the functions mentioned
+ * above to be specified at runtime or compile time respectively.
+ *
+ * \note This abstraction layer must be enabled on Windows (including MSYS2)
+ * as other module rely on it for a fixed snprintf implementation.
+ *
+ * Module: library/platform.c
+ * Caller: Most other .c files
+ *
+ * This module enables abstraction of common (libc) functions.
+ */
+#define MBEDCRYPTO_PLATFORM_C
+
+/**
+ * \def MBEDCRYPTO_PSA_CRYPTO_C
+ *
+ * Enable the Platform Security Architecture cryptography API.
+ *
+ * Module: library/psa_crypto.c
+ *
+ * Requires: MBEDCRYPTO_CTR_DRBG_C, MBEDCRYPTO_ENTROPY_C
+ *
+ */
+#define MBEDCRYPTO_PSA_CRYPTO_C
+
+/**
+ * \def MBEDCRYPTO_RIPEMD160_C
+ *
+ * Enable the RIPEMD-160 hash algorithm.
+ *
+ * Module: library/ripemd160.c
+ * Caller: library/md.c
+ *
+ */
+#define MBEDCRYPTO_RIPEMD160_C
+
+/**
+ * \def MBEDCRYPTO_RSA_C
+ *
+ * Enable the RSA public-key cryptosystem.
+ *
+ * Module: library/rsa.c
+ * library/rsa_internal.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ * library/x509.c
+ *
+ * This module is used by the following key exchanges:
+ * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK
+ *
+ * Requires: MBEDCRYPTO_BIGNUM_C, MBEDCRYPTO_OID_C
+ */
+#define MBEDCRYPTO_RSA_C
+
+/**
+ * \def MBEDCRYPTO_SHA1_C
+ *
+ * Enable the SHA1 cryptographic hash algorithm.
+ *
+ * Module: library/sha1.c
+ * Caller: library/md.c
+ * library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ * library/x509write_crt.c
+ *
+ * This module is required for SSL/TLS up to version 1.1, for TLS 1.2
+ * depending on the handshake parameters, and for SHA1-signed certificates.
+ *
+ * \warning SHA-1 is considered a weak message digest and its use constitutes
+ * a security risk. If possible, we recommend avoiding dependencies
+ * on it, and considering stronger message digests instead.
+ *
+ */
+#define MBEDCRYPTO_SHA1_C
+
+/**
+ * \def MBEDCRYPTO_SHA256_C
+ *
+ * Enable the SHA-224 and SHA-256 cryptographic hash algorithms.
+ *
+ * Module: library/sha256.c
+ * Caller: library/entropy.c
+ * library/md.c
+ * library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ *
+ * This module adds support for SHA-224 and SHA-256.
+ * This module is required for the SSL/TLS 1.2 PRF function.
+ */
+#define MBEDCRYPTO_SHA256_C
+
+/**
+ * \def MBEDCRYPTO_SHA512_C
+ *
+ * Enable the SHA-384 and SHA-512 cryptographic hash algorithms.
+ *
+ * Module: library/sha512.c
+ * Caller: library/entropy.c
+ * library/md.c
+ * library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * This module adds support for SHA-384 and SHA-512.
+ */
+#define MBEDCRYPTO_SHA512_C
+
+/**
+ * \def MBEDCRYPTO_THREADING_C
+ *
+ * Enable the threading abstraction layer.
+ * By default Mbed Crypto assumes it is used in a non-threaded environment or that
+ * contexts are not shared between threads. If you do intend to use contexts
+ * between threads, you will need to enable this layer to prevent race
+ * conditions. See also our Knowledge Base article about threading:
+ * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading
+ *
+ * Module: library/threading.c
+ *
+ * This allows different threading implementations (self-implemented or
+ * provided).
+ *
+ * You will have to enable either MBEDCRYPTO_THREADING_ALT or
+ * MBEDCRYPTO_THREADING_PTHREAD.
+ *
+ * Enable this layer to allow use of mutexes within Mbed Crypto
+ */
+//#define MBEDCRYPTO_THREADING_C
+
+/**
+ * \def MBEDCRYPTO_VERSION_C
+ *
+ * Enable run-time version information.
+ *
+ * Module: library/version.c
+ *
+ * This module provides run-time version information.
+ */
+#define MBEDCRYPTO_VERSION_C
+
+/**
+ * \def MBEDCRYPTO_XTEA_C
+ *
+ * Enable the XTEA block cipher.
+ *
+ * Module: library/xtea.c
+ * Caller:
+ */
+#define MBEDCRYPTO_XTEA_C
+
+/* \} name SECTION: Mbed Crypto modules */
+
+/**
+ * \name SECTION: Module configuration options
+ *
+ * This section allows for the setting of module specific sizes and
+ * configuration options. The default values are already present in the
+ * relevant header files and should suffice for the regular use cases.
+ *
+ * Our advice is to enable options and change their values here
+ * only if you have a good reason and know the consequences.
+ *
+ * Please check the respective header file for documentation on these
+ * parameters (to prevent duplicate documentation).
+ * \{
+ */
+
+/* MPI / BIGNUM options */
+//#define MBEDCRYPTO_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */
+//#define MBEDCRYPTO_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */
+
+/* CTR_DRBG options */
+//#define MBEDCRYPTO_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */
+//#define MBEDCRYPTO_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */
+//#define MBEDCRYPTO_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */
+//#define MBEDCRYPTO_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */
+//#define MBEDCRYPTO_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
+
+/* HMAC_DRBG options */
+//#define MBEDCRYPTO_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */
+//#define MBEDCRYPTO_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */
+//#define MBEDCRYPTO_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */
+//#define MBEDCRYPTO_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
+
+/* ECP options */
+//#define MBEDCRYPTO_ECP_MAX_BITS 521 /**< Maximum bit size of groups */
+//#define MBEDCRYPTO_ECP_WINDOW_SIZE 6 /**< Maximum window size used */
+//#define MBEDCRYPTO_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */
+
+/* Entropy options */
+//#define MBEDCRYPTO_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */
+//#define MBEDCRYPTO_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */
+//#define MBEDCRYPTO_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedcrypto_hardware_poll() before entropy is released */
+
+/* Memory buffer allocator options */
+//#define MBEDCRYPTO_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */
+
+/* Platform options */
+//#define MBEDCRYPTO_PLATFORM_STD_MEM_HDR <stdlib.h> /**< Header to include if MBEDCRYPTO_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */
+//#define MBEDCRYPTO_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */
+//#define MBEDCRYPTO_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */
+//#define MBEDCRYPTO_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */
+//#define MBEDCRYPTO_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDCRYPTO_HAVE_TIME must be enabled */
+//#define MBEDCRYPTO_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */
+//#define MBEDCRYPTO_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */
+/* Note: your snprintf must correclty zero-terminate the buffer! */
+//#define MBEDCRYPTO_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */
+//#define MBEDCRYPTO_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */
+//#define MBEDCRYPTO_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */
+//#define MBEDCRYPTO_PLATFORM_STD_NV_SEED_READ mbedcrypto_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
+//#define MBEDCRYPTO_PLATFORM_STD_NV_SEED_WRITE mbedcrypto_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
+//#define MBEDCRYPTO_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */
+
+/* To Use Function Macros MBEDCRYPTO_PLATFORM_C must be enabled */
+/* MBEDCRYPTO_PLATFORM_XXX_MACRO and MBEDCRYPTO_PLATFORM_XXX_ALT cannot both be defined */
+//#define MBEDCRYPTO_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */
+//#define MBEDCRYPTO_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */
+//#define MBEDCRYPTO_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */
+//#define MBEDCRYPTO_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDCRYPTO_HAVE_TIME must be enabled */
+//#define MBEDCRYPTO_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDCRYPTO_HAVE_TIME must be enabled */
+//#define MBEDCRYPTO_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */
+//#define MBEDCRYPTO_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */
+/* Note: your snprintf must correclty zero-terminate the buffer! */
+//#define MBEDCRYPTO_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */
+//#define MBEDCRYPTO_PLATFORM_NV_SEED_READ_MACRO mbedcrypto_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
+//#define MBEDCRYPTO_PLATFORM_NV_SEED_WRITE_MACRO mbedcrypto_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
+
+/**
+ * Uncomment the macro to let Mbed Crypto use your alternate implementation of
+ * mbedcrypto_platform_zeroize(). This replaces the default implementation in
+ * platform_util.c.
+ *
+ * mbedcrypto_platform_zeroize() is a widely used function across the library to
+ * zero a block of memory. The implementation is expected to be secure in the
+ * sense that it has been written to prevent the compiler from removing calls
+ * to mbedcrypto_platform_zeroize() as part of redundant code elimination
+ * optimizations. However, it is difficult to guarantee that calls to
+ * mbedcrypto_platform_zeroize() will not be optimized by the compiler as older
+ * versions of the C language standards do not provide a secure implementation
+ * of memset(). Therefore, MBEDCRYPTO_PLATFORM_ZEROIZE_ALT enables users to
+ * configure their own implementation of mbedcrypto_platform_zeroize(), for
+ * example by using directives specific to their compiler, features from newer
+ * C standards (e.g using memset_s() in C11) or calling a secure memset() from
+ * their system (e.g explicit_bzero() in BSD).
+ */
+//#define MBEDCRYPTO_PLATFORM_ZEROIZE_ALT
+
+/* \} name SECTION: Customisation configuration options */
+
+#include "mbedcrypto/check_config.h"
+
+#endif /* MBEDCRYPTO_CONFIG_H */
diff --git a/include/mbedcrypto/ctr_drbg.h b/include/mbedcrypto/ctr_drbg.h
new file mode 100644
index 0000000..eca2d9d
--- /dev/null
+++ b/include/mbedcrypto/ctr_drbg.h
@@ -0,0 +1,330 @@
+/**
+ * \file ctr_drbg.h
+ *
+ * \brief This file contains CTR_DRBG definitions and functions.
+ *
+ * CTR_DRBG is a standardized way of building a PRNG from a block-cipher
+ * in counter mode operation, as defined in <em>NIST SP 800-90A:
+ * Recommendation for Random Number Generation Using Deterministic Random
+ * Bit Generators</em>.
+ *
+ * The Mbed Crypto implementation of CTR_DRBG uses AES-256 as the underlying
+ * block cipher.
+ */
+/*
+ * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+#ifndef MBEDCRYPTO_CTR_DRBG_H
+#define MBEDCRYPTO_CTR_DRBG_H
+
+#include "aes.h"
+
+#if defined(MBEDCRYPTO_THREADING_C)
+#include "mbedcrypto/threading.h"
+#endif
+
+#define MBEDCRYPTO_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */
+#define MBEDCRYPTO_ERR_CTR_DRBG_REQUEST_TOO_BIG -0x0036 /**< The requested random buffer length is too big. */
+#define MBEDCRYPTO_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038 /**< The input (entropy + additional data) is too large. */
+#define MBEDCRYPTO_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A /**< Read or write error in file. */
+
+#define MBEDCRYPTO_CTR_DRBG_BLOCKSIZE 16 /**< The block size used by the cipher. */
+#define MBEDCRYPTO_CTR_DRBG_KEYSIZE 32 /**< The key size used by the cipher. */
+#define MBEDCRYPTO_CTR_DRBG_KEYBITS ( MBEDCRYPTO_CTR_DRBG_KEYSIZE * 8 ) /**< The key size for the DRBG operation, in bits. */
+#define MBEDCRYPTO_CTR_DRBG_SEEDLEN ( MBEDCRYPTO_CTR_DRBG_KEYSIZE + MBEDCRYPTO_CTR_DRBG_BLOCKSIZE ) /**< The seed length, calculated as (counter + AES key). */
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h or define them using the compiler command
+ * line.
+ * \{
+ */
+
+#if !defined(MBEDCRYPTO_CTR_DRBG_ENTROPY_LEN)
+#if defined(MBEDCRYPTO_SHA512_C) && !defined(MBEDCRYPTO_ENTROPY_FORCE_SHA256)
+#define MBEDCRYPTO_CTR_DRBG_ENTROPY_LEN 48
+/**< The amount of entropy used per seed by default:
+ * <ul><li>48 with SHA-512.</li>
+ * <li>32 with SHA-256.</li></ul>
+ */
+#else
+#define MBEDCRYPTO_CTR_DRBG_ENTROPY_LEN 32
+/**< Amount of entropy used per seed by default:
+ * <ul><li>48 with SHA-512.</li>
+ * <li>32 with SHA-256.</li></ul>
+ */
+#endif
+#endif
+
+#if !defined(MBEDCRYPTO_CTR_DRBG_RESEED_INTERVAL)
+#define MBEDCRYPTO_CTR_DRBG_RESEED_INTERVAL 10000
+/**< The interval before reseed is performed by default. */
+#endif
+
+#if !defined(MBEDCRYPTO_CTR_DRBG_MAX_INPUT)
+#define MBEDCRYPTO_CTR_DRBG_MAX_INPUT 256
+/**< The maximum number of additional input Bytes. */
+#endif
+
+#if !defined(MBEDCRYPTO_CTR_DRBG_MAX_REQUEST)
+#define MBEDCRYPTO_CTR_DRBG_MAX_REQUEST 1024
+/**< The maximum number of requested Bytes per call. */
+#endif
+
+#if !defined(MBEDCRYPTO_CTR_DRBG_MAX_SEED_INPUT)
+#define MBEDCRYPTO_CTR_DRBG_MAX_SEED_INPUT 384
+/**< The maximum size of seed or reseed buffer. */
+#endif
+
+/* \} name SECTION: Module settings */
+
+#define MBEDCRYPTO_CTR_DRBG_PR_OFF 0
+/**< Prediction resistance is disabled. */
+#define MBEDCRYPTO_CTR_DRBG_PR_ON 1
+/**< Prediction resistance is enabled. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief The CTR_DRBG context structure.
+ */
+typedef struct
+{
+ unsigned char counter[16]; /*!< The counter (V). */
+ int reseed_counter; /*!< The reseed counter. */
+ int prediction_resistance; /*!< This determines whether prediction
+ resistance is enabled, that is
+ whether to systematically reseed before
+ each random generation. */
+ size_t entropy_len; /*!< The amount of entropy grabbed on each
+ seed or reseed operation. */
+ int reseed_interval; /*!< The reseed interval. */
+
+ mbedcrypto_aes_context aes_ctx; /*!< The AES context. */
+
+ /*
+ * Callbacks (Entropy)
+ */
+ int (*f_entropy)(void *, unsigned char *, size_t);
+ /*!< The entropy callback function. */
+
+ void *p_entropy; /*!< The context for the entropy function. */
+
+#if defined(MBEDCRYPTO_THREADING_C)
+ mbedcrypto_threading_mutex_t mutex;
+#endif
+}
+mbedcrypto_ctr_drbg_context;
+
+/**
+ * \brief This function initializes the CTR_DRBG context,
+ * and prepares it for mbedcrypto_ctr_drbg_seed()
+ * or mbedcrypto_ctr_drbg_free().
+ *
+ * \param ctx The CTR_DRBG context to initialize.
+ */
+void mbedcrypto_ctr_drbg_init( mbedcrypto_ctr_drbg_context *ctx );
+
+/**
+ * \brief This function seeds and sets up the CTR_DRBG
+ * entropy source for future reseeds.
+ *
+ * \note Personalization data can be provided in addition to the more generic
+ * entropy source, to make this instantiation as unique as possible.
+ *
+ * \param ctx The CTR_DRBG context to seed.
+ * \param f_entropy The entropy callback, taking as arguments the
+ * \p p_entropy context, the buffer to fill, and the
+ length of the buffer.
+ * \param p_entropy The entropy context.
+ * \param custom Personalization data, that is device-specific
+ identifiers. Can be NULL.
+ * \param len The length of the personalization data.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
+ */
+int mbedcrypto_ctr_drbg_seed( mbedcrypto_ctr_drbg_context *ctx,
+ int (*f_entropy)(void *, unsigned char *, size_t),
+ void *p_entropy,
+ const unsigned char *custom,
+ size_t len );
+
+/**
+ * \brief This function clears CTR_CRBG context data.
+ *
+ * \param ctx The CTR_DRBG context to clear.
+ */
+void mbedcrypto_ctr_drbg_free( mbedcrypto_ctr_drbg_context *ctx );
+
+/**
+ * \brief This function turns prediction resistance on or off.
+ * The default value is off.
+ *
+ * \note If enabled, entropy is gathered at the beginning of
+ * every call to mbedcrypto_ctr_drbg_random_with_add().
+ * Only use this if your entropy source has sufficient
+ * throughput.
+ *
+ * \param ctx The CTR_DRBG context.
+ * \param resistance #MBEDCRYPTO_CTR_DRBG_PR_ON or #MBEDCRYPTO_CTR_DRBG_PR_OFF.
+ */
+void mbedcrypto_ctr_drbg_set_prediction_resistance( mbedcrypto_ctr_drbg_context *ctx,
+ int resistance );
+
+/**
+ * \brief This function sets the amount of entropy grabbed on each
+ * seed or reseed. The default value is
+ * #MBEDCRYPTO_CTR_DRBG_ENTROPY_LEN.
+ *
+ * \param ctx The CTR_DRBG context.
+ * \param len The amount of entropy to grab.
+ */
+void mbedcrypto_ctr_drbg_set_entropy_len( mbedcrypto_ctr_drbg_context *ctx,
+ size_t len );
+
+/**
+ * \brief This function sets the reseed interval.
+ * The default value is #MBEDCRYPTO_CTR_DRBG_RESEED_INTERVAL.
+ *
+ * \param ctx The CTR_DRBG context.
+ * \param interval The reseed interval.
+ */
+void mbedcrypto_ctr_drbg_set_reseed_interval( mbedcrypto_ctr_drbg_context *ctx,
+ int interval );
+
+/**
+ * \brief This function reseeds the CTR_DRBG context, that is
+ * extracts data from the entropy source.
+ *
+ * \param ctx The CTR_DRBG context.
+ * \param additional Additional data to add to the state. Can be NULL.
+ * \param len The length of the additional data.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
+ */
+int mbedcrypto_ctr_drbg_reseed( mbedcrypto_ctr_drbg_context *ctx,
+ const unsigned char *additional, size_t len );
+
+/**
+ * \brief This function updates the state of the CTR_DRBG context.
+ *
+ * \note If \p add_len is greater than
+ * #MBEDCRYPTO_CTR_DRBG_MAX_SEED_INPUT, only the first
+ * #MBEDCRYPTO_CTR_DRBG_MAX_SEED_INPUT Bytes are used.
+ * The remaining Bytes are silently discarded.
+ *
+ * \param ctx The CTR_DRBG context.
+ * \param additional The data to update the state with.
+ * \param add_len Length of \p additional data.
+ *
+ */
+void mbedcrypto_ctr_drbg_update( mbedcrypto_ctr_drbg_context *ctx,
+ const unsigned char *additional, size_t add_len );
+
+/**
+ * \brief This function updates a CTR_DRBG instance with additional
+ * data and uses it to generate random data.
+ *
+ * \note The function automatically reseeds if the reseed counter is exceeded.
+ *
+ * \param p_rng The CTR_DRBG context. This must be a pointer to a
+ * #mbedcrypto_ctr_drbg_context structure.
+ * \param output The buffer to fill.
+ * \param output_len The length of the buffer.
+ * \param additional Additional data to update. Can be NULL.
+ * \param add_len The length of the additional data.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
+ * #MBEDCRYPTO_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
+ */
+int mbedcrypto_ctr_drbg_random_with_add( void *p_rng,
+ unsigned char *output, size_t output_len,
+ const unsigned char *additional, size_t add_len );
+
+/**
+ * \brief This function uses CTR_DRBG to generate random data.
+ *
+ * \note The function automatically reseeds if the reseed counter is exceeded.
+ *
+ * \param p_rng The CTR_DRBG context. This must be a pointer to a
+ * #mbedcrypto_ctr_drbg_context structure.
+ * \param output The buffer to fill.
+ * \param output_len The length of the buffer.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
+ * #MBEDCRYPTO_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
+ */
+int mbedcrypto_ctr_drbg_random( void *p_rng,
+ unsigned char *output, size_t output_len );
+
+#if defined(MBEDCRYPTO_FS_IO)
+/**
+ * \brief This function writes a seed file.
+ *
+ * \param ctx The CTR_DRBG context.
+ * \param path The name of the file.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
+ * \return #MBEDCRYPTO_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on
+ * failure.
+ */
+int mbedcrypto_ctr_drbg_write_seed_file( mbedcrypto_ctr_drbg_context *ctx, const char *path );
+
+/**
+ * \brief This function reads and updates a seed file. The seed
+ * is added to this instance.
+ *
+ * \param ctx The CTR_DRBG context.
+ * \param path The name of the file.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
+ * \return #MBEDCRYPTO_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
+ * #MBEDCRYPTO_ERR_CTR_DRBG_INPUT_TOO_BIG on failure.
+ */
+int mbedcrypto_ctr_drbg_update_seed_file( mbedcrypto_ctr_drbg_context *ctx, const char *path );
+#endif /* MBEDCRYPTO_FS_IO */
+
+/**
+ * \brief The CTR_DRBG checkup routine.
+ *
+ * \return \c 0 on success.
+ * \return \c 1 on failure.
+ */
+int mbedcrypto_ctr_drbg_self_test( int verbose );
+
+/* Internal functions (do not call directly) */
+int mbedcrypto_ctr_drbg_seed_entropy_len( mbedcrypto_ctr_drbg_context *,
+ int (*)(void *, unsigned char *, size_t), void *,
+ const unsigned char *, size_t, size_t );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ctr_drbg.h */
diff --git a/include/mbedcrypto/des.h b/include/mbedcrypto/des.h
new file mode 100644
index 0000000..1eeb760
--- /dev/null
+++ b/include/mbedcrypto/des.h
@@ -0,0 +1,350 @@
+/**
+ * \file des.h
+ *
+ * \brief DES block cipher
+ *
+ * \warning DES is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers
+ * instead.
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ *
+ */
+#ifndef MBEDCRYPTO_DES_H
+#define MBEDCRYPTO_DES_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MBEDCRYPTO_DES_ENCRYPT 1
+#define MBEDCRYPTO_DES_DECRYPT 0
+
+#define MBEDCRYPTO_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */
+#define MBEDCRYPTO_ERR_DES_HW_ACCEL_FAILED -0x0033 /**< DES hardware accelerator failed. */
+
+#define MBEDCRYPTO_DES_KEY_SIZE 8
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDCRYPTO_DES_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief DES context structure
+ *
+ * \warning DES is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers
+ * instead.
+ */
+typedef struct
+{
+ uint32_t sk[32]; /*!< DES subkeys */
+}
+mbedcrypto_des_context;
+
+/**
+ * \brief Triple-DES context structure
+ */
+typedef struct
+{
+ uint32_t sk[96]; /*!< 3DES subkeys */
+}
+mbedcrypto_des3_context;
+
+#else /* MBEDCRYPTO_DES_ALT */
+#include "des_alt.h"
+#endif /* MBEDCRYPTO_DES_ALT */
+
+/**
+ * \brief Initialize DES context
+ *
+ * \param ctx DES context to be initialized
+ *
+ * \warning DES is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers
+ * instead.
+ */
+void mbedcrypto_des_init( mbedcrypto_des_context *ctx );
+
+/**
+ * \brief Clear DES context
+ *
+ * \param ctx DES context to be cleared
+ *
+ * \warning DES is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers
+ * instead.
+ */
+void mbedcrypto_des_free( mbedcrypto_des_context *ctx );
+
+/**
+ * \brief Initialize Triple-DES context
+ *
+ * \param ctx DES3 context to be initialized
+ */
+void mbedcrypto_des3_init( mbedcrypto_des3_context *ctx );
+
+/**
+ * \brief Clear Triple-DES context
+ *
+ * \param ctx DES3 context to be cleared
+ */
+void mbedcrypto_des3_free( mbedcrypto_des3_context *ctx );
+
+/**
+ * \brief Set key parity on the given key to odd.
+ *
+ * DES keys are 56 bits long, but each byte is padded with
+ * a parity bit to allow verification.
+ *
+ * \param key 8-byte secret key
+ *
+ * \warning DES is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers
+ * instead.
+ */
+void mbedcrypto_des_key_set_parity( unsigned char key[MBEDCRYPTO_DES_KEY_SIZE] );
+
+/**
+ * \brief Check that key parity on the given key is odd.
+ *
+ * DES keys are 56 bits long, but each byte is padded with
+ * a parity bit to allow verification.
+ *
+ * \param key 8-byte secret key
+ *
+ * \return 0 is parity was ok, 1 if parity was not correct.
+ *
+ * \warning DES is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers
+ * instead.
+ */
+int mbedcrypto_des_key_check_key_parity( const unsigned char key[MBEDCRYPTO_DES_KEY_SIZE] );
+
+/**
+ * \brief Check that key is not a weak or semi-weak DES key
+ *
+ * \param key 8-byte secret key
+ *
+ * \return 0 if no weak key was found, 1 if a weak key was identified.
+ *
+ * \warning DES is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers
+ * instead.
+ */
+int mbedcrypto_des_key_check_weak( const unsigned char key[MBEDCRYPTO_DES_KEY_SIZE] );
+
+/**
+ * \brief DES key schedule (56-bit, encryption)
+ *
+ * \param ctx DES context to be initialized
+ * \param key 8-byte secret key
+ *
+ * \return 0
+ *
+ * \warning DES is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers
+ * instead.
+ */
+int mbedcrypto_des_setkey_enc( mbedcrypto_des_context *ctx, const unsigned char key[MBEDCRYPTO_DES_KEY_SIZE] );
+
+/**
+ * \brief DES key schedule (56-bit, decryption)
+ *
+ * \param ctx DES context to be initialized
+ * \param key 8-byte secret key
+ *
+ * \return 0
+ *
+ * \warning DES is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers
+ * instead.
+ */
+int mbedcrypto_des_setkey_dec( mbedcrypto_des_context *ctx, const unsigned char key[MBEDCRYPTO_DES_KEY_SIZE] );
+
+/**
+ * \brief Triple-DES key schedule (112-bit, encryption)
+ *
+ * \param ctx 3DES context to be initialized
+ * \param key 16-byte secret key
+ *
+ * \return 0
+ */
+int mbedcrypto_des3_set2key_enc( mbedcrypto_des3_context *ctx,
+ const unsigned char key[MBEDCRYPTO_DES_KEY_SIZE * 2] );
+
+/**
+ * \brief Triple-DES key schedule (112-bit, decryption)
+ *
+ * \param ctx 3DES context to be initialized
+ * \param key 16-byte secret key
+ *
+ * \return 0
+ */
+int mbedcrypto_des3_set2key_dec( mbedcrypto_des3_context *ctx,
+ const unsigned char key[MBEDCRYPTO_DES_KEY_SIZE * 2] );
+
+/**
+ * \brief Triple-DES key schedule (168-bit, encryption)
+ *
+ * \param ctx 3DES context to be initialized
+ * \param key 24-byte secret key
+ *
+ * \return 0
+ */
+int mbedcrypto_des3_set3key_enc( mbedcrypto_des3_context *ctx,
+ const unsigned char key[MBEDCRYPTO_DES_KEY_SIZE * 3] );
+
+/**
+ * \brief Triple-DES key schedule (168-bit, decryption)
+ *
+ * \param ctx 3DES context to be initialized
+ * \param key 24-byte secret key
+ *
+ * \return 0
+ */
+int mbedcrypto_des3_set3key_dec( mbedcrypto_des3_context *ctx,
+ const unsigned char key[MBEDCRYPTO_DES_KEY_SIZE * 3] );
+
+/**
+ * \brief DES-ECB block encryption/decryption
+ *
+ * \param ctx DES context
+ * \param input 64-bit input block
+ * \param output 64-bit output block
+ *
+ * \return 0 if successful
+ *
+ * \warning DES is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers
+ * instead.
+ */
+int mbedcrypto_des_crypt_ecb( mbedcrypto_des_context *ctx,
+ const unsigned char input[8],
+ unsigned char output[8] );
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_CBC)
+/**
+ * \brief DES-CBC buffer encryption/decryption
+ *
+ * \note Upon exit, the content of the IV is updated so that you can
+ * call the function same function again on the following
+ * block(s) of data and get the same result as if it was
+ * encrypted in one call. This allows a "streaming" usage.
+ * If on the other hand you need to retain the contents of the
+ * IV, you should either save it manually or use the cipher
+ * module instead.
+ *
+ * \param ctx DES context
+ * \param mode MBEDCRYPTO_DES_ENCRYPT or MBEDCRYPTO_DES_DECRYPT
+ * \param length length of the input data
+ * \param iv initialization vector (updated after use)
+ * \param input buffer holding the input data
+ * \param output buffer holding the output data
+ *
+ * \warning DES is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers
+ * instead.
+ */
+int mbedcrypto_des_crypt_cbc( mbedcrypto_des_context *ctx,
+ int mode,
+ size_t length,
+ unsigned char iv[8],
+ const unsigned char *input,
+ unsigned char *output );
+#endif /* MBEDCRYPTO_CIPHER_MODE_CBC */
+
+/**
+ * \brief 3DES-ECB block encryption/decryption
+ *
+ * \param ctx 3DES context
+ * \param input 64-bit input block
+ * \param output 64-bit output block
+ *
+ * \return 0 if successful
+ */
+int mbedcrypto_des3_crypt_ecb( mbedcrypto_des3_context *ctx,
+ const unsigned char input[8],
+ unsigned char output[8] );
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_CBC)
+/**
+ * \brief 3DES-CBC buffer encryption/decryption
+ *
+ * \note Upon exit, the content of the IV is updated so that you can
+ * call the function same function again on the following
+ * block(s) of data and get the same result as if it was
+ * encrypted in one call. This allows a "streaming" usage.
+ * If on the other hand you need to retain the contents of the
+ * IV, you should either save it manually or use the cipher
+ * module instead.
+ *
+ * \param ctx 3DES context
+ * \param mode MBEDCRYPTO_DES_ENCRYPT or MBEDCRYPTO_DES_DECRYPT
+ * \param length length of the input data
+ * \param iv initialization vector (updated after use)
+ * \param input buffer holding the input data
+ * \param output buffer holding the output data
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_DES_INVALID_INPUT_LENGTH
+ */
+int mbedcrypto_des3_crypt_cbc( mbedcrypto_des3_context *ctx,
+ int mode,
+ size_t length,
+ unsigned char iv[8],
+ const unsigned char *input,
+ unsigned char *output );
+#endif /* MBEDCRYPTO_CIPHER_MODE_CBC */
+
+/**
+ * \brief Internal function for key expansion.
+ * (Only exposed to allow overriding it,
+ * see MBEDCRYPTO_DES_SETKEY_ALT)
+ *
+ * \param SK Round keys
+ * \param key Base key
+ *
+ * \warning DES is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers
+ * instead.
+ */
+void mbedcrypto_des_setkey( uint32_t SK[32],
+ const unsigned char key[MBEDCRYPTO_DES_KEY_SIZE] );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int mbedcrypto_des_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* des.h */
diff --git a/include/mbedcrypto/ecdsa.h b/include/mbedcrypto/ecdsa.h
new file mode 100644
index 0000000..93084a5
--- /dev/null
+++ b/include/mbedcrypto/ecdsa.h
@@ -0,0 +1,339 @@
+/**
+ * \file ecdsa.h
+ *
+ * \brief This file contains ECDSA definitions and functions.
+ *
+ * The Elliptic Curve Digital Signature Algorithm (ECDSA) is defined in
+ * <em>Standards for Efficient Cryptography Group (SECG):
+ * SEC1 Elliptic Curve Cryptography</em>.
+ * The use of ECDSA for TLS is defined in <em>RFC-4492: Elliptic Curve
+ * Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS)</em>.
+ *
+ */
+/*
+ * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+#ifndef MBEDCRYPTO_ECDSA_H
+#define MBEDCRYPTO_ECDSA_H
+
+#include "ecp.h"
+#include "md.h"
+
+/*
+ * RFC-4492 page 20:
+ *
+ * Ecdsa-Sig-Value ::= SEQUENCE {
+ * r INTEGER,
+ * s INTEGER
+ * }
+ *
+ * Size is at most
+ * 1 (tag) + 1 (len) + 1 (initial 0) + ECP_MAX_BYTES for each of r and s,
+ * twice that + 1 (tag) + 2 (len) for the sequence
+ * (assuming ECP_MAX_BYTES is less than 126 for r and s,
+ * and less than 124 (total len <= 255) for the sequence)
+ */
+#if MBEDCRYPTO_ECP_MAX_BYTES > 124
+#error "MBEDCRYPTO_ECP_MAX_BYTES bigger than expected, please fix MBEDCRYPTO_ECDSA_MAX_LEN"
+#endif
+/** The maximal size of an ECDSA signature in Bytes. */
+#define MBEDCRYPTO_ECDSA_MAX_LEN ( 3 + 2 * ( 3 + MBEDCRYPTO_ECP_MAX_BYTES ) )
+
+/**
+ * \brief The ECDSA context structure.
+ */
+typedef mbedcrypto_ecp_keypair mbedcrypto_ecdsa_context;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief This function computes the ECDSA signature of a
+ * previously-hashed message.
+ *
+ * \note The deterministic version is usually preferred.
+ *
+ * \note If the bitlength of the message hash is larger than the
+ * bitlength of the group order, then the hash is truncated
+ * as defined in <em>Standards for Efficient Cryptography Group
+ * (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ * 4.1.3, step 5.
+ *
+ * \see ecp.h
+ *
+ * \param grp The ECP group.
+ * \param r The first output integer.
+ * \param s The second output integer.
+ * \param d The private signing key.
+ * \param buf The message hash.
+ * \param blen The length of \p buf.
+ * \param f_rng The RNG function.
+ * \param p_rng The RNG context.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_ECP_XXX
+ * or \c MBEDCRYPTO_MPI_XXX error code on failure.
+ */
+int mbedcrypto_ecdsa_sign( mbedcrypto_ecp_group *grp, mbedcrypto_mpi *r, mbedcrypto_mpi *s,
+ const mbedcrypto_mpi *d, const unsigned char *buf, size_t blen,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+
+#if defined(MBEDCRYPTO_ECDSA_DETERMINISTIC)
+/**
+ * \brief This function computes the ECDSA signature of a
+ * previously-hashed message, deterministic version.
+ *
+ * For more information, see <em>RFC-6979: Deterministic
+ * Usage of the Digital Signature Algorithm (DSA) and Elliptic
+ * Curve Digital Signature Algorithm (ECDSA)</em>.
+ *
+ * \note If the bitlength of the message hash is larger than the
+ * bitlength of the group order, then the hash is truncated as
+ * defined in <em>Standards for Efficient Cryptography Group
+ * (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ * 4.1.3, step 5.
+ *
+ * \see ecp.h
+ *
+ * \param grp The ECP group.
+ * \param r The first output integer.
+ * \param s The second output integer.
+ * \param d The private signing key.
+ * \param buf The message hash.
+ * \param blen The length of \p buf.
+ * \param md_alg The MD algorithm used to hash the message.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_ECP_XXX or \c MBEDCRYPTO_MPI_XXX
+ * error code on failure.
+ */
+int mbedcrypto_ecdsa_sign_det( mbedcrypto_ecp_group *grp, mbedcrypto_mpi *r, mbedcrypto_mpi *s,
+ const mbedcrypto_mpi *d, const unsigned char *buf, size_t blen,
+ mbedcrypto_md_type_t md_alg );
+#endif /* MBEDCRYPTO_ECDSA_DETERMINISTIC */
+
+/**
+ * \brief This function verifies the ECDSA signature of a
+ * previously-hashed message.
+ *
+ * \note If the bitlength of the message hash is larger than the
+ * bitlength of the group order, then the hash is truncated as
+ * defined in <em>Standards for Efficient Cryptography Group
+ * (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ * 4.1.4, step 3.
+ *
+ * \see ecp.h
+ *
+ * \param grp The ECP group.
+ * \param buf The message hash.
+ * \param blen The length of \p buf.
+ * \param Q The public key to use for verification.
+ * \param r The first integer of the signature.
+ * \param s The second integer of the signature.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_ECP_BAD_INPUT_DATA if the signature
+ * is invalid.
+ * \return An \c MBEDCRYPTO_ERR_ECP_XXX or \c MBEDCRYPTO_MPI_XXX
+ * error code on failure for any other reason.
+ */
+int mbedcrypto_ecdsa_verify( mbedcrypto_ecp_group *grp,
+ const unsigned char *buf, size_t blen,
+ const mbedcrypto_ecp_point *Q, const mbedcrypto_mpi *r, const mbedcrypto_mpi *s);
+
+/**
+ * \brief This function computes the ECDSA signature and writes it
+ * to a buffer, serialized as defined in <em>RFC-4492:
+ * Elliptic Curve Cryptography (ECC) Cipher Suites for
+ * Transport Layer Security (TLS)</em>.
+ *
+ * \warning It is not thread-safe to use the same context in
+ * multiple threads.
+ *
+ * \note The deterministic version is used if
+ * #MBEDCRYPTO_ECDSA_DETERMINISTIC is defined. For more
+ * information, see <em>RFC-6979: Deterministic Usage
+ * of the Digital Signature Algorithm (DSA) and Elliptic
+ * Curve Digital Signature Algorithm (ECDSA)</em>.
+ *
+ * \note The \p sig buffer must be at least twice as large as the
+ * size of the curve used, plus 9. For example, 73 Bytes if
+ * a 256-bit curve is used. A buffer length of
+ * #MBEDCRYPTO_ECDSA_MAX_LEN is always safe.
+ *
+ * \note If the bitlength of the message hash is larger than the
+ * bitlength of the group order, then the hash is truncated as
+ * defined in <em>Standards for Efficient Cryptography Group
+ * (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ * 4.1.3, step 5.
+ *
+ * \see ecp.h
+ *
+ * \param ctx The ECDSA context.
+ * \param md_alg The message digest that was used to hash the message.
+ * \param hash The message hash.
+ * \param hlen The length of the hash.
+ * \param sig The buffer that holds the signature.
+ * \param slen The length of the signature written.
+ * \param f_rng The RNG function.
+ * \param p_rng The RNG context.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_ECP_XXX, \c MBEDCRYPTO_ERR_MPI_XXX or
+ * \c MBEDCRYPTO_ERR_ASN1_XXX error code on failure.
+ */
+int mbedcrypto_ecdsa_write_signature( mbedcrypto_ecdsa_context *ctx, mbedcrypto_md_type_t md_alg,
+ const unsigned char *hash, size_t hlen,
+ unsigned char *sig, size_t *slen,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
+#if defined(MBEDCRYPTO_ECDSA_DETERMINISTIC)
+#if ! defined(MBEDCRYPTO_DEPRECATED_REMOVED)
+#if defined(MBEDCRYPTO_DEPRECATED_WARNING)
+#define MBEDCRYPTO_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDCRYPTO_DEPRECATED
+#endif
+/**
+ * \brief This function computes an ECDSA signature and writes
+ * it to a buffer, serialized as defined in <em>RFC-4492:
+ * Elliptic Curve Cryptography (ECC) Cipher Suites for
+ * Transport Layer Security (TLS)</em>.
+ *
+ * The deterministic version is defined in <em>RFC-6979:
+ * Deterministic Usage of the Digital Signature Algorithm (DSA)
+ * and Elliptic Curve Digital Signature Algorithm (ECDSA)</em>.
+ *
+ * \warning It is not thread-safe to use the same context in
+ * multiple threads.
+ *
+ * \note The \p sig buffer must be at least twice as large as the
+ * size of the curve used, plus 9. For example, 73 Bytes if a
+ * 256-bit curve is used. A buffer length of
+ * #MBEDCRYPTO_ECDSA_MAX_LEN is always safe.
+ *
+ * \note If the bitlength of the message hash is larger than the
+ * bitlength of the group order, then the hash is truncated as
+ * defined in <em>Standards for Efficient Cryptography Group
+ * (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ * 4.1.3, step 5.
+ *
+ * \see ecp.h
+ *
+ * \deprecated Superseded by mbedcrypto_ecdsa_write_signature() in
+ * Mbed Crypto version 2.0 and later.
+ *
+ * \param ctx The ECDSA context.
+ * \param hash The message hash.
+ * \param hlen The length of the hash.
+ * \param sig The buffer that holds the signature.
+ * \param slen The length of the signature written.
+ * \param md_alg The MD algorithm used to hash the message.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_ECP_XXX, \c MBEDCRYPTO_ERR_MPI_XXX or
+ * \c MBEDCRYPTO_ERR_ASN1_XXX error code on failure.
+ */
+int mbedcrypto_ecdsa_write_signature_det( mbedcrypto_ecdsa_context *ctx,
+ const unsigned char *hash, size_t hlen,
+ unsigned char *sig, size_t *slen,
+ mbedcrypto_md_type_t md_alg ) MBEDCRYPTO_DEPRECATED;
+#undef MBEDCRYPTO_DEPRECATED
+#endif /* MBEDCRYPTO_DEPRECATED_REMOVED */
+#endif /* MBEDCRYPTO_ECDSA_DETERMINISTIC */
+
+/**
+ * \brief This function reads and verifies an ECDSA signature.
+ *
+ * \note If the bitlength of the message hash is larger than the
+ * bitlength of the group order, then the hash is truncated as
+ * defined in <em>Standards for Efficient Cryptography Group
+ * (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ * 4.1.4, step 3.
+ *
+ * \see ecp.h
+ *
+ * \param ctx The ECDSA context.
+ * \param hash The message hash.
+ * \param hlen The size of the hash.
+ * \param sig The signature to read and verify.
+ * \param slen The size of \p sig.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
+ * \return #MBEDCRYPTO_ERR_ECP_SIG_LEN_MISMATCH if there is a valid
+ * signature in \p sig, but its length is less than \p siglen.
+ * \return An \c MBEDCRYPTO_ERR_ECP_XXX or \c MBEDCRYPTO_ERR_MPI_XXX
+ * error code on failure for any other reason.
+ */
+int mbedcrypto_ecdsa_read_signature( mbedcrypto_ecdsa_context *ctx,
+ const unsigned char *hash, size_t hlen,
+ const unsigned char *sig, size_t slen );
+
+/**
+ * \brief This function generates an ECDSA keypair on the given curve.
+ *
+ * \see ecp.h
+ *
+ * \param ctx The ECDSA context to store the keypair in.
+ * \param gid The elliptic curve to use. One of the various
+ * \c MBEDCRYPTO_ECP_DP_XXX macros depending on configuration.
+ * \param f_rng The RNG function.
+ * \param p_rng The RNG context.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_ECP_XXX code on failure.
+ */
+int mbedcrypto_ecdsa_genkey( mbedcrypto_ecdsa_context *ctx, mbedcrypto_ecp_group_id gid,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+
+/**
+ * \brief This function sets an ECDSA context from an EC key pair.
+ *
+ * \see ecp.h
+ *
+ * \param ctx The ECDSA context to set.
+ * \param key The EC key to use.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_ECP_XXX code on failure.
+ */
+int mbedcrypto_ecdsa_from_keypair( mbedcrypto_ecdsa_context *ctx, const mbedcrypto_ecp_keypair *key );
+
+/**
+ * \brief This function initializes an ECDSA context.
+ *
+ * \param ctx The ECDSA context to initialize.
+ */
+void mbedcrypto_ecdsa_init( mbedcrypto_ecdsa_context *ctx );
+
+/**
+ * \brief This function frees an ECDSA context.
+ *
+ * \param ctx The ECDSA context to free.
+ */
+void mbedcrypto_ecdsa_free( mbedcrypto_ecdsa_context *ctx );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ecdsa.h */
diff --git a/include/mbedcrypto/ecp.h b/include/mbedcrypto/ecp.h
new file mode 100644
index 0000000..eb6bf6c
--- /dev/null
+++ b/include/mbedcrypto/ecp.h
@@ -0,0 +1,764 @@
+/**
+ * \file ecp.h
+ *
+ * \brief This file provides an API for Elliptic Curves over GF(P) (ECP).
+ *
+ * The use of ECP in cryptography and TLS is defined in
+ * <em>Standards for Efficient Cryptography Group (SECG): SEC1
+ * Elliptic Curve Cryptography</em> and
+ * <em>RFC-4492: Elliptic Curve Cryptography (ECC) Cipher Suites
+ * for Transport Layer Security (TLS)</em>.
+ *
+ * <em>RFC-2409: The Internet Key Exchange (IKE)</em> defines ECP
+ * group types.
+ *
+ */
+
+/*
+ * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+#ifndef MBEDCRYPTO_ECP_H
+#define MBEDCRYPTO_ECP_H
+
+#include "bignum.h"
+
+/*
+ * ECP error codes
+ */
+#define MBEDCRYPTO_ERR_ECP_BAD_INPUT_DATA -0x4F80 /**< Bad input parameters to function. */
+#define MBEDCRYPTO_ERR_ECP_BUFFER_TOO_SMALL -0x4F00 /**< The buffer is too small to write to. */
+#define MBEDCRYPTO_ERR_ECP_FEATURE_UNAVAILABLE -0x4E80 /**< The requested feature is not available, for example, the requested curve is not supported. */
+#define MBEDCRYPTO_ERR_ECP_VERIFY_FAILED -0x4E00 /**< The signature is not valid. */
+#define MBEDCRYPTO_ERR_ECP_ALLOC_FAILED -0x4D80 /**< Memory allocation failed. */
+#define MBEDCRYPTO_ERR_ECP_RANDOM_FAILED -0x4D00 /**< Generation of random value, such as ephemeral key, failed. */
+#define MBEDCRYPTO_ERR_ECP_INVALID_KEY -0x4C80 /**< Invalid private or public key. */
+#define MBEDCRYPTO_ERR_ECP_SIG_LEN_MISMATCH -0x4C00 /**< The buffer contains a valid signature followed by more data. */
+#define MBEDCRYPTO_ERR_ECP_HW_ACCEL_FAILED -0x4B80 /**< The ECP hardware accelerator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Domain-parameter identifiers: curve, subgroup, and generator.
+ *
+ * \note Only curves over prime fields are supported.
+ *
+ * \warning This library does not support validation of arbitrary domain
+ * parameters. Therefore, only standardized domain parameters from trusted
+ * sources should be used. See mbedcrypto_ecp_group_load().
+ */
+typedef enum
+{
+ MBEDCRYPTO_ECP_DP_NONE = 0, /*!< Curve not defined. */
+ MBEDCRYPTO_ECP_DP_SECP192R1, /*!< Domain parameters for the 192-bit curve defined by FIPS 186-4 and SEC1. */
+ MBEDCRYPTO_ECP_DP_SECP224R1, /*!< Domain parameters for the 224-bit curve defined by FIPS 186-4 and SEC1. */
+ MBEDCRYPTO_ECP_DP_SECP256R1, /*!< Domain parameters for the 256-bit curve defined by FIPS 186-4 and SEC1. */
+ MBEDCRYPTO_ECP_DP_SECP384R1, /*!< Domain parameters for the 384-bit curve defined by FIPS 186-4 and SEC1. */
+ MBEDCRYPTO_ECP_DP_SECP521R1, /*!< Domain parameters for the 521-bit curve defined by FIPS 186-4 and SEC1. */
+ MBEDCRYPTO_ECP_DP_BP256R1, /*!< Domain parameters for 256-bit Brainpool curve. */
+ MBEDCRYPTO_ECP_DP_BP384R1, /*!< Domain parameters for 384-bit Brainpool curve. */
+ MBEDCRYPTO_ECP_DP_BP512R1, /*!< Domain parameters for 512-bit Brainpool curve. */
+ MBEDCRYPTO_ECP_DP_CURVE25519, /*!< Domain parameters for Curve25519. */
+ MBEDCRYPTO_ECP_DP_SECP192K1, /*!< Domain parameters for 192-bit "Koblitz" curve. */
+ MBEDCRYPTO_ECP_DP_SECP224K1, /*!< Domain parameters for 224-bit "Koblitz" curve. */
+ MBEDCRYPTO_ECP_DP_SECP256K1, /*!< Domain parameters for 256-bit "Koblitz" curve. */
+ MBEDCRYPTO_ECP_DP_CURVE448, /*!< Domain parameters for Curve448. */
+} mbedcrypto_ecp_group_id;
+
+/**
+ * The number of supported curves, plus one for #MBEDCRYPTO_ECP_DP_NONE.
+ *
+ * \note Montgomery curves are currently excluded.
+ */
+#define MBEDCRYPTO_ECP_DP_MAX 12
+
+/**
+ * Curve information, for use by other modules.
+ */
+typedef struct
+{
+ mbedcrypto_ecp_group_id grp_id; /*!< An internal identifier. */
+ uint16_t tls_id; /*!< The TLS NamedCurve identifier. */
+ uint16_t bit_size; /*!< The curve size in bits. */
+ const char *name; /*!< A human-friendly name. */
+} mbedcrypto_ecp_curve_info;
+
+/**
+ * \brief The ECP point structure, in Jacobian coordinates.
+ *
+ * \note All functions expect and return points satisfying
+ * the following condition: <code>Z == 0</code> or
+ * <code>Z == 1</code>. Other values of \p Z are
+ * used only by internal functions.
+ * The point is zero, or "at infinity", if <code>Z == 0</code>.
+ * Otherwise, \p X and \p Y are its standard (affine)
+ * coordinates.
+ */
+typedef struct
+{
+ mbedcrypto_mpi X; /*!< The X coordinate of the ECP point. */
+ mbedcrypto_mpi Y; /*!< The Y coordinate of the ECP point. */
+ mbedcrypto_mpi Z; /*!< The Z coordinate of the ECP point. */
+}
+mbedcrypto_ecp_point;
+
+#if !defined(MBEDCRYPTO_ECP_ALT)
+/*
+ * default Mbed Crypto elliptic curve arithmetic implementation
+ *
+ * (in case MBEDCRYPTO_ECP_ALT is defined then the developer has to provide an
+ * alternative implementation for the whole module and it will replace this
+ * one.)
+ */
+
+/**
+ * \brief The ECP group structure.
+ *
+ * We consider two types of curve equations:
+ * <ul><li>Short Weierstrass: <code>y^2 = x^3 + A x + B mod P</code>
+ * (SEC1 + RFC-4492)</li>
+ * <li>Montgomery: <code>y^2 = x^3 + A x^2 + x mod P</code> (Curve25519,
+ * Curve448)</li></ul>
+ * In both cases, the generator (\p G) for a prime-order subgroup is fixed.
+ *
+ * For Short Weierstrass, this subgroup is the whole curve, and its
+ * cardinality is denoted by \p N. Our code requires that \p N is an
+ * odd prime as mbedcrypto_ecp_mul() requires an odd number, and
+ * mbedcrypto_ecdsa_sign() requires that it is prime for blinding purposes.
+ *
+ * For Montgomery curves, we do not store \p A, but <code>(A + 2) / 4</code>,
+ * which is the quantity used in the formulas. Additionally, \p nbits is
+ * not the size of \p N but the required size for private keys.
+ *
+ * If \p modp is NULL, reduction modulo \p P is done using a generic algorithm.
+ * Otherwise, \p modp must point to a function that takes an \p mbedcrypto_mpi in the
+ * range of <code>0..2^(2*pbits)-1</code>, and transforms it in-place to an integer
+ * which is congruent mod \p P to the given MPI, and is close enough to \p pbits
+ * in size, so that it may be efficiently brought in the 0..P-1 range by a few
+ * additions or subtractions. Therefore, it is only an approximative modular
+ * reduction. It must return 0 on success and non-zero on failure.
+ *
+ */
+typedef struct
+{
+ mbedcrypto_ecp_group_id id; /*!< An internal group identifier. */
+ mbedcrypto_mpi P; /*!< The prime modulus of the base field. */
+ mbedcrypto_mpi A; /*!< For Short Weierstrass: \p A in the equation. For
+ Montgomery curves: <code>(A + 2) / 4</code>. */
+ mbedcrypto_mpi B; /*!< For Short Weierstrass: \p B in the equation.
+ For Montgomery curves: unused. */
+ mbedcrypto_ecp_point G; /*!< The generator of the subgroup used. */
+ mbedcrypto_mpi N; /*!< The order of \p G. */
+ size_t pbits; /*!< The number of bits in \p P.*/
+ size_t nbits; /*!< For Short Weierstrass: The number of bits in \p P.
+ For Montgomery curves: the number of bits in the
+ private keys. */
+ unsigned int h; /*!< \internal 1 if the constants are static. */
+ int (*modp)(mbedcrypto_mpi *); /*!< The function for fast pseudo-reduction
+ mod \p P (see above).*/
+ int (*t_pre)(mbedcrypto_ecp_point *, void *); /*!< Unused. */
+ int (*t_post)(mbedcrypto_ecp_point *, void *); /*!< Unused. */
+ void *t_data; /*!< Unused. */
+ mbedcrypto_ecp_point *T; /*!< Pre-computed points for ecp_mul_comb(). */
+ size_t T_size; /*!< The number of pre-computed points. */
+}
+mbedcrypto_ecp_group;
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h, or define them using the compiler command line.
+ * \{
+ */
+
+#if !defined(MBEDCRYPTO_ECP_MAX_BITS)
+/**
+ * The maximum size of the groups, that is, of \c N and \c P.
+ */
+#define MBEDCRYPTO_ECP_MAX_BITS 521 /**< The maximum size of groups, in bits. */
+#endif
+
+#define MBEDCRYPTO_ECP_MAX_BYTES ( ( MBEDCRYPTO_ECP_MAX_BITS + 7 ) / 8 )
+#define MBEDCRYPTO_ECP_MAX_PT_LEN ( 2 * MBEDCRYPTO_ECP_MAX_BYTES + 1 )
+
+#if !defined(MBEDCRYPTO_ECP_WINDOW_SIZE)
+/*
+ * Maximum "window" size used for point multiplication.
+ * Default: 6.
+ * Minimum value: 2. Maximum value: 7.
+ *
+ * Result is an array of at most ( 1 << ( MBEDCRYPTO_ECP_WINDOW_SIZE - 1 ) )
+ * points used for point multiplication. This value is directly tied to EC
+ * peak memory usage, so decreasing it by one should roughly cut memory usage
+ * by two (if large curves are in use).
+ *
+ * Reduction in size may reduce speed, but larger curves are impacted first.
+ * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1):
+ * w-size: 6 5 4 3 2
+ * 521 145 141 135 120 97
+ * 384 214 209 198 177 146
+ * 256 320 320 303 262 226
+ * 224 475 475 453 398 342
+ * 192 640 640 633 587 476
+ */
+#define MBEDCRYPTO_ECP_WINDOW_SIZE 6 /**< The maximum window size used. */
+#endif /* MBEDCRYPTO_ECP_WINDOW_SIZE */
+
+#if !defined(MBEDCRYPTO_ECP_FIXED_POINT_OPTIM)
+/*
+ * Trade memory for speed on fixed-point multiplication.
+ *
+ * This speeds up repeated multiplication of the generator (that is, the
+ * multiplication in ECDSA signatures, and half of the multiplications in
+ * ECDSA verification and ECDHE) by a factor roughly 3 to 4.
+ *
+ * The cost is increasing EC peak memory usage by a factor roughly 2.
+ *
+ * Change this value to 0 to reduce peak memory usage.
+ */
+#define MBEDCRYPTO_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up. */
+#endif /* MBEDCRYPTO_ECP_FIXED_POINT_OPTIM */
+
+/* \} name SECTION: Module settings */
+
+#else /* MBEDCRYPTO_ECP_ALT */
+#include "ecp_alt.h"
+#endif /* MBEDCRYPTO_ECP_ALT */
+
+/**
+ * \brief The ECP key-pair structure.
+ *
+ * A generic key-pair that may be used for ECDSA and fixed ECDH, for example.
+ *
+ * \note Members are deliberately in the same order as in the
+ * ::mbedcrypto_ecdsa_context structure.
+ */
+typedef struct
+{
+ mbedcrypto_ecp_group grp; /*!< Elliptic curve and base point */
+ mbedcrypto_mpi d; /*!< our secret value */
+ mbedcrypto_ecp_point Q; /*!< our public value */
+}
+mbedcrypto_ecp_keypair;
+
+/*
+ * Point formats, from RFC 4492's enum ECPointFormat
+ */
+#define MBEDCRYPTO_ECP_PF_UNCOMPRESSED 0 /**< Uncompressed point format. */
+#define MBEDCRYPTO_ECP_PF_COMPRESSED 1 /**< Compressed point format. */
+
+/*
+ * Some other constants from RFC 4492
+ */
+#define MBEDCRYPTO_ECP_TLS_NAMED_CURVE 3 /**< The named_curve of ECCurveType. */
+
+/**
+ * \brief This function retrieves the information defined in
+ * mbedcrypto_ecp_curve_info() for all supported curves in order
+ * of preference.
+ *
+ * \return A statically allocated array. The last entry is 0.
+ */
+const mbedcrypto_ecp_curve_info *mbedcrypto_ecp_curve_list( void );
+
+/**
+ * \brief This function retrieves the list of internal group
+ * identifiers of all supported curves in the order of
+ * preference.
+ *
+ * \return A statically allocated array,
+ * terminated with MBEDCRYPTO_ECP_DP_NONE.
+ */
+const mbedcrypto_ecp_group_id *mbedcrypto_ecp_grp_id_list( void );
+
+/**
+ * \brief This function retrieves curve information from an internal
+ * group identifier.
+ *
+ * \param grp_id An \c MBEDCRYPTO_ECP_DP_XXX value.
+ *
+ * \return The associated curve information on success.
+ * \return NULL on failure.
+ */
+const mbedcrypto_ecp_curve_info *mbedcrypto_ecp_curve_info_from_grp_id( mbedcrypto_ecp_group_id grp_id );
+
+/**
+ * \brief This function retrieves curve information from a TLS
+ * NamedCurve value.
+ *
+ * \param tls_id An \c MBEDCRYPTO_ECP_DP_XXX value.
+ *
+ * \return The associated curve information on success.
+ * \return NULL on failure.
+ */
+const mbedcrypto_ecp_curve_info *mbedcrypto_ecp_curve_info_from_tls_id( uint16_t tls_id );
+
+/**
+ * \brief This function retrieves curve information from a
+ * human-readable name.
+ *
+ * \param name The human-readable name.
+ *
+ * \return The associated curve information on success.
+ * \return NULL on failure.
+ */
+const mbedcrypto_ecp_curve_info *mbedcrypto_ecp_curve_info_from_name( const char *name );
+
+/**
+ * \brief This function initializes a point as zero.
+ *
+ * \param pt The point to initialize.
+ */
+void mbedcrypto_ecp_point_init( mbedcrypto_ecp_point *pt );
+
+/**
+ * \brief This function initializes an ECP group context
+ * without loading any domain parameters.
+ *
+ * \note After this function is called, domain parameters
+ * for various ECP groups can be loaded through the
+ * mbedcrypto_ecp_load() or mbedcrypto_ecp_tls_read_group()
+ * functions.
+ */
+void mbedcrypto_ecp_group_init( mbedcrypto_ecp_group *grp );
+
+/**
+ * \brief This function initializes a key pair as an invalid one.
+ *
+ * \param key The key pair to initialize.
+ */
+void mbedcrypto_ecp_keypair_init( mbedcrypto_ecp_keypair *key );
+
+/**
+ * \brief This function frees the components of a point.
+ *
+ * \param pt The point to free.
+ */
+void mbedcrypto_ecp_point_free( mbedcrypto_ecp_point *pt );
+
+/**
+ * \brief This function frees the components of an ECP group.
+ * \param grp The group to free.
+ */
+void mbedcrypto_ecp_group_free( mbedcrypto_ecp_group *grp );
+
+/**
+ * \brief This function frees the components of a key pair.
+ * \param key The key pair to free.
+ */
+void mbedcrypto_ecp_keypair_free( mbedcrypto_ecp_keypair *key );
+
+/**
+ * \brief This function copies the contents of point \p Q into
+ * point \p P.
+ *
+ * \param P The destination point.
+ * \param Q The source point.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ */
+int mbedcrypto_ecp_copy( mbedcrypto_ecp_point *P, const mbedcrypto_ecp_point *Q );
+
+/**
+ * \brief This function copies the contents of group \p src into
+ * group \p dst.
+ *
+ * \param dst The destination group.
+ * \param src The source group.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ */
+int mbedcrypto_ecp_group_copy( mbedcrypto_ecp_group *dst, const mbedcrypto_ecp_group *src );
+
+/**
+ * \brief This function sets a point to zero.
+ *
+ * \param pt The point to set.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ */
+int mbedcrypto_ecp_set_zero( mbedcrypto_ecp_point *pt );
+
+/**
+ * \brief This function checks if a point is zero.
+ *
+ * \param pt The point to test.
+ *
+ * \return \c 1 if the point is zero.
+ * \return \c 0 if the point is non-zero.
+ */
+int mbedcrypto_ecp_is_zero( mbedcrypto_ecp_point *pt );
+
+/**
+ * \brief This function compares two points.
+ *
+ * \note This assumes that the points are normalized. Otherwise,
+ * they may compare as "not equal" even if they are.
+ *
+ * \param P The first point to compare.
+ * \param Q The second point to compare.
+ *
+ * \return \c 0 if the points are equal.
+ * \return #MBEDCRYPTO_ERR_ECP_BAD_INPUT_DATA if the points are not equal.
+ */
+int mbedcrypto_ecp_point_cmp( const mbedcrypto_ecp_point *P,
+ const mbedcrypto_ecp_point *Q );
+
+/**
+ * \brief This function imports a non-zero point from two ASCII
+ * strings.
+ *
+ * \param P The destination point.
+ * \param radix The numeric base of the input.
+ * \param x The first affine coordinate, as a null-terminated string.
+ * \param y The second affine coordinate, as a null-terminated string.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_MPI_XXX error code on failure.
+ */
+int mbedcrypto_ecp_point_read_string( mbedcrypto_ecp_point *P, int radix,
+ const char *x, const char *y );
+
+/**
+ * \brief This function exports a point into unsigned binary data.
+ *
+ * \param grp The group to which the point should belong.
+ * \param P The point to export.
+ * \param format The point format. Should be an \c MBEDCRYPTO_ECP_PF_XXX macro.
+ * \param olen The length of the output.
+ * \param buf The output buffer.
+ * \param buflen The length of the output buffer.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_ECP_BAD_INPUT_DATA
+ * or #MBEDCRYPTO_ERR_ECP_BUFFER_TOO_SMALL on failure.
+ */
+int mbedcrypto_ecp_point_write_binary( const mbedcrypto_ecp_group *grp, const mbedcrypto_ecp_point *P,
+ int format, size_t *olen,
+ unsigned char *buf, size_t buflen );
+
+/**
+ * \brief This function imports a point from unsigned binary data.
+ *
+ * \note This function does not check that the point actually
+ * belongs to the given group, see mbedcrypto_ecp_check_pubkey()
+ * for that.
+ *
+ * \param grp The group to which the point should belong.
+ * \param P The point to import.
+ * \param buf The input buffer.
+ * \param ilen The length of the input.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_ECP_BAD_INPUT_DATA if input is invalid.
+ * \return #MBEDCRYPTO_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return #MBEDCRYPTO_ERR_ECP_FEATURE_UNAVAILABLE if the point format
+ * is not implemented.
+ *
+ */
+int mbedcrypto_ecp_point_read_binary( const mbedcrypto_ecp_group *grp, mbedcrypto_ecp_point *P,
+ const unsigned char *buf, size_t ilen );
+
+/**
+ * \brief This function imports a point from a TLS ECPoint record.
+ *
+ * \note On function return, \p buf is updated to point to immediately
+ * after the ECPoint record.
+ *
+ * \param grp The ECP group used.
+ * \param pt The destination point.
+ * \param buf The address of the pointer to the start of the input buffer.
+ * \param len The length of the buffer.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_MPI_XXX error code on initialization failure.
+ * \return #MBEDCRYPTO_ERR_ECP_BAD_INPUT_DATA if input is invalid.
+ */
+int mbedcrypto_ecp_tls_read_point( const mbedcrypto_ecp_group *grp, mbedcrypto_ecp_point *pt,
+ const unsigned char **buf, size_t len );
+
+/**
+ * \brief This function exports a point as a TLS ECPoint record.
+ *
+ * \param grp The ECP group used.
+ * \param pt The point format to export to. The point format is an
+ * \c MBEDCRYPTO_ECP_PF_XXX constant.
+ * \param format The export format.
+ * \param olen The length of the data written.
+ * \param buf The buffer to write to.
+ * \param blen The length of the buffer.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_ECP_BAD_INPUT_DATA or
+ * #MBEDCRYPTO_ERR_ECP_BUFFER_TOO_SMALL on failure.
+ */
+int mbedcrypto_ecp_tls_write_point( const mbedcrypto_ecp_group *grp, const mbedcrypto_ecp_point *pt,
+ int format, size_t *olen,
+ unsigned char *buf, size_t blen );
+
+/**
+ * \brief This function sets a group using standardized domain parameters.
+ *
+ * \note The index should be a value of the NamedCurve enum,
+ * as defined in <em>RFC-4492: Elliptic Curve Cryptography
+ * (ECC) Cipher Suites for Transport Layer Security (TLS)</em>,
+ * usually in the form of an \c MBEDCRYPTO_ECP_DP_XXX macro.
+ *
+ * \param grp The destination group.
+ * \param id The identifier of the domain parameter set to load.
+ *
+ * \return \c 0 on success,
+ * \return An \c MBEDCRYPTO_ERR_MPI_XXX error code on initialization failure.
+ * \return #MBEDCRYPTO_ERR_ECP_FEATURE_UNAVAILABLE for unkownn groups.
+
+ */
+int mbedcrypto_ecp_group_load( mbedcrypto_ecp_group *grp, mbedcrypto_ecp_group_id id );
+
+/**
+ * \brief This function sets a group from a TLS ECParameters record.
+ *
+ * \note \p buf is updated to point right after the ECParameters record
+ * on exit.
+ *
+ * \param grp The destination group.
+ * \param buf The address of the pointer to the start of the input buffer.
+ * \param len The length of the buffer.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_MPI_XXX error code on initialization failure.
+ * \return #MBEDCRYPTO_ERR_ECP_BAD_INPUT_DATA if input is invalid.
+ */
+int mbedcrypto_ecp_tls_read_group( mbedcrypto_ecp_group *grp, const unsigned char **buf, size_t len );
+
+/**
+ * \brief This function writes the TLS ECParameters record for a group.
+ *
+ * \param grp The ECP group used.
+ * \param olen The number of Bytes written.
+ * \param buf The buffer to write to.
+ * \param blen The length of the buffer.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_ECP_BUFFER_TOO_SMALL on failure.
+ */
+int mbedcrypto_ecp_tls_write_group( const mbedcrypto_ecp_group *grp, size_t *olen,
+ unsigned char *buf, size_t blen );
+
+/**
+ * \brief This function performs multiplication of a point by
+ * an integer: \p R = \p m * \p P.
+ *
+ * It is not thread-safe to use same group in multiple threads.
+ *
+ * \note To prevent timing attacks, this function
+ * executes the exact same sequence of base-field
+ * operations for any valid \p m. It avoids any if-branch or
+ * array index depending on the value of \p m.
+ *
+ * \note If \p f_rng is not NULL, it is used to randomize
+ * intermediate results to prevent potential timing attacks
+ * targeting these results. We recommend always providing
+ * a non-NULL \p f_rng. The overhead is negligible.
+ *
+ * \param grp The ECP group.
+ * \param R The destination point.
+ * \param m The integer by which to multiply.
+ * \param P The point to multiply.
+ * \param f_rng The RNG function.
+ * \param p_rng The RNG context.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_ECP_INVALID_KEY if \p m is not a valid private
+ * key, or \p P is not a valid public key.
+ * \return #MBEDCRYPTO_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ */
+int mbedcrypto_ecp_mul( mbedcrypto_ecp_group *grp, mbedcrypto_ecp_point *R,
+ const mbedcrypto_mpi *m, const mbedcrypto_ecp_point *P,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+
+/**
+ * \brief This function performs multiplication and addition of two
+ * points by integers: \p R = \p m * \p P + \p n * \p Q
+ *
+ * It is not thread-safe to use same group in multiple threads.
+ *
+ * \note In contrast to mbedcrypto_ecp_mul(), this function does not
+ * guarantee a constant execution flow and timing.
+ *
+ * \param grp The ECP group.
+ * \param R The destination point.
+ * \param m The integer by which to multiply \p P.
+ * \param P The point to multiply by \p m.
+ * \param n The integer by which to multiply \p Q.
+ * \param Q The point to be multiplied by \p n.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_ECP_INVALID_KEY if \p m or \p n are not
+ * valid private keys, or \p P or \p Q are not valid public
+ * keys.
+ * \return #MBEDCRYPTO_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ */
+int mbedcrypto_ecp_muladd( mbedcrypto_ecp_group *grp, mbedcrypto_ecp_point *R,
+ const mbedcrypto_mpi *m, const mbedcrypto_ecp_point *P,
+ const mbedcrypto_mpi *n, const mbedcrypto_ecp_point *Q );
+
+/**
+ * \brief This function checks that a point is a valid public key
+ * on this curve.
+ *
+ * It only checks that the point is non-zero, has
+ * valid coordinates and lies on the curve. It does not verify
+ * that it is indeed a multiple of \p G. This additional
+ * check is computationally more expensive, is not required
+ * by standards, and should not be necessary if the group
+ * used has a small cofactor. In particular, it is useless for
+ * the NIST groups which all have a cofactor of 1.
+ *
+ * \note This function uses bare components rather than an
+ * ::mbedcrypto_ecp_keypair structure, to ease use with other
+ * structures, such as ::mbedcrypto_ecdh_context or
+ * ::mbedcrypto_ecdsa_context.
+ *
+ * \param grp The curve the point should lie on.
+ * \param pt The point to check.
+ *
+ * \return \c 0 if the point is a valid public key.
+ * \return #MBEDCRYPTO_ERR_ECP_INVALID_KEY on failure.
+ */
+int mbedcrypto_ecp_check_pubkey( const mbedcrypto_ecp_group *grp, const mbedcrypto_ecp_point *pt );
+
+/**
+ * \brief This function checks that an \p mbedcrypto_mpi is a valid private
+ * key for this curve.
+ *
+ * \note This function uses bare components rather than an
+ * ::mbedcrypto_ecp_keypair structure to ease use with other
+ * structures, such as ::mbedcrypto_ecdh_context or
+ * ::mbedcrypto_ecdsa_context.
+ *
+ * \param grp The group used.
+ * \param d The integer to check.
+ *
+ * \return \c 0 if the point is a valid private key.
+ * \return #MBEDCRYPTO_ERR_ECP_INVALID_KEY on failure.
+ */
+int mbedcrypto_ecp_check_privkey( const mbedcrypto_ecp_group *grp, const mbedcrypto_mpi *d );
+
+/**
+ * \brief This function generates a keypair with a configurable base
+ * point.
+ *
+ * \note This function uses bare components rather than an
+ * ::mbedcrypto_ecp_keypair structure to ease use with other
+ * structures, such as ::mbedcrypto_ecdh_context or
+ * ::mbedcrypto_ecdsa_context.
+ *
+ * \param grp The ECP group.
+ * \param G The chosen base point.
+ * \param d The destination MPI (secret part).
+ * \param Q The destination point (public part).
+ * \param f_rng The RNG function.
+ * \param p_rng The RNG context.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_ECP_XXX or \c MBEDCRYPTO_MPI_XXX error code
+ * on failure.
+ */
+int mbedcrypto_ecp_gen_keypair_base( mbedcrypto_ecp_group *grp,
+ const mbedcrypto_ecp_point *G,
+ mbedcrypto_mpi *d, mbedcrypto_ecp_point *Q,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
+/**
+ * \brief This function generates an ECP keypair.
+ *
+ * \note This function uses bare components rather than an
+ * ::mbedcrypto_ecp_keypair structure to ease use with other
+ * structures, such as ::mbedcrypto_ecdh_context or
+ * ::mbedcrypto_ecdsa_context.
+ *
+ * \param grp The ECP group.
+ * \param d The destination MPI (secret part).
+ * \param Q The destination point (public part).
+ * \param f_rng The RNG function.
+ * \param p_rng The RNG context.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_ECP_XXX or \c MBEDCRYPTO_MPI_XXX error code
+ * on failure.
+ */
+int mbedcrypto_ecp_gen_keypair( mbedcrypto_ecp_group *grp, mbedcrypto_mpi *d, mbedcrypto_ecp_point *Q,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
+/**
+ * \brief This function generates an ECP key.
+ *
+ * \param grp_id The ECP group identifier.
+ * \param key The destination key.
+ * \param f_rng The RNG function.
+ * \param p_rng The RNG context.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_ECP_XXX or \c MBEDCRYPTO_MPI_XXX error code
+ * on failure.
+ */
+int mbedcrypto_ecp_gen_key( mbedcrypto_ecp_group_id grp_id, mbedcrypto_ecp_keypair *key,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+
+/**
+ * \brief This function checks that the keypair objects
+ * \p pub and \p prv have the same group and the
+ * same public point, and that the private key in
+ * \p prv is consistent with the public key.
+ *
+ * \param pub The keypair structure holding the public key.
+ * If it contains a private key, that part is ignored.
+ * \param prv The keypair structure holding the full keypair.
+ *
+ * \return \c 0 on success, meaning that the keys are valid and match.
+ * \return #MBEDCRYPTO_ERR_ECP_BAD_INPUT_DATA if the keys are invalid or do not match.
+ * \return An \c MBEDCRYPTO_ERR_ECP_XXX or an \c MBEDCRYPTO_ERR_MPI_XXX
+ * error code on calculation failure.
+ */
+int mbedcrypto_ecp_check_pub_priv( const mbedcrypto_ecp_keypair *pub, const mbedcrypto_ecp_keypair *prv );
+
+#if defined(MBEDCRYPTO_SELF_TEST)
+
+/**
+ * \brief The ECP checkup routine.
+ *
+ * \return \c 0 on success.
+ * \return \c 1 on failure.
+ */
+int mbedcrypto_ecp_self_test( int verbose );
+
+#endif /* MBEDCRYPTO_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ecp.h */
diff --git a/include/mbedcrypto/ecp_internal.h b/include/mbedcrypto/ecp_internal.h
new file mode 100644
index 0000000..98a6bb7
--- /dev/null
+++ b/include/mbedcrypto/ecp_internal.h
@@ -0,0 +1,293 @@
+/**
+ * \file ecp_internal.h
+ *
+ * \brief Function declarations for alternative implementation of elliptic curve
+ * point arithmetic.
+ */
+/*
+ * Copyright (C) 2016, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+/*
+ * References:
+ *
+ * [1] BERNSTEIN, Daniel J. Curve25519: new Diffie-Hellman speed records.
+ * <http://cr.yp.to/ecdh/curve25519-20060209.pdf>
+ *
+ * [2] CORON, Jean-S'ebastien. Resistance against differential power analysis
+ * for elliptic curve cryptosystems. In : Cryptographic Hardware and
+ * Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302.
+ * <http://link.springer.com/chapter/10.1007/3-540-48059-5_25>
+ *
+ * [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to
+ * render ECC resistant against Side Channel Attacks. IACR Cryptology
+ * ePrint Archive, 2004, vol. 2004, p. 342.
+ * <http://eprint.iacr.org/2004/342.pdf>
+ *
+ * [4] Certicom Research. SEC 2: Recommended Elliptic Curve Domain Parameters.
+ * <http://www.secg.org/sec2-v2.pdf>
+ *
+ * [5] HANKERSON, Darrel, MENEZES, Alfred J., VANSTONE, Scott. Guide to Elliptic
+ * Curve Cryptography.
+ *
+ * [6] Digital Signature Standard (DSS), FIPS 186-4.
+ * <http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf>
+ *
+ * [7] Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer
+ * Security (TLS), RFC 4492.
+ * <https://tools.ietf.org/search/rfc4492>
+ *
+ * [8] <http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html>
+ *
+ * [9] COHEN, Henri. A Course in Computational Algebraic Number Theory.
+ * Springer Science & Business Media, 1 Aug 2000
+ */
+
+#ifndef MBEDCRYPTO_ECP_INTERNAL_H
+#define MBEDCRYPTO_ECP_INTERNAL_H
+
+#if defined(MBEDCRYPTO_ECP_INTERNAL_ALT)
+
+/**
+ * \brief Indicate if the Elliptic Curve Point module extension can
+ * handle the group.
+ *
+ * \param grp The pointer to the elliptic curve group that will be the
+ * basis of the cryptographic computations.
+ *
+ * \return Non-zero if successful.
+ */
+unsigned char mbedcrypto_internal_ecp_grp_capable( const mbedcrypto_ecp_group *grp );
+
+/**
+ * \brief Initialise the Elliptic Curve Point module extension.
+ *
+ * If mbedcrypto_internal_ecp_grp_capable returns true for a
+ * group, this function has to be able to initialise the
+ * module for it.
+ *
+ * This module can be a driver to a crypto hardware
+ * accelerator, for which this could be an initialise function.
+ *
+ * \param grp The pointer to the group the module needs to be
+ * initialised for.
+ *
+ * \return 0 if successful.
+ */
+int mbedcrypto_internal_ecp_init( const mbedcrypto_ecp_group *grp );
+
+/**
+ * \brief Frees and deallocates the Elliptic Curve Point module
+ * extension.
+ *
+ * \param grp The pointer to the group the module was initialised for.
+ */
+void mbedcrypto_internal_ecp_free( const mbedcrypto_ecp_group *grp );
+
+#if defined(ECP_SHORTWEIERSTRASS)
+
+#if defined(MBEDCRYPTO_ECP_RANDOMIZE_JAC_ALT)
+/**
+ * \brief Randomize jacobian coordinates:
+ * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l.
+ *
+ * \param grp Pointer to the group representing the curve.
+ *
+ * \param pt The point on the curve to be randomised, given with Jacobian
+ * coordinates.
+ *
+ * \param f_rng A function pointer to the random number generator.
+ *
+ * \param p_rng A pointer to the random number generator state.
+ *
+ * \return 0 if successful.
+ */
+int mbedcrypto_internal_ecp_randomize_jac( const mbedcrypto_ecp_group *grp,
+ mbedcrypto_ecp_point *pt, int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+#endif
+
+#if defined(MBEDCRYPTO_ECP_ADD_MIXED_ALT)
+/**
+ * \brief Addition: R = P + Q, mixed affine-Jacobian coordinates.
+ *
+ * The coordinates of Q must be normalized (= affine),
+ * but those of P don't need to. R is not normalized.
+ *
+ * This function is used only as a subrutine of
+ * ecp_mul_comb().
+ *
+ * Special cases: (1) P or Q is zero, (2) R is zero,
+ * (3) P == Q.
+ * None of these cases can happen as intermediate step in
+ * ecp_mul_comb():
+ * - at each step, P, Q and R are multiples of the base
+ * point, the factor being less than its order, so none of
+ * them is zero;
+ * - Q is an odd multiple of the base point, P an even
+ * multiple, due to the choice of precomputed points in the
+ * modified comb method.
+ * So branches for these cases do not leak secret information.
+ *
+ * We accept Q->Z being unset (saving memory in tables) as
+ * meaning 1.
+ *
+ * Cost in field operations if done by [5] 3.22:
+ * 1A := 8M + 3S
+ *
+ * \param grp Pointer to the group representing the curve.
+ *
+ * \param R Pointer to a point structure to hold the result.
+ *
+ * \param P Pointer to the first summand, given with Jacobian
+ * coordinates
+ *
+ * \param Q Pointer to the second summand, given with affine
+ * coordinates.
+ *
+ * \return 0 if successful.
+ */
+int mbedcrypto_internal_ecp_add_mixed( const mbedcrypto_ecp_group *grp,
+ mbedcrypto_ecp_point *R, const mbedcrypto_ecp_point *P,
+ const mbedcrypto_ecp_point *Q );
+#endif
+
+/**
+ * \brief Point doubling R = 2 P, Jacobian coordinates.
+ *
+ * Cost: 1D := 3M + 4S (A == 0)
+ * 4M + 4S (A == -3)
+ * 3M + 6S + 1a otherwise
+ * when the implementation is based on the "dbl-1998-cmo-2"
+ * doubling formulas in [8] and standard optimizations are
+ * applied when curve parameter A is one of { 0, -3 }.
+ *
+ * \param grp Pointer to the group representing the curve.
+ *
+ * \param R Pointer to a point structure to hold the result.
+ *
+ * \param P Pointer to the point that has to be doubled, given with
+ * Jacobian coordinates.
+ *
+ * \return 0 if successful.
+ */
+#if defined(MBEDCRYPTO_ECP_DOUBLE_JAC_ALT)
+int mbedcrypto_internal_ecp_double_jac( const mbedcrypto_ecp_group *grp,
+ mbedcrypto_ecp_point *R, const mbedcrypto_ecp_point *P );
+#endif
+
+/**
+ * \brief Normalize jacobian coordinates of an array of (pointers to)
+ * points.
+ *
+ * Using Montgomery's trick to perform only one inversion mod P
+ * the cost is:
+ * 1N(t) := 1I + (6t - 3)M + 1S
+ * (See for example Algorithm 10.3.4. in [9])
+ *
+ * This function is used only as a subrutine of
+ * ecp_mul_comb().
+ *
+ * Warning: fails (returning an error) if one of the points is
+ * zero!
+ * This should never happen, see choice of w in ecp_mul_comb().
+ *
+ * \param grp Pointer to the group representing the curve.
+ *
+ * \param T Array of pointers to the points to normalise.
+ *
+ * \param t_len Number of elements in the array.
+ *
+ * \return 0 if successful,
+ * an error if one of the points is zero.
+ */
+#if defined(MBEDCRYPTO_ECP_NORMALIZE_JAC_MANY_ALT)
+int mbedcrypto_internal_ecp_normalize_jac_many( const mbedcrypto_ecp_group *grp,
+ mbedcrypto_ecp_point *T[], size_t t_len );
+#endif
+
+/**
+ * \brief Normalize jacobian coordinates so that Z == 0 || Z == 1.
+ *
+ * Cost in field operations if done by [5] 3.2.1:
+ * 1N := 1I + 3M + 1S
+ *
+ * \param grp Pointer to the group representing the curve.
+ *
+ * \param pt pointer to the point to be normalised. This is an
+ * input/output parameter.
+ *
+ * \return 0 if successful.
+ */
+#if defined(MBEDCRYPTO_ECP_NORMALIZE_JAC_ALT)
+int mbedcrypto_internal_ecp_normalize_jac( const mbedcrypto_ecp_group *grp,
+ mbedcrypto_ecp_point *pt );
+#endif
+
+#endif /* ECP_SHORTWEIERSTRASS */
+
+#if defined(ECP_MONTGOMERY)
+
+#if defined(MBEDCRYPTO_ECP_DOUBLE_ADD_MXZ_ALT)
+int mbedcrypto_internal_ecp_double_add_mxz( const mbedcrypto_ecp_group *grp,
+ mbedcrypto_ecp_point *R, mbedcrypto_ecp_point *S, const mbedcrypto_ecp_point *P,
+ const mbedcrypto_ecp_point *Q, const mbedcrypto_mpi *d );
+#endif
+
+/**
+ * \brief Randomize projective x/z coordinates:
+ * (X, Z) -> (l X, l Z) for random l
+ *
+ * \param grp pointer to the group representing the curve
+ *
+ * \param P the point on the curve to be randomised given with
+ * projective coordinates. This is an input/output parameter.
+ *
+ * \param f_rng a function pointer to the random number generator
+ *
+ * \param p_rng a pointer to the random number generator state
+ *
+ * \return 0 if successful
+ */
+#if defined(MBEDCRYPTO_ECP_RANDOMIZE_MXZ_ALT)
+int mbedcrypto_internal_ecp_randomize_mxz( const mbedcrypto_ecp_group *grp,
+ mbedcrypto_ecp_point *P, int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+#endif
+
+/**
+ * \brief Normalize Montgomery x/z coordinates: X = X/Z, Z = 1.
+ *
+ * \param grp pointer to the group representing the curve
+ *
+ * \param P pointer to the point to be normalised. This is an
+ * input/output parameter.
+ *
+ * \return 0 if successful
+ */
+#if defined(MBEDCRYPTO_ECP_NORMALIZE_MXZ_ALT)
+int mbedcrypto_internal_ecp_normalize_mxz( const mbedcrypto_ecp_group *grp,
+ mbedcrypto_ecp_point *P );
+#endif
+
+#endif /* ECP_MONTGOMERY */
+
+#endif /* MBEDCRYPTO_ECP_INTERNAL_ALT */
+
+#endif /* ecp_internal.h */
+
diff --git a/include/mbedcrypto/entropy.h b/include/mbedcrypto/entropy.h
new file mode 100644
index 0000000..9ba727f
--- /dev/null
+++ b/include/mbedcrypto/entropy.h
@@ -0,0 +1,289 @@
+/**
+ * \file entropy.h
+ *
+ * \brief Entropy accumulator implementation
+ */
+/*
+ * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_ENTROPY_H
+#define MBEDCRYPTO_ENTROPY_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+
+#if defined(MBEDCRYPTO_SHA512_C) && !defined(MBEDCRYPTO_ENTROPY_FORCE_SHA256)
+#include "sha512.h"
+#define MBEDCRYPTO_ENTROPY_SHA512_ACCUMULATOR
+#else
+#if defined(MBEDCRYPTO_SHA256_C)
+#define MBEDCRYPTO_ENTROPY_SHA256_ACCUMULATOR
+#include "sha256.h"
+#endif
+#endif
+
+#if defined(MBEDCRYPTO_THREADING_C)
+#include "threading.h"
+#endif
+
+#if defined(MBEDCRYPTO_HAVEGE_C)
+#include "havege.h"
+#endif
+
+#define MBEDCRYPTO_ERR_ENTROPY_SOURCE_FAILED -0x003C /**< Critical entropy source failure. */
+#define MBEDCRYPTO_ERR_ENTROPY_MAX_SOURCES -0x003E /**< No more sources can be added. */
+#define MBEDCRYPTO_ERR_ENTROPY_NO_SOURCES_DEFINED -0x0040 /**< No sources have been added to poll. */
+#define MBEDCRYPTO_ERR_ENTROPY_NO_STRONG_SOURCE -0x003D /**< No strong sources have been added to poll. */
+#define MBEDCRYPTO_ERR_ENTROPY_FILE_IO_ERROR -0x003F /**< Read/write error in file. */
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h or define them on the compiler command line.
+ * \{
+ */
+
+#if !defined(MBEDCRYPTO_ENTROPY_MAX_SOURCES)
+#define MBEDCRYPTO_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */
+#endif
+
+#if !defined(MBEDCRYPTO_ENTROPY_MAX_GATHER)
+#define MBEDCRYPTO_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */
+#endif
+
+/* \} name SECTION: Module settings */
+
+#if defined(MBEDCRYPTO_ENTROPY_SHA512_ACCUMULATOR)
+#define MBEDCRYPTO_ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */
+#else
+#define MBEDCRYPTO_ENTROPY_BLOCK_SIZE 32 /**< Block size of entropy accumulator (SHA-256) */
+#endif
+
+#define MBEDCRYPTO_ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */
+#define MBEDCRYPTO_ENTROPY_SOURCE_MANUAL MBEDCRYPTO_ENTROPY_MAX_SOURCES
+
+#define MBEDCRYPTO_ENTROPY_SOURCE_STRONG 1 /**< Entropy source is strong */
+#define MBEDCRYPTO_ENTROPY_SOURCE_WEAK 0 /**< Entropy source is weak */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Entropy poll callback pointer
+ *
+ * \param data Callback-specific data pointer
+ * \param output Data to fill
+ * \param len Maximum size to provide
+ * \param olen The actual amount of bytes put into the buffer (Can be 0)
+ *
+ * \return 0 if no critical failures occurred,
+ * MBEDCRYPTO_ERR_ENTROPY_SOURCE_FAILED otherwise
+ */
+typedef int (*mbedcrypto_entropy_f_source_ptr)(void *data, unsigned char *output, size_t len,
+ size_t *olen);
+
+/**
+ * \brief Entropy source state
+ */
+typedef struct
+{
+ mbedcrypto_entropy_f_source_ptr f_source; /**< The entropy source callback */
+ void * p_source; /**< The callback data pointer */
+ size_t size; /**< Amount received in bytes */
+ size_t threshold; /**< Minimum bytes required before release */
+ int strong; /**< Is the source strong? */
+}
+mbedcrypto_entropy_source_state;
+
+/**
+ * \brief Entropy context structure
+ */
+typedef struct
+{
+ int accumulator_started;
+#if defined(MBEDCRYPTO_ENTROPY_SHA512_ACCUMULATOR)
+ mbedcrypto_sha512_context accumulator;
+#else
+ mbedcrypto_sha256_context accumulator;
+#endif
+ int source_count;
+ mbedcrypto_entropy_source_state source[MBEDCRYPTO_ENTROPY_MAX_SOURCES];
+#if defined(MBEDCRYPTO_HAVEGE_C)
+ mbedcrypto_havege_state havege_data;
+#endif
+#if defined(MBEDCRYPTO_THREADING_C)
+ mbedcrypto_threading_mutex_t mutex; /*!< mutex */
+#endif
+#if defined(MBEDCRYPTO_ENTROPY_NV_SEED)
+ int initial_entropy_run;
+#endif
+}
+mbedcrypto_entropy_context;
+
+/**
+ * \brief Initialize the context
+ *
+ * \param ctx Entropy context to initialize
+ */
+void mbedcrypto_entropy_init( mbedcrypto_entropy_context *ctx );
+
+/**
+ * \brief Free the data in the context
+ *
+ * \param ctx Entropy context to free
+ */
+void mbedcrypto_entropy_free( mbedcrypto_entropy_context *ctx );
+
+/**
+ * \brief Adds an entropy source to poll
+ * (Thread-safe if MBEDCRYPTO_THREADING_C is enabled)
+ *
+ * \param ctx Entropy context
+ * \param f_source Entropy function
+ * \param p_source Function data
+ * \param threshold Minimum required from source before entropy is released
+ * ( with mbedcrypto_entropy_func() ) (in bytes)
+ * \param strong MBEDCRYPTO_ENTROPY_SOURCE_STRONG or
+ * MBEDCRYPTO_ENTROPY_SOURCE_WEAK.
+ * At least one strong source needs to be added.
+ * Weaker sources (such as the cycle counter) can be used as
+ * a complement.
+ *
+ * \return 0 if successful or MBEDCRYPTO_ERR_ENTROPY_MAX_SOURCES
+ */
+int mbedcrypto_entropy_add_source( mbedcrypto_entropy_context *ctx,
+ mbedcrypto_entropy_f_source_ptr f_source, void *p_source,
+ size_t threshold, int strong );
+
+/**
+ * \brief Trigger an extra gather poll for the accumulator
+ * (Thread-safe if MBEDCRYPTO_THREADING_C is enabled)
+ *
+ * \param ctx Entropy context
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_ENTROPY_SOURCE_FAILED
+ */
+int mbedcrypto_entropy_gather( mbedcrypto_entropy_context *ctx );
+
+/**
+ * \brief Retrieve entropy from the accumulator
+ * (Maximum length: MBEDCRYPTO_ENTROPY_BLOCK_SIZE)
+ * (Thread-safe if MBEDCRYPTO_THREADING_C is enabled)
+ *
+ * \param data Entropy context
+ * \param output Buffer to fill
+ * \param len Number of bytes desired, must be at most MBEDCRYPTO_ENTROPY_BLOCK_SIZE
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_ENTROPY_SOURCE_FAILED
+ */
+int mbedcrypto_entropy_func( void *data, unsigned char *output, size_t len );
+
+/**
+ * \brief Add data to the accumulator manually
+ * (Thread-safe if MBEDCRYPTO_THREADING_C is enabled)
+ *
+ * \param ctx Entropy context
+ * \param data Data to add
+ * \param len Length of data
+ *
+ * \return 0 if successful
+ */
+int mbedcrypto_entropy_update_manual( mbedcrypto_entropy_context *ctx,
+ const unsigned char *data, size_t len );
+
+#if defined(MBEDCRYPTO_ENTROPY_NV_SEED)
+/**
+ * \brief Trigger an update of the seed file in NV by using the
+ * current entropy pool.
+ *
+ * \param ctx Entropy context
+ *
+ * \return 0 if successful
+ */
+int mbedcrypto_entropy_update_nv_seed( mbedcrypto_entropy_context *ctx );
+#endif /* MBEDCRYPTO_ENTROPY_NV_SEED */
+
+#if defined(MBEDCRYPTO_FS_IO)
+/**
+ * \brief Write a seed file
+ *
+ * \param ctx Entropy context
+ * \param path Name of the file
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_ENTROPY_FILE_IO_ERROR on file error, or
+ * MBEDCRYPTO_ERR_ENTROPY_SOURCE_FAILED
+ */
+int mbedcrypto_entropy_write_seed_file( mbedcrypto_entropy_context *ctx, const char *path );
+
+/**
+ * \brief Read and update a seed file. Seed is added to this
+ * instance. No more than MBEDCRYPTO_ENTROPY_MAX_SEED_SIZE bytes are
+ * read from the seed file. The rest is ignored.
+ *
+ * \param ctx Entropy context
+ * \param path Name of the file
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_ENTROPY_FILE_IO_ERROR on file error,
+ * MBEDCRYPTO_ERR_ENTROPY_SOURCE_FAILED
+ */
+int mbedcrypto_entropy_update_seed_file( mbedcrypto_entropy_context *ctx, const char *path );
+#endif /* MBEDCRYPTO_FS_IO */
+
+#if defined(MBEDCRYPTO_SELF_TEST)
+/**
+ * \brief Checkup routine
+ *
+ * This module self-test also calls the entropy self-test,
+ * mbedcrypto_entropy_source_self_test();
+ *
+ * \return 0 if successful, or 1 if a test failed
+ */
+int mbedcrypto_entropy_self_test( int verbose );
+
+#if defined(MBEDCRYPTO_ENTROPY_HARDWARE_ALT)
+/**
+ * \brief Checkup routine
+ *
+ * Verifies the integrity of the hardware entropy source
+ * provided by the function 'mbedcrypto_hardware_poll()'.
+ *
+ * Note this is the only hardware entropy source that is known
+ * at link time, and other entropy sources configured
+ * dynamically at runtime by the function
+ * mbedcrypto_entropy_add_source() will not be tested.
+ *
+ * \return 0 if successful, or 1 if a test failed
+ */
+int mbedcrypto_entropy_source_self_test( int verbose );
+#endif /* MBEDCRYPTO_ENTROPY_HARDWARE_ALT */
+#endif /* MBEDCRYPTO_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* entropy.h */
diff --git a/include/mbedcrypto/entropy_poll.h b/include/mbedcrypto/entropy_poll.h
new file mode 100644
index 0000000..a044557
--- /dev/null
+++ b/include/mbedcrypto/entropy_poll.h
@@ -0,0 +1,110 @@
+/**
+ * \file entropy_poll.h
+ *
+ * \brief Platform-specific and custom entropy polling functions
+ */
+/*
+ * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_ENTROPY_POLL_H
+#define MBEDCRYPTO_ENTROPY_POLL_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Default thresholds for built-in sources, in bytes
+ */
+#define MBEDCRYPTO_ENTROPY_MIN_PLATFORM 32 /**< Minimum for platform source */
+#define MBEDCRYPTO_ENTROPY_MIN_HAVEGE 32 /**< Minimum for HAVEGE */
+#define MBEDCRYPTO_ENTROPY_MIN_HARDCLOCK 4 /**< Minimum for mbedcrypto_timing_hardclock() */
+#if !defined(MBEDCRYPTO_ENTROPY_MIN_HARDWARE)
+#define MBEDCRYPTO_ENTROPY_MIN_HARDWARE 32 /**< Minimum for the hardware source */
+#endif
+
+/**
+ * \brief Entropy poll callback that provides 0 entropy.
+ */
+#if defined(MBEDCRYPTO_TEST_NULL_ENTROPY)
+ int mbedcrypto_null_entropy_poll( void *data,
+ unsigned char *output, size_t len, size_t *olen );
+#endif
+
+#if !defined(MBEDCRYPTO_NO_PLATFORM_ENTROPY)
+/**
+ * \brief Platform-specific entropy poll callback
+ */
+int mbedcrypto_platform_entropy_poll( void *data,
+ unsigned char *output, size_t len, size_t *olen );
+#endif
+
+#if defined(MBEDCRYPTO_HAVEGE_C)
+/**
+ * \brief HAVEGE based entropy poll callback
+ *
+ * Requires an HAVEGE state as its data pointer.
+ */
+int mbedcrypto_havege_poll( void *data,
+ unsigned char *output, size_t len, size_t *olen );
+#endif
+
+#if defined(MBEDCRYPTO_TIMING_C)
+/**
+ * \brief mbedcrypto_timing_hardclock-based entropy poll callback
+ */
+int mbedcrypto_hardclock_poll( void *data,
+ unsigned char *output, size_t len, size_t *olen );
+#endif
+
+#if defined(MBEDCRYPTO_ENTROPY_HARDWARE_ALT)
+/**
+ * \brief Entropy poll callback for a hardware source
+ *
+ * \warning This is not provided by Mbed Crypto!
+ * See \c MBEDCRYPTO_ENTROPY_HARDWARE_ALT in config.h.
+ *
+ * \note This must accept NULL as its first argument.
+ */
+int mbedcrypto_hardware_poll( void *data,
+ unsigned char *output, size_t len, size_t *olen );
+#endif
+
+#if defined(MBEDCRYPTO_ENTROPY_NV_SEED)
+/**
+ * \brief Entropy poll callback for a non-volatile seed file
+ *
+ * \note This must accept NULL as its first argument.
+ */
+int mbedcrypto_nv_seed_poll( void *data,
+ unsigned char *output, size_t len, size_t *olen );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* entropy_poll.h */
diff --git a/include/mbedcrypto/error.h b/include/mbedcrypto/error.h
new file mode 100644
index 0000000..3c7721f
--- /dev/null
+++ b/include/mbedcrypto/error.h
@@ -0,0 +1,117 @@
+/**
+ * \file error.h
+ *
+ * \brief Error to string translation
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_ERROR_H
+#define MBEDCRYPTO_ERROR_H
+
+#include <stddef.h>
+
+/**
+ * Error code layout.
+ *
+ * Currently we try to keep all error codes within the negative space of 16
+ * bits signed integers to support all platforms (-0x0001 - -0x7FFF). In
+ * addition we'd like to give two layers of information on the error if
+ * possible.
+ *
+ * For that purpose the error codes are segmented in the following manner:
+ *
+ * 16 bit error code bit-segmentation
+ *
+ * 1 bit - Unused (sign bit)
+ * 3 bits - High level module ID
+ * 5 bits - Module-dependent error code
+ * 7 bits - Low level module errors
+ *
+ * For historical reasons, low-level error codes are divided in even and odd,
+ * even codes were assigned first, and -1 is reserved for other errors.
+ *
+ * Low-level module errors (0x0002-0x007E, 0x0003-0x007F)
+ *
+ * Module Nr Codes assigned
+ * MPI 7 0x0002-0x0010
+ * GCM 3 0x0012-0x0014 0x0013-0x0013
+ * BLOWFISH 3 0x0016-0x0018 0x0017-0x0017
+ * THREADING 3 0x001A-0x001E
+ * AES 4 0x0020-0x0022 0x0023-0x0025
+ * CAMELLIA 3 0x0024-0x0026 0x0027-0x0027
+ * XTEA 2 0x0028-0x0028 0x0029-0x0029
+ * BASE64 2 0x002A-0x002C
+ * OID 1 0x002E-0x002E 0x000B-0x000B
+ * PADLOCK 1 0x0030-0x0030
+ * DES 2 0x0032-0x0032 0x0033-0x0033
+ * CTR_DBRG 4 0x0034-0x003A
+ * ENTROPY 3 0x003C-0x0040 0x003D-0x003F
+ * NET 11 0x0042-0x0052 0x0043-0x0045
+ * ASN1 7 0x0060-0x006C
+ * CMAC 1 0x007A-0x007A
+ * PBKDF2 1 0x007C-0x007C
+ * HMAC_DRBG 4 0x0003-0x0009
+ * CCM 3 0x000D-0x0011
+ * ARC4 1 0x0019-0x0019
+ * MD2 1 0x002B-0x002B
+ * MD4 1 0x002D-0x002D
+ * MD5 1 0x002F-0x002F
+ * RIPEMD160 1 0x0031-0x0031
+ * SHA1 1 0x0035-0x0035
+ * SHA256 1 0x0037-0x0037
+ * SHA512 1 0x0039-0x0039
+ *
+ * High-level module nr (3 bits - 0x0...-0x7...)
+ * Name ID Nr of Errors
+ * PEM 1 9
+ * PKCS#12 1 4 (Started from top)
+ * X509 2 20
+ * PKCS5 2 4 (Started from top)
+ * DHM 3 11
+ * PK 3 15 (Started from top)
+ * RSA 4 11
+ * ECP 4 9 (Started from top)
+ * MD 5 5
+ * CIPHER 6 8
+ * SSL 6 17 (Started from top)
+ * SSL 7 31
+ *
+ * Module dependent error code (5 bits 0x.00.-0x.F8.)
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Translate a Mbed Crypto error code into a string representation,
+ * Result is truncated if necessary and always includes a terminating
+ * null byte.
+ *
+ * \param errnum error code
+ * \param buffer buffer to place representation in
+ * \param buflen length of the buffer
+ */
+void mbedcrypto_strerror( int errnum, char *buffer, size_t buflen );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* error.h */
diff --git a/include/mbedcrypto/gcm.h b/include/mbedcrypto/gcm.h
new file mode 100644
index 0000000..373797a
--- /dev/null
+++ b/include/mbedcrypto/gcm.h
@@ -0,0 +1,266 @@
+/**
+ * \file gcm.h
+ *
+ * \brief This file contains GCM definitions and functions.
+ *
+ * The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined
+ * in <em>D. McGrew, J. Viega, The Galois/Counter Mode of Operation
+ * (GCM), Natl. Inst. Stand. Technol.</em>
+ *
+ * For more information on GCM, see <em>NIST SP 800-38D: Recommendation for
+ * Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC</em>.
+ *
+ */
+/*
+ * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+#ifndef MBEDCRYPTO_GCM_H
+#define MBEDCRYPTO_GCM_H
+
+#include "cipher.h"
+
+#include <stdint.h>
+
+#define MBEDCRYPTO_GCM_ENCRYPT 1
+#define MBEDCRYPTO_GCM_DECRYPT 0
+
+#define MBEDCRYPTO_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */
+#define MBEDCRYPTO_ERR_GCM_HW_ACCEL_FAILED -0x0013 /**< GCM hardware accelerator failed. */
+#define MBEDCRYPTO_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDCRYPTO_GCM_ALT)
+
+/**
+ * \brief The GCM context structure.
+ */
+typedef struct {
+ mbedcrypto_cipher_context_t cipher_ctx; /*!< The cipher context used. */
+ uint64_t HL[16]; /*!< Precalculated HTable low. */
+ uint64_t HH[16]; /*!< Precalculated HTable high. */
+ uint64_t len; /*!< The total length of the encrypted data. */
+ uint64_t add_len; /*!< The total length of the additional data. */
+ unsigned char base_ectr[16]; /*!< The first ECTR for tag. */
+ unsigned char y[16]; /*!< The Y working value. */
+ unsigned char buf[16]; /*!< The buf working value. */
+ int mode; /*!< The operation to perform:
+ #MBEDCRYPTO_GCM_ENCRYPT or
+ #MBEDCRYPTO_GCM_DECRYPT. */
+}
+mbedcrypto_gcm_context;
+
+#else /* !MBEDCRYPTO_GCM_ALT */
+#include "gcm_alt.h"
+#endif /* !MBEDCRYPTO_GCM_ALT */
+
+/**
+ * \brief This function initializes the specified GCM context,
+ * to make references valid, and prepares the context
+ * for mbedcrypto_gcm_setkey() or mbedcrypto_gcm_free().
+ *
+ * The function does not bind the GCM context to a particular
+ * cipher, nor set the key. For this purpose, use
+ * mbedcrypto_gcm_setkey().
+ *
+ * \param ctx The GCM context to initialize.
+ */
+void mbedcrypto_gcm_init( mbedcrypto_gcm_context *ctx );
+
+/**
+ * \brief This function associates a GCM context with a
+ * cipher algorithm and a key.
+ *
+ * \param ctx The GCM context to initialize.
+ * \param cipher The 128-bit block cipher to use.
+ * \param key The encryption key.
+ * \param keybits The key size in bits. Valid options are:
+ * <ul><li>128 bits</li>
+ * <li>192 bits</li>
+ * <li>256 bits</li></ul>
+ *
+ * \return \c 0 on success.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedcrypto_gcm_setkey( mbedcrypto_gcm_context *ctx,
+ mbedcrypto_cipher_id_t cipher,
+ const unsigned char *key,
+ unsigned int keybits );
+
+/**
+ * \brief This function performs GCM encryption or decryption of a buffer.
+ *
+ * \note For encryption, the output buffer can be the same as the
+ * input buffer. For decryption, the output buffer cannot be
+ * the same as input buffer. If the buffers overlap, the output
+ * buffer must trail at least 8 Bytes behind the input buffer.
+ *
+ * \param ctx The GCM context to use for encryption or decryption.
+ * \param mode The operation to perform: #MBEDCRYPTO_GCM_ENCRYPT or
+ * #MBEDCRYPTO_GCM_DECRYPT.
+ * \param length The length of the input data. This must be a multiple of
+ * 16 except in the last call before mbedcrypto_gcm_finish().
+ * \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 tag_len The length of the tag to generate.
+ * \param tag The buffer for holding the tag.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_gcm_crypt_and_tag( mbedcrypto_gcm_context *ctx,
+ int mode,
+ size_t length,
+ const unsigned char *iv,
+ size_t iv_len,
+ const unsigned char *add,
+ size_t add_len,
+ const unsigned char *input,
+ unsigned char *output,
+ size_t tag_len,
+ unsigned char *tag );
+
+/**
+ * \brief This function performs a GCM authenticated decryption of a
+ * buffer.
+ *
+ * \note For decryption, the output buffer cannot be the same as
+ * input buffer. If the buffers overlap, the output buffer
+ * must trail at least 8 Bytes behind the input buffer.
+ *
+ * \param ctx The GCM context.
+ * \param length The length of the input data. This must be a multiple
+ * of 16 except in the last call before mbedcrypto_gcm_finish().
+ * \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.
+ *
+ * \return 0 if successful and authenticated.
+ * \return #MBEDCRYPTO_ERR_GCM_AUTH_FAILED if the tag does not match.
+ */
+int mbedcrypto_gcm_auth_decrypt( mbedcrypto_gcm_context *ctx,
+ size_t length,
+ const unsigned char *iv,
+ size_t iv_len,
+ const unsigned char *add,
+ size_t add_len,
+ const unsigned char *tag,
+ size_t tag_len,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief This function starts a GCM encryption or decryption
+ * operation.
+ *
+ * \param ctx The GCM context.
+ * \param mode The operation to perform: #MBEDCRYPTO_GCM_ENCRYPT or
+ * #MBEDCRYPTO_GCM_DECRYPT.
+ * \param iv The initialization vector.
+ * \param iv_len The length of the IV.
+ * \param add The buffer holding the additional data, or NULL
+ * if \p add_len is 0.
+ * \param add_len The length of the additional data. If 0,
+ * \p add is NULL.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_gcm_starts( mbedcrypto_gcm_context *ctx,
+ int mode,
+ const unsigned char *iv,
+ size_t iv_len,
+ const unsigned char *add,
+ size_t add_len );
+
+/**
+ * \brief This function feeds an input buffer into an ongoing GCM
+ * encryption or decryption operation.
+ *
+ * ` The function expects input to be a multiple of 16
+ * Bytes. Only the last call before calling
+ * mbedcrypto_gcm_finish() can be less than 16 Bytes.
+ *
+ * \note For decryption, the output buffer cannot be the same as
+ * input buffer. If the buffers overlap, the output buffer
+ * must trail at least 8 Bytes behind the input buffer.
+ *
+ * \param ctx The GCM context.
+ * \param length The length of the input data. This must be a multiple of
+ * 16 except in the last call before mbedcrypto_gcm_finish().
+ * \param input The buffer holding the input data.
+ * \param output The buffer for holding the output data.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_GCM_BAD_INPUT on failure.
+ */
+int mbedcrypto_gcm_update( mbedcrypto_gcm_context *ctx,
+ size_t length,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief This function finishes the GCM operation and generates
+ * the authentication tag.
+ *
+ * It wraps up the GCM stream, and generates the
+ * tag. The tag can have a maximum length of 16 Bytes.
+ *
+ * \param ctx The GCM context.
+ * \param tag The buffer for holding the tag.
+ * \param tag_len The length of the tag to generate. Must be at least four.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_GCM_BAD_INPUT on failure.
+ */
+int mbedcrypto_gcm_finish( mbedcrypto_gcm_context *ctx,
+ unsigned char *tag,
+ size_t tag_len );
+
+/**
+ * \brief This function clears a GCM context and the underlying
+ * cipher sub-context.
+ *
+ * \param ctx The GCM context to clear.
+ */
+void mbedcrypto_gcm_free( mbedcrypto_gcm_context *ctx );
+
+/**
+ * \brief The GCM checkup routine.
+ *
+ * \return \c 0 on success.
+ * \return \c 1 on failure.
+ */
+int mbedcrypto_gcm_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* gcm.h */
diff --git a/include/mbedcrypto/hmac_drbg.h b/include/mbedcrypto/hmac_drbg.h
new file mode 100644
index 0000000..4e87fcd
--- /dev/null
+++ b/include/mbedcrypto/hmac_drbg.h
@@ -0,0 +1,300 @@
+/**
+ * \file hmac_drbg.h
+ *
+ * \brief HMAC_DRBG (NIST SP 800-90A)
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_HMAC_DRBG_H
+#define MBEDCRYPTO_HMAC_DRBG_H
+
+#include "md.h"
+
+#if defined(MBEDCRYPTO_THREADING_C)
+#include "mbedcrypto/threading.h"
+#endif
+
+/*
+ * Error codes
+ */
+#define MBEDCRYPTO_ERR_HMAC_DRBG_REQUEST_TOO_BIG -0x0003 /**< Too many random requested in single call. */
+#define MBEDCRYPTO_ERR_HMAC_DRBG_INPUT_TOO_BIG -0x0005 /**< Input too large (Entropy + additional). */
+#define MBEDCRYPTO_ERR_HMAC_DRBG_FILE_IO_ERROR -0x0007 /**< Read/write error in file. */
+#define MBEDCRYPTO_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED -0x0009 /**< The entropy source failed. */
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h or define them on the compiler command line.
+ * \{
+ */
+
+#if !defined(MBEDCRYPTO_HMAC_DRBG_RESEED_INTERVAL)
+#define MBEDCRYPTO_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */
+#endif
+
+#if !defined(MBEDCRYPTO_HMAC_DRBG_MAX_INPUT)
+#define MBEDCRYPTO_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */
+#endif
+
+#if !defined(MBEDCRYPTO_HMAC_DRBG_MAX_REQUEST)
+#define MBEDCRYPTO_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */
+#endif
+
+#if !defined(MBEDCRYPTO_HMAC_DRBG_MAX_SEED_INPUT)
+#define MBEDCRYPTO_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
+#endif
+
+/* \} name SECTION: Module settings */
+
+#define MBEDCRYPTO_HMAC_DRBG_PR_OFF 0 /**< No prediction resistance */
+#define MBEDCRYPTO_HMAC_DRBG_PR_ON 1 /**< Prediction resistance enabled */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * HMAC_DRBG context.
+ */
+typedef struct
+{
+ /* Working state: the key K is not stored explicitely,
+ * but is implied by the HMAC context */
+ mbedcrypto_md_context_t md_ctx; /*!< HMAC context (inc. K) */
+ unsigned char V[MBEDCRYPTO_MD_MAX_SIZE]; /*!< V in the spec */
+ int reseed_counter; /*!< reseed counter */
+
+ /* Administrative state */
+ size_t entropy_len; /*!< entropy bytes grabbed on each (re)seed */
+ int prediction_resistance; /*!< enable prediction resistance (Automatic
+ reseed before every random generation) */
+ int reseed_interval; /*!< reseed interval */
+
+ /* Callbacks */
+ int (*f_entropy)(void *, unsigned char *, size_t); /*!< entropy function */
+ void *p_entropy; /*!< context for the entropy function */
+
+#if defined(MBEDCRYPTO_THREADING_C)
+ mbedcrypto_threading_mutex_t mutex;
+#endif
+} mbedcrypto_hmac_drbg_context;
+
+/**
+ * \brief HMAC_DRBG context initialization
+ * Makes the context ready for mbedcrypto_hmac_drbg_seed(),
+ * mbedcrypto_hmac_drbg_seed_buf() or
+ * mbedcrypto_hmac_drbg_free().
+ *
+ * \param ctx HMAC_DRBG context to be initialized
+ */
+void mbedcrypto_hmac_drbg_init( mbedcrypto_hmac_drbg_context *ctx );
+
+/**
+ * \brief HMAC_DRBG initial seeding
+ * Seed and setup entropy source for future reseeds.
+ *
+ * \param ctx HMAC_DRBG context to be seeded
+ * \param md_info MD algorithm to use for HMAC_DRBG
+ * \param f_entropy Entropy callback (p_entropy, buffer to fill, buffer
+ * length)
+ * \param p_entropy Entropy context
+ * \param custom Personalization data (Device specific identifiers)
+ * (Can be NULL)
+ * \param len Length of personalization data
+ *
+ * \note The "security strength" as defined by NIST is set to:
+ * 128 bits if md_alg is SHA-1,
+ * 192 bits if md_alg is SHA-224,
+ * 256 bits if md_alg is SHA-256 or higher.
+ * Note that SHA-256 is just as efficient as SHA-224.
+ *
+ * \return 0 if successful, or
+ * MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA, or
+ * MBEDCRYPTO_ERR_MD_ALLOC_FAILED, or
+ * MBEDCRYPTO_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED.
+ */
+int mbedcrypto_hmac_drbg_seed( mbedcrypto_hmac_drbg_context *ctx,
+ const mbedcrypto_md_info_t * md_info,
+ int (*f_entropy)(void *, unsigned char *, size_t),
+ void *p_entropy,
+ const unsigned char *custom,
+ size_t len );
+
+/**
+ * \brief Initilisation of simpified HMAC_DRBG (never reseeds).
+ * (For use with deterministic ECDSA.)
+ *
+ * \param ctx HMAC_DRBG context to be initialised
+ * \param md_info MD algorithm to use for HMAC_DRBG
+ * \param data Concatenation of entropy string and additional data
+ * \param data_len Length of data in bytes
+ *
+ * \return 0 if successful, or
+ * MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA, or
+ * MBEDCRYPTO_ERR_MD_ALLOC_FAILED.
+ */
+int mbedcrypto_hmac_drbg_seed_buf( mbedcrypto_hmac_drbg_context *ctx,
+ const mbedcrypto_md_info_t * md_info,
+ const unsigned char *data, size_t data_len );
+
+/**
+ * \brief Enable / disable prediction resistance (Default: Off)
+ *
+ * Note: If enabled, entropy is used for ctx->entropy_len before each call!
+ * Only use this if you have ample supply of good entropy!
+ *
+ * \param ctx HMAC_DRBG context
+ * \param resistance MBEDCRYPTO_HMAC_DRBG_PR_ON or MBEDCRYPTO_HMAC_DRBG_PR_OFF
+ */
+void mbedcrypto_hmac_drbg_set_prediction_resistance( mbedcrypto_hmac_drbg_context *ctx,
+ int resistance );
+
+/**
+ * \brief Set the amount of entropy grabbed on each reseed
+ * (Default: given by the security strength, which
+ * depends on the hash used, see \c mbedcrypto_hmac_drbg_init() )
+ *
+ * \param ctx HMAC_DRBG context
+ * \param len Amount of entropy to grab, in bytes
+ */
+void mbedcrypto_hmac_drbg_set_entropy_len( mbedcrypto_hmac_drbg_context *ctx,
+ size_t len );
+
+/**
+ * \brief Set the reseed interval
+ * (Default: MBEDCRYPTO_HMAC_DRBG_RESEED_INTERVAL)
+ *
+ * \param ctx HMAC_DRBG context
+ * \param interval Reseed interval
+ */
+void mbedcrypto_hmac_drbg_set_reseed_interval( mbedcrypto_hmac_drbg_context *ctx,
+ int interval );
+
+/**
+ * \brief HMAC_DRBG update state
+ *
+ * \param ctx HMAC_DRBG context
+ * \param additional Additional data to update state with, or NULL
+ * \param add_len Length of additional data, or 0
+ *
+ * \note Additional data is optional, pass NULL and 0 as second
+ * third argument if no additional data is being used.
+ */
+void mbedcrypto_hmac_drbg_update( mbedcrypto_hmac_drbg_context *ctx,
+ const unsigned char *additional, size_t add_len );
+
+/**
+ * \brief HMAC_DRBG reseeding (extracts data from entropy source)
+ *
+ * \param ctx HMAC_DRBG context
+ * \param additional Additional data to add to state (Can be NULL)
+ * \param len Length of additional data
+ *
+ * \return 0 if successful, or
+ * MBEDCRYPTO_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
+ */
+int mbedcrypto_hmac_drbg_reseed( mbedcrypto_hmac_drbg_context *ctx,
+ const unsigned char *additional, size_t len );
+
+/**
+ * \brief HMAC_DRBG generate random with additional update input
+ *
+ * Note: Automatically reseeds if reseed_counter is reached or PR is enabled.
+ *
+ * \param p_rng HMAC_DRBG context
+ * \param output Buffer to fill
+ * \param output_len Length of the buffer
+ * \param additional Additional data to update with (can be NULL)
+ * \param add_len Length of additional data (can be 0)
+ *
+ * \return 0 if successful, or
+ * MBEDCRYPTO_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or
+ * MBEDCRYPTO_ERR_HMAC_DRBG_REQUEST_TOO_BIG, or
+ * MBEDCRYPTO_ERR_HMAC_DRBG_INPUT_TOO_BIG.
+ */
+int mbedcrypto_hmac_drbg_random_with_add( void *p_rng,
+ unsigned char *output, size_t output_len,
+ const unsigned char *additional,
+ size_t add_len );
+
+/**
+ * \brief HMAC_DRBG generate random
+ *
+ * Note: Automatically reseeds if reseed_counter is reached or PR is enabled.
+ *
+ * \param p_rng HMAC_DRBG context
+ * \param output Buffer to fill
+ * \param out_len Length of the buffer
+ *
+ * \return 0 if successful, or
+ * MBEDCRYPTO_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or
+ * MBEDCRYPTO_ERR_HMAC_DRBG_REQUEST_TOO_BIG
+ */
+int mbedcrypto_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len );
+
+/**
+ * \brief Free an HMAC_DRBG context
+ *
+ * \param ctx HMAC_DRBG context to free.
+ */
+void mbedcrypto_hmac_drbg_free( mbedcrypto_hmac_drbg_context *ctx );
+
+#if defined(MBEDCRYPTO_FS_IO)
+/**
+ * \brief Write a seed file
+ *
+ * \param ctx HMAC_DRBG context
+ * \param path Name of the file
+ *
+ * \return 0 if successful, 1 on file error, or
+ * MBEDCRYPTO_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
+ */
+int mbedcrypto_hmac_drbg_write_seed_file( mbedcrypto_hmac_drbg_context *ctx, const char *path );
+
+/**
+ * \brief Read and update a seed file. Seed is added to this
+ * instance
+ *
+ * \param ctx HMAC_DRBG context
+ * \param path Name of the file
+ *
+ * \return 0 if successful, 1 on file error,
+ * MBEDCRYPTO_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED or
+ * MBEDCRYPTO_ERR_HMAC_DRBG_INPUT_TOO_BIG
+ */
+int mbedcrypto_hmac_drbg_update_seed_file( mbedcrypto_hmac_drbg_context *ctx, const char *path );
+#endif /* MBEDCRYPTO_FS_IO */
+
+
+#if defined(MBEDCRYPTO_SELF_TEST)
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int mbedcrypto_hmac_drbg_self_test( int verbose );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* hmac_drbg.h */
diff --git a/include/mbedcrypto/md.h b/include/mbedcrypto/md.h
new file mode 100644
index 0000000..4098662
--- /dev/null
+++ b/include/mbedcrypto/md.h
@@ -0,0 +1,465 @@
+ /**
+ * \file md.h
+ *
+ * \brief This file contains the generic message-digest wrapper.
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ */
+/*
+ * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+#ifndef MBEDCRYPTO_MD_H
+#define MBEDCRYPTO_MD_H
+
+#include <stddef.h>
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#define MBEDCRYPTO_ERR_MD_FEATURE_UNAVAILABLE -0x5080 /**< The selected feature is not available. */
+#define MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA -0x5100 /**< Bad input parameters to function. */
+#define MBEDCRYPTO_ERR_MD_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */
+#define MBEDCRYPTO_ERR_MD_FILE_IO_ERROR -0x5200 /**< Opening or reading of file failed. */
+#define MBEDCRYPTO_ERR_MD_HW_ACCEL_FAILED -0x5280 /**< MD hardware accelerator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Supported message digests.
+ *
+ * \warning MD2, MD4, MD5 and SHA-1 are considered weak message digests and
+ * their use constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+typedef enum {
+ MBEDCRYPTO_MD_NONE=0, /**< None. */
+ MBEDCRYPTO_MD_MD2, /**< The MD2 message digest. */
+ MBEDCRYPTO_MD_MD4, /**< The MD4 message digest. */
+ MBEDCRYPTO_MD_MD5, /**< The MD5 message digest. */
+ MBEDCRYPTO_MD_SHA1, /**< The SHA-1 message digest. */
+ MBEDCRYPTO_MD_SHA224, /**< The SHA-224 message digest. */
+ MBEDCRYPTO_MD_SHA256, /**< The SHA-256 message digest. */
+ MBEDCRYPTO_MD_SHA384, /**< The SHA-384 message digest. */
+ MBEDCRYPTO_MD_SHA512, /**< The SHA-512 message digest. */
+ MBEDCRYPTO_MD_RIPEMD160, /**< The RIPEMD-160 message digest. */
+} mbedcrypto_md_type_t;
+
+#if defined(MBEDCRYPTO_SHA512_C)
+#define MBEDCRYPTO_MD_MAX_SIZE 64 /* longest known is SHA512 */
+#else
+#define MBEDCRYPTO_MD_MAX_SIZE 32 /* longest known is SHA256 or less */
+#endif
+
+/**
+ * Opaque struct defined in md_internal.h.
+ */
+typedef struct mbedcrypto_md_info_t mbedcrypto_md_info_t;
+
+/**
+ * The generic message-digest context.
+ */
+typedef struct {
+ /** Information about the associated message digest. */
+ const mbedcrypto_md_info_t *md_info;
+
+ /** The digest-specific context. */
+ void *md_ctx;
+
+ /** The HMAC part of the context. */
+ void *hmac_ctx;
+} mbedcrypto_md_context_t;
+
+/**
+ * \brief This function returns the list of digests supported by the
+ * generic digest module.
+ *
+ * \return A statically allocated array of digests. Each element
+ * in the returned list is an integer belonging to the
+ * message-digest enumeration #mbedcrypto_md_type_t.
+ * The last entry is 0.
+ */
+const int *mbedcrypto_md_list( void );
+
+/**
+ * \brief This function returns the message-digest information
+ * associated with the given digest name.
+ *
+ * \param md_name The name of the digest to search for.
+ *
+ * \return The message-digest information associated with \p md_name.
+ * \return NULL if the associated message-digest information is not found.
+ */
+const mbedcrypto_md_info_t *mbedcrypto_md_info_from_string( const char *md_name );
+
+/**
+ * \brief This function returns the message-digest information
+ * associated with the given digest type.
+ *
+ * \param md_type The type of digest to search for.
+ *
+ * \return The message-digest information associated with \p md_type.
+ * \return NULL if the associated message-digest information is not found.
+ */
+const mbedcrypto_md_info_t *mbedcrypto_md_info_from_type( mbedcrypto_md_type_t md_type );
+
+/**
+ * \brief This function initializes a message-digest context without
+ * binding it to a particular message-digest algorithm.
+ *
+ * This function should always be called first. It prepares the
+ * context for mbedcrypto_md_setup() for binding it to a
+ * message-digest algorithm.
+ */
+void mbedcrypto_md_init( mbedcrypto_md_context_t *ctx );
+
+/**
+ * \brief This function clears the internal structure of \p ctx and
+ * frees any embedded internal structure, but does not free
+ * \p ctx itself.
+ *
+ * If you have called mbedcrypto_md_setup() on \p ctx, you must
+ * call mbedcrypto_md_free() when you are no longer using the
+ * context.
+ * Calling this function if you have previously
+ * called mbedcrypto_md_init() and nothing else is optional.
+ * You must not call this function if you have not called
+ * mbedcrypto_md_init().
+ */
+void mbedcrypto_md_free( mbedcrypto_md_context_t *ctx );
+
+#if ! defined(MBEDCRYPTO_DEPRECATED_REMOVED)
+#if defined(MBEDCRYPTO_DEPRECATED_WARNING)
+#define MBEDCRYPTO_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDCRYPTO_DEPRECATED
+#endif
+/**
+ * \brief This function selects the message digest algorithm to use,
+ * and allocates internal structures.
+ *
+ * It should be called after mbedcrypto_md_init() or mbedcrypto_md_free().
+ * Makes it necessary to call mbedcrypto_md_free() later.
+ *
+ * \deprecated Superseded by mbedcrypto_md_setup() in 2.0.0
+ *
+ * \param ctx The context to set up.
+ * \param md_info The information structure of the message-digest algorithm
+ * to use.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ * failure.
+ * \return #MBEDCRYPTO_ERR_MD_ALLOC_FAILED on memory-allocation failure.
+ */
+int mbedcrypto_md_init_ctx( mbedcrypto_md_context_t *ctx, const mbedcrypto_md_info_t *md_info ) MBEDCRYPTO_DEPRECATED;
+#undef MBEDCRYPTO_DEPRECATED
+#endif /* MBEDCRYPTO_DEPRECATED_REMOVED */
+
+/**
+ * \brief This function selects the message digest algorithm to use,
+ * and allocates internal structures.
+ *
+ * It should be called after mbedcrypto_md_init() or
+ * mbedcrypto_md_free(). Makes it necessary to call
+ * mbedcrypto_md_free() later.
+ *
+ * \param ctx The context to set up.
+ * \param md_info The information structure of the message-digest algorithm
+ * to use.
+ * \param hmac Defines if HMAC is used. 0: HMAC is not used (saves some memory),
+ * or non-zero: HMAC is used with this context.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ * failure.
+ * \return #MBEDCRYPTO_ERR_MD_ALLOC_FAILED on memory-allocation failure.
+ */
+int mbedcrypto_md_setup( mbedcrypto_md_context_t *ctx, const mbedcrypto_md_info_t *md_info, int hmac );
+
+/**
+ * \brief This function clones the state of an message-digest
+ * context.
+ *
+ * \note You must call mbedcrypto_md_setup() on \c dst before calling
+ * this function.
+ *
+ * \note The two contexts must have the same type,
+ * for example, both are SHA-256.
+ *
+ * \warning This function clones the message-digest state, not the
+ * HMAC state.
+ *
+ * \param dst The destination context.
+ * \param src The context to be cloned.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA on parameter-verification failure.
+ */
+int mbedcrypto_md_clone( mbedcrypto_md_context_t *dst,
+ const mbedcrypto_md_context_t *src );
+
+/**
+ * \brief This function extracts the message-digest size from the
+ * message-digest information structure.
+ *
+ * \param md_info The information structure of the message-digest algorithm
+ * to use.
+ *
+ * \return The size of the message-digest output in Bytes.
+ */
+unsigned char mbedcrypto_md_get_size( const mbedcrypto_md_info_t *md_info );
+
+/**
+ * \brief This function extracts the message-digest type from the
+ * message-digest information structure.
+ *
+ * \param md_info The information structure of the message-digest algorithm
+ * to use.
+ *
+ * \return The type of the message digest.
+ */
+mbedcrypto_md_type_t mbedcrypto_md_get_type( const mbedcrypto_md_info_t *md_info );
+
+/**
+ * \brief This function extracts the message-digest name from the
+ * message-digest information structure.
+ *
+ * \param md_info The information structure of the message-digest algorithm
+ * to use.
+ *
+ * \return The name of the message digest.
+ */
+const char *mbedcrypto_md_get_name( const mbedcrypto_md_info_t *md_info );
+
+/**
+ * \brief This function starts a message-digest computation.
+ *
+ * You must call this function after setting up the context
+ * with mbedcrypto_md_setup(), and before passing data with
+ * mbedcrypto_md_update().
+ *
+ * \param ctx The generic message-digest context.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ * failure.
+ */
+int mbedcrypto_md_starts( mbedcrypto_md_context_t *ctx );
+
+/**
+ * \brief This function feeds an input buffer into an ongoing
+ * message-digest computation.
+ *
+ * You must call mbedcrypto_md_starts() before calling this
+ * function. You may call this function multiple times.
+ * Afterwards, call mbedcrypto_md_finish().
+ *
+ * \param ctx The generic message-digest context.
+ * \param input The buffer holding the input data.
+ * \param ilen The length of the input data.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ * failure.
+ */
+int mbedcrypto_md_update( mbedcrypto_md_context_t *ctx, const unsigned char *input, size_t ilen );
+
+/**
+ * \brief This function finishes the digest operation,
+ * and writes the result to the output buffer.
+ *
+ * Call this function after a call to mbedcrypto_md_starts(),
+ * followed by any number of calls to mbedcrypto_md_update().
+ * Afterwards, you may either clear the context with
+ * mbedcrypto_md_free(), or call mbedcrypto_md_starts() to reuse
+ * the context for another digest operation with the same
+ * algorithm.
+ *
+ * \param ctx The generic message-digest context.
+ * \param output The buffer for the generic message-digest checksum result.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ * failure.
+ */
+int mbedcrypto_md_finish( mbedcrypto_md_context_t *ctx, unsigned char *output );
+
+/**
+ * \brief This function calculates the message-digest of a buffer,
+ * with respect to a configurable message-digest algorithm
+ * in a single call.
+ *
+ * The result is calculated as
+ * Output = message_digest(input buffer).
+ *
+ * \param md_info The information structure of the message-digest algorithm
+ * to use.
+ * \param input The buffer holding the data.
+ * \param ilen The length of the input data.
+ * \param output The generic message-digest checksum result.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ * failure.
+ */
+int mbedcrypto_md( const mbedcrypto_md_info_t *md_info, const unsigned char *input, size_t ilen,
+ unsigned char *output );
+
+#if defined(MBEDCRYPTO_FS_IO)
+/**
+ * \brief This function calculates the message-digest checksum
+ * result of the contents of the provided file.
+ *
+ * The result is calculated as
+ * Output = message_digest(file contents).
+ *
+ * \param md_info The information structure of the message-digest algorithm
+ * to use.
+ * \param path The input file name.
+ * \param output The generic message-digest checksum result.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MD_FILE_IO_ERROR on an I/O error accessing
+ * the file pointed by \p path.
+ * \return #MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL.
+ */
+int mbedcrypto_md_file( const mbedcrypto_md_info_t *md_info, const char *path,
+ unsigned char *output );
+#endif /* MBEDCRYPTO_FS_IO */
+
+/**
+ * \brief This function sets the HMAC key and prepares to
+ * authenticate a new message.
+ *
+ * Call this function after mbedcrypto_md_setup(), to use
+ * the MD context for an HMAC calculation, then call
+ * mbedcrypto_md_hmac_update() to provide the input data, and
+ * mbedcrypto_md_hmac_finish() to get the HMAC value.
+ *
+ * \param ctx The message digest context containing an embedded HMAC
+ * context.
+ * \param key The HMAC secret key.
+ * \param keylen The length of the HMAC key in Bytes.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ * failure.
+ */
+int mbedcrypto_md_hmac_starts( mbedcrypto_md_context_t *ctx, const unsigned char *key,
+ size_t keylen );
+
+/**
+ * \brief This function feeds an input buffer into an ongoing HMAC
+ * computation.
+ *
+ * Call mbedcrypto_md_hmac_starts() or mbedcrypto_md_hmac_reset()
+ * before calling this function.
+ * You may call this function multiple times to pass the
+ * input piecewise.
+ * Afterwards, call mbedcrypto_md_hmac_finish().
+ *
+ * \param ctx The message digest context containing an embedded HMAC
+ * context.
+ * \param input The buffer holding the input data.
+ * \param ilen The length of the input data.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ * failure.
+ */
+int mbedcrypto_md_hmac_update( mbedcrypto_md_context_t *ctx, const unsigned char *input,
+ size_t ilen );
+
+/**
+ * \brief This function finishes the HMAC operation, and writes
+ * the result to the output buffer.
+ *
+ * Call this function after mbedcrypto_md_hmac_starts() and
+ * mbedcrypto_md_hmac_update() to get the HMAC value. Afterwards
+ * you may either call mbedcrypto_md_free() to clear the context,
+ * or call mbedcrypto_md_hmac_reset() to reuse the context with
+ * the same HMAC key.
+ *
+ * \param ctx The message digest context containing an embedded HMAC
+ * context.
+ * \param output The generic HMAC checksum result.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ * failure.
+ */
+int mbedcrypto_md_hmac_finish( mbedcrypto_md_context_t *ctx, unsigned char *output);
+
+/**
+ * \brief This function prepares to authenticate a new message with
+ * the same key as the previous HMAC operation.
+ *
+ * You may call this function after mbedcrypto_md_hmac_finish().
+ * Afterwards call mbedcrypto_md_hmac_update() to pass the new
+ * input.
+ *
+ * \param ctx The message digest context containing an embedded HMAC
+ * context.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ * failure.
+ */
+int mbedcrypto_md_hmac_reset( mbedcrypto_md_context_t *ctx );
+
+/**
+ * \brief This function calculates the full generic HMAC
+ * on the input buffer with the provided key.
+ *
+ * The function allocates the context, performs the
+ * calculation, and frees the context.
+ *
+ * The HMAC result is calculated as
+ * output = generic HMAC(hmac key, input buffer).
+ *
+ * \param md_info The information structure of the message-digest algorithm
+ * to use.
+ * \param key The HMAC secret key.
+ * \param keylen The length of the HMAC secret key in Bytes.
+ * \param input The buffer holding the input data.
+ * \param ilen The length of the input data.
+ * \param output The generic HMAC result.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ * failure.
+ */
+int mbedcrypto_md_hmac( const mbedcrypto_md_info_t *md_info, const unsigned char *key, size_t keylen,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output );
+
+/* Internal use */
+int mbedcrypto_md_process( mbedcrypto_md_context_t *ctx, const unsigned char *data );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDCRYPTO_MD_H */
diff --git a/include/mbedcrypto/md2.h b/include/mbedcrypto/md2.h
new file mode 100644
index 0000000..dc56387
--- /dev/null
+++ b/include/mbedcrypto/md2.h
@@ -0,0 +1,301 @@
+/**
+ * \file md2.h
+ *
+ * \brief MD2 message digest algorithm (hash function)
+ *
+ * \warning MD2 is considered a weak message digest and its use constitutes a
+ * security risk. We recommend considering stronger message digests
+ * instead.
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ *
+ */
+#ifndef MBEDCRYPTO_MD2_H
+#define MBEDCRYPTO_MD2_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+
+#define MBEDCRYPTO_ERR_MD2_HW_ACCEL_FAILED -0x002B /**< MD2 hardware accelerator failed */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDCRYPTO_MD2_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief MD2 context structure
+ *
+ * \warning MD2 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+typedef struct
+{
+ unsigned char cksum[16]; /*!< checksum of the data block */
+ unsigned char state[48]; /*!< intermediate digest state */
+ unsigned char buffer[16]; /*!< data block being processed */
+ size_t left; /*!< amount of data in buffer */
+}
+mbedcrypto_md2_context;
+
+#else /* MBEDCRYPTO_MD2_ALT */
+#include "md2_alt.h"
+#endif /* MBEDCRYPTO_MD2_ALT */
+
+/**
+ * \brief Initialize MD2 context
+ *
+ * \param ctx MD2 context to be initialized
+ *
+ * \warning MD2 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+void mbedcrypto_md2_init( mbedcrypto_md2_context *ctx );
+
+/**
+ * \brief Clear MD2 context
+ *
+ * \param ctx MD2 context to be cleared
+ *
+ * \warning MD2 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+void mbedcrypto_md2_free( mbedcrypto_md2_context *ctx );
+
+/**
+ * \brief Clone (the state of) an MD2 context
+ *
+ * \param dst The destination context
+ * \param src The context to be cloned
+ *
+ * \warning MD2 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+void mbedcrypto_md2_clone( mbedcrypto_md2_context *dst,
+ const mbedcrypto_md2_context *src );
+
+/**
+ * \brief MD2 context setup
+ *
+ * \param ctx context to be initialized
+ *
+ * \return 0 if successful
+ *
+ * \warning MD2 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+int mbedcrypto_md2_starts_ret( mbedcrypto_md2_context *ctx );
+
+/**
+ * \brief MD2 process buffer
+ *
+ * \param ctx MD2 context
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ *
+ * \return 0 if successful
+ *
+ * \warning MD2 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+int mbedcrypto_md2_update_ret( mbedcrypto_md2_context *ctx,
+ const unsigned char *input,
+ size_t ilen );
+
+/**
+ * \brief MD2 final digest
+ *
+ * \param ctx MD2 context
+ * \param output MD2 checksum result
+ *
+ * \return 0 if successful
+ *
+ * \warning MD2 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+int mbedcrypto_md2_finish_ret( mbedcrypto_md2_context *ctx,
+ unsigned char output[16] );
+
+/**
+ * \brief MD2 process data block (internal use only)
+ *
+ * \param ctx MD2 context
+ *
+ * \return 0 if successful
+ *
+ * \warning MD2 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+int mbedcrypto_internal_md2_process( mbedcrypto_md2_context *ctx );
+
+#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
+#if defined(MBEDCRYPTO_DEPRECATED_WARNING)
+#define MBEDCRYPTO_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDCRYPTO_DEPRECATED
+#endif
+/**
+ * \brief MD2 context setup
+ *
+ * \deprecated Superseded by mbedcrypto_md2_starts_ret() in 2.7.0
+ *
+ * \param ctx context to be initialized
+ *
+ * \warning MD2 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_md2_starts( mbedcrypto_md2_context *ctx );
+
+/**
+ * \brief MD2 process buffer
+ *
+ * \deprecated Superseded by mbedcrypto_md2_update_ret() in 2.7.0
+ *
+ * \param ctx MD2 context
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ *
+ * \warning MD2 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_md2_update( mbedcrypto_md2_context *ctx,
+ const unsigned char *input,
+ size_t ilen );
+
+/**
+ * \brief MD2 final digest
+ *
+ * \deprecated Superseded by mbedcrypto_md2_finish_ret() in 2.7.0
+ *
+ * \param ctx MD2 context
+ * \param output MD2 checksum result
+ *
+ * \warning MD2 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_md2_finish( mbedcrypto_md2_context *ctx,
+ unsigned char output[16] );
+
+/**
+ * \brief MD2 process data block (internal use only)
+ *
+ * \deprecated Superseded by mbedcrypto_internal_md2_process() in 2.7.0
+ *
+ * \param ctx MD2 context
+ *
+ * \warning MD2 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_md2_process( mbedcrypto_md2_context *ctx );
+
+#undef MBEDCRYPTO_DEPRECATED
+#endif /* !MBEDCRYPTO_DEPRECATED_REMOVED */
+
+/**
+ * \brief Output = MD2( input buffer )
+ *
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output MD2 checksum result
+ *
+ * \warning MD2 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+int mbedcrypto_md2_ret( const unsigned char *input,
+ size_t ilen,
+ unsigned char output[16] );
+
+#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
+#if defined(MBEDCRYPTO_DEPRECATED_WARNING)
+#define MBEDCRYPTO_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDCRYPTO_DEPRECATED
+#endif
+/**
+ * \brief Output = MD2( input buffer )
+ *
+ * \deprecated Superseded by mbedcrypto_md2_ret() in 2.7.0
+ *
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output MD2 checksum result
+ *
+ * \warning MD2 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_md2( const unsigned char *input,
+ size_t ilen,
+ unsigned char output[16] );
+
+#undef MBEDCRYPTO_DEPRECATED
+#endif /* !MBEDCRYPTO_DEPRECATED_REMOVED */
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ *
+ * \warning MD2 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+int mbedcrypto_md2_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedcrypto_md2.h */
diff --git a/include/mbedcrypto/md4.h b/include/mbedcrypto/md4.h
new file mode 100644
index 0000000..5b61db3
--- /dev/null
+++ b/include/mbedcrypto/md4.h
@@ -0,0 +1,306 @@
+/**
+ * \file md4.h
+ *
+ * \brief MD4 message digest algorithm (hash function)
+ *
+ * \warning MD4 is considered a weak message digest and its use constitutes a
+ * security risk. We recommend considering stronger message digests
+ * instead.
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ *
+ */
+#ifndef MBEDCRYPTO_MD4_H
+#define MBEDCRYPTO_MD4_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MBEDCRYPTO_ERR_MD4_HW_ACCEL_FAILED -0x002D /**< MD4 hardware accelerator failed */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDCRYPTO_MD4_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief MD4 context structure
+ *
+ * \warning MD4 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+typedef struct
+{
+ uint32_t total[2]; /*!< number of bytes processed */
+ uint32_t state[4]; /*!< intermediate digest state */
+ unsigned char buffer[64]; /*!< data block being processed */
+}
+mbedcrypto_md4_context;
+
+#else /* MBEDCRYPTO_MD4_ALT */
+#include "md4_alt.h"
+#endif /* MBEDCRYPTO_MD4_ALT */
+
+/**
+ * \brief Initialize MD4 context
+ *
+ * \param ctx MD4 context to be initialized
+ *
+ * \warning MD4 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+void mbedcrypto_md4_init( mbedcrypto_md4_context *ctx );
+
+/**
+ * \brief Clear MD4 context
+ *
+ * \param ctx MD4 context to be cleared
+ *
+ * \warning MD4 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+void mbedcrypto_md4_free( mbedcrypto_md4_context *ctx );
+
+/**
+ * \brief Clone (the state of) an MD4 context
+ *
+ * \param dst The destination context
+ * \param src The context to be cloned
+ *
+ * \warning MD4 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+void mbedcrypto_md4_clone( mbedcrypto_md4_context *dst,
+ const mbedcrypto_md4_context *src );
+
+/**
+ * \brief MD4 context setup
+ *
+ * \param ctx context to be initialized
+ *
+ * \return 0 if successful
+ *
+ * \warning MD4 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ */
+int mbedcrypto_md4_starts_ret( mbedcrypto_md4_context *ctx );
+
+/**
+ * \brief MD4 process buffer
+ *
+ * \param ctx MD4 context
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ *
+ * \return 0 if successful
+ *
+ * \warning MD4 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+int mbedcrypto_md4_update_ret( mbedcrypto_md4_context *ctx,
+ const unsigned char *input,
+ size_t ilen );
+
+/**
+ * \brief MD4 final digest
+ *
+ * \param ctx MD4 context
+ * \param output MD4 checksum result
+ *
+ * \return 0 if successful
+ *
+ * \warning MD4 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+int mbedcrypto_md4_finish_ret( mbedcrypto_md4_context *ctx,
+ unsigned char output[16] );
+
+/**
+ * \brief MD4 process data block (internal use only)
+ *
+ * \param ctx MD4 context
+ * \param data buffer holding one block of data
+ *
+ * \return 0 if successful
+ *
+ * \warning MD4 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+int mbedcrypto_internal_md4_process( mbedcrypto_md4_context *ctx,
+ const unsigned char data[64] );
+
+#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
+#if defined(MBEDCRYPTO_DEPRECATED_WARNING)
+#define MBEDCRYPTO_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDCRYPTO_DEPRECATED
+#endif
+/**
+ * \brief MD4 context setup
+ *
+ * \deprecated Superseded by mbedcrypto_md4_starts_ret() in 2.7.0
+ *
+ * \param ctx context to be initialized
+ *
+ * \warning MD4 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_md4_starts( mbedcrypto_md4_context *ctx );
+
+/**
+ * \brief MD4 process buffer
+ *
+ * \deprecated Superseded by mbedcrypto_md4_update_ret() in 2.7.0
+ *
+ * \param ctx MD4 context
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ *
+ * \warning MD4 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_md4_update( mbedcrypto_md4_context *ctx,
+ const unsigned char *input,
+ size_t ilen );
+
+/**
+ * \brief MD4 final digest
+ *
+ * \deprecated Superseded by mbedcrypto_md4_finish_ret() in 2.7.0
+ *
+ * \param ctx MD4 context
+ * \param output MD4 checksum result
+ *
+ * \warning MD4 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_md4_finish( mbedcrypto_md4_context *ctx,
+ unsigned char output[16] );
+
+/**
+ * \brief MD4 process data block (internal use only)
+ *
+ * \deprecated Superseded by mbedcrypto_internal_md4_process() in 2.7.0
+ *
+ * \param ctx MD4 context
+ * \param data buffer holding one block of data
+ *
+ * \warning MD4 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_md4_process( mbedcrypto_md4_context *ctx,
+ const unsigned char data[64] );
+
+#undef MBEDCRYPTO_DEPRECATED
+#endif /* !MBEDCRYPTO_DEPRECATED_REMOVED */
+
+/**
+ * \brief Output = MD4( input buffer )
+ *
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output MD4 checksum result
+ *
+ * \return 0 if successful
+ *
+ * \warning MD4 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+int mbedcrypto_md4_ret( const unsigned char *input,
+ size_t ilen,
+ unsigned char output[16] );
+
+#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
+#if defined(MBEDCRYPTO_DEPRECATED_WARNING)
+#define MBEDCRYPTO_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDCRYPTO_DEPRECATED
+#endif
+/**
+ * \brief Output = MD4( input buffer )
+ *
+ * \deprecated Superseded by mbedcrypto_md4_ret() in 2.7.0
+ *
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output MD4 checksum result
+ *
+ * \warning MD4 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_md4( const unsigned char *input,
+ size_t ilen,
+ unsigned char output[16] );
+
+#undef MBEDCRYPTO_DEPRECATED
+#endif /* !MBEDCRYPTO_DEPRECATED_REMOVED */
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ *
+ * \warning MD4 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+int mbedcrypto_md4_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedcrypto_md4.h */
diff --git a/include/mbedcrypto/md5.h b/include/mbedcrypto/md5.h
new file mode 100644
index 0000000..8d24581
--- /dev/null
+++ b/include/mbedcrypto/md5.h
@@ -0,0 +1,306 @@
+/**
+ * \file md5.h
+ *
+ * \brief MD5 message digest algorithm (hash function)
+ *
+ * \warning MD5 is considered a weak message digest and its use constitutes a
+ * security risk. We recommend considering stronger message
+ * digests instead.
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_MD5_H
+#define MBEDCRYPTO_MD5_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MBEDCRYPTO_ERR_MD5_HW_ACCEL_FAILED -0x002F /**< MD5 hardware accelerator failed */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDCRYPTO_MD5_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief MD5 context structure
+ *
+ * \warning MD5 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+typedef struct
+{
+ uint32_t total[2]; /*!< number of bytes processed */
+ uint32_t state[4]; /*!< intermediate digest state */
+ unsigned char buffer[64]; /*!< data block being processed */
+}
+mbedcrypto_md5_context;
+
+#else /* MBEDCRYPTO_MD5_ALT */
+#include "md5_alt.h"
+#endif /* MBEDCRYPTO_MD5_ALT */
+
+/**
+ * \brief Initialize MD5 context
+ *
+ * \param ctx MD5 context to be initialized
+ *
+ * \warning MD5 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+void mbedcrypto_md5_init( mbedcrypto_md5_context *ctx );
+
+/**
+ * \brief Clear MD5 context
+ *
+ * \param ctx MD5 context to be cleared
+ *
+ * \warning MD5 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+void mbedcrypto_md5_free( mbedcrypto_md5_context *ctx );
+
+/**
+ * \brief Clone (the state of) an MD5 context
+ *
+ * \param dst The destination context
+ * \param src The context to be cloned
+ *
+ * \warning MD5 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+void mbedcrypto_md5_clone( mbedcrypto_md5_context *dst,
+ const mbedcrypto_md5_context *src );
+
+/**
+ * \brief MD5 context setup
+ *
+ * \param ctx context to be initialized
+ *
+ * \return 0 if successful
+ *
+ * \warning MD5 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+int mbedcrypto_md5_starts_ret( mbedcrypto_md5_context *ctx );
+
+/**
+ * \brief MD5 process buffer
+ *
+ * \param ctx MD5 context
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ *
+ * \return 0 if successful
+ *
+ * \warning MD5 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+int mbedcrypto_md5_update_ret( mbedcrypto_md5_context *ctx,
+ const unsigned char *input,
+ size_t ilen );
+
+/**
+ * \brief MD5 final digest
+ *
+ * \param ctx MD5 context
+ * \param output MD5 checksum result
+ *
+ * \return 0 if successful
+ *
+ * \warning MD5 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+int mbedcrypto_md5_finish_ret( mbedcrypto_md5_context *ctx,
+ unsigned char output[16] );
+
+/**
+ * \brief MD5 process data block (internal use only)
+ *
+ * \param ctx MD5 context
+ * \param data buffer holding one block of data
+ *
+ * \return 0 if successful
+ *
+ * \warning MD5 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+int mbedcrypto_internal_md5_process( mbedcrypto_md5_context *ctx,
+ const unsigned char data[64] );
+
+#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
+#if defined(MBEDCRYPTO_DEPRECATED_WARNING)
+#define MBEDCRYPTO_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDCRYPTO_DEPRECATED
+#endif
+/**
+ * \brief MD5 context setup
+ *
+ * \deprecated Superseded by mbedcrypto_md5_starts_ret() in 2.7.0
+ *
+ * \param ctx context to be initialized
+ *
+ * \warning MD5 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_md5_starts( mbedcrypto_md5_context *ctx );
+
+/**
+ * \brief MD5 process buffer
+ *
+ * \deprecated Superseded by mbedcrypto_md5_update_ret() in 2.7.0
+ *
+ * \param ctx MD5 context
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ *
+ * \warning MD5 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_md5_update( mbedcrypto_md5_context *ctx,
+ const unsigned char *input,
+ size_t ilen );
+
+/**
+ * \brief MD5 final digest
+ *
+ * \deprecated Superseded by mbedcrypto_md5_finish_ret() in 2.7.0
+ *
+ * \param ctx MD5 context
+ * \param output MD5 checksum result
+ *
+ * \warning MD5 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_md5_finish( mbedcrypto_md5_context *ctx,
+ unsigned char output[16] );
+
+/**
+ * \brief MD5 process data block (internal use only)
+ *
+ * \deprecated Superseded by mbedcrypto_internal_md5_process() in 2.7.0
+ *
+ * \param ctx MD5 context
+ * \param data buffer holding one block of data
+ *
+ * \warning MD5 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_md5_process( mbedcrypto_md5_context *ctx,
+ const unsigned char data[64] );
+
+#undef MBEDCRYPTO_DEPRECATED
+#endif /* !MBEDCRYPTO_DEPRECATED_REMOVED */
+
+/**
+ * \brief Output = MD5( input buffer )
+ *
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output MD5 checksum result
+ *
+ * \return 0 if successful
+ *
+ * \warning MD5 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+int mbedcrypto_md5_ret( const unsigned char *input,
+ size_t ilen,
+ unsigned char output[16] );
+
+#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
+#if defined(MBEDCRYPTO_DEPRECATED_WARNING)
+#define MBEDCRYPTO_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDCRYPTO_DEPRECATED
+#endif
+/**
+ * \brief Output = MD5( input buffer )
+ *
+ * \deprecated Superseded by mbedcrypto_md5_ret() in 2.7.0
+ *
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output MD5 checksum result
+ *
+ * \warning MD5 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_md5( const unsigned char *input,
+ size_t ilen,
+ unsigned char output[16] );
+
+#undef MBEDCRYPTO_DEPRECATED
+#endif /* !MBEDCRYPTO_DEPRECATED_REMOVED */
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ *
+ * \warning MD5 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+int mbedcrypto_md5_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedcrypto_md5.h */
diff --git a/include/mbedcrypto/md_internal.h b/include/mbedcrypto/md_internal.h
new file mode 100644
index 0000000..bc151e9
--- /dev/null
+++ b/include/mbedcrypto/md_internal.h
@@ -0,0 +1,115 @@
+/**
+ * \file md_internal.h
+ *
+ * \brief Message digest wrappers.
+ *
+ * \warning This in an internal header. Do not include directly.
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_MD_WRAP_H
+#define MBEDCRYPTO_MD_WRAP_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include "md.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Message digest information.
+ * Allows message digest functions to be called in a generic way.
+ */
+struct mbedcrypto_md_info_t
+{
+ /** Digest identifier */
+ mbedcrypto_md_type_t type;
+
+ /** Name of the message digest */
+ const char * name;
+
+ /** Output length of the digest function in bytes */
+ int size;
+
+ /** Block length of the digest function in bytes */
+ int block_size;
+
+ /** Digest initialisation function */
+ int (*starts_func)( void *ctx );
+
+ /** Digest update function */
+ int (*update_func)( void *ctx, const unsigned char *input, size_t ilen );
+
+ /** Digest finalisation function */
+ int (*finish_func)( void *ctx, unsigned char *output );
+
+ /** Generic digest function */
+ int (*digest_func)( const unsigned char *input, size_t ilen,
+ unsigned char *output );
+
+ /** Allocate a new context */
+ void * (*ctx_alloc_func)( void );
+
+ /** Free the given context */
+ void (*ctx_free_func)( void *ctx );
+
+ /** Clone state from a context */
+ void (*clone_func)( void *dst, const void *src );
+
+ /** Internal use only */
+ int (*process_func)( void *ctx, const unsigned char *input );
+};
+
+#if defined(MBEDCRYPTO_MD2_C)
+extern const mbedcrypto_md_info_t mbedcrypto_md2_info;
+#endif
+#if defined(MBEDCRYPTO_MD4_C)
+extern const mbedcrypto_md_info_t mbedcrypto_md4_info;
+#endif
+#if defined(MBEDCRYPTO_MD5_C)
+extern const mbedcrypto_md_info_t mbedcrypto_md5_info;
+#endif
+#if defined(MBEDCRYPTO_RIPEMD160_C)
+extern const mbedcrypto_md_info_t mbedcrypto_ripemd160_info;
+#endif
+#if defined(MBEDCRYPTO_SHA1_C)
+extern const mbedcrypto_md_info_t mbedcrypto_sha1_info;
+#endif
+#if defined(MBEDCRYPTO_SHA256_C)
+extern const mbedcrypto_md_info_t mbedcrypto_sha224_info;
+extern const mbedcrypto_md_info_t mbedcrypto_sha256_info;
+#endif
+#if defined(MBEDCRYPTO_SHA512_C)
+extern const mbedcrypto_md_info_t mbedcrypto_sha384_info;
+extern const mbedcrypto_md_info_t mbedcrypto_sha512_info;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDCRYPTO_MD_WRAP_H */
diff --git a/include/mbedcrypto/oid.h b/include/mbedcrypto/oid.h
new file mode 100644
index 0000000..d162b10
--- /dev/null
+++ b/include/mbedcrypto/oid.h
@@ -0,0 +1,589 @@
+/**
+ * \file oid.h
+ *
+ * \brief Object Identifier (OID) database
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_OID_H
+#define MBEDCRYPTO_OID_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include "asn1.h"
+#include "pk.h"
+
+#include <stddef.h>
+
+#if defined(MBEDCRYPTO_CIPHER_C)
+#include "cipher.h"
+#endif
+
+#if defined(MBEDCRYPTO_MD_C)
+#include "md.h"
+#endif
+
+#if defined(MBEDCRYPTO_X509_USE_C) || defined(MBEDCRYPTO_X509_CREATE_C)
+#include "x509.h"
+#endif
+
+#define MBEDCRYPTO_ERR_OID_NOT_FOUND -0x002E /**< OID is not found. */
+#define MBEDCRYPTO_ERR_OID_BUF_TOO_SMALL -0x000B /**< output buffer is too small */
+
+/*
+ * Top level OID tuples
+ */
+#define MBEDCRYPTO_OID_ISO_MEMBER_BODIES "\x2a" /* {iso(1) member-body(2)} */
+#define MBEDCRYPTO_OID_ISO_IDENTIFIED_ORG "\x2b" /* {iso(1) identified-organization(3)} */
+#define MBEDCRYPTO_OID_ISO_CCITT_DS "\x55" /* {joint-iso-ccitt(2) ds(5)} */
+#define MBEDCRYPTO_OID_ISO_ITU_COUNTRY "\x60" /* {joint-iso-itu-t(2) country(16)} */
+
+/*
+ * ISO Member bodies OID parts
+ */
+#define MBEDCRYPTO_OID_COUNTRY_US "\x86\x48" /* {us(840)} */
+#define MBEDCRYPTO_OID_ORG_RSA_DATA_SECURITY "\x86\xf7\x0d" /* {rsadsi(113549)} */
+#define MBEDCRYPTO_OID_RSA_COMPANY MBEDCRYPTO_OID_ISO_MEMBER_BODIES MBEDCRYPTO_OID_COUNTRY_US \
+ MBEDCRYPTO_OID_ORG_RSA_DATA_SECURITY /* {iso(1) member-body(2) us(840) rsadsi(113549)} */
+#define MBEDCRYPTO_OID_ORG_ANSI_X9_62 "\xce\x3d" /* ansi-X9-62(10045) */
+#define MBEDCRYPTO_OID_ANSI_X9_62 MBEDCRYPTO_OID_ISO_MEMBER_BODIES MBEDCRYPTO_OID_COUNTRY_US \
+ MBEDCRYPTO_OID_ORG_ANSI_X9_62
+
+/*
+ * ISO Identified organization OID parts
+ */
+#define MBEDCRYPTO_OID_ORG_DOD "\x06" /* {dod(6)} */
+#define MBEDCRYPTO_OID_ORG_OIW "\x0e"
+#define MBEDCRYPTO_OID_OIW_SECSIG MBEDCRYPTO_OID_ORG_OIW "\x03"
+#define MBEDCRYPTO_OID_OIW_SECSIG_ALG MBEDCRYPTO_OID_OIW_SECSIG "\x02"
+#define MBEDCRYPTO_OID_OIW_SECSIG_SHA1 MBEDCRYPTO_OID_OIW_SECSIG_ALG "\x1a"
+#define MBEDCRYPTO_OID_ORG_CERTICOM "\x81\x04" /* certicom(132) */
+#define MBEDCRYPTO_OID_CERTICOM MBEDCRYPTO_OID_ISO_IDENTIFIED_ORG MBEDCRYPTO_OID_ORG_CERTICOM
+#define MBEDCRYPTO_OID_ORG_TELETRUST "\x24" /* teletrust(36) */
+#define MBEDCRYPTO_OID_TELETRUST MBEDCRYPTO_OID_ISO_IDENTIFIED_ORG MBEDCRYPTO_OID_ORG_TELETRUST
+
+/*
+ * ISO ITU OID parts
+ */
+#define MBEDCRYPTO_OID_ORGANIZATION "\x01" /* {organization(1)} */
+#define MBEDCRYPTO_OID_ISO_ITU_US_ORG MBEDCRYPTO_OID_ISO_ITU_COUNTRY MBEDCRYPTO_OID_COUNTRY_US MBEDCRYPTO_OID_ORGANIZATION /* {joint-iso-itu-t(2) country(16) us(840) organization(1)} */
+
+#define MBEDCRYPTO_OID_ORG_GOV "\x65" /* {gov(101)} */
+#define MBEDCRYPTO_OID_GOV MBEDCRYPTO_OID_ISO_ITU_US_ORG MBEDCRYPTO_OID_ORG_GOV /* {joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)} */
+
+#define MBEDCRYPTO_OID_ORG_NETSCAPE "\x86\xF8\x42" /* {netscape(113730)} */
+#define MBEDCRYPTO_OID_NETSCAPE MBEDCRYPTO_OID_ISO_ITU_US_ORG MBEDCRYPTO_OID_ORG_NETSCAPE /* Netscape OID {joint-iso-itu-t(2) country(16) us(840) organization(1) netscape(113730)} */
+
+/* ISO arc for standard certificate and CRL extensions */
+#define MBEDCRYPTO_OID_ID_CE MBEDCRYPTO_OID_ISO_CCITT_DS "\x1D" /**< id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29} */
+
+/**
+ * Private Internet Extensions
+ * { iso(1) identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) }
+ */
+#define MBEDCRYPTO_OID_PKIX MBEDCRYPTO_OID_ISO_IDENTIFIED_ORG MBEDCRYPTO_OID_ORG_DOD "\x01\x05\x05\x07"
+
+/*
+ * Arc for standard naming attributes
+ */
+#define MBEDCRYPTO_OID_AT MBEDCRYPTO_OID_ISO_CCITT_DS "\x04" /**< id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4} */
+#define MBEDCRYPTO_OID_AT_CN MBEDCRYPTO_OID_AT "\x03" /**< id-at-commonName AttributeType:= {id-at 3} */
+#define MBEDCRYPTO_OID_AT_SUR_NAME MBEDCRYPTO_OID_AT "\x04" /**< id-at-surName AttributeType:= {id-at 4} */
+#define MBEDCRYPTO_OID_AT_SERIAL_NUMBER MBEDCRYPTO_OID_AT "\x05" /**< id-at-serialNumber AttributeType:= {id-at 5} */
+#define MBEDCRYPTO_OID_AT_COUNTRY MBEDCRYPTO_OID_AT "\x06" /**< id-at-countryName AttributeType:= {id-at 6} */
+#define MBEDCRYPTO_OID_AT_LOCALITY MBEDCRYPTO_OID_AT "\x07" /**< id-at-locality AttributeType:= {id-at 7} */
+#define MBEDCRYPTO_OID_AT_STATE MBEDCRYPTO_OID_AT "\x08" /**< id-at-state AttributeType:= {id-at 8} */
+#define MBEDCRYPTO_OID_AT_ORGANIZATION MBEDCRYPTO_OID_AT "\x0A" /**< id-at-organizationName AttributeType:= {id-at 10} */
+#define MBEDCRYPTO_OID_AT_ORG_UNIT MBEDCRYPTO_OID_AT "\x0B" /**< id-at-organizationalUnitName AttributeType:= {id-at 11} */
+#define MBEDCRYPTO_OID_AT_TITLE MBEDCRYPTO_OID_AT "\x0C" /**< id-at-title AttributeType:= {id-at 12} */
+#define MBEDCRYPTO_OID_AT_POSTAL_ADDRESS MBEDCRYPTO_OID_AT "\x10" /**< id-at-postalAddress AttributeType:= {id-at 16} */
+#define MBEDCRYPTO_OID_AT_POSTAL_CODE MBEDCRYPTO_OID_AT "\x11" /**< id-at-postalCode AttributeType:= {id-at 17} */
+#define MBEDCRYPTO_OID_AT_GIVEN_NAME MBEDCRYPTO_OID_AT "\x2A" /**< id-at-givenName AttributeType:= {id-at 42} */
+#define MBEDCRYPTO_OID_AT_INITIALS MBEDCRYPTO_OID_AT "\x2B" /**< id-at-initials AttributeType:= {id-at 43} */
+#define MBEDCRYPTO_OID_AT_GENERATION_QUALIFIER MBEDCRYPTO_OID_AT "\x2C" /**< id-at-generationQualifier AttributeType:= {id-at 44} */
+#define MBEDCRYPTO_OID_AT_UNIQUE_IDENTIFIER MBEDCRYPTO_OID_AT "\x2D" /**< id-at-uniqueIdentifier AttributType:= {id-at 45} */
+#define MBEDCRYPTO_OID_AT_DN_QUALIFIER MBEDCRYPTO_OID_AT "\x2E" /**< id-at-dnQualifier AttributeType:= {id-at 46} */
+#define MBEDCRYPTO_OID_AT_PSEUDONYM MBEDCRYPTO_OID_AT "\x41" /**< id-at-pseudonym AttributeType:= {id-at 65} */
+
+#define MBEDCRYPTO_OID_DOMAIN_COMPONENT "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x19" /** id-domainComponent AttributeType:= {itu-t(0) data(9) pss(2342) ucl(19200300) pilot(100) pilotAttributeType(1) domainComponent(25)} */
+
+/*
+ * OIDs for standard certificate extensions
+ */
+#define MBEDCRYPTO_OID_AUTHORITY_KEY_IDENTIFIER MBEDCRYPTO_OID_ID_CE "\x23" /**< id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 } */
+#define MBEDCRYPTO_OID_SUBJECT_KEY_IDENTIFIER MBEDCRYPTO_OID_ID_CE "\x0E" /**< id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 } */
+#define MBEDCRYPTO_OID_KEY_USAGE MBEDCRYPTO_OID_ID_CE "\x0F" /**< id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } */
+#define MBEDCRYPTO_OID_CERTIFICATE_POLICIES MBEDCRYPTO_OID_ID_CE "\x20" /**< id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 } */
+#define MBEDCRYPTO_OID_POLICY_MAPPINGS MBEDCRYPTO_OID_ID_CE "\x21" /**< id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 } */
+#define MBEDCRYPTO_OID_SUBJECT_ALT_NAME MBEDCRYPTO_OID_ID_CE "\x11" /**< id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 } */
+#define MBEDCRYPTO_OID_ISSUER_ALT_NAME MBEDCRYPTO_OID_ID_CE "\x12" /**< id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 } */
+#define MBEDCRYPTO_OID_SUBJECT_DIRECTORY_ATTRS MBEDCRYPTO_OID_ID_CE "\x09" /**< id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 } */
+#define MBEDCRYPTO_OID_BASIC_CONSTRAINTS MBEDCRYPTO_OID_ID_CE "\x13" /**< id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 } */
+#define MBEDCRYPTO_OID_NAME_CONSTRAINTS MBEDCRYPTO_OID_ID_CE "\x1E" /**< id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 } */
+#define MBEDCRYPTO_OID_POLICY_CONSTRAINTS MBEDCRYPTO_OID_ID_CE "\x24" /**< id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 } */
+#define MBEDCRYPTO_OID_EXTENDED_KEY_USAGE MBEDCRYPTO_OID_ID_CE "\x25" /**< id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 } */
+#define MBEDCRYPTO_OID_CRL_DISTRIBUTION_POINTS MBEDCRYPTO_OID_ID_CE "\x1F" /**< id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-ce 31 } */
+#define MBEDCRYPTO_OID_INIHIBIT_ANYPOLICY MBEDCRYPTO_OID_ID_CE "\x36" /**< id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 } */
+#define MBEDCRYPTO_OID_FRESHEST_CRL MBEDCRYPTO_OID_ID_CE "\x2E" /**< id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 } */
+
+/*
+ * Netscape certificate extensions
+ */
+#define MBEDCRYPTO_OID_NS_CERT MBEDCRYPTO_OID_NETSCAPE "\x01"
+#define MBEDCRYPTO_OID_NS_CERT_TYPE MBEDCRYPTO_OID_NS_CERT "\x01"
+#define MBEDCRYPTO_OID_NS_BASE_URL MBEDCRYPTO_OID_NS_CERT "\x02"
+#define MBEDCRYPTO_OID_NS_REVOCATION_URL MBEDCRYPTO_OID_NS_CERT "\x03"
+#define MBEDCRYPTO_OID_NS_CA_REVOCATION_URL MBEDCRYPTO_OID_NS_CERT "\x04"
+#define MBEDCRYPTO_OID_NS_RENEWAL_URL MBEDCRYPTO_OID_NS_CERT "\x07"
+#define MBEDCRYPTO_OID_NS_CA_POLICY_URL MBEDCRYPTO_OID_NS_CERT "\x08"
+#define MBEDCRYPTO_OID_NS_SSL_SERVER_NAME MBEDCRYPTO_OID_NS_CERT "\x0C"
+#define MBEDCRYPTO_OID_NS_COMMENT MBEDCRYPTO_OID_NS_CERT "\x0D"
+#define MBEDCRYPTO_OID_NS_DATA_TYPE MBEDCRYPTO_OID_NETSCAPE "\x02"
+#define MBEDCRYPTO_OID_NS_CERT_SEQUENCE MBEDCRYPTO_OID_NS_DATA_TYPE "\x05"
+
+/*
+ * OIDs for CRL extensions
+ */
+#define MBEDCRYPTO_OID_PRIVATE_KEY_USAGE_PERIOD MBEDCRYPTO_OID_ID_CE "\x10"
+#define MBEDCRYPTO_OID_CRL_NUMBER MBEDCRYPTO_OID_ID_CE "\x14" /**< id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 } */
+
+/*
+ * X.509 v3 Extended key usage OIDs
+ */
+#define MBEDCRYPTO_OID_ANY_EXTENDED_KEY_USAGE MBEDCRYPTO_OID_EXTENDED_KEY_USAGE "\x00" /**< anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } */
+
+#define MBEDCRYPTO_OID_KP MBEDCRYPTO_OID_PKIX "\x03" /**< id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } */
+#define MBEDCRYPTO_OID_SERVER_AUTH MBEDCRYPTO_OID_KP "\x01" /**< id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } */
+#define MBEDCRYPTO_OID_CLIENT_AUTH MBEDCRYPTO_OID_KP "\x02" /**< id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } */
+#define MBEDCRYPTO_OID_CODE_SIGNING MBEDCRYPTO_OID_KP "\x03" /**< id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } */
+#define MBEDCRYPTO_OID_EMAIL_PROTECTION MBEDCRYPTO_OID_KP "\x04" /**< id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } */
+#define MBEDCRYPTO_OID_TIME_STAMPING MBEDCRYPTO_OID_KP "\x08" /**< id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } */
+#define MBEDCRYPTO_OID_OCSP_SIGNING MBEDCRYPTO_OID_KP "\x09" /**< id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } */
+
+/*
+ * PKCS definition OIDs
+ */
+
+#define MBEDCRYPTO_OID_PKCS MBEDCRYPTO_OID_RSA_COMPANY "\x01" /**< pkcs OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) 1 } */
+#define MBEDCRYPTO_OID_PKCS1 MBEDCRYPTO_OID_PKCS "\x01" /**< pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } */
+#define MBEDCRYPTO_OID_PKCS5 MBEDCRYPTO_OID_PKCS "\x05" /**< pkcs-5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 } */
+#define MBEDCRYPTO_OID_PKCS9 MBEDCRYPTO_OID_PKCS "\x09" /**< pkcs-9 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } */
+#define MBEDCRYPTO_OID_PKCS12 MBEDCRYPTO_OID_PKCS "\x0c" /**< pkcs-12 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 } */
+
+/*
+ * PKCS#1 OIDs
+ */
+#define MBEDCRYPTO_OID_PKCS1_RSA MBEDCRYPTO_OID_PKCS1 "\x01" /**< rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } */
+#define MBEDCRYPTO_OID_PKCS1_MD2 MBEDCRYPTO_OID_PKCS1 "\x02" /**< md2WithRSAEncryption ::= { pkcs-1 2 } */
+#define MBEDCRYPTO_OID_PKCS1_MD4 MBEDCRYPTO_OID_PKCS1 "\x03" /**< md4WithRSAEncryption ::= { pkcs-1 3 } */
+#define MBEDCRYPTO_OID_PKCS1_MD5 MBEDCRYPTO_OID_PKCS1 "\x04" /**< md5WithRSAEncryption ::= { pkcs-1 4 } */
+#define MBEDCRYPTO_OID_PKCS1_SHA1 MBEDCRYPTO_OID_PKCS1 "\x05" /**< sha1WithRSAEncryption ::= { pkcs-1 5 } */
+#define MBEDCRYPTO_OID_PKCS1_SHA224 MBEDCRYPTO_OID_PKCS1 "\x0e" /**< sha224WithRSAEncryption ::= { pkcs-1 14 } */
+#define MBEDCRYPTO_OID_PKCS1_SHA256 MBEDCRYPTO_OID_PKCS1 "\x0b" /**< sha256WithRSAEncryption ::= { pkcs-1 11 } */
+#define MBEDCRYPTO_OID_PKCS1_SHA384 MBEDCRYPTO_OID_PKCS1 "\x0c" /**< sha384WithRSAEncryption ::= { pkcs-1 12 } */
+#define MBEDCRYPTO_OID_PKCS1_SHA512 MBEDCRYPTO_OID_PKCS1 "\x0d" /**< sha512WithRSAEncryption ::= { pkcs-1 13 } */
+
+#define MBEDCRYPTO_OID_RSA_SHA_OBS "\x2B\x0E\x03\x02\x1D"
+
+#define MBEDCRYPTO_OID_PKCS9_EMAIL MBEDCRYPTO_OID_PKCS9 "\x01" /**< emailAddress AttributeType ::= { pkcs-9 1 } */
+
+/* RFC 4055 */
+#define MBEDCRYPTO_OID_RSASSA_PSS MBEDCRYPTO_OID_PKCS1 "\x0a" /**< id-RSASSA-PSS ::= { pkcs-1 10 } */
+#define MBEDCRYPTO_OID_MGF1 MBEDCRYPTO_OID_PKCS1 "\x08" /**< id-mgf1 ::= { pkcs-1 8 } */
+
+/*
+ * Digest algorithms
+ */
+#define MBEDCRYPTO_OID_DIGEST_ALG_MD2 MBEDCRYPTO_OID_RSA_COMPANY "\x02\x02" /**< id-mbedcrypto_md2 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2 } */
+#define MBEDCRYPTO_OID_DIGEST_ALG_MD4 MBEDCRYPTO_OID_RSA_COMPANY "\x02\x04" /**< id-mbedcrypto_md4 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 4 } */
+#define MBEDCRYPTO_OID_DIGEST_ALG_MD5 MBEDCRYPTO_OID_RSA_COMPANY "\x02\x05" /**< id-mbedcrypto_md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 } */
+#define MBEDCRYPTO_OID_DIGEST_ALG_SHA1 MBEDCRYPTO_OID_ISO_IDENTIFIED_ORG MBEDCRYPTO_OID_OIW_SECSIG_SHA1 /**< id-mbedcrypto_sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } */
+#define MBEDCRYPTO_OID_DIGEST_ALG_SHA224 MBEDCRYPTO_OID_GOV "\x03\x04\x02\x04" /**< id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 4 } */
+#define MBEDCRYPTO_OID_DIGEST_ALG_SHA256 MBEDCRYPTO_OID_GOV "\x03\x04\x02\x01" /**< id-mbedcrypto_sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */
+
+#define MBEDCRYPTO_OID_DIGEST_ALG_SHA384 MBEDCRYPTO_OID_GOV "\x03\x04\x02\x02" /**< id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 } */
+
+#define MBEDCRYPTO_OID_DIGEST_ALG_SHA512 MBEDCRYPTO_OID_GOV "\x03\x04\x02\x03" /**< id-mbedcrypto_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */
+
+#define MBEDCRYPTO_OID_HMAC_SHA1 MBEDCRYPTO_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */
+
+#define MBEDCRYPTO_OID_HMAC_SHA224 MBEDCRYPTO_OID_RSA_COMPANY "\x02\x08" /**< id-hmacWithSHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 8 } */
+
+#define MBEDCRYPTO_OID_HMAC_SHA256 MBEDCRYPTO_OID_RSA_COMPANY "\x02\x09" /**< id-hmacWithSHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 9 } */
+
+#define MBEDCRYPTO_OID_HMAC_SHA384 MBEDCRYPTO_OID_RSA_COMPANY "\x02\x0A" /**< id-hmacWithSHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 10 } */
+
+#define MBEDCRYPTO_OID_HMAC_SHA512 MBEDCRYPTO_OID_RSA_COMPANY "\x02\x0B" /**< id-hmacWithSHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 11 } */
+
+/*
+ * Encryption algorithms
+ */
+#define MBEDCRYPTO_OID_DES_CBC MBEDCRYPTO_OID_ISO_IDENTIFIED_ORG MBEDCRYPTO_OID_OIW_SECSIG_ALG "\x07" /**< desCBC OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 7 } */
+#define MBEDCRYPTO_OID_DES_EDE3_CBC MBEDCRYPTO_OID_RSA_COMPANY "\x03\x07" /**< des-ede3-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2) -- us(840) rsadsi(113549) encryptionAlgorithm(3) 7 } */
+
+/*
+ * PKCS#5 OIDs
+ */
+#define MBEDCRYPTO_OID_PKCS5_PBKDF2 MBEDCRYPTO_OID_PKCS5 "\x0c" /**< id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12} */
+#define MBEDCRYPTO_OID_PKCS5_PBES2 MBEDCRYPTO_OID_PKCS5 "\x0d" /**< id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13} */
+#define MBEDCRYPTO_OID_PKCS5_PBMAC1 MBEDCRYPTO_OID_PKCS5 "\x0e" /**< id-PBMAC1 OBJECT IDENTIFIER ::= {pkcs-5 14} */
+
+/*
+ * PKCS#5 PBES1 algorithms
+ */
+#define MBEDCRYPTO_OID_PKCS5_PBE_MD2_DES_CBC MBEDCRYPTO_OID_PKCS5 "\x01" /**< pbeWithMD2AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 1} */
+#define MBEDCRYPTO_OID_PKCS5_PBE_MD2_RC2_CBC MBEDCRYPTO_OID_PKCS5 "\x04" /**< pbeWithMD2AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 4} */
+#define MBEDCRYPTO_OID_PKCS5_PBE_MD5_DES_CBC MBEDCRYPTO_OID_PKCS5 "\x03" /**< pbeWithMD5AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 3} */
+#define MBEDCRYPTO_OID_PKCS5_PBE_MD5_RC2_CBC MBEDCRYPTO_OID_PKCS5 "\x06" /**< pbeWithMD5AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 6} */
+#define MBEDCRYPTO_OID_PKCS5_PBE_SHA1_DES_CBC MBEDCRYPTO_OID_PKCS5 "\x0a" /**< pbeWithSHA1AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 10} */
+#define MBEDCRYPTO_OID_PKCS5_PBE_SHA1_RC2_CBC MBEDCRYPTO_OID_PKCS5 "\x0b" /**< pbeWithSHA1AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 11} */
+
+/*
+ * PKCS#8 OIDs
+ */
+#define MBEDCRYPTO_OID_PKCS9_CSR_EXT_REQ MBEDCRYPTO_OID_PKCS9 "\x0e" /**< extensionRequest OBJECT IDENTIFIER ::= {pkcs-9 14} */
+
+/*
+ * PKCS#12 PBE OIDs
+ */
+#define MBEDCRYPTO_OID_PKCS12_PBE MBEDCRYPTO_OID_PKCS12 "\x01" /**< pkcs-12PbeIds OBJECT IDENTIFIER ::= {pkcs-12 1} */
+
+#define MBEDCRYPTO_OID_PKCS12_PBE_SHA1_RC4_128 MBEDCRYPTO_OID_PKCS12_PBE "\x01" /**< pbeWithSHAAnd128BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 1} */
+#define MBEDCRYPTO_OID_PKCS12_PBE_SHA1_RC4_40 MBEDCRYPTO_OID_PKCS12_PBE "\x02" /**< pbeWithSHAAnd40BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 2} */
+#define MBEDCRYPTO_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC MBEDCRYPTO_OID_PKCS12_PBE "\x03" /**< pbeWithSHAAnd3-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 3} */
+#define MBEDCRYPTO_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC MBEDCRYPTO_OID_PKCS12_PBE "\x04" /**< pbeWithSHAAnd2-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 4} */
+#define MBEDCRYPTO_OID_PKCS12_PBE_SHA1_RC2_128_CBC MBEDCRYPTO_OID_PKCS12_PBE "\x05" /**< pbeWithSHAAnd128BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 5} */
+#define MBEDCRYPTO_OID_PKCS12_PBE_SHA1_RC2_40_CBC MBEDCRYPTO_OID_PKCS12_PBE "\x06" /**< pbeWithSHAAnd40BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 6} */
+
+/*
+ * EC key algorithms from RFC 5480
+ */
+
+/* id-ecPublicKey OBJECT IDENTIFIER ::= {
+ * iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 } */
+#define MBEDCRYPTO_OID_EC_ALG_UNRESTRICTED MBEDCRYPTO_OID_ANSI_X9_62 "\x02\01"
+
+/* id-ecDH OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) certicom(132)
+ * schemes(1) ecdh(12) } */
+#define MBEDCRYPTO_OID_EC_ALG_ECDH MBEDCRYPTO_OID_CERTICOM "\x01\x0c"
+
+/*
+ * ECParameters namedCurve identifiers, from RFC 5480, RFC 5639, and SEC2
+ */
+
+/* secp192r1 OBJECT IDENTIFIER ::= {
+ * iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 1 } */
+#define MBEDCRYPTO_OID_EC_GRP_SECP192R1 MBEDCRYPTO_OID_ANSI_X9_62 "\x03\x01\x01"
+
+/* secp224r1 OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) certicom(132) curve(0) 33 } */
+#define MBEDCRYPTO_OID_EC_GRP_SECP224R1 MBEDCRYPTO_OID_CERTICOM "\x00\x21"
+
+/* secp256r1 OBJECT IDENTIFIER ::= {
+ * iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 7 } */
+#define MBEDCRYPTO_OID_EC_GRP_SECP256R1 MBEDCRYPTO_OID_ANSI_X9_62 "\x03\x01\x07"
+
+/* secp384r1 OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) certicom(132) curve(0) 34 } */
+#define MBEDCRYPTO_OID_EC_GRP_SECP384R1 MBEDCRYPTO_OID_CERTICOM "\x00\x22"
+
+/* secp521r1 OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) certicom(132) curve(0) 35 } */
+#define MBEDCRYPTO_OID_EC_GRP_SECP521R1 MBEDCRYPTO_OID_CERTICOM "\x00\x23"
+
+/* secp192k1 OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) certicom(132) curve(0) 31 } */
+#define MBEDCRYPTO_OID_EC_GRP_SECP192K1 MBEDCRYPTO_OID_CERTICOM "\x00\x1f"
+
+/* secp224k1 OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) certicom(132) curve(0) 32 } */
+#define MBEDCRYPTO_OID_EC_GRP_SECP224K1 MBEDCRYPTO_OID_CERTICOM "\x00\x20"
+
+/* secp256k1 OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) certicom(132) curve(0) 10 } */
+#define MBEDCRYPTO_OID_EC_GRP_SECP256K1 MBEDCRYPTO_OID_CERTICOM "\x00\x0a"
+
+/* RFC 5639 4.1
+ * ecStdCurvesAndGeneration OBJECT IDENTIFIER::= {iso(1)
+ * identified-organization(3) teletrust(36) algorithm(3) signature-
+ * algorithm(3) ecSign(2) 8}
+ * ellipticCurve OBJECT IDENTIFIER ::= {ecStdCurvesAndGeneration 1}
+ * versionOne OBJECT IDENTIFIER ::= {ellipticCurve 1} */
+#define MBEDCRYPTO_OID_EC_BRAINPOOL_V1 MBEDCRYPTO_OID_TELETRUST "\x03\x03\x02\x08\x01\x01"
+
+/* brainpoolP256r1 OBJECT IDENTIFIER ::= {versionOne 7} */
+#define MBEDCRYPTO_OID_EC_GRP_BP256R1 MBEDCRYPTO_OID_EC_BRAINPOOL_V1 "\x07"
+
+/* brainpoolP384r1 OBJECT IDENTIFIER ::= {versionOne 11} */
+#define MBEDCRYPTO_OID_EC_GRP_BP384R1 MBEDCRYPTO_OID_EC_BRAINPOOL_V1 "\x0B"
+
+/* brainpoolP512r1 OBJECT IDENTIFIER ::= {versionOne 13} */
+#define MBEDCRYPTO_OID_EC_GRP_BP512R1 MBEDCRYPTO_OID_EC_BRAINPOOL_V1 "\x0D"
+
+/*
+ * SEC1 C.1
+ *
+ * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
+ * id-fieldType OBJECT IDENTIFIER ::= { ansi-X9-62 fieldType(1)}
+ */
+#define MBEDCRYPTO_OID_ANSI_X9_62_FIELD_TYPE MBEDCRYPTO_OID_ANSI_X9_62 "\x01"
+#define MBEDCRYPTO_OID_ANSI_X9_62_PRIME_FIELD MBEDCRYPTO_OID_ANSI_X9_62_FIELD_TYPE "\x01"
+
+/*
+ * ECDSA signature identifiers, from RFC 5480
+ */
+#define MBEDCRYPTO_OID_ANSI_X9_62_SIG MBEDCRYPTO_OID_ANSI_X9_62 "\x04" /* signatures(4) */
+#define MBEDCRYPTO_OID_ANSI_X9_62_SIG_SHA2 MBEDCRYPTO_OID_ANSI_X9_62_SIG "\x03" /* ecdsa-with-SHA2(3) */
+
+/* ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
+ * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) 1 } */
+#define MBEDCRYPTO_OID_ECDSA_SHA1 MBEDCRYPTO_OID_ANSI_X9_62_SIG "\x01"
+
+/* ecdsa-with-SHA224 OBJECT IDENTIFIER ::= {
+ * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+ * ecdsa-with-SHA2(3) 1 } */
+#define MBEDCRYPTO_OID_ECDSA_SHA224 MBEDCRYPTO_OID_ANSI_X9_62_SIG_SHA2 "\x01"
+
+/* ecdsa-with-SHA256 OBJECT IDENTIFIER ::= {
+ * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+ * ecdsa-with-SHA2(3) 2 } */
+#define MBEDCRYPTO_OID_ECDSA_SHA256 MBEDCRYPTO_OID_ANSI_X9_62_SIG_SHA2 "\x02"
+
+/* ecdsa-with-SHA384 OBJECT IDENTIFIER ::= {
+ * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+ * ecdsa-with-SHA2(3) 3 } */
+#define MBEDCRYPTO_OID_ECDSA_SHA384 MBEDCRYPTO_OID_ANSI_X9_62_SIG_SHA2 "\x03"
+
+/* ecdsa-with-SHA512 OBJECT IDENTIFIER ::= {
+ * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+ * ecdsa-with-SHA2(3) 4 } */
+#define MBEDCRYPTO_OID_ECDSA_SHA512 MBEDCRYPTO_OID_ANSI_X9_62_SIG_SHA2 "\x04"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Base OID descriptor structure
+ */
+typedef struct {
+ const char *asn1; /*!< OID ASN.1 representation */
+ size_t asn1_len; /*!< length of asn1 */
+ const char *name; /*!< official name (e.g. from RFC) */
+ const char *description; /*!< human friendly description */
+} mbedcrypto_oid_descriptor_t;
+
+/**
+ * \brief Translate an ASN.1 OID into its numeric representation
+ * (e.g. "\x2A\x86\x48\x86\xF7\x0D" into "1.2.840.113549")
+ *
+ * \param buf buffer to put representation in
+ * \param size size of the buffer
+ * \param oid OID to translate
+ *
+ * \return Length of the string written (excluding final NULL) or
+ * MBEDCRYPTO_ERR_OID_BUF_TOO_SMALL in case of error
+ */
+int mbedcrypto_oid_get_numeric_string( char *buf, size_t size, const mbedcrypto_asn1_buf *oid );
+
+#if defined(MBEDCRYPTO_X509_USE_C) || defined(MBEDCRYPTO_X509_CREATE_C)
+/**
+ * \brief Translate an X.509 extension OID into local values
+ *
+ * \param oid OID to use
+ * \param ext_type place to store the extension type
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_OID_NOT_FOUND
+ */
+int mbedcrypto_oid_get_x509_ext_type( const mbedcrypto_asn1_buf *oid, int *ext_type );
+#endif
+
+/**
+ * \brief Translate an X.509 attribute type OID into the short name
+ * (e.g. the OID for an X520 Common Name into "CN")
+ *
+ * \param oid OID to use
+ * \param short_name place to store the string pointer
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_OID_NOT_FOUND
+ */
+int mbedcrypto_oid_get_attr_short_name( const mbedcrypto_asn1_buf *oid, const char **short_name );
+
+/**
+ * \brief Translate PublicKeyAlgorithm OID into pk_type
+ *
+ * \param oid OID to use
+ * \param pk_alg place to store public key algorithm
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_OID_NOT_FOUND
+ */
+int mbedcrypto_oid_get_pk_alg( const mbedcrypto_asn1_buf *oid, mbedcrypto_pk_type_t *pk_alg );
+
+/**
+ * \brief Translate pk_type into PublicKeyAlgorithm OID
+ *
+ * \param pk_alg Public key type to look for
+ * \param oid place to store ASN.1 OID string pointer
+ * \param olen length of the OID
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_OID_NOT_FOUND
+ */
+int mbedcrypto_oid_get_oid_by_pk_alg( mbedcrypto_pk_type_t pk_alg,
+ const char **oid, size_t *olen );
+
+#if defined(MBEDCRYPTO_ECP_C)
+/**
+ * \brief Translate NamedCurve OID into an EC group identifier
+ *
+ * \param oid OID to use
+ * \param grp_id place to store group id
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_OID_NOT_FOUND
+ */
+int mbedcrypto_oid_get_ec_grp( const mbedcrypto_asn1_buf *oid, mbedcrypto_ecp_group_id *grp_id );
+
+/**
+ * \brief Translate EC group identifier into NamedCurve OID
+ *
+ * \param grp_id EC group identifier
+ * \param oid place to store ASN.1 OID string pointer
+ * \param olen length of the OID
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_OID_NOT_FOUND
+ */
+int mbedcrypto_oid_get_oid_by_ec_grp( mbedcrypto_ecp_group_id grp_id,
+ const char **oid, size_t *olen );
+#endif /* MBEDCRYPTO_ECP_C */
+
+#if defined(MBEDCRYPTO_MD_C)
+/**
+ * \brief Translate SignatureAlgorithm OID into md_type and pk_type
+ *
+ * \param oid OID to use
+ * \param md_alg place to store message digest algorithm
+ * \param pk_alg place to store public key algorithm
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_OID_NOT_FOUND
+ */
+int mbedcrypto_oid_get_sig_alg( const mbedcrypto_asn1_buf *oid,
+ mbedcrypto_md_type_t *md_alg, mbedcrypto_pk_type_t *pk_alg );
+
+/**
+ * \brief Translate SignatureAlgorithm OID into description
+ *
+ * \param oid OID to use
+ * \param desc place to store string pointer
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_OID_NOT_FOUND
+ */
+int mbedcrypto_oid_get_sig_alg_desc( const mbedcrypto_asn1_buf *oid, const char **desc );
+
+/**
+ * \brief Translate md_type and pk_type into SignatureAlgorithm OID
+ *
+ * \param md_alg message digest algorithm
+ * \param pk_alg public key algorithm
+ * \param oid place to store ASN.1 OID string pointer
+ * \param olen length of the OID
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_OID_NOT_FOUND
+ */
+int mbedcrypto_oid_get_oid_by_sig_alg( mbedcrypto_pk_type_t pk_alg, mbedcrypto_md_type_t md_alg,
+ const char **oid, size_t *olen );
+
+/**
+ * \brief Translate hash algorithm OID into md_type
+ *
+ * \param oid OID to use
+ * \param md_alg place to store message digest algorithm
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_OID_NOT_FOUND
+ */
+int mbedcrypto_oid_get_md_alg( const mbedcrypto_asn1_buf *oid, mbedcrypto_md_type_t *md_alg );
+
+/**
+ * \brief Translate hmac algorithm OID into md_type
+ *
+ * \param oid OID to use
+ * \param md_hmac place to store message hmac algorithm
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_OID_NOT_FOUND
+ */
+int mbedcrypto_oid_get_md_hmac( const mbedcrypto_asn1_buf *oid, mbedcrypto_md_type_t *md_hmac );
+#endif /* MBEDCRYPTO_MD_C */
+
+/**
+ * \brief Translate Extended Key Usage OID into description
+ *
+ * \param oid OID to use
+ * \param desc place to store string pointer
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_OID_NOT_FOUND
+ */
+int mbedcrypto_oid_get_extended_key_usage( const mbedcrypto_asn1_buf *oid, const char **desc );
+
+/**
+ * \brief Translate md_type into hash algorithm OID
+ *
+ * \param md_alg message digest algorithm
+ * \param oid place to store ASN.1 OID string pointer
+ * \param olen length of the OID
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_OID_NOT_FOUND
+ */
+int mbedcrypto_oid_get_oid_by_md( mbedcrypto_md_type_t md_alg, const char **oid, size_t *olen );
+
+#if defined(MBEDCRYPTO_CIPHER_C)
+/**
+ * \brief Translate encryption algorithm OID into cipher_type
+ *
+ * \param oid OID to use
+ * \param cipher_alg place to store cipher algorithm
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_OID_NOT_FOUND
+ */
+int mbedcrypto_oid_get_cipher_alg( const mbedcrypto_asn1_buf *oid, mbedcrypto_cipher_type_t *cipher_alg );
+#endif /* MBEDCRYPTO_CIPHER_C */
+
+#if defined(MBEDCRYPTO_PKCS12_C)
+/**
+ * \brief Translate PKCS#12 PBE algorithm OID into md_type and
+ * cipher_type
+ *
+ * \param oid OID to use
+ * \param md_alg place to store message digest algorithm
+ * \param cipher_alg place to store cipher algorithm
+ *
+ * \return 0 if successful, or MBEDCRYPTO_ERR_OID_NOT_FOUND
+ */
+int mbedcrypto_oid_get_pkcs12_pbe_alg( const mbedcrypto_asn1_buf *oid, mbedcrypto_md_type_t *md_alg,
+ mbedcrypto_cipher_type_t *cipher_alg );
+#endif /* MBEDCRYPTO_PKCS12_C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* oid.h */
diff --git a/include/mbedcrypto/pem.h b/include/mbedcrypto/pem.h
new file mode 100644
index 0000000..e742eea
--- /dev/null
+++ b/include/mbedcrypto/pem.h
@@ -0,0 +1,130 @@
+/**
+ * \file pem.h
+ *
+ * \brief Privacy Enhanced Mail (PEM) decoding
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_PEM_H
+#define MBEDCRYPTO_PEM_H
+
+#include <stddef.h>
+
+/**
+ * \name PEM Error codes
+ * These error codes are returned in case of errors reading the
+ * PEM data.
+ * \{
+ */
+#define MBEDCRYPTO_ERR_PEM_NO_HEADER_FOOTER_PRESENT -0x1080 /**< No PEM header or footer found. */
+#define MBEDCRYPTO_ERR_PEM_INVALID_DATA -0x1100 /**< PEM string is not as expected. */
+#define MBEDCRYPTO_ERR_PEM_ALLOC_FAILED -0x1180 /**< Failed to allocate memory. */
+#define MBEDCRYPTO_ERR_PEM_INVALID_ENC_IV -0x1200 /**< RSA IV is not in hex-format. */
+#define MBEDCRYPTO_ERR_PEM_UNKNOWN_ENC_ALG -0x1280 /**< Unsupported key encryption algorithm. */
+#define MBEDCRYPTO_ERR_PEM_PASSWORD_REQUIRED -0x1300 /**< Private key password can't be empty. */
+#define MBEDCRYPTO_ERR_PEM_PASSWORD_MISMATCH -0x1380 /**< Given private key password does not allow for correct decryption. */
+#define MBEDCRYPTO_ERR_PEM_FEATURE_UNAVAILABLE -0x1400 /**< Unavailable feature, e.g. hashing/encryption combination. */
+#define MBEDCRYPTO_ERR_PEM_BAD_INPUT_DATA -0x1480 /**< Bad input parameters to function. */
+/* \} name */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDCRYPTO_PEM_PARSE_C)
+/**
+ * \brief PEM context structure
+ */
+typedef struct
+{
+ unsigned char *buf; /*!< buffer for decoded data */
+ size_t buflen; /*!< length of the buffer */
+ unsigned char *info; /*!< buffer for extra header information */
+}
+mbedcrypto_pem_context;
+
+/**
+ * \brief PEM context setup
+ *
+ * \param ctx context to be initialized
+ */
+void mbedcrypto_pem_init( mbedcrypto_pem_context *ctx );
+
+/**
+ * \brief Read a buffer for PEM information and store the resulting
+ * data into the specified context buffers.
+ *
+ * \param ctx context to use
+ * \param header header string to seek and expect
+ * \param footer footer string to seek and expect
+ * \param data source data to look in (must be nul-terminated)
+ * \param pwd password for decryption (can be NULL)
+ * \param pwdlen length of password
+ * \param use_len destination for total length used (set after header is
+ * correctly read, so unless you get
+ * MBEDCRYPTO_ERR_PEM_BAD_INPUT_DATA or
+ * MBEDCRYPTO_ERR_PEM_NO_HEADER_FOOTER_PRESENT, use_len is
+ * the length to skip)
+ *
+ * \note Attempts to check password correctness by verifying if
+ * the decrypted text starts with an ASN.1 sequence of
+ * appropriate length
+ *
+ * \return 0 on success, or a specific PEM error code
+ */
+int mbedcrypto_pem_read_buffer( mbedcrypto_pem_context *ctx, const char *header, const char *footer,
+ const unsigned char *data,
+ const unsigned char *pwd,
+ size_t pwdlen, size_t *use_len );
+
+/**
+ * \brief PEM context memory freeing
+ *
+ * \param ctx context to be freed
+ */
+void mbedcrypto_pem_free( mbedcrypto_pem_context *ctx );
+#endif /* MBEDCRYPTO_PEM_PARSE_C */
+
+#if defined(MBEDCRYPTO_PEM_WRITE_C)
+/**
+ * \brief Write a buffer of PEM information from a DER encoded
+ * buffer.
+ *
+ * \param header header string to write
+ * \param footer footer string to write
+ * \param der_data DER data to write
+ * \param der_len length of the DER data
+ * \param buf buffer to write to
+ * \param buf_len length of output buffer
+ * \param olen total length written / required (if buf_len is not enough)
+ *
+ * \return 0 on success, or a specific PEM or BASE64 error code. On
+ * MBEDCRYPTO_ERR_BASE64_BUFFER_TOO_SMALL olen is the required
+ * size.
+ */
+int mbedcrypto_pem_write_buffer( const char *header, const char *footer,
+ const unsigned char *der_data, size_t der_len,
+ unsigned char *buf, size_t buf_len, size_t *olen );
+#endif /* MBEDCRYPTO_PEM_WRITE_C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* pem.h */
diff --git a/include/mbedcrypto/pk.h b/include/mbedcrypto/pk.h
new file mode 100644
index 0000000..469b96c
--- /dev/null
+++ b/include/mbedcrypto/pk.h
@@ -0,0 +1,618 @@
+/**
+ * \file pk.h
+ *
+ * \brief Public Key abstraction layer
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+#ifndef MBEDCRYPTO_PK_H
+#define MBEDCRYPTO_PK_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include "md.h"
+
+#if defined(MBEDCRYPTO_RSA_C)
+#include "rsa.h"
+#endif
+
+#if defined(MBEDCRYPTO_ECP_C)
+#include "ecp.h"
+#endif
+
+#if defined(MBEDCRYPTO_ECDSA_C)
+#include "ecdsa.h"
+#endif
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+ !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+#define MBEDCRYPTO_ERR_PK_ALLOC_FAILED -0x3F80 /**< Memory allocation failed. */
+#define MBEDCRYPTO_ERR_PK_TYPE_MISMATCH -0x3F00 /**< Type mismatch, eg attempt to encrypt with an ECDSA key */
+#define MBEDCRYPTO_ERR_PK_BAD_INPUT_DATA -0x3E80 /**< Bad input parameters to function. */
+#define MBEDCRYPTO_ERR_PK_FILE_IO_ERROR -0x3E00 /**< Read/write of file failed. */
+#define MBEDCRYPTO_ERR_PK_KEY_INVALID_VERSION -0x3D80 /**< Unsupported key version */
+#define MBEDCRYPTO_ERR_PK_KEY_INVALID_FORMAT -0x3D00 /**< Invalid key tag or value. */
+#define MBEDCRYPTO_ERR_PK_UNKNOWN_PK_ALG -0x3C80 /**< Key algorithm is unsupported (only RSA and EC are supported). */
+#define MBEDCRYPTO_ERR_PK_PASSWORD_REQUIRED -0x3C00 /**< Private key password can't be empty. */
+#define MBEDCRYPTO_ERR_PK_PASSWORD_MISMATCH -0x3B80 /**< Given private key password does not allow for correct decryption. */
+#define MBEDCRYPTO_ERR_PK_INVALID_PUBKEY -0x3B00 /**< The pubkey tag or value is invalid (only RSA and EC are supported). */
+#define MBEDCRYPTO_ERR_PK_INVALID_ALG -0x3A80 /**< The algorithm tag or value is invalid. */
+#define MBEDCRYPTO_ERR_PK_UNKNOWN_NAMED_CURVE -0x3A00 /**< Elliptic curve is unsupported (only NIST curves are supported). */
+#define MBEDCRYPTO_ERR_PK_FEATURE_UNAVAILABLE -0x3980 /**< Unavailable feature, e.g. RSA disabled for RSA key. */
+#define MBEDCRYPTO_ERR_PK_SIG_LEN_MISMATCH -0x3900 /**< The buffer contains a valid signature followed by more data. */
+#define MBEDCRYPTO_ERR_PK_HW_ACCEL_FAILED -0x3880 /**< PK hardware accelerator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Public key types
+ */
+typedef enum {
+ MBEDCRYPTO_PK_NONE=0,
+ MBEDCRYPTO_PK_RSA,
+ MBEDCRYPTO_PK_ECKEY,
+ MBEDCRYPTO_PK_ECKEY_DH,
+ MBEDCRYPTO_PK_ECDSA,
+ MBEDCRYPTO_PK_RSA_ALT,
+ MBEDCRYPTO_PK_RSASSA_PSS,
+} mbedcrypto_pk_type_t;
+
+/**
+ * \brief Options for RSASSA-PSS signature verification.
+ * See \c mbedcrypto_rsa_rsassa_pss_verify_ext()
+ */
+typedef struct
+{
+ mbedcrypto_md_type_t mgf1_hash_id;
+ int expected_salt_len;
+
+} mbedcrypto_pk_rsassa_pss_options;
+
+/**
+ * \brief Types for interfacing with the debug module
+ */
+typedef enum
+{
+ MBEDCRYPTO_PK_DEBUG_NONE = 0,
+ MBEDCRYPTO_PK_DEBUG_MPI,
+ MBEDCRYPTO_PK_DEBUG_ECP,
+} mbedcrypto_pk_debug_type;
+
+/**
+ * \brief Item to send to the debug module
+ */
+typedef struct
+{
+ mbedcrypto_pk_debug_type type;
+ const char *name;
+ void *value;
+} mbedcrypto_pk_debug_item;
+
+/** Maximum number of item send for debugging, plus 1 */
+#define MBEDCRYPTO_PK_DEBUG_MAX_ITEMS 3
+
+/**
+ * \brief Public key information and operations
+ */
+typedef struct mbedcrypto_pk_info_t mbedcrypto_pk_info_t;
+
+/**
+ * \brief Public key container
+ */
+typedef struct
+{
+ const mbedcrypto_pk_info_t * pk_info; /**< Public key informations */
+ void * pk_ctx; /**< Underlying public key context */
+} mbedcrypto_pk_context;
+
+#if defined(MBEDCRYPTO_RSA_C)
+/**
+ * Quick access to an RSA context inside a PK context.
+ *
+ * \warning You must make sure the PK context actually holds an RSA context
+ * before using this function!
+ */
+static inline mbedcrypto_rsa_context *mbedcrypto_pk_rsa( const mbedcrypto_pk_context pk )
+{
+ return( (mbedcrypto_rsa_context *) (pk).pk_ctx );
+}
+#endif /* MBEDCRYPTO_RSA_C */
+
+#if defined(MBEDCRYPTO_ECP_C)
+/**
+ * Quick access to an EC context inside a PK context.
+ *
+ * \warning You must make sure the PK context actually holds an EC context
+ * before using this function!
+ */
+static inline mbedcrypto_ecp_keypair *mbedcrypto_pk_ec( const mbedcrypto_pk_context pk )
+{
+ return( (mbedcrypto_ecp_keypair *) (pk).pk_ctx );
+}
+#endif /* MBEDCRYPTO_ECP_C */
+
+#if defined(MBEDCRYPTO_PK_RSA_ALT_SUPPORT)
+/**
+ * \brief Types for RSA-alt abstraction
+ */
+typedef int (*mbedcrypto_pk_rsa_alt_decrypt_func)( void *ctx, int mode, size_t *olen,
+ const unsigned char *input, unsigned char *output,
+ size_t output_max_len );
+typedef int (*mbedcrypto_pk_rsa_alt_sign_func)( void *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+ int mode, mbedcrypto_md_type_t md_alg, unsigned int hashlen,
+ const unsigned char *hash, unsigned char *sig );
+typedef size_t (*mbedcrypto_pk_rsa_alt_key_len_func)( void *ctx );
+#endif /* MBEDCRYPTO_PK_RSA_ALT_SUPPORT */
+
+/**
+ * \brief Return information associated with the given PK type
+ *
+ * \param pk_type PK type to search for.
+ *
+ * \return The PK info associated with the type or NULL if not found.
+ */
+const mbedcrypto_pk_info_t *mbedcrypto_pk_info_from_type( mbedcrypto_pk_type_t pk_type );
+
+/**
+ * \brief Initialize a mbedcrypto_pk_context (as NONE)
+ */
+void mbedcrypto_pk_init( mbedcrypto_pk_context *ctx );
+
+/**
+ * \brief Free a mbedcrypto_pk_context
+ */
+void mbedcrypto_pk_free( mbedcrypto_pk_context *ctx );
+
+/**
+ * \brief Initialize a PK context with the information given
+ * and allocates the type-specific PK subcontext.
+ *
+ * \param ctx Context to initialize. Must be empty (type NONE).
+ * \param info Information to use
+ *
+ * \return 0 on success,
+ * MBEDCRYPTO_ERR_PK_BAD_INPUT_DATA on invalid input,
+ * MBEDCRYPTO_ERR_PK_ALLOC_FAILED on allocation failure.
+ *
+ * \note For contexts holding an RSA-alt key, use
+ * \c mbedcrypto_pk_setup_rsa_alt() instead.
+ */
+int mbedcrypto_pk_setup( mbedcrypto_pk_context *ctx, const mbedcrypto_pk_info_t *info );
+
+#if defined(MBEDCRYPTO_PK_RSA_ALT_SUPPORT)
+/**
+ * \brief Initialize an RSA-alt context
+ *
+ * \param ctx Context to initialize. Must be empty (type NONE).
+ * \param key RSA key pointer
+ * \param decrypt_func Decryption function
+ * \param sign_func Signing function
+ * \param key_len_func Function returning key length in bytes
+ *
+ * \return 0 on success, or MBEDCRYPTO_ERR_PK_BAD_INPUT_DATA if the
+ * context wasn't already initialized as RSA_ALT.
+ *
+ * \note This function replaces \c mbedcrypto_pk_setup() for RSA-alt.
+ */
+int mbedcrypto_pk_setup_rsa_alt( mbedcrypto_pk_context *ctx, void * key,
+ mbedcrypto_pk_rsa_alt_decrypt_func decrypt_func,
+ mbedcrypto_pk_rsa_alt_sign_func sign_func,
+ mbedcrypto_pk_rsa_alt_key_len_func key_len_func );
+#endif /* MBEDCRYPTO_PK_RSA_ALT_SUPPORT */
+
+/**
+ * \brief Get the size in bits of the underlying key
+ *
+ * \param ctx Context to use
+ *
+ * \return Key size in bits, or 0 on error
+ */
+size_t mbedcrypto_pk_get_bitlen( const mbedcrypto_pk_context *ctx );
+
+/**
+ * \brief Get the length in bytes of the underlying key
+ * \param ctx Context to use
+ *
+ * \return Key length in bytes, or 0 on error
+ */
+static inline size_t mbedcrypto_pk_get_len( const mbedcrypto_pk_context *ctx )
+{
+ return( ( mbedcrypto_pk_get_bitlen( ctx ) + 7 ) / 8 );
+}
+
+/**
+ * \brief Tell if a context can do the operation given by type
+ *
+ * \param ctx Context to test
+ * \param type Target type
+ *
+ * \return 0 if context can't do the operations,
+ * 1 otherwise.
+ */
+int mbedcrypto_pk_can_do( const mbedcrypto_pk_context *ctx, mbedcrypto_pk_type_t type );
+
+/**
+ * \brief Verify signature (including padding if relevant).
+ *
+ * \param ctx PK context to use
+ * \param md_alg Hash algorithm used (see notes)
+ * \param hash Hash of the message to sign
+ * \param hash_len Hash length or 0 (see notes)
+ * \param sig Signature to verify
+ * \param sig_len Signature length
+ *
+ * \return 0 on success (signature is valid),
+ * #MBEDCRYPTO_ERR_PK_SIG_LEN_MISMATCH if there is a valid
+ * signature in sig but its length is less than \p siglen,
+ * or a specific error code.
+ *
+ * \note For RSA keys, the default padding type is PKCS#1 v1.5.
+ * Use \c mbedcrypto_pk_verify_ext( MBEDCRYPTO_PK_RSASSA_PSS, ... )
+ * to verify RSASSA_PSS signatures.
+ *
+ * \note If hash_len is 0, then the length associated with md_alg
+ * is used instead, or an error returned if it is invalid.
+ *
+ * \note md_alg may be MBEDCRYPTO_MD_NONE, only if hash_len != 0
+ */
+int mbedcrypto_pk_verify( mbedcrypto_pk_context *ctx, mbedcrypto_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ const unsigned char *sig, size_t sig_len );
+
+/**
+ * \brief Verify signature, with options.
+ * (Includes verification of the padding depending on type.)
+ *
+ * \param type Signature type (inc. possible padding type) to verify
+ * \param options Pointer to type-specific options, or NULL
+ * \param ctx PK context to use
+ * \param md_alg Hash algorithm used (see notes)
+ * \param hash Hash of the message to sign
+ * \param hash_len Hash length or 0 (see notes)
+ * \param sig Signature to verify
+ * \param sig_len Signature length
+ *
+ * \return 0 on success (signature is valid),
+ * #MBEDCRYPTO_ERR_PK_TYPE_MISMATCH if the PK context can't be
+ * used for this type of signatures,
+ * #MBEDCRYPTO_ERR_PK_SIG_LEN_MISMATCH if there is a valid
+ * signature in sig but its length is less than \p siglen,
+ * or a specific error code.
+ *
+ * \note If hash_len is 0, then the length associated with md_alg
+ * is used instead, or an error returned if it is invalid.
+ *
+ * \note md_alg may be MBEDCRYPTO_MD_NONE, only if hash_len != 0
+ *
+ * \note If type is MBEDCRYPTO_PK_RSASSA_PSS, then options must point
+ * to a mbedcrypto_pk_rsassa_pss_options structure,
+ * otherwise it must be NULL.
+ */
+int mbedcrypto_pk_verify_ext( mbedcrypto_pk_type_t type, const void *options,
+ mbedcrypto_pk_context *ctx, mbedcrypto_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ const unsigned char *sig, size_t sig_len );
+
+/**
+ * \brief Make signature, including padding if relevant.
+ *
+ * \param ctx PK context to use - must hold a private key
+ * \param md_alg Hash algorithm used (see notes)
+ * \param hash Hash of the message to sign
+ * \param hash_len Hash length or 0 (see notes)
+ * \param sig Place to write the signature
+ * \param sig_len Number of bytes written
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
+ *
+ * \return 0 on success, or a specific error code.
+ *
+ * \note For RSA keys, the default padding type is PKCS#1 v1.5.
+ * There is no interface in the PK module to make RSASSA-PSS
+ * signatures yet.
+ *
+ * \note If hash_len is 0, then the length associated with md_alg
+ * is used instead, or an error returned if it is invalid.
+ *
+ * \note For RSA, md_alg may be MBEDCRYPTO_MD_NONE if hash_len != 0.
+ * For ECDSA, md_alg may never be MBEDCRYPTO_MD_NONE.
+ */
+int mbedcrypto_pk_sign( mbedcrypto_pk_context *ctx, mbedcrypto_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ unsigned char *sig, size_t *sig_len,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+
+/**
+ * \brief Decrypt message (including padding if relevant).
+ *
+ * \param ctx PK context to use - must hold a private key
+ * \param input Input to decrypt
+ * \param ilen Input size
+ * \param output Decrypted output
+ * \param olen Decrypted message length
+ * \param osize Size of the output buffer
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
+ *
+ * \note For RSA keys, the default padding type is PKCS#1 v1.5.
+ *
+ * \return 0 on success, or a specific error code.
+ */
+int mbedcrypto_pk_decrypt( mbedcrypto_pk_context *ctx,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen, size_t osize,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+
+/**
+ * \brief Encrypt message (including padding if relevant).
+ *
+ * \param ctx PK context to use
+ * \param input Message to encrypt
+ * \param ilen Message size
+ * \param output Encrypted output
+ * \param olen Encrypted output length
+ * \param osize Size of the output buffer
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
+ *
+ * \note For RSA keys, the default padding type is PKCS#1 v1.5.
+ *
+ * \return 0 on success, or a specific error code.
+ */
+int mbedcrypto_pk_encrypt( mbedcrypto_pk_context *ctx,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen, size_t osize,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+
+/**
+ * \brief Check if a public-private pair of keys matches.
+ *
+ * \param pub Context holding a public key.
+ * \param prv Context holding a private (and public) key.
+ *
+ * \return 0 on success or MBEDCRYPTO_ERR_PK_BAD_INPUT_DATA
+ */
+int mbedcrypto_pk_check_pair( const mbedcrypto_pk_context *pub, const mbedcrypto_pk_context *prv );
+
+/**
+ * \brief Export debug information
+ *
+ * \param ctx Context to use
+ * \param items Place to write debug items
+ *
+ * \return 0 on success or MBEDCRYPTO_ERR_PK_BAD_INPUT_DATA
+ */
+int mbedcrypto_pk_debug( const mbedcrypto_pk_context *ctx, mbedcrypto_pk_debug_item *items );
+
+/**
+ * \brief Access the type name
+ *
+ * \param ctx Context to use
+ *
+ * \return Type name on success, or "invalid PK"
+ */
+const char * mbedcrypto_pk_get_name( const mbedcrypto_pk_context *ctx );
+
+/**
+ * \brief Get the key type
+ *
+ * \param ctx Context to use
+ *
+ * \return Type on success, or MBEDCRYPTO_PK_NONE
+ */
+mbedcrypto_pk_type_t mbedcrypto_pk_get_type( const mbedcrypto_pk_context *ctx );
+
+#if defined(MBEDCRYPTO_PK_PARSE_C)
+/** \ingroup pk_module */
+/**
+ * \brief Parse a private key in PEM or DER format
+ *
+ * \param ctx key to be initialized
+ * \param key input buffer
+ * \param keylen size of the buffer
+ * (including the terminating null byte for PEM data)
+ * \param pwd password for decryption (optional)
+ * \param pwdlen size of the password
+ *
+ * \note On entry, ctx must be empty, either freshly initialised
+ * with mbedcrypto_pk_init() or reset with mbedcrypto_pk_free(). If you need a
+ * specific key type, check the result with mbedcrypto_pk_can_do().
+ *
+ * \note The key is also checked for correctness.
+ *
+ * \return 0 if successful, or a specific PK or PEM error code
+ */
+int mbedcrypto_pk_parse_key( mbedcrypto_pk_context *ctx,
+ const unsigned char *key, size_t keylen,
+ const unsigned char *pwd, size_t pwdlen );
+
+/** \ingroup pk_module */
+/**
+ * \brief Parse a public key in PEM or DER format
+ *
+ * \param ctx key to be initialized
+ * \param key input buffer
+ * \param keylen size of the buffer
+ * (including the terminating null byte for PEM data)
+ *
+ * \note On entry, ctx must be empty, either freshly initialised
+ * with mbedcrypto_pk_init() or reset with mbedcrypto_pk_free(). If you need a
+ * specific key type, check the result with mbedcrypto_pk_can_do().
+ *
+ * \note The key is also checked for correctness.
+ *
+ * \return 0 if successful, or a specific PK or PEM error code
+ */
+int mbedcrypto_pk_parse_public_key( mbedcrypto_pk_context *ctx,
+ const unsigned char *key, size_t keylen );
+
+#if defined(MBEDCRYPTO_FS_IO)
+/** \ingroup pk_module */
+/**
+ * \brief Load and parse a private key
+ *
+ * \param ctx key to be initialized
+ * \param path filename to read the private key from
+ * \param password password to decrypt the file (can be NULL)
+ *
+ * \note On entry, ctx must be empty, either freshly initialised
+ * with mbedcrypto_pk_init() or reset with mbedcrypto_pk_free(). If you need a
+ * specific key type, check the result with mbedcrypto_pk_can_do().
+ *
+ * \note The key is also checked for correctness.
+ *
+ * \return 0 if successful, or a specific PK or PEM error code
+ */
+int mbedcrypto_pk_parse_keyfile( mbedcrypto_pk_context *ctx,
+ const char *path, const char *password );
+
+/** \ingroup pk_module */
+/**
+ * \brief Load and parse a public key
+ *
+ * \param ctx key to be initialized
+ * \param path filename to read the public key from
+ *
+ * \note On entry, ctx must be empty, either freshly initialised
+ * with mbedcrypto_pk_init() or reset with mbedcrypto_pk_free(). If
+ * you need a specific key type, check the result with
+ * mbedcrypto_pk_can_do().
+ *
+ * \note The key is also checked for correctness.
+ *
+ * \return 0 if successful, or a specific PK or PEM error code
+ */
+int mbedcrypto_pk_parse_public_keyfile( mbedcrypto_pk_context *ctx, const char *path );
+#endif /* MBEDCRYPTO_FS_IO */
+#endif /* MBEDCRYPTO_PK_PARSE_C */
+
+#if defined(MBEDCRYPTO_PK_WRITE_C)
+/**
+ * \brief Write a private key to a PKCS#1 or SEC1 DER structure
+ * Note: data is written at the end of the buffer! Use the
+ * return value to determine where you should start
+ * using the buffer
+ *
+ * \param ctx private to write away
+ * \param buf buffer to write to
+ * \param size size of the buffer
+ *
+ * \return length of data written if successful, or a specific
+ * error code
+ */
+int mbedcrypto_pk_write_key_der( mbedcrypto_pk_context *ctx, unsigned char *buf, size_t size );
+
+/**
+ * \brief Write a public key to a SubjectPublicKeyInfo DER structure
+ * Note: data is written at the end of the buffer! Use the
+ * return value to determine where you should start
+ * using the buffer
+ *
+ * \param ctx public key to write away
+ * \param buf buffer to write to
+ * \param size size of the buffer
+ *
+ * \return length of data written if successful, or a specific
+ * error code
+ */
+int mbedcrypto_pk_write_pubkey_der( mbedcrypto_pk_context *ctx, unsigned char *buf, size_t size );
+
+#if defined(MBEDCRYPTO_PEM_WRITE_C)
+/**
+ * \brief Write a public key to a PEM string
+ *
+ * \param ctx public key to write away
+ * \param buf buffer to write to
+ * \param size size of the buffer
+ *
+ * \return 0 if successful, or a specific error code
+ */
+int mbedcrypto_pk_write_pubkey_pem( mbedcrypto_pk_context *ctx, unsigned char *buf, size_t size );
+
+/**
+ * \brief Write a private key to a PKCS#1 or SEC1 PEM string
+ *
+ * \param ctx private to write away
+ * \param buf buffer to write to
+ * \param size size of the buffer
+ *
+ * \return 0 if successful, or a specific error code
+ */
+int mbedcrypto_pk_write_key_pem( mbedcrypto_pk_context *ctx, unsigned char *buf, size_t size );
+#endif /* MBEDCRYPTO_PEM_WRITE_C */
+#endif /* MBEDCRYPTO_PK_WRITE_C */
+
+/*
+ * WARNING: Low-level functions. You probably do not want to use these unless
+ * you are certain you do ;)
+ */
+
+#if defined(MBEDCRYPTO_PK_PARSE_C)
+/**
+ * \brief Parse a SubjectPublicKeyInfo DER structure
+ *
+ * \param p the position in the ASN.1 data
+ * \param end end of the buffer
+ * \param pk the key to fill
+ *
+ * \return 0 if successful, or a specific PK error code
+ */
+int mbedcrypto_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
+ mbedcrypto_pk_context *pk );
+#endif /* MBEDCRYPTO_PK_PARSE_C */
+
+#if defined(MBEDCRYPTO_PK_WRITE_C)
+/**
+ * \brief Write a subjectPublicKey to ASN.1 data
+ * Note: function works backwards in data buffer
+ *
+ * \param p reference to current position pointer
+ * \param start start of the buffer (for bounds-checking)
+ * \param key public key to write away
+ *
+ * \return the length written or a negative error code
+ */
+int mbedcrypto_pk_write_pubkey( unsigned char **p, unsigned char *start,
+ const mbedcrypto_pk_context *key );
+#endif /* MBEDCRYPTO_PK_WRITE_C */
+
+/*
+ * Internal module functions. You probably do not want to use these unless you
+ * know you do.
+ */
+#if defined(MBEDCRYPTO_FS_IO)
+int mbedcrypto_pk_load_file( const char *path, unsigned char **buf, size_t *n );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDCRYPTO_PK_H */
diff --git a/include/mbedcrypto/pk_internal.h b/include/mbedcrypto/pk_internal.h
new file mode 100644
index 0000000..b208c6e
--- /dev/null
+++ b/include/mbedcrypto/pk_internal.h
@@ -0,0 +1,115 @@
+/**
+ * \file pk_internal.h
+ *
+ * \brief Public Key abstraction layer: wrapper functions
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+#ifndef MBEDCRYPTO_PK_WRAP_H
+#define MBEDCRYPTO_PK_WRAP_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include "pk.h"
+
+struct mbedcrypto_pk_info_t
+{
+ /** Public key type */
+ mbedcrypto_pk_type_t type;
+
+ /** Type name */
+ const char *name;
+
+ /** Get key size in bits */
+ size_t (*get_bitlen)( const void * );
+
+ /** Tell if the context implements this type (e.g. ECKEY can do ECDSA) */
+ int (*can_do)( mbedcrypto_pk_type_t type );
+
+ /** Verify signature */
+ int (*verify_func)( void *ctx, mbedcrypto_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ const unsigned char *sig, size_t sig_len );
+
+ /** Make signature */
+ int (*sign_func)( void *ctx, mbedcrypto_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ unsigned char *sig, size_t *sig_len,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
+ /** Decrypt message */
+ int (*decrypt_func)( void *ctx, const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen, size_t osize,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
+ /** Encrypt message */
+ int (*encrypt_func)( void *ctx, const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen, size_t osize,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
+ /** Check public-private key pair */
+ int (*check_pair_func)( const void *pub, const void *prv );
+
+ /** Allocate a new context */
+ void * (*ctx_alloc_func)( void );
+
+ /** Free the given context */
+ void (*ctx_free_func)( void *ctx );
+
+ /** Interface with the debug module */
+ void (*debug_func)( const void *ctx, mbedcrypto_pk_debug_item *items );
+
+};
+#if defined(MBEDCRYPTO_PK_RSA_ALT_SUPPORT)
+/* Container for RSA-alt */
+typedef struct
+{
+ void *key;
+ mbedcrypto_pk_rsa_alt_decrypt_func decrypt_func;
+ mbedcrypto_pk_rsa_alt_sign_func sign_func;
+ mbedcrypto_pk_rsa_alt_key_len_func key_len_func;
+} mbedcrypto_rsa_alt_context;
+#endif
+
+#if defined(MBEDCRYPTO_RSA_C)
+extern const mbedcrypto_pk_info_t mbedcrypto_rsa_info;
+#endif
+
+#if defined(MBEDCRYPTO_ECP_C)
+extern const mbedcrypto_pk_info_t mbedcrypto_eckey_info;
+extern const mbedcrypto_pk_info_t mbedcrypto_eckeydh_info;
+#endif
+
+#if defined(MBEDCRYPTO_ECDSA_C)
+extern const mbedcrypto_pk_info_t mbedcrypto_ecdsa_info;
+#endif
+
+#if defined(MBEDCRYPTO_PK_RSA_ALT_SUPPORT)
+extern const mbedcrypto_pk_info_t mbedcrypto_rsa_alt_info;
+#endif
+
+#endif /* MBEDCRYPTO_PK_WRAP_H */
diff --git a/include/mbedcrypto/pkcs11.h b/include/mbedcrypto/pkcs11.h
new file mode 100644
index 0000000..2233ec8
--- /dev/null
+++ b/include/mbedcrypto/pkcs11.h
@@ -0,0 +1,174 @@
+/**
+ * \file pkcs11.h
+ *
+ * \brief Wrapper for PKCS#11 library libpkcs11-helper
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_PKCS11_H
+#define MBEDCRYPTO_PKCS11_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#if defined(MBEDCRYPTO_PKCS11_C)
+
+#include "x509_crt.h"
+
+#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+ !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Context for PKCS #11 private keys.
+ */
+typedef struct {
+ pkcs11h_certificate_t pkcs11h_cert;
+ int len;
+} mbedcrypto_pkcs11_context;
+
+/**
+ * Initialize a mbedcrypto_pkcs11_context.
+ * (Just making memory references valid.)
+ */
+void mbedcrypto_pkcs11_init( mbedcrypto_pkcs11_context *ctx );
+
+/**
+ * Fill in a Mbed Crypto certificate, based on the given PKCS11 helper certificate.
+ *
+ * \param cert X.509 certificate to fill
+ * \param pkcs11h_cert PKCS #11 helper certificate
+ *
+ * \return 0 on success.
+ */
+int mbedcrypto_pkcs11_x509_cert_bind( mbedcrypto_x509_crt *cert, pkcs11h_certificate_t pkcs11h_cert );
+
+/**
+ * Set up a mbedcrypto_pkcs11_context storing the given certificate. Note that the
+ * mbedcrypto_pkcs11_context will take over control of the certificate, freeing it when
+ * done.
+ *
+ * \param priv_key Private key structure to fill.
+ * \param pkcs11_cert PKCS #11 helper certificate
+ *
+ * \return 0 on success
+ */
+int mbedcrypto_pkcs11_priv_key_bind( mbedcrypto_pkcs11_context *priv_key,
+ pkcs11h_certificate_t pkcs11_cert );
+
+/**
+ * Free the contents of the given private key context. Note that the structure
+ * itself is not freed.
+ *
+ * \param priv_key Private key structure to cleanup
+ */
+void mbedcrypto_pkcs11_priv_key_free( mbedcrypto_pkcs11_context *priv_key );
+
+/**
+ * \brief Do an RSA private key decrypt, then remove the message
+ * padding
+ *
+ * \param ctx PKCS #11 context
+ * \param mode must be MBEDCRYPTO_RSA_PRIVATE, for compatibility with rsa.c's signature
+ * \param input buffer holding the encrypted data
+ * \param output buffer that will hold the plaintext
+ * \param olen will contain the plaintext length
+ * \param output_max_len maximum length of the output buffer
+ *
+ * \return 0 if successful, or an MBEDCRYPTO_ERR_RSA_XXX error code
+ *
+ * \note The output buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
+ * an error is thrown.
+ */
+int mbedcrypto_pkcs11_decrypt( mbedcrypto_pkcs11_context *ctx,
+ int mode, size_t *olen,
+ const unsigned char *input,
+ unsigned char *output,
+ size_t output_max_len );
+
+/**
+ * \brief Do a private RSA to sign a message digest
+ *
+ * \param ctx PKCS #11 context
+ * \param mode must be MBEDCRYPTO_RSA_PRIVATE, for compatibility with rsa.c's signature
+ * \param md_alg a MBEDCRYPTO_MD_XXX (use MBEDCRYPTO_MD_NONE for signing raw data)
+ * \param hashlen message digest length (for MBEDCRYPTO_MD_NONE only)
+ * \param hash buffer holding the message digest
+ * \param sig buffer that will hold the ciphertext
+ *
+ * \return 0 if the signing operation was successful,
+ * or an MBEDCRYPTO_ERR_RSA_XXX error code
+ *
+ * \note The "sig" buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int mbedcrypto_pkcs11_sign( mbedcrypto_pkcs11_context *ctx,
+ int mode,
+ mbedcrypto_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig );
+
+/**
+ * SSL/TLS wrappers for PKCS#11 functions
+ */
+static inline int mbedcrypto_ssl_pkcs11_decrypt( void *ctx, int mode, size_t *olen,
+ const unsigned char *input, unsigned char *output,
+ size_t output_max_len )
+{
+ return mbedcrypto_pkcs11_decrypt( (mbedcrypto_pkcs11_context *) ctx, mode, olen, input, output,
+ output_max_len );
+}
+
+static inline int mbedcrypto_ssl_pkcs11_sign( void *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+ int mode, mbedcrypto_md_type_t md_alg, unsigned int hashlen,
+ const unsigned char *hash, unsigned char *sig )
+{
+ ((void) f_rng);
+ ((void) p_rng);
+ return mbedcrypto_pkcs11_sign( (mbedcrypto_pkcs11_context *) ctx, mode, md_alg,
+ hashlen, hash, sig );
+}
+
+static inline size_t mbedcrypto_ssl_pkcs11_key_len( void *ctx )
+{
+ return ( (mbedcrypto_pkcs11_context *) ctx )->len;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDCRYPTO_PKCS11_C */
+
+#endif /* MBEDCRYPTO_PKCS11_H */
diff --git a/include/mbedcrypto/pkcs12.h b/include/mbedcrypto/pkcs12.h
new file mode 100644
index 0000000..403f20a
--- /dev/null
+++ b/include/mbedcrypto/pkcs12.h
@@ -0,0 +1,120 @@
+/**
+ * \file pkcs12.h
+ *
+ * \brief PKCS#12 Personal Information Exchange Syntax
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_PKCS12_H
+#define MBEDCRYPTO_PKCS12_H
+
+#include "md.h"
+#include "cipher.h"
+#include "asn1.h"
+
+#include <stddef.h>
+
+#define MBEDCRYPTO_ERR_PKCS12_BAD_INPUT_DATA -0x1F80 /**< Bad input parameters to function. */
+#define MBEDCRYPTO_ERR_PKCS12_FEATURE_UNAVAILABLE -0x1F00 /**< Feature not available, e.g. unsupported encryption scheme. */
+#define MBEDCRYPTO_ERR_PKCS12_PBE_INVALID_FORMAT -0x1E80 /**< PBE ASN.1 data not as expected. */
+#define MBEDCRYPTO_ERR_PKCS12_PASSWORD_MISMATCH -0x1E00 /**< Given private key password does not allow for correct decryption. */
+
+#define MBEDCRYPTO_PKCS12_DERIVE_KEY 1 /**< encryption/decryption key */
+#define MBEDCRYPTO_PKCS12_DERIVE_IV 2 /**< initialization vector */
+#define MBEDCRYPTO_PKCS12_DERIVE_MAC_KEY 3 /**< integrity / MAC key */
+
+#define MBEDCRYPTO_PKCS12_PBE_DECRYPT 0
+#define MBEDCRYPTO_PKCS12_PBE_ENCRYPT 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief PKCS12 Password Based function (encryption / decryption)
+ * for pbeWithSHAAnd128BitRC4
+ *
+ * \param pbe_params an ASN1 buffer containing the pkcs-12PbeParams structure
+ * \param mode either MBEDCRYPTO_PKCS12_PBE_ENCRYPT or MBEDCRYPTO_PKCS12_PBE_DECRYPT
+ * \param pwd the password used (may be NULL if no password is used)
+ * \param pwdlen length of the password (may be 0)
+ * \param input the input data
+ * \param len data length
+ * \param output the output buffer
+ *
+ * \return 0 if successful, or a MBEDCRYPTO_ERR_XXX code
+ */
+int mbedcrypto_pkcs12_pbe_sha1_rc4_128( mbedcrypto_asn1_buf *pbe_params, int mode,
+ const unsigned char *pwd, size_t pwdlen,
+ const unsigned char *input, size_t len,
+ unsigned char *output );
+
+/**
+ * \brief PKCS12 Password Based function (encryption / decryption)
+ * for cipher-based and mbedcrypto_md-based PBE's
+ *
+ * \param pbe_params an ASN1 buffer containing the pkcs-12PbeParams structure
+ * \param mode either MBEDCRYPTO_PKCS12_PBE_ENCRYPT or MBEDCRYPTO_PKCS12_PBE_DECRYPT
+ * \param cipher_type the cipher used
+ * \param md_type the mbedcrypto_md used
+ * \param pwd the password used (may be NULL if no password is used)
+ * \param pwdlen length of the password (may be 0)
+ * \param input the input data
+ * \param len data length
+ * \param output the output buffer
+ *
+ * \return 0 if successful, or a MBEDCRYPTO_ERR_XXX code
+ */
+int mbedcrypto_pkcs12_pbe( mbedcrypto_asn1_buf *pbe_params, int mode,
+ mbedcrypto_cipher_type_t cipher_type, mbedcrypto_md_type_t md_type,
+ const unsigned char *pwd, size_t pwdlen,
+ const unsigned char *input, size_t len,
+ unsigned char *output );
+
+/**
+ * \brief The PKCS#12 derivation function uses a password and a salt
+ * to produce pseudo-random bits for a particular "purpose".
+ *
+ * Depending on the given id, this function can produce an
+ * encryption/decryption key, an nitialization vector or an
+ * integrity key.
+ *
+ * \param data buffer to store the derived data in
+ * \param datalen length to fill
+ * \param pwd password to use (may be NULL if no password is used)
+ * \param pwdlen length of the password (may be 0)
+ * \param salt salt buffer to use
+ * \param saltlen length of the salt
+ * \param mbedcrypto_md mbedcrypto_md type to use during the derivation
+ * \param id id that describes the purpose (can be MBEDCRYPTO_PKCS12_DERIVE_KEY,
+ * MBEDCRYPTO_PKCS12_DERIVE_IV or MBEDCRYPTO_PKCS12_DERIVE_MAC_KEY)
+ * \param iterations number of iterations
+ *
+ * \return 0 if successful, or a MD, BIGNUM type error.
+ */
+int mbedcrypto_pkcs12_derivation( unsigned char *data, size_t datalen,
+ const unsigned char *pwd, size_t pwdlen,
+ const unsigned char *salt, size_t saltlen,
+ mbedcrypto_md_type_t mbedcrypto_md, int id, int iterations );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* pkcs12.h */
diff --git a/include/mbedcrypto/pkcs5.h b/include/mbedcrypto/pkcs5.h
new file mode 100644
index 0000000..d3921cb
--- /dev/null
+++ b/include/mbedcrypto/pkcs5.h
@@ -0,0 +1,95 @@
+/**
+ * \file pkcs5.h
+ *
+ * \brief PKCS#5 functions
+ *
+ * \author Mathias Olsson <mathias@kompetensum.com>
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_PKCS5_H
+#define MBEDCRYPTO_PKCS5_H
+
+#include "asn1.h"
+#include "md.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MBEDCRYPTO_ERR_PKCS5_BAD_INPUT_DATA -0x2f80 /**< Bad input parameters to function. */
+#define MBEDCRYPTO_ERR_PKCS5_INVALID_FORMAT -0x2f00 /**< Unexpected ASN.1 data. */
+#define MBEDCRYPTO_ERR_PKCS5_FEATURE_UNAVAILABLE -0x2e80 /**< Requested encryption or digest alg not available. */
+#define MBEDCRYPTO_ERR_PKCS5_PASSWORD_MISMATCH -0x2e00 /**< Given private key password does not allow for correct decryption. */
+
+#define MBEDCRYPTO_PKCS5_DECRYPT 0
+#define MBEDCRYPTO_PKCS5_ENCRYPT 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief PKCS#5 PBES2 function
+ *
+ * \param pbe_params the ASN.1 algorithm parameters
+ * \param mode either MBEDCRYPTO_PKCS5_DECRYPT or MBEDCRYPTO_PKCS5_ENCRYPT
+ * \param pwd password to use when generating key
+ * \param pwdlen length of password
+ * \param data data to process
+ * \param datalen length of data
+ * \param output output buffer
+ *
+ * \returns 0 on success, or a MBEDCRYPTO_ERR_XXX code if verification fails.
+ */
+int mbedcrypto_pkcs5_pbes2( const mbedcrypto_asn1_buf *pbe_params, int mode,
+ const unsigned char *pwd, size_t pwdlen,
+ const unsigned char *data, size_t datalen,
+ unsigned char *output );
+
+/**
+ * \brief PKCS#5 PBKDF2 using HMAC
+ *
+ * \param ctx Generic HMAC context
+ * \param password Password to use when generating key
+ * \param plen Length of password
+ * \param salt Salt to use when generating key
+ * \param slen Length of salt
+ * \param iteration_count Iteration count
+ * \param key_length Length of generated key in bytes
+ * \param output Generated key. Must be at least as big as key_length
+ *
+ * \returns 0 on success, or a MBEDCRYPTO_ERR_XXX code if verification fails.
+ */
+int mbedcrypto_pkcs5_pbkdf2_hmac( mbedcrypto_md_context_t *ctx, const unsigned char *password,
+ size_t plen, const unsigned char *salt, size_t slen,
+ unsigned int iteration_count,
+ uint32_t key_length, unsigned char *output );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int mbedcrypto_pkcs5_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* pkcs5.h */
diff --git a/include/mbedcrypto/platform.h b/include/mbedcrypto/platform.h
new file mode 100644
index 0000000..61613f9
--- /dev/null
+++ b/include/mbedcrypto/platform.h
@@ -0,0 +1,363 @@
+/**
+ * \file platform.h
+ *
+ * \brief This file contains the definitions and functions of the
+ * Mbed Crypto platform abstraction layer.
+ *
+ * The platform abstraction layer removes the need for the library
+ * to directly link to standard C library functions or operating
+ * system services, making the library easier to port and embed.
+ * Application developers and users of the library can provide their own
+ * implementations of these functions, or implementations specific to
+ * their platform, which can be statically linked to the library or
+ * dynamically configured at runtime.
+ */
+/*
+ * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_PLATFORM_H
+#define MBEDCRYPTO_PLATFORM_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#if defined(MBEDCRYPTO_HAVE_TIME)
+#include "mbedcrypto/platform_time.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h or define them on the compiler command line.
+ * \{
+ */
+
+#if !defined(MBEDCRYPTO_PLATFORM_NO_STD_FUNCTIONS)
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#if !defined(MBEDCRYPTO_PLATFORM_STD_SNPRINTF)
+#if defined(_WIN32)
+#define MBEDCRYPTO_PLATFORM_STD_SNPRINTF mbedcrypto_platform_win32_snprintf /**< The default \c snprintf function to use. */
+#else
+#define MBEDCRYPTO_PLATFORM_STD_SNPRINTF snprintf /**< The default \c snprintf function to use. */
+#endif
+#endif
+#if !defined(MBEDCRYPTO_PLATFORM_STD_PRINTF)
+#define MBEDCRYPTO_PLATFORM_STD_PRINTF printf /**< The default \c printf function to use. */
+#endif
+#if !defined(MBEDCRYPTO_PLATFORM_STD_FPRINTF)
+#define MBEDCRYPTO_PLATFORM_STD_FPRINTF fprintf /**< The default \c fprintf function to use. */
+#endif
+#if !defined(MBEDCRYPTO_PLATFORM_STD_CALLOC)
+#define MBEDCRYPTO_PLATFORM_STD_CALLOC calloc /**< The default \c calloc function to use. */
+#endif
+#if !defined(MBEDCRYPTO_PLATFORM_STD_FREE)
+#define MBEDCRYPTO_PLATFORM_STD_FREE free /**< The default \c free function to use. */
+#endif
+#if !defined(MBEDCRYPTO_PLATFORM_STD_EXIT)
+#define MBEDCRYPTO_PLATFORM_STD_EXIT exit /**< The default \c exit function to use. */
+#endif
+#if !defined(MBEDCRYPTO_PLATFORM_STD_TIME)
+#define MBEDCRYPTO_PLATFORM_STD_TIME time /**< The default \c time function to use. */
+#endif
+#if !defined(MBEDCRYPTO_PLATFORM_STD_EXIT_SUCCESS)
+#define MBEDCRYPTO_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS /**< The default exit value to use. */
+#endif
+#if !defined(MBEDCRYPTO_PLATFORM_STD_EXIT_FAILURE)
+#define MBEDCRYPTO_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE /**< The default exit value to use. */
+#endif
+#if defined(MBEDCRYPTO_FS_IO)
+#if !defined(MBEDCRYPTO_PLATFORM_STD_NV_SEED_READ)
+#define MBEDCRYPTO_PLATFORM_STD_NV_SEED_READ mbedcrypto_platform_std_nv_seed_read
+#endif
+#if !defined(MBEDCRYPTO_PLATFORM_STD_NV_SEED_WRITE)
+#define MBEDCRYPTO_PLATFORM_STD_NV_SEED_WRITE mbedcrypto_platform_std_nv_seed_write
+#endif
+#if !defined(MBEDCRYPTO_PLATFORM_STD_NV_SEED_FILE)
+#define MBEDCRYPTO_PLATFORM_STD_NV_SEED_FILE "seedfile"
+#endif
+#endif /* MBEDCRYPTO_FS_IO */
+#else /* MBEDCRYPTO_PLATFORM_NO_STD_FUNCTIONS */
+#if defined(MBEDCRYPTO_PLATFORM_STD_MEM_HDR)
+#include MBEDCRYPTO_PLATFORM_STD_MEM_HDR
+#endif
+#endif /* MBEDCRYPTO_PLATFORM_NO_STD_FUNCTIONS */
+
+
+/* \} name SECTION: Module settings */
+
+/*
+ * The function pointers for calloc and free.
+ */
+#if defined(MBEDCRYPTO_PLATFORM_MEMORY)
+#if defined(MBEDCRYPTO_PLATFORM_FREE_MACRO) && \
+ defined(MBEDCRYPTO_PLATFORM_CALLOC_MACRO)
+#define mbedcrypto_free MBEDCRYPTO_PLATFORM_FREE_MACRO
+#define mbedcrypto_calloc MBEDCRYPTO_PLATFORM_CALLOC_MACRO
+#else
+/* For size_t */
+#include <stddef.h>
+extern void * (*mbedcrypto_calloc)( size_t n, size_t size );
+extern void (*mbedcrypto_free)( void *ptr );
+
+/**
+ * \brief This function dynamically sets the memory-management
+ * functions used by the library, during runtime.
+ *
+ * \param calloc_func The \c calloc function implementation.
+ * \param free_func The \c free function implementation.
+ *
+ * \return \c 0.
+ */
+int mbedcrypto_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
+ void (*free_func)( void * ) );
+#endif /* MBEDCRYPTO_PLATFORM_FREE_MACRO && MBEDCRYPTO_PLATFORM_CALLOC_MACRO */
+#else /* !MBEDCRYPTO_PLATFORM_MEMORY */
+#define mbedcrypto_free free
+#define mbedcrypto_calloc calloc
+#endif /* MBEDCRYPTO_PLATFORM_MEMORY && !MBEDCRYPTO_PLATFORM_{FREE,CALLOC}_MACRO */
+
+/*
+ * The function pointers for fprintf
+ */
+#if defined(MBEDCRYPTO_PLATFORM_FPRINTF_ALT)
+/* We need FILE * */
+#include <stdio.h>
+extern int (*mbedcrypto_fprintf)( FILE *stream, const char *format, ... );
+
+/**
+ * \brief This function dynamically configures the fprintf
+ * function that is called when the
+ * mbedcrypto_fprintf() function is invoked by the library.
+ *
+ * \param fprintf_func The \c fprintf function implementation.
+ *
+ * \return \c 0.
+ */
+int mbedcrypto_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *,
+ ... ) );
+#else
+#if defined(MBEDCRYPTO_PLATFORM_FPRINTF_MACRO)
+#define mbedcrypto_fprintf MBEDCRYPTO_PLATFORM_FPRINTF_MACRO
+#else
+#define mbedcrypto_fprintf fprintf
+#endif /* MBEDCRYPTO_PLATFORM_FPRINTF_MACRO */
+#endif /* MBEDCRYPTO_PLATFORM_FPRINTF_ALT */
+
+/*
+ * The function pointers for printf
+ */
+#if defined(MBEDCRYPTO_PLATFORM_PRINTF_ALT)
+extern int (*mbedcrypto_printf)( const char *format, ... );
+
+/**
+ * \brief This function dynamically configures the snprintf
+ * function that is called when the mbedcrypto_snprintf()
+ * function is invoked by the library.
+ *
+ * \param printf_func The \c printf function implementation.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_platform_set_printf( int (*printf_func)( const char *, ... ) );
+#else /* !MBEDCRYPTO_PLATFORM_PRINTF_ALT */
+#if defined(MBEDCRYPTO_PLATFORM_PRINTF_MACRO)
+#define mbedcrypto_printf MBEDCRYPTO_PLATFORM_PRINTF_MACRO
+#else
+#define mbedcrypto_printf printf
+#endif /* MBEDCRYPTO_PLATFORM_PRINTF_MACRO */
+#endif /* MBEDCRYPTO_PLATFORM_PRINTF_ALT */
+
+/*
+ * The function pointers for snprintf
+ *
+ * The snprintf implementation should conform to C99:
+ * - it *must* always correctly zero-terminate the buffer
+ * (except when n == 0, then it must leave the buffer untouched)
+ * - however it is acceptable to return -1 instead of the required length when
+ * the destination buffer is too short.
+ */
+#if defined(_WIN32)
+/* For Windows (inc. MSYS2), we provide our own fixed implementation */
+int mbedcrypto_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... );
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_SNPRINTF_ALT)
+extern int (*mbedcrypto_snprintf)( char * s, size_t n, const char * format, ... );
+
+/**
+ * \brief This function allows configuring a custom
+ * \c snprintf function pointer.
+ *
+ * \param snprintf_func The \c snprintf function implementation.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
+ const char * format, ... ) );
+#else /* MBEDCRYPTO_PLATFORM_SNPRINTF_ALT */
+#if defined(MBEDCRYPTO_PLATFORM_SNPRINTF_MACRO)
+#define mbedcrypto_snprintf MBEDCRYPTO_PLATFORM_SNPRINTF_MACRO
+#else
+#define mbedcrypto_snprintf MBEDCRYPTO_PLATFORM_STD_SNPRINTF
+#endif /* MBEDCRYPTO_PLATFORM_SNPRINTF_MACRO */
+#endif /* MBEDCRYPTO_PLATFORM_SNPRINTF_ALT */
+
+/*
+ * The function pointers for exit
+ */
+#if defined(MBEDCRYPTO_PLATFORM_EXIT_ALT)
+extern void (*mbedcrypto_exit)( int status );
+
+/**
+ * \brief This function dynamically configures the exit
+ * function that is called when the mbedcrypto_exit()
+ * function is invoked by the library.
+ *
+ * \param exit_func The \c exit function implementation.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_platform_set_exit( void (*exit_func)( int status ) );
+#else
+#if defined(MBEDCRYPTO_PLATFORM_EXIT_MACRO)
+#define mbedcrypto_exit MBEDCRYPTO_PLATFORM_EXIT_MACRO
+#else
+#define mbedcrypto_exit exit
+#endif /* MBEDCRYPTO_PLATFORM_EXIT_MACRO */
+#endif /* MBEDCRYPTO_PLATFORM_EXIT_ALT */
+
+/*
+ * The default exit values
+ */
+#if defined(MBEDCRYPTO_PLATFORM_STD_EXIT_SUCCESS)
+#define MBEDCRYPTO_EXIT_SUCCESS MBEDCRYPTO_PLATFORM_STD_EXIT_SUCCESS
+#else
+#define MBEDCRYPTO_EXIT_SUCCESS 0
+#endif
+#if defined(MBEDCRYPTO_PLATFORM_STD_EXIT_FAILURE)
+#define MBEDCRYPTO_EXIT_FAILURE MBEDCRYPTO_PLATFORM_STD_EXIT_FAILURE
+#else
+#define MBEDCRYPTO_EXIT_FAILURE 1
+#endif
+
+/*
+ * The function pointers for reading from and writing a seed file to
+ * Non-Volatile storage (NV) in a platform-independent way
+ *
+ * Only enabled when the NV seed entropy source is enabled
+ */
+#if defined(MBEDCRYPTO_ENTROPY_NV_SEED)
+#if !defined(MBEDCRYPTO_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDCRYPTO_FS_IO)
+/* Internal standard platform definitions */
+int mbedcrypto_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len );
+int mbedcrypto_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len );
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_NV_SEED_ALT)
+extern int (*mbedcrypto_nv_seed_read)( unsigned char *buf, size_t buf_len );
+extern int (*mbedcrypto_nv_seed_write)( unsigned char *buf, size_t buf_len );
+
+/**
+ * \brief This function allows configuring custom seed file writing and
+ * reading functions.
+ *
+ * \param nv_seed_read_func The seed reading function implementation.
+ * \param nv_seed_write_func The seed writing function implementation.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_platform_set_nv_seed(
+ int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ),
+ int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len )
+ );
+#else
+#if defined(MBEDCRYPTO_PLATFORM_NV_SEED_READ_MACRO) && \
+ defined(MBEDCRYPTO_PLATFORM_NV_SEED_WRITE_MACRO)
+#define mbedcrypto_nv_seed_read MBEDCRYPTO_PLATFORM_NV_SEED_READ_MACRO
+#define mbedcrypto_nv_seed_write MBEDCRYPTO_PLATFORM_NV_SEED_WRITE_MACRO
+#else
+#define mbedcrypto_nv_seed_read mbedcrypto_platform_std_nv_seed_read
+#define mbedcrypto_nv_seed_write mbedcrypto_platform_std_nv_seed_write
+#endif
+#endif /* MBEDCRYPTO_PLATFORM_NV_SEED_ALT */
+#endif /* MBEDCRYPTO_ENTROPY_NV_SEED */
+
+#if !defined(MBEDCRYPTO_PLATFORM_SETUP_TEARDOWN_ALT)
+
+/**
+ * \brief The platform context structure.
+ *
+ * \note This structure may be used to assist platform-specific
+ * setup or teardown operations.
+ */
+typedef struct {
+ char dummy; /**< A placeholder member, as empty structs are not portable. */
+}
+mbedcrypto_platform_context;
+
+#else
+#include "platform_alt.h"
+#endif /* !MBEDCRYPTO_PLATFORM_SETUP_TEARDOWN_ALT */
+
+/**
+ * \brief This function performs any platform-specific initialization
+ * operations.
+ *
+ * \note This function should be called before any other library functions.
+ *
+ * Its implementation is platform-specific, and unless
+ * platform-specific code is provided, it does nothing.
+ *
+ * \note The usage and necessity of this function is dependent on the platform.
+ *
+ * \param ctx The platform context.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_platform_setup( mbedcrypto_platform_context *ctx );
+/**
+ * \brief This function performs any platform teardown operations.
+ *
+ * \note This function should be called after every other Mbed Crypto module
+ * has been correctly freed using the appropriate free function.
+ *
+ * Its implementation is platform-specific, and unless
+ * platform-specific code is provided, it does nothing.
+ *
+ * \note The usage and necessity of this function is dependent on the platform.
+ *
+ * \param ctx The platform context.
+ *
+ */
+void mbedcrypto_platform_teardown( mbedcrypto_platform_context *ctx );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* platform.h */
diff --git a/include/mbedcrypto/platform_util.h b/include/mbedcrypto/platform_util.h
new file mode 100644
index 0000000..5375313
--- /dev/null
+++ b/include/mbedcrypto/platform_util.h
@@ -0,0 +1,62 @@
+/**
+ * \file platform_util.h
+ *
+ * \brief Common and shared functions used by multiple modules in the Mbed Crypto
+ * library.
+ */
+/*
+ * Copyright (C) 2018, Arm Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_PLATFORM_UTIL_H
+#define MBEDCRYPTO_PLATFORM_UTIL_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Securely zeroize a buffer
+ *
+ * The function is meant to wipe the data contained in a buffer so
+ * that it can no longer be recovered even if the program memory
+ * is later compromised. Call this function on sensitive data
+ * stored on the stack before returning from a function, and on
+ * sensitive data stored on the heap before freeing the heap
+ * object.
+ *
+ * It is extremely difficult to guarantee that calls to
+ * mbedcrypto_platform_zeroize() are not removed by aggressive
+ * compiler optimizations in a portable way. For this reason, Mbed
+ * TLS provides the configuration option
+ * MBEDCRYPTO_PLATFORM_ZEROIZE_ALT, which allows users to configure
+ * mbedcrypto_platform_zeroize() to use a suitable implementation for
+ * their platform and needs
+ *
+ * \param buf Buffer to be zeroized
+ * \param len Length of the buffer in bytes
+ *
+ */
+void mbedcrypto_platform_zeroize( void *buf, size_t len );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDCRYPTO_PLATFORM_UTIL_H */
diff --git a/include/mbedcrypto/ripemd160.h b/include/mbedcrypto/ripemd160.h
new file mode 100644
index 0000000..ca245fb
--- /dev/null
+++ b/include/mbedcrypto/ripemd160.h
@@ -0,0 +1,231 @@
+/**
+ * \file ripemd160.h
+ *
+ * \brief RIPE MD-160 message digest
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_RIPEMD160_H
+#define MBEDCRYPTO_RIPEMD160_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MBEDCRYPTO_ERR_RIPEMD160_HW_ACCEL_FAILED -0x0031 /**< RIPEMD160 hardware accelerator failed */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDCRYPTO_RIPEMD160_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief RIPEMD-160 context structure
+ */
+typedef struct
+{
+ uint32_t total[2]; /*!< number of bytes processed */
+ uint32_t state[5]; /*!< intermediate digest state */
+ unsigned char buffer[64]; /*!< data block being processed */
+}
+mbedcrypto_ripemd160_context;
+
+#else /* MBEDCRYPTO_RIPEMD160_ALT */
+#include "ripemd160.h"
+#endif /* MBEDCRYPTO_RIPEMD160_ALT */
+
+/**
+ * \brief Initialize RIPEMD-160 context
+ *
+ * \param ctx RIPEMD-160 context to be initialized
+ */
+void mbedcrypto_ripemd160_init( mbedcrypto_ripemd160_context *ctx );
+
+/**
+ * \brief Clear RIPEMD-160 context
+ *
+ * \param ctx RIPEMD-160 context to be cleared
+ */
+void mbedcrypto_ripemd160_free( mbedcrypto_ripemd160_context *ctx );
+
+/**
+ * \brief Clone (the state of) an RIPEMD-160 context
+ *
+ * \param dst The destination context
+ * \param src The context to be cloned
+ */
+void mbedcrypto_ripemd160_clone( mbedcrypto_ripemd160_context *dst,
+ const mbedcrypto_ripemd160_context *src );
+
+/**
+ * \brief RIPEMD-160 context setup
+ *
+ * \param ctx context to be initialized
+ *
+ * \return 0 if successful
+ */
+int mbedcrypto_ripemd160_starts_ret( mbedcrypto_ripemd160_context *ctx );
+
+/**
+ * \brief RIPEMD-160 process buffer
+ *
+ * \param ctx RIPEMD-160 context
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ *
+ * \return 0 if successful
+ */
+int mbedcrypto_ripemd160_update_ret( mbedcrypto_ripemd160_context *ctx,
+ const unsigned char *input,
+ size_t ilen );
+
+/**
+ * \brief RIPEMD-160 final digest
+ *
+ * \param ctx RIPEMD-160 context
+ * \param output RIPEMD-160 checksum result
+ *
+ * \return 0 if successful
+ */
+int mbedcrypto_ripemd160_finish_ret( mbedcrypto_ripemd160_context *ctx,
+ unsigned char output[20] );
+
+/**
+ * \brief RIPEMD-160 process data block (internal use only)
+ *
+ * \param ctx RIPEMD-160 context
+ * \param data buffer holding one block of data
+ *
+ * \return 0 if successful
+ */
+int mbedcrypto_internal_ripemd160_process( mbedcrypto_ripemd160_context *ctx,
+ const unsigned char data[64] );
+
+#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
+#if defined(MBEDCRYPTO_DEPRECATED_WARNING)
+#define MBEDCRYPTO_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDCRYPTO_DEPRECATED
+#endif
+/**
+ * \brief RIPEMD-160 context setup
+ *
+ * \deprecated Superseded by mbedcrypto_ripemd160_starts_ret() in 2.7.0
+ *
+ * \param ctx context to be initialized
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_ripemd160_starts(
+ mbedcrypto_ripemd160_context *ctx );
+
+/**
+ * \brief RIPEMD-160 process buffer
+ *
+ * \deprecated Superseded by mbedcrypto_ripemd160_update_ret() in 2.7.0
+ *
+ * \param ctx RIPEMD-160 context
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_ripemd160_update(
+ mbedcrypto_ripemd160_context *ctx,
+ const unsigned char *input,
+ size_t ilen );
+
+/**
+ * \brief RIPEMD-160 final digest
+ *
+ * \deprecated Superseded by mbedcrypto_ripemd160_finish_ret() in 2.7.0
+ *
+ * \param ctx RIPEMD-160 context
+ * \param output RIPEMD-160 checksum result
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_ripemd160_finish(
+ mbedcrypto_ripemd160_context *ctx,
+ unsigned char output[20] );
+
+/**
+ * \brief RIPEMD-160 process data block (internal use only)
+ *
+ * \deprecated Superseded by mbedcrypto_internal_ripemd160_process() in 2.7.0
+ *
+ * \param ctx RIPEMD-160 context
+ * \param data buffer holding one block of data
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_ripemd160_process(
+ mbedcrypto_ripemd160_context *ctx,
+ const unsigned char data[64] );
+
+#undef MBEDCRYPTO_DEPRECATED
+#endif /* !MBEDCRYPTO_DEPRECATED_REMOVED */
+
+/**
+ * \brief Output = RIPEMD-160( input buffer )
+ *
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output RIPEMD-160 checksum result
+ *
+ * \return 0 if successful
+ */
+int mbedcrypto_ripemd160_ret( const unsigned char *input,
+ size_t ilen,
+ unsigned char output[20] );
+
+#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
+#if defined(MBEDCRYPTO_DEPRECATED_WARNING)
+#define MBEDCRYPTO_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDCRYPTO_DEPRECATED
+#endif
+/**
+ * \brief Output = RIPEMD-160( input buffer )
+ *
+ * \deprecated Superseded by mbedcrypto_ripemd160_ret() in 2.7.0
+ *
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output RIPEMD-160 checksum result
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_ripemd160( const unsigned char *input,
+ size_t ilen,
+ unsigned char output[20] );
+
+#undef MBEDCRYPTO_DEPRECATED
+#endif /* !MBEDCRYPTO_DEPRECATED_REMOVED */
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int mbedcrypto_ripemd160_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedcrypto_ripemd160.h */
diff --git a/include/mbedcrypto/rsa.h b/include/mbedcrypto/rsa.h
new file mode 100644
index 0000000..0c33cae
--- /dev/null
+++ b/include/mbedcrypto/rsa.h
@@ -0,0 +1,1141 @@
+/**
+ * \file rsa.h
+ *
+ * \brief This file provides an API for the RSA public-key cryptosystem.
+ *
+ * The RSA public-key cryptosystem is defined in <em>Public-Key
+ * Cryptography Standards (PKCS) #1 v1.5: RSA Encryption</em>
+ * and <em>Public-Key Cryptography Standards (PKCS) #1 v2.1:
+ * RSA Cryptography Specifications</em>.
+ *
+ */
+/*
+ * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_RSA_H
+#define MBEDCRYPTO_RSA_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include "bignum.h"
+#include "md.h"
+
+#if defined(MBEDCRYPTO_THREADING_C)
+#include "threading.h"
+#endif
+
+/*
+ * RSA Error codes
+ */
+#define MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA -0x4080 /**< Bad input parameters to function. */
+#define MBEDCRYPTO_ERR_RSA_INVALID_PADDING -0x4100 /**< Input data contains invalid padding and is rejected. */
+#define MBEDCRYPTO_ERR_RSA_KEY_GEN_FAILED -0x4180 /**< Something failed during generation of a key. */
+#define MBEDCRYPTO_ERR_RSA_KEY_CHECK_FAILED -0x4200 /**< Key failed to pass the validity check of the library. */
+#define MBEDCRYPTO_ERR_RSA_PUBLIC_FAILED -0x4280 /**< The public key operation failed. */
+#define MBEDCRYPTO_ERR_RSA_PRIVATE_FAILED -0x4300 /**< The private key operation failed. */
+#define MBEDCRYPTO_ERR_RSA_VERIFY_FAILED -0x4380 /**< The PKCS#1 verification failed. */
+#define MBEDCRYPTO_ERR_RSA_OUTPUT_TOO_LARGE -0x4400 /**< The output buffer for decryption is not large enough. */
+#define MBEDCRYPTO_ERR_RSA_RNG_FAILED -0x4480 /**< The random generator failed to generate non-zeros. */
+#define MBEDCRYPTO_ERR_RSA_UNSUPPORTED_OPERATION -0x4500 /**< The implementation does not offer the requested operation, for example, because of security violations or lack of functionality. */
+#define MBEDCRYPTO_ERR_RSA_HW_ACCEL_FAILED -0x4580 /**< RSA hardware accelerator failed. */
+
+/*
+ * RSA constants
+ */
+#define MBEDCRYPTO_RSA_PUBLIC 0 /**< Request private key operation. */
+#define MBEDCRYPTO_RSA_PRIVATE 1 /**< Request public key operation. */
+
+#define MBEDCRYPTO_RSA_PKCS_V15 0 /**< Use PKCS#1 v1.5 encoding. */
+#define MBEDCRYPTO_RSA_PKCS_V21 1 /**< Use PKCS#1 v2.1 encoding. */
+
+#define MBEDCRYPTO_RSA_SIGN 1 /**< Identifier for RSA signature operations. */
+#define MBEDCRYPTO_RSA_CRYPT 2 /**< Identifier for RSA encryption and decryption operations. */
+
+#define MBEDCRYPTO_RSA_SALT_LEN_ANY -1
+
+/*
+ * The above constants may be used even if the RSA module is compile out,
+ * eg for alternative (PKCS#11) RSA implemenations in the PK layers.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDCRYPTO_RSA_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief The RSA context structure.
+ *
+ * \note Direct manipulation of the members of this structure
+ * is deprecated. All manipulation should instead be done through
+ * the public interface functions.
+ */
+typedef struct
+{
+ int ver; /*!< Always 0.*/
+ size_t len; /*!< The size of \p N in Bytes. */
+
+ mbedcrypto_mpi N; /*!< The public modulus. */
+ mbedcrypto_mpi E; /*!< The public exponent. */
+
+ mbedcrypto_mpi D; /*!< The private exponent. */
+ mbedcrypto_mpi P; /*!< The first prime factor. */
+ mbedcrypto_mpi Q; /*!< The second prime factor. */
+
+ mbedcrypto_mpi DP; /*!< <code>D % (P - 1)</code>. */
+ mbedcrypto_mpi DQ; /*!< <code>D % (Q - 1)</code>. */
+ mbedcrypto_mpi QP; /*!< <code>1 / (Q % P)</code>. */
+
+ mbedcrypto_mpi RN; /*!< cached <code>R^2 mod N</code>. */
+
+ mbedcrypto_mpi RP; /*!< cached <code>R^2 mod P</code>. */
+ mbedcrypto_mpi RQ; /*!< cached <code>R^2 mod Q</code>. */
+
+ mbedcrypto_mpi Vi; /*!< The cached blinding value. */
+ mbedcrypto_mpi Vf; /*!< The cached un-blinding value. */
+
+ int padding; /*!< Selects padding mode:
+ #MBEDCRYPTO_RSA_PKCS_V15 for 1.5 padding and
+ #MBEDCRYPTO_RSA_PKCS_V21 for OAEP or PSS. */
+ int hash_id; /*!< Hash identifier of mbedcrypto_md_type_t type,
+ as specified in md.h for use in the MGF
+ mask generating function used in the
+ EME-OAEP and EMSA-PSS encodings. */
+#if defined(MBEDCRYPTO_THREADING_C)
+ mbedcrypto_threading_mutex_t mutex; /*!< Thread-safety mutex. */
+#endif
+}
+mbedcrypto_rsa_context;
+
+#else /* MBEDCRYPTO_RSA_ALT */
+#include "rsa_alt.h"
+#endif /* MBEDCRYPTO_RSA_ALT */
+
+/**
+ * \brief This function initializes an RSA context.
+ *
+ * \note Set padding to #MBEDCRYPTO_RSA_PKCS_V21 for the RSAES-OAEP
+ * encryption scheme and the RSASSA-PSS signature scheme.
+ *
+ * \note The \p hash_id parameter is ignored when using
+ * #MBEDCRYPTO_RSA_PKCS_V15 padding.
+ *
+ * \note The choice of padding mode is strictly enforced for private key
+ * operations, since there might be security concerns in
+ * mixing padding modes. For public key operations it is
+ * a default value, which can be overriden by calling specific
+ * \c rsa_rsaes_xxx or \c rsa_rsassa_xxx functions.
+ *
+ * \note The hash selected in \p hash_id is always used for OEAP
+ * encryption. For PSS signatures, it is always used for
+ * making signatures, but can be overriden for verifying them.
+ * If set to #MBEDCRYPTO_MD_NONE, it is always overriden.
+ *
+ * \param ctx The RSA context to initialize.
+ * \param padding Selects padding mode: #MBEDCRYPTO_RSA_PKCS_V15 or
+ * #MBEDCRYPTO_RSA_PKCS_V21.
+ * \param hash_id The hash identifier of #mbedcrypto_md_type_t type, if
+ * \p padding is #MBEDCRYPTO_RSA_PKCS_V21.
+ */
+void mbedcrypto_rsa_init( mbedcrypto_rsa_context *ctx,
+ int padding,
+ int hash_id);
+
+/**
+ * \brief This function imports a set of core parameters into an
+ * RSA context.
+ *
+ * \note This function can be called multiple times for successive
+ * imports, if the parameters are not simultaneously present.
+ *
+ * Any sequence of calls to this function should be followed
+ * by a call to mbedcrypto_rsa_complete(), which checks and
+ * completes the provided information to a ready-for-use
+ * public or private RSA key.
+ *
+ * \note See mbedcrypto_rsa_complete() for more information on which
+ * parameters are necessary to set up a private or public
+ * RSA key.
+ *
+ * \note The imported parameters are copied and need not be preserved
+ * for the lifetime of the RSA context being set up.
+ *
+ * \param ctx The initialized RSA context to store the parameters in.
+ * \param N The RSA modulus, or NULL.
+ * \param P The first prime factor of \p N, or NULL.
+ * \param Q The second prime factor of \p N, or NULL.
+ * \param D The private exponent, or NULL.
+ * \param E The public exponent, or NULL.
+ *
+ * \return \c 0 on success.
+ * \return A non-zero error code on failure.
+ */
+int mbedcrypto_rsa_import( mbedcrypto_rsa_context *ctx,
+ const mbedcrypto_mpi *N,
+ const mbedcrypto_mpi *P, const mbedcrypto_mpi *Q,
+ const mbedcrypto_mpi *D, const mbedcrypto_mpi *E );
+
+/**
+ * \brief This function imports core RSA parameters, in raw big-endian
+ * binary format, into an RSA context.
+ *
+ * \note This function can be called multiple times for successive
+ * imports, if the parameters are not simultaneously present.
+ *
+ * Any sequence of calls to this function should be followed
+ * by a call to mbedcrypto_rsa_complete(), which checks and
+ * completes the provided information to a ready-for-use
+ * public or private RSA key.
+ *
+ * \note See mbedcrypto_rsa_complete() for more information on which
+ * parameters are necessary to set up a private or public
+ * RSA key.
+ *
+ * \note The imported parameters are copied and need not be preserved
+ * for the lifetime of the RSA context being set up.
+ *
+ * \param ctx The initialized RSA context to store the parameters in.
+ * \param N The RSA modulus, or NULL.
+ * \param N_len The Byte length of \p N, ignored if \p N == NULL.
+ * \param P The first prime factor of \p N, or NULL.
+ * \param P_len The Byte length of \p P, ignored if \p P == NULL.
+ * \param Q The second prime factor of \p N, or NULL.
+ * \param Q_len The Byte length of \p Q, ignored if \p Q == NULL.
+ * \param D The private exponent, or NULL.
+ * \param D_len The Byte length of \p D, ignored if \p D == NULL.
+ * \param E The public exponent, or NULL.
+ * \param E_len The Byte length of \p E, ignored if \p E == NULL.
+ *
+ * \return \c 0 on success.
+ * \return A non-zero error code on failure.
+ */
+int mbedcrypto_rsa_import_raw( mbedcrypto_rsa_context *ctx,
+ unsigned char const *N, size_t N_len,
+ unsigned char const *P, size_t P_len,
+ unsigned char const *Q, size_t Q_len,
+ unsigned char const *D, size_t D_len,
+ unsigned char const *E, size_t E_len );
+
+/**
+ * \brief This function completes an RSA context from
+ * a set of imported core parameters.
+ *
+ * To setup an RSA public key, precisely \p N and \p E
+ * must have been imported.
+ *
+ * To setup an RSA private key, sufficient information must
+ * be present for the other parameters to be derivable.
+ *
+ * The default implementation supports the following:
+ * <ul><li>Derive \p P, \p Q from \p N, \p D, \p E.</li>
+ * <li>Derive \p N, \p D from \p P, \p Q, \p E.</li></ul>
+ * Alternative implementations need not support these.
+ *
+ * If this function runs successfully, it guarantees that
+ * the RSA context can be used for RSA operations without
+ * the risk of failure or crash.
+ *
+ * \warning This function need not perform consistency checks
+ * for the imported parameters. In particular, parameters that
+ * are not needed by the implementation might be silently
+ * discarded and left unchecked. To check the consistency
+ * of the key material, see mbedcrypto_rsa_check_privkey().
+ *
+ * \param ctx The initialized RSA context holding imported parameters.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA if the attempted derivations
+ * failed.
+ *
+ */
+int mbedcrypto_rsa_complete( mbedcrypto_rsa_context *ctx );
+
+/**
+ * \brief This function exports the core parameters of an RSA key.
+ *
+ * If this function runs successfully, the non-NULL buffers
+ * pointed to by \p N, \p P, \p Q, \p D, and \p E are fully
+ * written, with additional unused space filled leading by
+ * zero Bytes.
+ *
+ * Possible reasons for returning
+ * #MBEDCRYPTO_ERR_RSA_UNSUPPORTED_OPERATION:<ul>
+ * <li>An alternative RSA implementation is in use, which
+ * stores the key externally, and either cannot or should
+ * not export it into RAM.</li>
+ * <li>A SW or HW implementation might not support a certain
+ * deduction. For example, \p P, \p Q from \p N, \p D,
+ * and \p E if the former are not part of the
+ * implementation.</li></ul>
+ *
+ * If the function fails due to an unsupported operation,
+ * the RSA context stays intact and remains usable.
+ *
+ * \param ctx The initialized RSA context.
+ * \param N The MPI to hold the RSA modulus, or NULL.
+ * \param P The MPI to hold the first prime factor of \p N, or NULL.
+ * \param Q The MPI to hold the second prime factor of \p N, or NULL.
+ * \param D The MPI to hold the private exponent, or NULL.
+ * \param E The MPI to hold the public exponent, or NULL.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_RSA_UNSUPPORTED_OPERATION if exporting the
+ * requested parameters cannot be done due to missing
+ * functionality or because of security policies.
+ * \return A non-zero return code on any other failure.
+ *
+ */
+int mbedcrypto_rsa_export( const mbedcrypto_rsa_context *ctx,
+ mbedcrypto_mpi *N, mbedcrypto_mpi *P, mbedcrypto_mpi *Q,
+ mbedcrypto_mpi *D, mbedcrypto_mpi *E );
+
+/**
+ * \brief This function exports core parameters of an RSA key
+ * in raw big-endian binary format.
+ *
+ * If this function runs successfully, the non-NULL buffers
+ * pointed to by \p N, \p P, \p Q, \p D, and \p E are fully
+ * written, with additional unused space filled leading by
+ * zero Bytes.
+ *
+ * Possible reasons for returning
+ * #MBEDCRYPTO_ERR_RSA_UNSUPPORTED_OPERATION:<ul>
+ * <li>An alternative RSA implementation is in use, which
+ * stores the key externally, and either cannot or should
+ * not export it into RAM.</li>
+ * <li>A SW or HW implementation might not support a certain
+ * deduction. For example, \p P, \p Q from \p N, \p D,
+ * and \p E if the former are not part of the
+ * implementation.</li></ul>
+ * If the function fails due to an unsupported operation,
+ * the RSA context stays intact and remains usable.
+ *
+ * \note The length parameters are ignored if the corresponding
+ * buffer pointers are NULL.
+ *
+ * \param ctx The initialized RSA context.
+ * \param N The Byte array to store the RSA modulus, or NULL.
+ * \param N_len The size of the buffer for the modulus.
+ * \param P The Byte array to hold the first prime factor of \p N, or
+ * NULL.
+ * \param P_len The size of the buffer for the first prime factor.
+ * \param Q The Byte array to hold the second prime factor of \p N, or
+ * NULL.
+ * \param Q_len The size of the buffer for the second prime factor.
+ * \param D The Byte array to hold the private exponent, or NULL.
+ * \param D_len The size of the buffer for the private exponent.
+ * \param E The Byte array to hold the public exponent, or NULL.
+ * \param E_len The size of the buffer for the public exponent.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_RSA_UNSUPPORTED_OPERATION if exporting the
+ * requested parameters cannot be done due to missing
+ * functionality or because of security policies.
+ * \return A non-zero return code on any other failure.
+ */
+int mbedcrypto_rsa_export_raw( const mbedcrypto_rsa_context *ctx,
+ unsigned char *N, size_t N_len,
+ unsigned char *P, size_t P_len,
+ unsigned char *Q, size_t Q_len,
+ unsigned char *D, size_t D_len,
+ unsigned char *E, size_t E_len );
+
+/**
+ * \brief This function exports CRT parameters of a private RSA key.
+ *
+ * \note Alternative RSA implementations not using CRT-parameters
+ * internally can implement this function based on
+ * mbedcrypto_rsa_deduce_opt().
+ *
+ * \param ctx The initialized RSA context.
+ * \param DP The MPI to hold D modulo P-1, or NULL.
+ * \param DQ The MPI to hold D modulo Q-1, or NULL.
+ * \param QP The MPI to hold modular inverse of Q modulo P, or NULL.
+ *
+ * \return \c 0 on success.
+ * \return A non-zero error code on failure.
+ *
+ */
+int mbedcrypto_rsa_export_crt( const mbedcrypto_rsa_context *ctx,
+ mbedcrypto_mpi *DP, mbedcrypto_mpi *DQ, mbedcrypto_mpi *QP );
+
+/**
+ * \brief This function sets padding for an already initialized RSA
+ * context. See mbedcrypto_rsa_init() for details.
+ *
+ * \param ctx The RSA context to be set.
+ * \param padding Selects padding mode: #MBEDCRYPTO_RSA_PKCS_V15 or
+ * #MBEDCRYPTO_RSA_PKCS_V21.
+ * \param hash_id The #MBEDCRYPTO_RSA_PKCS_V21 hash identifier.
+ */
+void mbedcrypto_rsa_set_padding( mbedcrypto_rsa_context *ctx, int padding,
+ int hash_id);
+
+/**
+ * \brief This function retrieves the length of RSA modulus in Bytes.
+ *
+ * \param ctx The initialized RSA context.
+ *
+ * \return The length of the RSA modulus in Bytes.
+ *
+ */
+size_t mbedcrypto_rsa_get_len( const mbedcrypto_rsa_context *ctx );
+
+/**
+ * \brief This function retrieves the length of the RSA modulus in bits.
+ *
+ * \param ctx The initialized RSA context.
+ *
+ * \return The length of the RSA modulus in bits.
+ *
+ */
+size_t mbedcrypto_rsa_get_bitlen( const mbedcrypto_rsa_context *ctx );
+
+/**
+ * \brief This function generates an RSA keypair.
+ *
+ * \note mbedcrypto_rsa_init() must be called before this function,
+ * to set up the RSA context.
+ *
+ * \param ctx The RSA context used to hold the key.
+ * \param f_rng The RNG function.
+ * \param p_rng The RNG context.
+ * \param nbits The size of the public key in bits.
+ * \param exponent The public exponent. For example, 65537.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ */
+int mbedcrypto_rsa_gen_key( mbedcrypto_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ unsigned int nbits, int exponent );
+
+/**
+ * \brief This function checks if a context contains at least an RSA
+ * public key.
+ *
+ * If the function runs successfully, it is guaranteed that
+ * enough information is present to perform an RSA public key
+ * operation using mbedcrypto_rsa_public().
+ *
+ * \param ctx The RSA context to check.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ *
+ */
+int mbedcrypto_rsa_check_pubkey( const mbedcrypto_rsa_context *ctx );
+
+/**
+ * \brief This function checks if a context contains an RSA private key
+ * and perform basic consistency checks.
+ *
+ * \note The consistency checks performed by this function not only
+ * ensure that mbedcrypto_rsa_private() can be called successfully
+ * on the given context, but that the various parameters are
+ * mutually consistent with high probability, in the sense that
+ * mbedcrypto_rsa_public() and mbedcrypto_rsa_private() are inverses.
+ *
+ * \warning This function should catch accidental misconfigurations
+ * like swapping of parameters, but it cannot establish full
+ * trust in neither the quality nor the consistency of the key
+ * material that was used to setup the given RSA context:
+ * <ul><li>Consistency: Imported parameters that are irrelevant
+ * for the implementation might be silently dropped. If dropped,
+ * the current function does not have access to them,
+ * and therefore cannot check them. See mbedcrypto_rsa_complete().
+ * If you want to check the consistency of the entire
+ * content of an PKCS1-encoded RSA private key, for example, you
+ * should use mbedcrypto_rsa_validate_params() before setting
+ * up the RSA context.
+ * Additionally, if the implementation performs empirical checks,
+ * these checks substantiate but do not guarantee consistency.</li>
+ * <li>Quality: This function is not expected to perform
+ * extended quality assessments like checking that the prime
+ * factors are safe. Additionally, it is the responsibility of the
+ * user to ensure the trustworthiness of the source of his RSA
+ * parameters, which goes beyond what is effectively checkable
+ * by the library.</li></ul>
+ *
+ * \param ctx The RSA context to check.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ */
+int mbedcrypto_rsa_check_privkey( const mbedcrypto_rsa_context *ctx );
+
+/**
+ * \brief This function checks a public-private RSA key pair.
+ *
+ * It checks each of the contexts, and makes sure they match.
+ *
+ * \param pub The RSA context holding the public key.
+ * \param prv The RSA context holding the private key.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ */
+int mbedcrypto_rsa_check_pub_priv( const mbedcrypto_rsa_context *pub,
+ const mbedcrypto_rsa_context *prv );
+
+/**
+ * \brief This function performs an RSA public key operation.
+ *
+ * \note This function does not handle message padding.
+ *
+ * \note Make sure to set \p input[0] = 0 or ensure that
+ * input is smaller than \p N.
+ *
+ * \note The input and output buffers must be large
+ * enough. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \param ctx The RSA context.
+ * \param input The input buffer.
+ * \param output The output buffer.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ */
+int mbedcrypto_rsa_public( mbedcrypto_rsa_context *ctx,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief This function performs an RSA private key operation.
+ *
+ * \note The input and output buffers must be large
+ * enough. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \note Blinding is used if and only if a PRNG is provided.
+ *
+ * \note If blinding is used, both the base of exponentation
+ * and the exponent are blinded, providing protection
+ * against some side-channel attacks.
+ *
+ * \warning It is deprecated and a security risk to not provide
+ * a PRNG here and thereby prevent the use of blinding.
+ * Future versions of the library may enforce the presence
+ * of a PRNG.
+ *
+ * \param ctx The RSA context.
+ * \param f_rng The RNG function. Needed for blinding.
+ * \param p_rng The RNG context.
+ * \param input The input buffer.
+ * \param output The output buffer.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ *
+ */
+int mbedcrypto_rsa_private( mbedcrypto_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief This function adds the message padding, then performs an RSA
+ * operation.
+ *
+ * It is the generic wrapper for performing a PKCS#1 encryption
+ * operation using the \p mode from the context.
+ *
+ * \note The input and output buffers must be as large as the size
+ * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \deprecated It is deprecated and discouraged to call this function
+ * in #MBEDCRYPTO_RSA_PRIVATE mode. Future versions of the library
+ * are likely to remove the \p mode argument and have it
+ * implicitly set to #MBEDCRYPTO_RSA_PUBLIC.
+ *
+ * \note Alternative implementations of RSA need not support
+ * mode being set to #MBEDCRYPTO_RSA_PRIVATE and might instead
+ * return #MBEDCRYPTO_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \param ctx The RSA context.
+ * \param f_rng The RNG function. Needed for padding, PKCS#1 v2.1
+ * encoding, and #MBEDCRYPTO_RSA_PRIVATE.
+ * \param p_rng The RNG context.
+ * \param mode #MBEDCRYPTO_RSA_PUBLIC or #MBEDCRYPTO_RSA_PRIVATE.
+ * \param ilen The length of the plaintext.
+ * \param input The buffer holding the data to encrypt.
+ * \param output The buffer used to hold the ciphertext.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ */
+int mbedcrypto_rsa_pkcs1_encrypt( mbedcrypto_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode, size_t ilen,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief This function performs a PKCS#1 v1.5 encryption operation
+ * (RSAES-PKCS1-v1_5-ENCRYPT).
+ *
+ * \note The output buffer must be as large as the size
+ * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \deprecated It is deprecated and discouraged to call this function
+ * in #MBEDCRYPTO_RSA_PRIVATE mode. Future versions of the library
+ * are likely to remove the \p mode argument and have it
+ * implicitly set to #MBEDCRYPTO_RSA_PUBLIC.
+ *
+ * \note Alternative implementations of RSA need not support
+ * mode being set to #MBEDCRYPTO_RSA_PRIVATE and might instead
+ * return #MBEDCRYPTO_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \param ctx The RSA context.
+ * \param f_rng The RNG function. Needed for padding and
+ * #MBEDCRYPTO_RSA_PRIVATE.
+ * \param p_rng The RNG context.
+ * \param mode #MBEDCRYPTO_RSA_PUBLIC or #MBEDCRYPTO_RSA_PRIVATE.
+ * \param ilen The length of the plaintext.
+ * \param input The buffer holding the data to encrypt.
+ * \param output The buffer used to hold the ciphertext.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ */
+int mbedcrypto_rsa_rsaes_pkcs1_v15_encrypt( mbedcrypto_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode, size_t ilen,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief This function performs a PKCS#1 v2.1 OAEP encryption
+ * operation (RSAES-OAEP-ENCRYPT).
+ *
+ * \note The output buffer must be as large as the size
+ * of ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \deprecated It is deprecated and discouraged to call this function
+ * in #MBEDCRYPTO_RSA_PRIVATE mode. Future versions of the library
+ * are likely to remove the \p mode argument and have it
+ * implicitly set to #MBEDCRYPTO_RSA_PUBLIC.
+ *
+ * \note Alternative implementations of RSA need not support
+ * mode being set to #MBEDCRYPTO_RSA_PRIVATE and might instead
+ * return #MBEDCRYPTO_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \param ctx The RSA context.
+ * \param f_rng The RNG function. Needed for padding and PKCS#1 v2.1
+ * encoding and #MBEDCRYPTO_RSA_PRIVATE.
+ * \param p_rng The RNG context.
+ * \param mode #MBEDCRYPTO_RSA_PUBLIC or #MBEDCRYPTO_RSA_PRIVATE.
+ * \param label The buffer holding the custom label to use.
+ * \param label_len The length of the label.
+ * \param ilen The length of the plaintext.
+ * \param input The buffer holding the data to encrypt.
+ * \param output The buffer used to hold the ciphertext.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ */
+int mbedcrypto_rsa_rsaes_oaep_encrypt( mbedcrypto_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode,
+ const unsigned char *label, size_t label_len,
+ size_t ilen,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief This function performs an RSA operation, then removes the
+ * message padding.
+ *
+ * It is the generic wrapper for performing a PKCS#1 decryption
+ * operation using the \p mode from the context.
+ *
+ * \note The output buffer length \c output_max_len should be
+ * as large as the size \p ctx->len of \p ctx->N (for example,
+ * 128 Bytes if RSA-1024 is used) to be able to hold an
+ * arbitrary decrypted message. If it is not large enough to
+ * hold the decryption of the particular ciphertext provided,
+ * the function returns \c MBEDCRYPTO_ERR_RSA_OUTPUT_TOO_LARGE.
+ *
+ * \note The input buffer must be as large as the size
+ * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \deprecated It is deprecated and discouraged to call this function
+ * in #MBEDCRYPTO_RSA_PUBLIC mode. Future versions of the library
+ * are likely to remove the \p mode argument and have it
+ * implicitly set to #MBEDCRYPTO_RSA_PRIVATE.
+ *
+ * \note Alternative implementations of RSA need not support
+ * mode being set to #MBEDCRYPTO_RSA_PUBLIC and might instead
+ * return #MBEDCRYPTO_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \param ctx The RSA context.
+ * \param f_rng The RNG function. Only needed for #MBEDCRYPTO_RSA_PRIVATE.
+ * \param p_rng The RNG context.
+ * \param mode #MBEDCRYPTO_RSA_PUBLIC or #MBEDCRYPTO_RSA_PRIVATE.
+ * \param olen The length of the plaintext.
+ * \param input The buffer holding the encrypted data.
+ * \param output The buffer used to hold the plaintext.
+ * \param output_max_len The maximum length of the output buffer.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ */
+int mbedcrypto_rsa_pkcs1_decrypt( mbedcrypto_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode, size_t *olen,
+ const unsigned char *input,
+ unsigned char *output,
+ size_t output_max_len );
+
+/**
+ * \brief This function performs a PKCS#1 v1.5 decryption
+ * operation (RSAES-PKCS1-v1_5-DECRYPT).
+ *
+ * \note The output buffer length \c output_max_len should be
+ * as large as the size \p ctx->len of \p ctx->N, for example,
+ * 128 Bytes if RSA-1024 is used, to be able to hold an
+ * arbitrary decrypted message. If it is not large enough to
+ * hold the decryption of the particular ciphertext provided,
+ * the function returns #MBEDCRYPTO_ERR_RSA_OUTPUT_TOO_LARGE.
+ *
+ * \note The input buffer must be as large as the size
+ * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \deprecated It is deprecated and discouraged to call this function
+ * in #MBEDCRYPTO_RSA_PUBLIC mode. Future versions of the library
+ * are likely to remove the \p mode argument and have it
+ * implicitly set to #MBEDCRYPTO_RSA_PRIVATE.
+ *
+ * \note Alternative implementations of RSA need not support
+ * mode being set to #MBEDCRYPTO_RSA_PUBLIC and might instead
+ * return #MBEDCRYPTO_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \param ctx The RSA context.
+ * \param f_rng The RNG function. Only needed for #MBEDCRYPTO_RSA_PRIVATE.
+ * \param p_rng The RNG context.
+ * \param mode #MBEDCRYPTO_RSA_PUBLIC or #MBEDCRYPTO_RSA_PRIVATE.
+ * \param olen The length of the plaintext.
+ * \param input The buffer holding the encrypted data.
+ * \param output The buffer to hold the plaintext.
+ * \param output_max_len The maximum length of the output buffer.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ *
+ */
+int mbedcrypto_rsa_rsaes_pkcs1_v15_decrypt( mbedcrypto_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode, size_t *olen,
+ const unsigned char *input,
+ unsigned char *output,
+ size_t output_max_len );
+
+/**
+ * \brief This function performs a PKCS#1 v2.1 OAEP decryption
+ * operation (RSAES-OAEP-DECRYPT).
+ *
+ * \note The output buffer length \c output_max_len should be
+ * as large as the size \p ctx->len of \p ctx->N, for
+ * example, 128 Bytes if RSA-1024 is used, to be able to
+ * hold an arbitrary decrypted message. If it is not
+ * large enough to hold the decryption of the particular
+ * ciphertext provided, the function returns
+ * #MBEDCRYPTO_ERR_RSA_OUTPUT_TOO_LARGE.
+ *
+ * \note The input buffer must be as large as the size
+ * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \deprecated It is deprecated and discouraged to call this function
+ * in #MBEDCRYPTO_RSA_PUBLIC mode. Future versions of the library
+ * are likely to remove the \p mode argument and have it
+ * implicitly set to #MBEDCRYPTO_RSA_PRIVATE.
+ *
+ * \note Alternative implementations of RSA need not support
+ * mode being set to #MBEDCRYPTO_RSA_PUBLIC and might instead
+ * return #MBEDCRYPTO_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \param ctx The RSA context.
+ * \param f_rng The RNG function. Only needed for #MBEDCRYPTO_RSA_PRIVATE.
+ * \param p_rng The RNG context.
+ * \param mode #MBEDCRYPTO_RSA_PUBLIC or #MBEDCRYPTO_RSA_PRIVATE.
+ * \param label The buffer holding the custom label to use.
+ * \param label_len The length of the label.
+ * \param olen The length of the plaintext.
+ * \param input The buffer holding the encrypted data.
+ * \param output The buffer to hold the plaintext.
+ * \param output_max_len The maximum length of the output buffer.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ */
+int mbedcrypto_rsa_rsaes_oaep_decrypt( mbedcrypto_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode,
+ const unsigned char *label, size_t label_len,
+ size_t *olen,
+ const unsigned char *input,
+ unsigned char *output,
+ size_t output_max_len );
+
+/**
+ * \brief This function performs a private RSA operation to sign
+ * a message digest using PKCS#1.
+ *
+ * It is the generic wrapper for performing a PKCS#1
+ * signature using the \p mode from the context.
+ *
+ * \note The \p sig buffer must be as large as the size
+ * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \note For PKCS#1 v2.1 encoding, see comments on
+ * mbedcrypto_rsa_rsassa_pss_sign() for details on
+ * \p md_alg and \p hash_id.
+ *
+ * \deprecated It is deprecated and discouraged to call this function
+ * in #MBEDCRYPTO_RSA_PUBLIC mode. Future versions of the library
+ * are likely to remove the \p mode argument and have it
+ * implicitly set to #MBEDCRYPTO_RSA_PRIVATE.
+ *
+ * \note Alternative implementations of RSA need not support
+ * mode being set to #MBEDCRYPTO_RSA_PUBLIC and might instead
+ * return #MBEDCRYPTO_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \param ctx The RSA context.
+ * \param f_rng The RNG function. Needed for PKCS#1 v2.1 encoding and for
+ * #MBEDCRYPTO_RSA_PRIVATE.
+ * \param p_rng The RNG context.
+ * \param mode #MBEDCRYPTO_RSA_PUBLIC or #MBEDCRYPTO_RSA_PRIVATE.
+ * \param md_alg The message-digest algorithm used to hash the original data.
+ * Use #MBEDCRYPTO_MD_NONE for signing raw data.
+ * \param hashlen The length of the message digest. Only used if \p md_alg is #MBEDCRYPTO_MD_NONE.
+ * \param hash The buffer holding the message digest.
+ * \param sig The buffer to hold the ciphertext.
+ *
+ * \return \c 0 if the signing operation was successful.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ */
+int mbedcrypto_rsa_pkcs1_sign( mbedcrypto_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode,
+ mbedcrypto_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig );
+
+/**
+ * \brief This function performs a PKCS#1 v1.5 signature
+ * operation (RSASSA-PKCS1-v1_5-SIGN).
+ *
+ * \note The \p sig buffer must be as large as the size
+ * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \deprecated It is deprecated and discouraged to call this function
+ * in #MBEDCRYPTO_RSA_PUBLIC mode. Future versions of the library
+ * are likely to remove the \p mode argument and have it
+ * implicitly set to #MBEDCRYPTO_RSA_PRIVATE.
+ *
+ * \note Alternative implementations of RSA need not support
+ * mode being set to #MBEDCRYPTO_RSA_PUBLIC and might instead
+ * return #MBEDCRYPTO_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \param ctx The RSA context.
+ * \param f_rng The RNG function. Only needed for #MBEDCRYPTO_RSA_PRIVATE.
+ * \param p_rng The RNG context.
+ * \param mode #MBEDCRYPTO_RSA_PUBLIC or #MBEDCRYPTO_RSA_PRIVATE.
+ * \param md_alg The message-digest algorithm used to hash the original data.
+ * Use #MBEDCRYPTO_MD_NONE for signing raw data.
+ * \param hashlen The length of the message digest. Only used if \p md_alg is #MBEDCRYPTO_MD_NONE.
+ * \param hash The buffer holding the message digest.
+ * \param sig The buffer to hold the ciphertext.
+ *
+ * \return \c 0 if the signing operation was successful.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ */
+int mbedcrypto_rsa_rsassa_pkcs1_v15_sign( mbedcrypto_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode,
+ mbedcrypto_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig );
+
+/**
+ * \brief This function performs a PKCS#1 v2.1 PSS signature
+ * operation (RSASSA-PSS-SIGN).
+ *
+ * \note The \p sig buffer must be as large as the size
+ * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \note The \p hash_id in the RSA context is the one used for the
+ * encoding. \p md_alg in the function call is the type of hash
+ * that is encoded. According to <em>RFC-3447: Public-Key
+ * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography
+ * Specifications</em> it is advised to keep both hashes the
+ * same.
+ *
+ * \deprecated It is deprecated and discouraged to call this function
+ * in #MBEDCRYPTO_RSA_PUBLIC mode. Future versions of the library
+ * are likely to remove the \p mode argument and have it
+ * implicitly set to #MBEDCRYPTO_RSA_PRIVATE.
+ *
+ * \note Alternative implementations of RSA need not support
+ * mode being set to #MBEDCRYPTO_RSA_PUBLIC and might instead
+ * return #MBEDCRYPTO_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \param ctx The RSA context.
+ * \param f_rng The RNG function. Needed for PKCS#1 v2.1 encoding and for
+ * #MBEDCRYPTO_RSA_PRIVATE.
+ * \param p_rng The RNG context.
+ * \param mode #MBEDCRYPTO_RSA_PUBLIC or #MBEDCRYPTO_RSA_PRIVATE.
+ * \param md_alg The message-digest algorithm used to hash the original data.
+ * Use #MBEDCRYPTO_MD_NONE for signing raw data.
+ * \param hashlen The length of the message digest. Only used if \p md_alg is #MBEDCRYPTO_MD_NONE.
+ * \param hash The buffer holding the message digest.
+ * \param sig The buffer to hold the ciphertext.
+ *
+ * \return \c 0 if the signing operation was successful.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ */
+int mbedcrypto_rsa_rsassa_pss_sign( mbedcrypto_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode,
+ mbedcrypto_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig );
+
+/**
+ * \brief This function performs a public RSA operation and checks
+ * the message digest.
+ *
+ * This is the generic wrapper for performing a PKCS#1
+ * verification using the mode from the context.
+ *
+ * \note The \p sig buffer must be as large as the size
+ * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \note For PKCS#1 v2.1 encoding, see comments on
+ * mbedcrypto_rsa_rsassa_pss_verify() about \p md_alg and
+ * \p hash_id.
+ *
+ * \deprecated It is deprecated and discouraged to call this function
+ * in #MBEDCRYPTO_RSA_PRIVATE mode. Future versions of the library
+ * are likely to remove the \p mode argument and have it
+ * set to #MBEDCRYPTO_RSA_PUBLIC.
+ *
+ * \note Alternative implementations of RSA need not support
+ * mode being set to #MBEDCRYPTO_RSA_PRIVATE and might instead
+ * return #MBEDCRYPTO_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \param ctx The RSA public key context.
+ * \param f_rng The RNG function. Only needed for #MBEDCRYPTO_RSA_PRIVATE.
+ * \param p_rng The RNG context.
+ * \param mode #MBEDCRYPTO_RSA_PUBLIC or #MBEDCRYPTO_RSA_PRIVATE.
+ * \param md_alg The message-digest algorithm used to hash the original data.
+ * Use #MBEDCRYPTO_MD_NONE for signing raw data.
+ * \param hashlen The length of the message digest. Only used if \p md_alg is #MBEDCRYPTO_MD_NONE.
+ * \param hash The buffer holding the message digest.
+ * \param sig The buffer holding the ciphertext.
+ *
+ * \return \c 0 if the verify operation was successful.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ */
+int mbedcrypto_rsa_pkcs1_verify( mbedcrypto_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode,
+ mbedcrypto_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ const unsigned char *sig );
+
+/**
+ * \brief This function performs a PKCS#1 v1.5 verification
+ * operation (RSASSA-PKCS1-v1_5-VERIFY).
+ *
+ * \note The \p sig buffer must be as large as the size
+ * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \deprecated It is deprecated and discouraged to call this function
+ * in #MBEDCRYPTO_RSA_PRIVATE mode. Future versions of the library
+ * are likely to remove the \p mode argument and have it
+ * set to #MBEDCRYPTO_RSA_PUBLIC.
+ *
+ * \note Alternative implementations of RSA need not support
+ * mode being set to #MBEDCRYPTO_RSA_PRIVATE and might instead
+ * return #MBEDCRYPTO_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \param ctx The RSA public key context.
+ * \param f_rng The RNG function. Only needed for #MBEDCRYPTO_RSA_PRIVATE.
+ * \param p_rng The RNG context.
+ * \param mode #MBEDCRYPTO_RSA_PUBLIC or #MBEDCRYPTO_RSA_PRIVATE.
+ * \param md_alg The message-digest algorithm used to hash the original data.
+ * Use #MBEDCRYPTO_MD_NONE for signing raw data.
+ * \param hashlen The length of the message digest. Only used if \p md_alg is #MBEDCRYPTO_MD_NONE.
+ * \param hash The buffer holding the message digest.
+ * \param sig The buffer holding the ciphertext.
+ *
+ * \return \c 0 if the verify operation was successful.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ */
+int mbedcrypto_rsa_rsassa_pkcs1_v15_verify( mbedcrypto_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode,
+ mbedcrypto_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ const unsigned char *sig );
+
+/**
+ * \brief This function performs a PKCS#1 v2.1 PSS verification
+ * operation (RSASSA-PSS-VERIFY).
+ *
+ * The hash function for the MGF mask generating function
+ * is that specified in the RSA context.
+ *
+ * \note The \p sig buffer must be as large as the size
+ * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \note The \p hash_id in the RSA context is the one used for the
+ * verification. \p md_alg in the function call is the type of
+ * hash that is verified. According to <em>RFC-3447: Public-Key
+ * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography
+ * Specifications</em> it is advised to keep both hashes the
+ * same. If \p hash_id in the RSA context is unset,
+ * the \p md_alg from the function call is used.
+ *
+ * \deprecated It is deprecated and discouraged to call this function
+ * in #MBEDCRYPTO_RSA_PRIVATE mode. Future versions of the library
+ * are likely to remove the \p mode argument and have it
+ * implicitly set to #MBEDCRYPTO_RSA_PUBLIC.
+ *
+ * \note Alternative implementations of RSA need not support
+ * mode being set to #MBEDCRYPTO_RSA_PRIVATE and might instead
+ * return #MBEDCRYPTO_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \param ctx The RSA public key context.
+ * \param f_rng The RNG function. Only needed for #MBEDCRYPTO_RSA_PRIVATE.
+ * \param p_rng The RNG context.
+ * \param mode #MBEDCRYPTO_RSA_PUBLIC or #MBEDCRYPTO_RSA_PRIVATE.
+ * \param md_alg The message-digest algorithm used to hash the original data.
+ * Use #MBEDCRYPTO_MD_NONE for signing raw data.
+ * \param hashlen The length of the message digest. Only used if \p md_alg is #MBEDCRYPTO_MD_NONE.
+ * \param hash The buffer holding the message digest.
+ * \param sig The buffer holding the ciphertext.
+ *
+ * \return \c 0 if the verify operation was successful.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ */
+int mbedcrypto_rsa_rsassa_pss_verify( mbedcrypto_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode,
+ mbedcrypto_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ const unsigned char *sig );
+
+/**
+ * \brief This function performs a PKCS#1 v2.1 PSS verification
+ * operation (RSASSA-PSS-VERIFY).
+ *
+ * The hash function for the MGF mask generating function
+ * is that specified in \p mgf1_hash_id.
+ *
+ * \note The \p sig buffer must be as large as the size
+ * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \note The \p hash_id in the RSA context is ignored.
+ *
+ * \param ctx The RSA public key context.
+ * \param f_rng The RNG function. Only needed for #MBEDCRYPTO_RSA_PRIVATE.
+ * \param p_rng The RNG context.
+ * \param mode #MBEDCRYPTO_RSA_PUBLIC or #MBEDCRYPTO_RSA_PRIVATE.
+ * \param md_alg The message-digest algorithm used to hash the original data.
+ * Use #MBEDCRYPTO_MD_NONE for signing raw data.
+ * \param hashlen The length of the message digest. Only used if \p md_alg is
+ * #MBEDCRYPTO_MD_NONE.
+ * \param hash The buffer holding the message digest.
+ * \param mgf1_hash_id The message digest used for mask generation.
+ * \param expected_salt_len The length of the salt used in padding. Use
+ * #MBEDCRYPTO_RSA_SALT_LEN_ANY to accept any salt length.
+ * \param sig The buffer holding the ciphertext.
+ *
+ * \return \c 0 if the verify operation was successful.
+ * \return An \c MBEDCRYPTO_ERR_RSA_XXX error code on failure.
+ */
+int mbedcrypto_rsa_rsassa_pss_verify_ext( mbedcrypto_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode,
+ mbedcrypto_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ mbedcrypto_md_type_t mgf1_hash_id,
+ int expected_salt_len,
+ const unsigned char *sig );
+
+/**
+ * \brief This function copies the components of an RSA context.
+ *
+ * \param dst The destination context.
+ * \param src The source context.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDCRYPTO_ERR_MPI_ALLOC_FAILED on memory allocation failure.
+ */
+int mbedcrypto_rsa_copy( mbedcrypto_rsa_context *dst, const mbedcrypto_rsa_context *src );
+
+/**
+ * \brief This function frees the components of an RSA key.
+ *
+ * \param ctx The RSA Context to free.
+ */
+void mbedcrypto_rsa_free( mbedcrypto_rsa_context *ctx );
+
+/**
+ * \brief The RSA checkup routine.
+ *
+ * \return \c 0 on success.
+ * \return \c 1 on failure.
+ */
+int mbedcrypto_rsa_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* rsa.h */
diff --git a/include/mbedcrypto/rsa_internal.h b/include/mbedcrypto/rsa_internal.h
new file mode 100644
index 0000000..635fa18
--- /dev/null
+++ b/include/mbedcrypto/rsa_internal.h
@@ -0,0 +1,226 @@
+/**
+ * \file rsa_internal.h
+ *
+ * \brief Context-independent RSA helper functions
+ *
+ * This module declares some RSA-related helper functions useful when
+ * implementing the RSA interface. These functions are provided in a separate
+ * compilation unit in order to make it easy for designers of alternative RSA
+ * implementations to use them in their own code, as it is conceived that the
+ * functionality they provide will be necessary for most complete
+ * implementations.
+ *
+ * End-users of Mbed Crypto who are not providing their own alternative RSA
+ * implementations should not use these functions directly, and should instead
+ * use only the functions declared in rsa.h.
+ *
+ * The interface provided by this module will be maintained through LTS (Long
+ * Term Support) branches of Mbed Crypto, but may otherwise be subject to change,
+ * and must be considered an internal interface of the library.
+ *
+ * There are two classes of helper functions:
+ *
+ * (1) Parameter-generating helpers. These are:
+ * - mbedcrypto_rsa_deduce_primes
+ * - mbedcrypto_rsa_deduce_private_exponent
+ * - mbedcrypto_rsa_deduce_crt
+ * Each of these functions takes a set of core RSA parameters and
+ * generates some other, or CRT related parameters.
+ *
+ * (2) Parameter-checking helpers. These are:
+ * - mbedcrypto_rsa_validate_params
+ * - mbedcrypto_rsa_validate_crt
+ * They take a set of core or CRT related RSA parameters and check their
+ * validity.
+ *
+ */
+/*
+ * Copyright (C) 2006-2017, 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 Crypto (https://tls.mbed.org)
+ *
+ */
+
+#ifndef MBEDCRYPTO_RSA_INTERNAL_H
+#define MBEDCRYPTO_RSA_INTERNAL_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include "bignum.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * \brief Compute RSA prime moduli P, Q from public modulus N=PQ
+ * and a pair of private and public key.
+ *
+ * \note This is a 'static' helper function not operating on
+ * an RSA context. Alternative implementations need not
+ * overwrite it.
+ *
+ * \param N RSA modulus N = PQ, with P, Q to be found
+ * \param E RSA public exponent
+ * \param D RSA private exponent
+ * \param P Pointer to MPI holding first prime factor of N on success
+ * \param Q Pointer to MPI holding second prime factor of N on success
+ *
+ * \return
+ * - 0 if successful. In this case, P and Q constitute a
+ * factorization of N.
+ * - A non-zero error code otherwise.
+ *
+ * \note It is neither checked that P, Q are prime nor that
+ * D, E are modular inverses wrt. P-1 and Q-1. For that,
+ * use the helper function \c mbedcrypto_rsa_validate_params.
+ *
+ */
+int mbedcrypto_rsa_deduce_primes( mbedcrypto_mpi const *N, mbedcrypto_mpi const *E,
+ mbedcrypto_mpi const *D,
+ mbedcrypto_mpi *P, mbedcrypto_mpi *Q );
+
+/**
+ * \brief Compute RSA private exponent from
+ * prime moduli and public key.
+ *
+ * \note This is a 'static' helper function not operating on
+ * an RSA context. Alternative implementations need not
+ * overwrite it.
+ *
+ * \param P First prime factor of RSA modulus
+ * \param Q Second prime factor of RSA modulus
+ * \param E RSA public exponent
+ * \param D Pointer to MPI holding the private exponent on success.
+ *
+ * \return
+ * - 0 if successful. In this case, D is set to a simultaneous
+ * modular inverse of E modulo both P-1 and Q-1.
+ * - A non-zero error code otherwise.
+ *
+ * \note This function does not check whether P and Q are primes.
+ *
+ */
+int mbedcrypto_rsa_deduce_private_exponent( mbedcrypto_mpi const *P,
+ mbedcrypto_mpi const *Q,
+ mbedcrypto_mpi const *E,
+ mbedcrypto_mpi *D );
+
+
+/**
+ * \brief Generate RSA-CRT parameters
+ *
+ * \note This is a 'static' helper function not operating on
+ * an RSA context. Alternative implementations need not
+ * overwrite it.
+ *
+ * \param P First prime factor of N
+ * \param Q Second prime factor of N
+ * \param D RSA private exponent
+ * \param DP Output variable for D modulo P-1
+ * \param DQ Output variable for D modulo Q-1
+ * \param QP Output variable for the modular inverse of Q modulo P.
+ *
+ * \return 0 on success, non-zero error code otherwise.
+ *
+ * \note This function does not check whether P, Q are
+ * prime and whether D is a valid private exponent.
+ *
+ */
+int mbedcrypto_rsa_deduce_crt( const mbedcrypto_mpi *P, const mbedcrypto_mpi *Q,
+ const mbedcrypto_mpi *D, mbedcrypto_mpi *DP,
+ mbedcrypto_mpi *DQ, mbedcrypto_mpi *QP );
+
+
+/**
+ * \brief Check validity of core RSA parameters
+ *
+ * \note This is a 'static' helper function not operating on
+ * an RSA context. Alternative implementations need not
+ * overwrite it.
+ *
+ * \param N RSA modulus N = PQ
+ * \param P First prime factor of N
+ * \param Q Second prime factor of N
+ * \param D RSA private exponent
+ * \param E RSA public exponent
+ * \param f_rng PRNG to be used for primality check, or NULL
+ * \param p_rng PRNG context for f_rng, or NULL
+ *
+ * \return
+ * - 0 if the following conditions are satisfied
+ * if all relevant parameters are provided:
+ * - P prime if f_rng != NULL (%)
+ * - Q prime if f_rng != NULL (%)
+ * - 1 < N = P * Q
+ * - 1 < D, E < N
+ * - D and E are modular inverses modulo P-1 and Q-1
+ * (%) This is only done if MBEDCRYPTO_GENPRIME is defined.
+ * - A non-zero error code otherwise.
+ *
+ * \note The function can be used with a restricted set of arguments
+ * to perform specific checks only. E.g., calling it with
+ * (-,P,-,-,-) and a PRNG amounts to a primality check for P.
+ */
+int mbedcrypto_rsa_validate_params( const mbedcrypto_mpi *N, const mbedcrypto_mpi *P,
+ const mbedcrypto_mpi *Q, const mbedcrypto_mpi *D,
+ const mbedcrypto_mpi *E,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
+/**
+ * \brief Check validity of RSA CRT parameters
+ *
+ * \note This is a 'static' helper function not operating on
+ * an RSA context. Alternative implementations need not
+ * overwrite it.
+ *
+ * \param P First prime factor of RSA modulus
+ * \param Q Second prime factor of RSA modulus
+ * \param D RSA private exponent
+ * \param DP MPI to check for D modulo P-1
+ * \param DQ MPI to check for D modulo P-1
+ * \param QP MPI to check for the modular inverse of Q modulo P.
+ *
+ * \return
+ * - 0 if the following conditions are satisfied:
+ * - D = DP mod P-1 if P, D, DP != NULL
+ * - Q = DQ mod P-1 if P, D, DQ != NULL
+ * - QP = Q^-1 mod P if P, Q, QP != NULL
+ * - \c MBEDCRYPTO_ERR_RSA_KEY_CHECK_FAILED if check failed,
+ * potentially including \c MBEDCRYPTO_ERR_MPI_XXX if some
+ * MPI calculations failed.
+ * - \c MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA if insufficient
+ * data was provided to check DP, DQ or QP.
+ *
+ * \note The function can be used with a restricted set of arguments
+ * to perform specific checks only. E.g., calling it with the
+ * parameters (P, -, D, DP, -, -) will check DP = D mod P-1.
+ */
+int mbedcrypto_rsa_validate_crt( const mbedcrypto_mpi *P, const mbedcrypto_mpi *Q,
+ const mbedcrypto_mpi *D, const mbedcrypto_mpi *DP,
+ const mbedcrypto_mpi *DQ, const mbedcrypto_mpi *QP );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* rsa_internal.h */
diff --git a/include/mbedcrypto/sha1.h b/include/mbedcrypto/sha1.h
new file mode 100644
index 0000000..9f7fe5a
--- /dev/null
+++ b/include/mbedcrypto/sha1.h
@@ -0,0 +1,324 @@
+/**
+ * \file sha1.h
+ *
+ * \brief This file contains SHA-1 definitions and functions.
+ *
+ * The Secure Hash Algorithm 1 (SHA-1) cryptographic hash function is defined in
+ * <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
+ *
+ * \warning SHA-1 is considered a weak message digest and its use constitutes
+ * a security risk. We recommend considering stronger message
+ * digests instead.
+ */
+/*
+ * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_SHA1_H
+#define MBEDCRYPTO_SHA1_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MBEDCRYPTO_ERR_SHA1_HW_ACCEL_FAILED -0x0035 /**< SHA-1 hardware accelerator failed */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDCRYPTO_SHA1_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief The SHA-1 context structure.
+ *
+ * \warning SHA-1 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ */
+typedef struct
+{
+ uint32_t total[2]; /*!< The number of Bytes processed. */
+ uint32_t state[5]; /*!< The intermediate digest state. */
+ unsigned char buffer[64]; /*!< The data block being processed. */
+}
+mbedcrypto_sha1_context;
+
+#else /* MBEDCRYPTO_SHA1_ALT */
+#include "sha1_alt.h"
+#endif /* MBEDCRYPTO_SHA1_ALT */
+
+/**
+ * \brief This function initializes a SHA-1 context.
+ *
+ * \warning SHA-1 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ * \param ctx The SHA-1 context to initialize.
+ *
+ */
+void mbedcrypto_sha1_init( mbedcrypto_sha1_context *ctx );
+
+/**
+ * \brief This function clears a SHA-1 context.
+ *
+ * \warning SHA-1 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ * \param ctx The SHA-1 context to clear.
+ *
+ */
+void mbedcrypto_sha1_free( mbedcrypto_sha1_context *ctx );
+
+/**
+ * \brief This function clones the state of a SHA-1 context.
+ *
+ * \warning SHA-1 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ * \param dst The SHA-1 context to clone to.
+ * \param src The SHA-1 context to clone from.
+ *
+ */
+void mbedcrypto_sha1_clone( mbedcrypto_sha1_context *dst,
+ const mbedcrypto_sha1_context *src );
+
+/**
+ * \brief This function starts a SHA-1 checksum calculation.
+ *
+ * \warning SHA-1 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ * \param ctx The SHA-1 context to initialize.
+ *
+ * \return \c 0 on success.
+ *
+ */
+int mbedcrypto_sha1_starts_ret( mbedcrypto_sha1_context *ctx );
+
+/**
+ * \brief This function feeds an input buffer into an ongoing SHA-1
+ * checksum calculation.
+ *
+ * \warning SHA-1 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ * \param ctx The SHA-1 context.
+ * \param input The buffer holding the input data.
+ * \param ilen The length of the input data.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_sha1_update_ret( mbedcrypto_sha1_context *ctx,
+ const unsigned char *input,
+ size_t ilen );
+
+/**
+ * \brief This function finishes the SHA-1 operation, and writes
+ * the result to the output buffer.
+ *
+ * \warning SHA-1 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ * \param ctx The SHA-1 context.
+ * \param output The SHA-1 checksum result.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_sha1_finish_ret( mbedcrypto_sha1_context *ctx,
+ unsigned char output[20] );
+
+/**
+ * \brief SHA-1 process data block (internal use only).
+ *
+ * \warning SHA-1 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ * \param ctx The SHA-1 context.
+ * \param data The data block being processed.
+ *
+ * \return \c 0 on success.
+ *
+ */
+int mbedcrypto_internal_sha1_process( mbedcrypto_sha1_context *ctx,
+ const unsigned char data[64] );
+
+#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
+#if defined(MBEDCRYPTO_DEPRECATED_WARNING)
+#define MBEDCRYPTO_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDCRYPTO_DEPRECATED
+#endif
+/**
+ * \brief This function starts a SHA-1 checksum calculation.
+ *
+ * \warning SHA-1 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ * \deprecated Superseded by mbedcrypto_sha1_starts_ret() in 2.7.0.
+ *
+ * \param ctx The SHA-1 context to initialize.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_sha1_starts( mbedcrypto_sha1_context *ctx );
+
+/**
+ * \brief This function feeds an input buffer into an ongoing SHA-1
+ * checksum calculation.
+ *
+ * \warning SHA-1 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ * \deprecated Superseded by mbedcrypto_sha1_update_ret() in 2.7.0.
+ *
+ * \param ctx The SHA-1 context.
+ * \param input The buffer holding the input data.
+ * \param ilen The length of the input data.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_sha1_update( mbedcrypto_sha1_context *ctx,
+ const unsigned char *input,
+ size_t ilen );
+
+/**
+ * \brief This function finishes the SHA-1 operation, and writes
+ * the result to the output buffer.
+ *
+ * \warning SHA-1 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ * \deprecated Superseded by mbedcrypto_sha1_finish_ret() in 2.7.0.
+ *
+ * \param ctx The SHA-1 context.
+ * \param output The SHA-1 checksum result.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_sha1_finish( mbedcrypto_sha1_context *ctx,
+ unsigned char output[20] );
+
+/**
+ * \brief SHA-1 process data block (internal use only).
+ *
+ * \warning SHA-1 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ * \deprecated Superseded by mbedcrypto_internal_sha1_process() in 2.7.0.
+ *
+ * \param ctx The SHA-1 context.
+ * \param data The data block being processed.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_sha1_process( mbedcrypto_sha1_context *ctx,
+ const unsigned char data[64] );
+
+#undef MBEDCRYPTO_DEPRECATED
+#endif /* !MBEDCRYPTO_DEPRECATED_REMOVED */
+
+/**
+ * \brief This function calculates the SHA-1 checksum of a buffer.
+ *
+ * The function allocates the context, performs the
+ * calculation, and frees the context.
+ *
+ * The SHA-1 result is calculated as
+ * output = SHA-1(input buffer).
+ *
+ * \warning SHA-1 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ * \param input The buffer holding the input data.
+ * \param ilen The length of the input data.
+ * \param output The SHA-1 checksum result.
+ *
+ * \return \c 0 on success.
+ *
+ */
+int mbedcrypto_sha1_ret( const unsigned char *input,
+ size_t ilen,
+ unsigned char output[20] );
+
+#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
+#if defined(MBEDCRYPTO_DEPRECATED_WARNING)
+#define MBEDCRYPTO_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDCRYPTO_DEPRECATED
+#endif
+/**
+ * \brief This function calculates the SHA-1 checksum of a buffer.
+ *
+ * The function allocates the context, performs the
+ * calculation, and frees the context.
+ *
+ * The SHA-1 result is calculated as
+ * output = SHA-1(input buffer).
+ *
+ * \warning SHA-1 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ * \deprecated Superseded by mbedcrypto_sha1_ret() in 2.7.0
+ *
+ * \param input The buffer holding the input data.
+ * \param ilen The length of the input data.
+ * \param output The SHA-1 checksum result.
+ *
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_sha1( const unsigned char *input,
+ size_t ilen,
+ unsigned char output[20] );
+
+#undef MBEDCRYPTO_DEPRECATED
+#endif /* !MBEDCRYPTO_DEPRECATED_REMOVED */
+
+/**
+ * \brief The SHA-1 checkup routine.
+ *
+ * \warning SHA-1 is considered a weak message digest and its use
+ * constitutes a security risk. We recommend considering
+ * stronger message digests instead.
+ *
+ * \return \c 0 on success.
+ * \return \c 1 on failure.
+ *
+ */
+int mbedcrypto_sha1_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedcrypto_sha1.h */
diff --git a/include/mbedcrypto/sha256.h b/include/mbedcrypto/sha256.h
new file mode 100644
index 0000000..edeb157
--- /dev/null
+++ b/include/mbedcrypto/sha256.h
@@ -0,0 +1,272 @@
+/**
+ * \file sha256.h
+ *
+ * \brief This file contains SHA-224 and SHA-256 definitions and functions.
+ *
+ * The Secure Hash Algorithms 224 and 256 (SHA-224 and SHA-256) cryptographic
+ * hash functions are defined in <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
+ */
+/*
+ * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_SHA256_H
+#define MBEDCRYPTO_SHA256_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MBEDCRYPTO_ERR_SHA256_HW_ACCEL_FAILED -0x0037 /**< SHA-256 hardware accelerator failed */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDCRYPTO_SHA256_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief The SHA-256 context structure.
+ *
+ * The structure is used both for SHA-256 and for SHA-224
+ * checksum calculations. The choice between these two is
+ * made in the call to mbedcrypto_sha256_starts_ret().
+ */
+typedef struct
+{
+ uint32_t total[2]; /*!< The number of Bytes processed. */
+ uint32_t state[8]; /*!< The intermediate digest state. */
+ unsigned char buffer[64]; /*!< The data block being processed. */
+ int is224; /*!< Determines which function to use:
+ 0: Use SHA-256, or 1: Use SHA-224. */
+}
+mbedcrypto_sha256_context;
+
+#else /* MBEDCRYPTO_SHA256_ALT */
+#include "sha256_alt.h"
+#endif /* MBEDCRYPTO_SHA256_ALT */
+
+/**
+ * \brief This function initializes a SHA-256 context.
+ *
+ * \param ctx The SHA-256 context to initialize.
+ */
+void mbedcrypto_sha256_init( mbedcrypto_sha256_context *ctx );
+
+/**
+ * \brief This function clears a SHA-256 context.
+ *
+ * \param ctx The SHA-256 context to clear.
+ */
+void mbedcrypto_sha256_free( mbedcrypto_sha256_context *ctx );
+
+/**
+ * \brief This function clones the state of a SHA-256 context.
+ *
+ * \param dst The destination context.
+ * \param src The context to clone.
+ */
+void mbedcrypto_sha256_clone( mbedcrypto_sha256_context *dst,
+ const mbedcrypto_sha256_context *src );
+
+/**
+ * \brief This function starts a SHA-224 or SHA-256 checksum
+ * calculation.
+ *
+ * \param ctx The context to initialize.
+ * \param is224 Determines which function to use:
+ * 0: Use SHA-256, or 1: Use SHA-224.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_sha256_starts_ret( mbedcrypto_sha256_context *ctx, int is224 );
+
+/**
+ * \brief This function feeds an input buffer into an ongoing
+ * SHA-256 checksum calculation.
+ *
+ * \param ctx The SHA-256 context.
+ * \param input The buffer holding the data.
+ * \param ilen The length of the input data.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_sha256_update_ret( mbedcrypto_sha256_context *ctx,
+ const unsigned char *input,
+ size_t ilen );
+
+/**
+ * \brief This function finishes the SHA-256 operation, and writes
+ * the result to the output buffer.
+ *
+ * \param ctx The SHA-256 context.
+ * \param output The SHA-224 or SHA-256 checksum result.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_sha256_finish_ret( mbedcrypto_sha256_context *ctx,
+ unsigned char output[32] );
+
+/**
+ * \brief This function processes a single data block within
+ * the ongoing SHA-256 computation. This function is for
+ * internal use only.
+ *
+ * \param ctx The SHA-256 context.
+ * \param data The buffer holding one block of data.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_internal_sha256_process( mbedcrypto_sha256_context *ctx,
+ const unsigned char data[64] );
+
+#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
+#if defined(MBEDCRYPTO_DEPRECATED_WARNING)
+#define MBEDCRYPTO_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDCRYPTO_DEPRECATED
+#endif
+/**
+ * \brief This function starts a SHA-224 or SHA-256 checksum
+ * calculation.
+ *
+ *
+ * \deprecated Superseded by mbedcrypto_sha256_starts_ret() in 2.7.0.
+ *
+ * \param ctx The context to initialize.
+ * \param is224 Determines which function to use:
+ * 0: Use SHA-256, or 1: Use SHA-224.
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_sha256_starts( mbedcrypto_sha256_context *ctx,
+ int is224 );
+
+/**
+ * \brief This function feeds an input buffer into an ongoing
+ * SHA-256 checksum calculation.
+ *
+ * \deprecated Superseded by mbedcrypto_sha256_update_ret() in 2.7.0.
+ *
+ * \param ctx The SHA-256 context to initialize.
+ * \param input The buffer holding the data.
+ * \param ilen The length of the input data.
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_sha256_update( mbedcrypto_sha256_context *ctx,
+ const unsigned char *input,
+ size_t ilen );
+
+/**
+ * \brief This function finishes the SHA-256 operation, and writes
+ * the result to the output buffer.
+ *
+ * \deprecated Superseded by mbedcrypto_sha256_finish_ret() in 2.7.0.
+ *
+ * \param ctx The SHA-256 context.
+ * \param output The SHA-224 or SHA-256 checksum result.
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_sha256_finish( mbedcrypto_sha256_context *ctx,
+ unsigned char output[32] );
+
+/**
+ * \brief This function processes a single data block within
+ * the ongoing SHA-256 computation. This function is for
+ * internal use only.
+ *
+ * \deprecated Superseded by mbedcrypto_internal_sha256_process() in 2.7.0.
+ *
+ * \param ctx The SHA-256 context.
+ * \param data The buffer holding one block of data.
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_sha256_process( mbedcrypto_sha256_context *ctx,
+ const unsigned char data[64] );
+
+#undef MBEDCRYPTO_DEPRECATED
+#endif /* !MBEDCRYPTO_DEPRECATED_REMOVED */
+
+/**
+ * \brief This function calculates the SHA-224 or SHA-256
+ * checksum of a buffer.
+ *
+ * The function allocates the context, performs the
+ * calculation, and frees the context.
+ *
+ * The SHA-256 result is calculated as
+ * output = SHA-256(input buffer).
+ *
+ * \param input The buffer holding the input data.
+ * \param ilen The length of the input data.
+ * \param output The SHA-224 or SHA-256 checksum result.
+ * \param is224 Determines which function to use:
+ * 0: Use SHA-256, or 1: Use SHA-224.
+ */
+int mbedcrypto_sha256_ret( const unsigned char *input,
+ size_t ilen,
+ unsigned char output[32],
+ int is224 );
+
+#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
+#if defined(MBEDCRYPTO_DEPRECATED_WARNING)
+#define MBEDCRYPTO_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDCRYPTO_DEPRECATED
+#endif
+
+/**
+ * \brief This function calculates the SHA-224 or SHA-256 checksum
+ * of a buffer.
+ *
+ * The function allocates the context, performs the
+ * calculation, and frees the context.
+ *
+ * The SHA-256 result is calculated as
+ * output = SHA-256(input buffer).
+ *
+ * \deprecated Superseded by mbedcrypto_sha256_ret() in 2.7.0.
+ *
+ * \param input The buffer holding the data.
+ * \param ilen The length of the input data.
+ * \param output The SHA-224 or SHA-256 checksum result.
+ * \param is224 Determines which function to use:
+ * 0: Use SHA-256, or 1: Use SHA-224.
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_sha256( const unsigned char *input,
+ size_t ilen,
+ unsigned char output[32],
+ int is224 );
+
+#undef MBEDCRYPTO_DEPRECATED
+#endif /* !MBEDCRYPTO_DEPRECATED_REMOVED */
+
+/**
+ * \brief The SHA-224 and SHA-256 checkup routine.
+ *
+ * \return \c 0 on success.
+ * \return \c 1 on failure.
+ */
+int mbedcrypto_sha256_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedcrypto_sha256.h */
diff --git a/include/mbedcrypto/sha512.h b/include/mbedcrypto/sha512.h
new file mode 100644
index 0000000..f3f0fdf
--- /dev/null
+++ b/include/mbedcrypto/sha512.h
@@ -0,0 +1,270 @@
+/**
+ * \file sha512.h
+ * \brief This file contains SHA-384 and SHA-512 definitions and functions.
+ *
+ * The Secure Hash Algorithms 384 and 512 (SHA-384 and SHA-512) cryptographic
+ * hash functions are defined in <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
+ */
+/*
+ * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_SHA512_H
+#define MBEDCRYPTO_SHA512_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MBEDCRYPTO_ERR_SHA512_HW_ACCEL_FAILED -0x0039 /**< SHA-512 hardware accelerator failed */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDCRYPTO_SHA512_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief The SHA-512 context structure.
+ *
+ * The structure is used both for SHA-384 and for SHA-512
+ * checksum calculations. The choice between these two is
+ * made in the call to mbedcrypto_sha512_starts_ret().
+ */
+typedef struct
+{
+ uint64_t total[2]; /*!< The number of Bytes processed. */
+ uint64_t state[8]; /*!< The intermediate digest state. */
+ unsigned char buffer[128]; /*!< The data block being processed. */
+ int is384; /*!< Determines which function to use:
+ 0: Use SHA-512, or 1: Use SHA-384. */
+}
+mbedcrypto_sha512_context;
+
+#else /* MBEDCRYPTO_SHA512_ALT */
+#include "sha512_alt.h"
+#endif /* MBEDCRYPTO_SHA512_ALT */
+
+/**
+ * \brief This function initializes a SHA-512 context.
+ *
+ * \param ctx The SHA-512 context to initialize.
+ */
+void mbedcrypto_sha512_init( mbedcrypto_sha512_context *ctx );
+
+/**
+ * \brief This function clears a SHA-512 context.
+ *
+ * \param ctx The SHA-512 context to clear.
+ */
+void mbedcrypto_sha512_free( mbedcrypto_sha512_context *ctx );
+
+/**
+ * \brief This function clones the state of a SHA-512 context.
+ *
+ * \param dst The destination context.
+ * \param src The context to clone.
+ */
+void mbedcrypto_sha512_clone( mbedcrypto_sha512_context *dst,
+ const mbedcrypto_sha512_context *src );
+
+/**
+ * \brief This function starts a SHA-384 or SHA-512 checksum
+ * calculation.
+ *
+ * \param ctx The SHA-512 context to initialize.
+ * \param is384 Determines which function to use:
+ * 0: Use SHA-512, or 1: Use SHA-384.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_sha512_starts_ret( mbedcrypto_sha512_context *ctx, int is384 );
+
+/**
+ * \brief This function feeds an input buffer into an ongoing
+ * SHA-512 checksum calculation.
+ *
+ * \param ctx The SHA-512 context.
+ * \param input The buffer holding the input data.
+ * \param ilen The length of the input data.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_sha512_update_ret( mbedcrypto_sha512_context *ctx,
+ const unsigned char *input,
+ size_t ilen );
+
+/**
+ * \brief This function finishes the SHA-512 operation, and writes
+ * the result to the output buffer. This function is for
+ * internal use only.
+ *
+ * \param ctx The SHA-512 context.
+ * \param output The SHA-384 or SHA-512 checksum result.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_sha512_finish_ret( mbedcrypto_sha512_context *ctx,
+ unsigned char output[64] );
+
+/**
+ * \brief This function processes a single data block within
+ * the ongoing SHA-512 computation.
+ *
+ * \param ctx The SHA-512 context.
+ * \param data The buffer holding one block of data.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_internal_sha512_process( mbedcrypto_sha512_context *ctx,
+ const unsigned char data[128] );
+#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
+#if defined(MBEDCRYPTO_DEPRECATED_WARNING)
+#define MBEDCRYPTO_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDCRYPTO_DEPRECATED
+#endif
+/**
+ * \brief This function starts a SHA-384 or SHA-512 checksum
+ * calculation.
+ *
+ * \deprecated Superseded by mbedcrypto_sha512_starts_ret() in 2.7.0
+ *
+ * \param ctx The SHA-512 context to initialize.
+ * \param is384 Determines which function to use:
+ * 0: Use SHA-512, or 1: Use SHA-384.
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_sha512_starts( mbedcrypto_sha512_context *ctx,
+ int is384 );
+
+/**
+ * \brief This function feeds an input buffer into an ongoing
+ * SHA-512 checksum calculation.
+ *
+ * \deprecated Superseded by mbedcrypto_sha512_update_ret() in 2.7.0.
+ *
+ * \param ctx The SHA-512 context.
+ * \param input The buffer holding the data.
+ * \param ilen The length of the input data.
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_sha512_update( mbedcrypto_sha512_context *ctx,
+ const unsigned char *input,
+ size_t ilen );
+
+/**
+ * \brief This function finishes the SHA-512 operation, and writes
+ * the result to the output buffer.
+ *
+ * \deprecated Superseded by mbedcrypto_sha512_finish_ret() in 2.7.0.
+ *
+ * \param ctx The SHA-512 context.
+ * \param output The SHA-384 or SHA-512 checksum result.
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_sha512_finish( mbedcrypto_sha512_context *ctx,
+ unsigned char output[64] );
+
+/**
+ * \brief This function processes a single data block within
+ * the ongoing SHA-512 computation. This function is for
+ * internal use only.
+ *
+ * \deprecated Superseded by mbedcrypto_internal_sha512_process() in 2.7.0.
+ *
+ * \param ctx The SHA-512 context.
+ * \param data The buffer holding one block of data.
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_sha512_process(
+ mbedcrypto_sha512_context *ctx,
+ const unsigned char data[128] );
+
+#undef MBEDCRYPTO_DEPRECATED
+#endif /* !MBEDCRYPTO_DEPRECATED_REMOVED */
+
+/**
+ * \brief This function calculates the SHA-512 or SHA-384
+ * checksum of a buffer.
+ *
+ * The function allocates the context, performs the
+ * calculation, and frees the context.
+ *
+ * The SHA-512 result is calculated as
+ * output = SHA-512(input buffer).
+ *
+ * \param input The buffer holding the input data.
+ * \param ilen The length of the input data.
+ * \param output The SHA-384 or SHA-512 checksum result.
+ * \param is384 Determines which function to use:
+ * 0: Use SHA-512, or 1: Use SHA-384.
+ *
+ * \return \c 0 on success.
+ */
+int mbedcrypto_sha512_ret( const unsigned char *input,
+ size_t ilen,
+ unsigned char output[64],
+ int is384 );
+
+#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
+#if defined(MBEDCRYPTO_DEPRECATED_WARNING)
+#define MBEDCRYPTO_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDCRYPTO_DEPRECATED
+#endif
+/**
+ * \brief This function calculates the SHA-512 or SHA-384
+ * checksum of a buffer.
+ *
+ * The function allocates the context, performs the
+ * calculation, and frees the context.
+ *
+ * The SHA-512 result is calculated as
+ * output = SHA-512(input buffer).
+ *
+ * \deprecated Superseded by mbedcrypto_sha512_ret() in 2.7.0
+ *
+ * \param input The buffer holding the data.
+ * \param ilen The length of the input data.
+ * \param output The SHA-384 or SHA-512 checksum result.
+ * \param is384 Determines which function to use:
+ * 0: Use SHA-512, or 1: Use SHA-384.
+ */
+MBEDCRYPTO_DEPRECATED void mbedcrypto_sha512( const unsigned char *input,
+ size_t ilen,
+ unsigned char output[64],
+ int is384 );
+
+#undef MBEDCRYPTO_DEPRECATED
+#endif /* !MBEDCRYPTO_DEPRECATED_REMOVED */
+ /**
+ * \brief The SHA-384 or SHA-512 checkup routine.
+ *
+ * \return \c 0 on success.
+ * \return \c 1 on failure.
+ */
+int mbedcrypto_sha512_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedcrypto_sha512.h */
diff --git a/include/mbedcrypto/threading.h b/include/mbedcrypto/threading.h
new file mode 100644
index 0000000..8e14f6b
--- /dev/null
+++ b/include/mbedcrypto/threading.h
@@ -0,0 +1,111 @@
+/**
+ * \file threading.h
+ *
+ * \brief Threading abstraction layer
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_THREADING_H
+#define MBEDCRYPTO_THREADING_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MBEDCRYPTO_ERR_THREADING_FEATURE_UNAVAILABLE -0x001A /**< The selected feature is not available. */
+#define MBEDCRYPTO_ERR_THREADING_BAD_INPUT_DATA -0x001C /**< Bad input parameters to function. */
+#define MBEDCRYPTO_ERR_THREADING_MUTEX_ERROR -0x001E /**< Locking / unlocking / free failed with error code. */
+
+#if defined(MBEDCRYPTO_THREADING_PTHREAD)
+#include <pthread.h>
+typedef struct
+{
+ pthread_mutex_t mutex;
+ char is_valid;
+} mbedcrypto_threading_mutex_t;
+#endif
+
+#if defined(MBEDCRYPTO_THREADING_ALT)
+/* You should define the mbedcrypto_threading_mutex_t type in your header */
+#include "threading_alt.h"
+
+/**
+ * \brief Set your alternate threading implementation function
+ * pointers and initialize global mutexes. If used, this
+ * function must be called once in the main thread before any
+ * other Mbed Crypto function is called, and
+ * mbedcrypto_threading_free_alt() must be called once in the main
+ * thread after all other Mbed Crypto functions.
+ *
+ * \note mutex_init() and mutex_free() don't return a status code.
+ * If mutex_init() fails, it should leave its argument (the
+ * mutex) in a state such that mutex_lock() will fail when
+ * called with this argument.
+ *
+ * \param mutex_init the init function implementation
+ * \param mutex_free the free function implementation
+ * \param mutex_lock the lock function implementation
+ * \param mutex_unlock the unlock function implementation
+ */
+void mbedcrypto_threading_set_alt( void (*mutex_init)( mbedcrypto_threading_mutex_t * ),
+ void (*mutex_free)( mbedcrypto_threading_mutex_t * ),
+ int (*mutex_lock)( mbedcrypto_threading_mutex_t * ),
+ int (*mutex_unlock)( mbedcrypto_threading_mutex_t * ) );
+
+/**
+ * \brief Free global mutexes.
+ */
+void mbedcrypto_threading_free_alt( void );
+#endif /* MBEDCRYPTO_THREADING_ALT */
+
+#if defined(MBEDCRYPTO_THREADING_C)
+/*
+ * The function pointers for mutex_init, mutex_free, mutex_ and mutex_unlock
+ *
+ * All these functions are expected to work or the result will be undefined.
+ */
+extern void (*mbedcrypto_mutex_init)( mbedcrypto_threading_mutex_t *mutex );
+extern void (*mbedcrypto_mutex_free)( mbedcrypto_threading_mutex_t *mutex );
+extern int (*mbedcrypto_mutex_lock)( mbedcrypto_threading_mutex_t *mutex );
+extern int (*mbedcrypto_mutex_unlock)( mbedcrypto_threading_mutex_t *mutex );
+
+/*
+ * Global mutexes
+ */
+#if defined(MBEDCRYPTO_FS_IO)
+extern mbedcrypto_threading_mutex_t mbedcrypto_threading_readdir_mutex;
+#endif
+#if defined(MBEDCRYPTO_HAVE_TIME_DATE)
+extern mbedcrypto_threading_mutex_t mbedcrypto_threading_gmtime_mutex;
+#endif
+#endif /* MBEDCRYPTO_THREADING_C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* threading.h */
diff --git a/include/mbedcrypto/xtea.h b/include/mbedcrypto/xtea.h
new file mode 100644
index 0000000..5db947d
--- /dev/null
+++ b/include/mbedcrypto/xtea.h
@@ -0,0 +1,133 @@
+/**
+ * \file xtea.h
+ *
+ * \brief XTEA block cipher (32-bit)
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+#ifndef MBEDCRYPTO_XTEA_H
+#define MBEDCRYPTO_XTEA_H
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MBEDCRYPTO_XTEA_ENCRYPT 1
+#define MBEDCRYPTO_XTEA_DECRYPT 0
+
+#define MBEDCRYPTO_ERR_XTEA_INVALID_INPUT_LENGTH -0x0028 /**< The data input has an invalid length. */
+#define MBEDCRYPTO_ERR_XTEA_HW_ACCEL_FAILED -0x0029 /**< XTEA hardware accelerator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDCRYPTO_XTEA_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief XTEA context structure
+ */
+typedef struct
+{
+ uint32_t k[4]; /*!< key */
+}
+mbedcrypto_xtea_context;
+
+#else /* MBEDCRYPTO_XTEA_ALT */
+#include "xtea_alt.h"
+#endif /* MBEDCRYPTO_XTEA_ALT */
+
+/**
+ * \brief Initialize XTEA context
+ *
+ * \param ctx XTEA context to be initialized
+ */
+void mbedcrypto_xtea_init( mbedcrypto_xtea_context *ctx );
+
+/**
+ * \brief Clear XTEA context
+ *
+ * \param ctx XTEA context to be cleared
+ */
+void mbedcrypto_xtea_free( mbedcrypto_xtea_context *ctx );
+
+/**
+ * \brief XTEA key schedule
+ *
+ * \param ctx XTEA context to be initialized
+ * \param key the secret key
+ */
+void mbedcrypto_xtea_setup( mbedcrypto_xtea_context *ctx, const unsigned char key[16] );
+
+/**
+ * \brief XTEA cipher function
+ *
+ * \param ctx XTEA context
+ * \param mode MBEDCRYPTO_XTEA_ENCRYPT or MBEDCRYPTO_XTEA_DECRYPT
+ * \param input 8-byte input block
+ * \param output 8-byte output block
+ *
+ * \return 0 if successful
+ */
+int mbedcrypto_xtea_crypt_ecb( mbedcrypto_xtea_context *ctx,
+ int mode,
+ const unsigned char input[8],
+ unsigned char output[8] );
+
+#if defined(MBEDCRYPTO_CIPHER_MODE_CBC)
+/**
+ * \brief XTEA CBC cipher function
+ *
+ * \param ctx XTEA context
+ * \param mode MBEDCRYPTO_XTEA_ENCRYPT or MBEDCRYPTO_XTEA_DECRYPT
+ * \param length the length of input, multiple of 8
+ * \param iv initialization vector for CBC mode
+ * \param input input block
+ * \param output output block
+ *
+ * \return 0 if successful,
+ * MBEDCRYPTO_ERR_XTEA_INVALID_INPUT_LENGTH if the length % 8 != 0
+ */
+int mbedcrypto_xtea_crypt_cbc( mbedcrypto_xtea_context *ctx,
+ int mode,
+ size_t length,
+ unsigned char iv[8],
+ const unsigned char *input,
+ unsigned char *output);
+#endif /* MBEDCRYPTO_CIPHER_MODE_CBC */
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int mbedcrypto_xtea_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* xtea.h */
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
new file mode 100644
index 0000000..6d31322
--- /dev/null
+++ b/include/psa/crypto.h
@@ -0,0 +1,2839 @@
+/**
+ * \file psa/crypto.h
+ * \brief Platform Security Architecture cryptography module
+ */
+/*
+ * Copyright (C) 2018, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PSA_CRYPTO_H
+#define PSA_CRYPTO_H
+
+#include "crypto_platform.h"
+
+#include <stddef.h>
+
+#ifdef __DOXYGEN_ONLY__
+/* This __DOXYGEN_ONLY__ block contains mock definitions for things that
+ * must be defined in the crypto_platform.h header. These mock definitions
+ * are present in this file as a convenience to generate pretty-printed
+ * documentation that includes those definitions. */
+
+/** \defgroup platform Implementation-specific definitions
+ * @{
+ */
+
+/** \brief Key slot number.
+ *
+ * This type represents key slots. It must be an unsigned integral
+ * type. The choice of type is implementation-dependent.
+ * 0 is not a valid key slot number. The meaning of other values is
+ * implementation dependent.
+ *
+ * At any given point in time, each key slot either contains a
+ * cryptographic object, or is empty. Key slots are persistent:
+ * once set, the cryptographic object remains in the key slot until
+ * explicitly destroyed.
+ */
+typedef _unsigned_integral_type_ psa_key_slot_t;
+
+/**@}*/
+#endif /* __DOXYGEN_ONLY__ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup basic Basic definitions
+ * @{
+ */
+
+#if defined(PSA_SUCCESS)
+/* If PSA_SUCCESS is defined, assume that PSA crypto is being used
+ * together with PSA IPC, which also defines the identifier
+ * PSA_SUCCESS. We must not define PSA_SUCCESS ourselves in that case;
+ * the other error code names don't clash. Also define psa_status_t as
+ * an alias for the type used by PSA IPC. This is a temporary hack
+ * until we unify error reporting in PSA IPC and PSA crypto.
+ *
+ * Note that psa_defs.h must be included before this header!
+ */
+typedef psa_error_t psa_status_t;
+
+#else /* defined(PSA_SUCCESS) */
+
+/**
+ * \brief Function return status.
+ *
+ * This is either #PSA_SUCCESS (which is zero), indicating success,
+ * or a nonzero value indicating that an error occurred. Errors are
+ * encoded as one of the \c PSA_ERROR_xxx values defined here.
+ */
+typedef int32_t psa_status_t;
+
+/** The action was completed successfully. */
+#define PSA_SUCCESS ((psa_status_t)0)
+
+#endif /* !defined(PSA_SUCCESS) */
+
+/** An error occurred that does not correspond to any defined
+ * failure cause.
+ *
+ * Implementations may use this error code if none of the other standard
+ * error codes are applicable. */
+#define PSA_ERROR_UNKNOWN_ERROR ((psa_status_t)1)
+
+/** The requested operation or a parameter is not supported
+ * by this implementation.
+ *
+ * Implementations should return this error code when an enumeration
+ * parameter such as a key type, algorithm, etc. is not recognized.
+ * If a combination of parameters is recognized and identified as
+ * not valid, return #PSA_ERROR_INVALID_ARGUMENT instead. */
+#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t)2)
+
+/** The requested action is denied by a policy.
+ *
+ * Implementations should return this error code when the parameters
+ * are recognized as valid and supported, and a policy explicitly
+ * denies the requested operation.
+ *
+ * If a subset of the parameters of a function call identify a
+ * forbidden operation, and another subset of the parameters are
+ * not valid or not supported, it is unspecified whether the function
+ * returns #PSA_ERROR_NOT_PERMITTED, #PSA_ERROR_NOT_SUPPORTED or
+ * #PSA_ERROR_INVALID_ARGUMENT. */
+#define PSA_ERROR_NOT_PERMITTED ((psa_status_t)3)
+
+/** An output buffer is too small.
+ *
+ * Applications can call the \c PSA_xxx_SIZE macro listed in the function
+ * description to determine a sufficient buffer size.
+ *
+ * Implementations should preferably return this error code only
+ * in cases when performing the operation with a larger output
+ * buffer would succeed. However implementations may return this
+ * error if a function has invalid or unsupported parameters in addition
+ * to the parameters that determine the necessary output buffer size. */
+#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t)4)
+
+/** A slot is occupied, but must be empty to carry out the
+ * requested action.
+ *
+ * If the slot number is invalid (i.e. the requested action could
+ * not be performed even after erasing the slot's content),
+ * implementations shall return #PSA_ERROR_INVALID_ARGUMENT instead. */
+#define PSA_ERROR_OCCUPIED_SLOT ((psa_status_t)5)
+
+/** A slot is empty, but must be occupied to carry out the
+ * requested action.
+ *
+ * If the slot number is invalid (i.e. the requested action could
+ * not be performed even after creating appropriate content in the slot),
+ * implementations shall return #PSA_ERROR_INVALID_ARGUMENT instead. */
+#define PSA_ERROR_EMPTY_SLOT ((psa_status_t)6)
+
+/** The requested action cannot be performed in the current state.
+ *
+ * Multipart operations return this error when one of the
+ * functions is called out of sequence. Refer to the function
+ * descriptions for permitted sequencing of functions.
+ *
+ * Implementations shall not return this error code to indicate
+ * that a key slot is occupied when it needs to be free or vice versa,
+ * but shall return #PSA_ERROR_OCCUPIED_SLOT or #PSA_ERROR_EMPTY_SLOT
+ * as applicable. */
+#define PSA_ERROR_BAD_STATE ((psa_status_t)7)
+
+/** The parameters passed to the function are invalid.
+ *
+ * Implementations may return this error any time a parameter or
+ * combination of parameters are recognized as invalid.
+ *
+ * Implementations shall not return this error code to indicate
+ * that a key slot is occupied when it needs to be free or vice versa,
+ * but shall return #PSA_ERROR_OCCUPIED_SLOT or #PSA_ERROR_EMPTY_SLOT
+ * as applicable. */
+#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)8)
+
+/** There is not enough runtime memory.
+ *
+ * If the action is carried out across multiple security realms, this
+ * error can refer to available memory in any of the security realms. */
+#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t)9)
+
+/** There is not enough persistent storage.
+ *
+ * Functions that modify the key storage return this error code if
+ * there is insufficient storage space on the host media. In addition,
+ * many functions that do not otherwise access storage may return this
+ * error code if the implementation requires a mandatory log entry for
+ * the requested action and the log storage space is full. */
+#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t)10)
+
+/** There was a communication failure inside the implementation.
+ *
+ * This can indicate a communication failure between the application
+ * and an external cryptoprocessor or between the cryptoprocessor and
+ * an external volatile or persistent memory. A communication failure
+ * may be transient or permanent depending on the cause.
+ *
+ * \warning If a function returns this error, it is undetermined
+ * whether the requested action has completed or not. Implementations
+ * should return #PSA_SUCCESS on successful completion whenver
+ * possible, however functions may return #PSA_ERROR_COMMUNICATION_FAILURE
+ * if the requested action was completed successfully in an external
+ * cryptoprocessor but there was a breakdown of communication before
+ * the cryptoprocessor could report the status to the application.
+ */
+#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)11)
+
+/** There was a storage failure that may have led to data loss.
+ *
+ * This error indicates that some persistent storage is corrupted.
+ * It should not be used for a corruption of volatile memory
+ * (use #PSA_ERROR_TAMPERING_DETECTED), for a communication error
+ * between the cryptoprocessor and its external storage (use
+ * #PSA_ERROR_COMMUNICATION_FAILURE), or when the storage is
+ * in a valid state but is full (use #PSA_ERROR_INSUFFICIENT_STORAGE).
+ *
+ * Note that a storage failure does not indicate that any data that was
+ * previously read is invalid. However this previously read data may no
+ * longer be readable from storage.
+ *
+ * When a storage failure occurs, it is no longer possible to ensure
+ * the global integrity of the keystore. Depending on the global
+ * integrity guarantees offered by the implementation, access to other
+ * data may or may not fail even if the data is still readable but
+ * its integrity canont be guaranteed.
+ *
+ * Implementations should only use this error code to report a
+ * permanent storage corruption. However application writers should
+ * keep in mind that transient errors while reading the storage may be
+ * reported using this error code. */
+#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t)12)
+
+/** A hardware failure was detected.
+ *
+ * A hardware failure may be transient or permanent depending on the
+ * cause. */
+#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t)13)
+
+/** A tampering attempt was detected.
+ *
+ * If an application receives this error code, there is no guarantee
+ * that previously accessed or computed data was correct and remains
+ * confidential. Applications should not perform any security function
+ * and should enter a safe failure state.
+ *
+ * Implementations may return this error code if they detect an invalid
+ * state that cannot happen during normal operation and that indicates
+ * that the implementation's security guarantees no longer hold. Depending
+ * on the implementation architecture and on its security and safety goals,
+ * the implementation may forcibly terminate the application.
+ *
+ * This error code is intended as a last resort when a security breach
+ * is detected and it is unsure whether the keystore data is still
+ * protected. Implementations shall only return this error code
+ * to report an alarm from a tampering detector, to indicate that
+ * the confidentiality of stored data can no longer be guaranteed,
+ * or to indicate that the integrity of previously returned data is now
+ * considered compromised. Implementations shall not use this error code
+ * to indicate a hardware failure that merely makes it impossible to
+ * perform the requested operation (use #PSA_ERROR_COMMUNICATION_FAILURE,
+ * #PSA_ERROR_STORAGE_FAILURE, #PSA_ERROR_HARDWARE_FAILURE,
+ * #PSA_ERROR_INSUFFICIENT_ENTROPY or other applicable error code
+ * instead).
+ *
+ * This error indicates an attack against the application. Implementations
+ * shall not return this error code as a consequence of the behavior of
+ * the application itself. */
+#define PSA_ERROR_TAMPERING_DETECTED ((psa_status_t)14)
+
+/** There is not enough entropy to generate random data needed
+ * for the requested action.
+ *
+ * This error indicates a failure of a hardware random generator.
+ * Application writers should note that this error can be returned not
+ * only by functions whose purpose is to generate random data, such
+ * as key, IV or nonce generation, but also by functions that execute
+ * an algorithm with a randomized result, as well as functions that
+ * use randomization of intermediate computations as a countermeasure
+ * to certain attacks.
+ *
+ * Implementations should avoid returning this error after psa_crypto_init()
+ * has succeeded. Implementations should generate sufficient
+ * entropy during initialization and subsequently use a cryptographically
+ * secure pseudorandom generator (PRNG). However implementations may return
+ * this error at any time if a policy requires the PRNG to be reseeded
+ * during normal operation. */
+#define PSA_ERROR_INSUFFICIENT_ENTROPY ((psa_status_t)15)
+
+/** The signature, MAC or hash is incorrect.
+ *
+ * Verification functions return this error if the verification
+ * calculations completed successfully, and the value to be verified
+ * was determined to be incorrect.
+ *
+ * If the value to verify has an invalid size, implementations may return
+ * either #PSA_ERROR_INVALID_ARGUMENT or #PSA_ERROR_INVALID_SIGNATURE. */
+#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)16)
+
+/** The decrypted padding is incorrect.
+ *
+ * \warning In some protocols, when decrypting data, it is essential that
+ * the behavior of the application does not depend on whether the padding
+ * is correct, down to precise timing. Applications should prefer
+ * protocols that use authenticated encryption rather than plain
+ * encryption. If the application must perform a decryption of
+ * unauthenticated data, the application writer should take care not
+ * to reveal whether the padding is invalid.
+ *
+ * Implementations should strive to make valid and invalid padding
+ * as close as possible to indistinguishable to an external observer.
+ * In particular, the timing of a decryption operation should not
+ * depend on the validity of the padding. */
+#define PSA_ERROR_INVALID_PADDING ((psa_status_t)17)
+
+/** The generator has insufficient capacity left.
+ *
+ * Once a function returns this error, attempts to read from the
+ * generator will always return this error. */
+#define PSA_ERROR_INSUFFICIENT_CAPACITY ((psa_status_t)18)
+
+/**
+ * \brief Library initialization.
+ *
+ * Applications must call this function before calling any other
+ * function in this module.
+ *
+ * Applications may call this function more than once. Once a call
+ * succeeds, subsequent calls are guaranteed to succeed.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
+ */
+psa_status_t psa_crypto_init(void);
+
+#define PSA_BITS_TO_BYTES(bits) (((bits) + 7) / 8)
+#define PSA_BYTES_TO_BITS(bytes) ((bytes) * 8)
+
+/**@}*/
+
+/** \defgroup crypto_types Key and algorithm types
+ * @{
+ */
+
+/** \brief Encoding of a key type.
+ */
+typedef uint32_t psa_key_type_t;
+
+/** An invalid key type value.
+ *
+ * Zero is not the encoding of any key type.
+ */
+#define PSA_KEY_TYPE_NONE ((psa_key_type_t)0x00000000)
+
+/** Vendor-defined flag
+ *
+ * Key types defined by this standard will never have the
+ * #PSA_KEY_TYPE_VENDOR_FLAG bit set. Vendors who define additional key types
+ * must use an encoding with the #PSA_KEY_TYPE_VENDOR_FLAG bit set and should
+ * respect the bitwise structure used by standard encodings whenever practical.
+ */
+#define PSA_KEY_TYPE_VENDOR_FLAG ((psa_key_type_t)0x80000000)
+
+#define PSA_KEY_TYPE_CATEGORY_MASK ((psa_key_type_t)0x7e000000)
+
+/** Raw data.
+ *
+ * A "key" of this type cannot be used for any cryptographic operation.
+ * Applications may use this type to store arbitrary data in the keystore. */
+#define PSA_KEY_TYPE_RAW_DATA ((psa_key_type_t)0x02000000)
+
+#define PSA_KEY_TYPE_CATEGORY_SYMMETRIC ((psa_key_type_t)0x04000000)
+#define PSA_KEY_TYPE_CATEGORY_ASYMMETRIC ((psa_key_type_t)0x06000000)
+#define PSA_KEY_TYPE_PAIR_FLAG ((psa_key_type_t)0x01000000)
+
+/** HMAC key.
+ *
+ * The key policy determines which underlying hash algorithm the key can be
+ * used for.
+ *
+ * HMAC keys should generally have the same size as the underlying hash.
+ * This size can be calculated with #PSA_HASH_SIZE(\c alg) where
+ * \c alg is the HMAC algorithm or the underlying hash algorithm. */
+#define PSA_KEY_TYPE_HMAC ((psa_key_type_t)0x02000001)
+
+/** A secret for key derivation.
+ *
+ * The key policy determines which key derivation algorithm the key
+ * can be used for.
+ */
+#define PSA_KEY_TYPE_DERIVE ((psa_key_type_t)0x02000101)
+
+/** Key for an cipher, AEAD or MAC algorithm based on the AES block cipher.
+ *
+ * The size of the key can be 16 bytes (AES-128), 24 bytes (AES-192) or
+ * 32 bytes (AES-256).
+ */
+#define PSA_KEY_TYPE_AES ((psa_key_type_t)0x04000001)
+
+/** Key for a cipher or MAC algorithm based on DES or 3DES (Triple-DES).
+ *
+ * The size of the key can be 8 bytes (single DES), 16 bytes (2-key 3DES) or
+ * 24 bytes (3-key 3DES).
+ *
+ * Note that single DES and 2-key 3DES are weak and strongly
+ * deprecated and should only be used to decrypt legacy data. 3-key 3DES
+ * is weak and deprecated and should only be used in legacy protocols.
+ */
+#define PSA_KEY_TYPE_DES ((psa_key_type_t)0x04000002)
+
+/** Key for an cipher, AEAD or MAC algorithm based on the
+ * Camellia block cipher. */
+#define PSA_KEY_TYPE_CAMELLIA ((psa_key_type_t)0x04000003)
+
+/** Key for the RC4 stream cipher.
+ *
+ * Note that RC4 is weak and deprecated and should only be used in
+ * legacy protocols. */
+#define PSA_KEY_TYPE_ARC4 ((psa_key_type_t)0x04000004)
+
+/** RSA public key. */
+#define PSA_KEY_TYPE_RSA_PUBLIC_KEY ((psa_key_type_t)0x06010000)
+/** RSA key pair (private and public key). */
+#define PSA_KEY_TYPE_RSA_KEYPAIR ((psa_key_type_t)0x07010000)
+
+/** DSA public key. */
+#define PSA_KEY_TYPE_DSA_PUBLIC_KEY ((psa_key_type_t)0x06020000)
+/** DSA key pair (private and public key). */
+#define PSA_KEY_TYPE_DSA_KEYPAIR ((psa_key_type_t)0x07020000)
+
+#define PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE ((psa_key_type_t)0x06030000)
+#define PSA_KEY_TYPE_ECC_KEYPAIR_BASE ((psa_key_type_t)0x07030000)
+#define PSA_KEY_TYPE_ECC_CURVE_MASK ((psa_key_type_t)0x0000ffff)
+/** Elliptic curve key pair. */
+#define PSA_KEY_TYPE_ECC_KEYPAIR(curve) \
+ (PSA_KEY_TYPE_ECC_KEYPAIR_BASE | (curve))
+/** Elliptic curve public key. */
+#define PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve) \
+ (PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE | (curve))
+
+/** Whether a key type is vendor-defined. */
+#define PSA_KEY_TYPE_IS_VENDOR_DEFINED(type) \
+ (((type) & PSA_KEY_TYPE_VENDOR_FLAG) != 0)
+
+/** Whether a key type is asymmetric: either a key pair or a public key. */
+#define PSA_KEY_TYPE_IS_ASYMMETRIC(type) \
+ (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_ASYMMETRIC)
+/** Whether a key type is the public part of a key pair. */
+#define PSA_KEY_TYPE_IS_PUBLIC_KEY(type) \
+ (((type) & (PSA_KEY_TYPE_CATEGORY_MASK | PSA_KEY_TYPE_PAIR_FLAG)) == \
+ PSA_KEY_TYPE_CATEGORY_ASYMMETRIC)
+/** Whether a key type is a key pair containing a private part and a public
+ * part. */
+#define PSA_KEY_TYPE_IS_KEYPAIR(type) \
+ (((type) & (PSA_KEY_TYPE_CATEGORY_MASK | PSA_KEY_TYPE_PAIR_FLAG)) == \
+ (PSA_KEY_TYPE_CATEGORY_ASYMMETRIC | PSA_KEY_TYPE_PAIR_FLAG))
+/** The key pair type corresponding to a public key type. */
+#define PSA_KEY_TYPE_KEYPAIR_OF_PUBLIC_KEY(type) \
+ ((type) | PSA_KEY_TYPE_PAIR_FLAG)
+/** The public key type corresponding to a key pair type. */
+#define PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) \
+ ((type) & ~PSA_KEY_TYPE_PAIR_FLAG)
+/** Whether a key type is an RSA key (pair or public-only). */
+#define PSA_KEY_TYPE_IS_RSA(type) \
+ (PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY)
+
+/** Whether a key type is an elliptic curve key (pair or public-only). */
+#define PSA_KEY_TYPE_IS_ECC(type) \
+ ((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) & \
+ ~PSA_KEY_TYPE_ECC_CURVE_MASK) == PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE)
+#define PSA_KEY_TYPE_IS_ECC_KEYPAIR(type) \
+ (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \
+ PSA_KEY_TYPE_ECC_KEYPAIR_BASE)
+#define PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type) \
+ (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \
+ PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE)
+
+/** The type of PSA elliptic curve identifiers. */
+typedef uint16_t psa_ecc_curve_t;
+/** Extract the curve from an elliptic curve key type. */
+#define PSA_KEY_TYPE_GET_CURVE(type) \
+ ((psa_ecc_curve_t) (PSA_KEY_TYPE_IS_ECC(type) ? \
+ ((type) & PSA_KEY_TYPE_ECC_CURVE_MASK) : \
+ 0))
+
+/* The encoding of curve identifiers is currently aligned with the
+ * TLS Supported Groups Registry (formerly known as the
+ * TLS EC Named Curve Registry)
+ * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
+ * The values are defined by RFC 4492, RFC 7027 and RFC 7919. */
+#define PSA_ECC_CURVE_SECT163K1 ((psa_ecc_curve_t) 0x0001)
+#define PSA_ECC_CURVE_SECT163R1 ((psa_ecc_curve_t) 0x0002)
+#define PSA_ECC_CURVE_SECT163R2 ((psa_ecc_curve_t) 0x0003)
+#define PSA_ECC_CURVE_SECT193R1 ((psa_ecc_curve_t) 0x0004)
+#define PSA_ECC_CURVE_SECT193R2 ((psa_ecc_curve_t) 0x0005)
+#define PSA_ECC_CURVE_SECT233K1 ((psa_ecc_curve_t) 0x0006)
+#define PSA_ECC_CURVE_SECT233R1 ((psa_ecc_curve_t) 0x0007)
+#define PSA_ECC_CURVE_SECT239K1 ((psa_ecc_curve_t) 0x0008)
+#define PSA_ECC_CURVE_SECT283K1 ((psa_ecc_curve_t) 0x0009)
+#define PSA_ECC_CURVE_SECT283R1 ((psa_ecc_curve_t) 0x000a)
+#define PSA_ECC_CURVE_SECT409K1 ((psa_ecc_curve_t) 0x000b)
+#define PSA_ECC_CURVE_SECT409R1 ((psa_ecc_curve_t) 0x000c)
+#define PSA_ECC_CURVE_SECT571K1 ((psa_ecc_curve_t) 0x000d)
+#define PSA_ECC_CURVE_SECT571R1 ((psa_ecc_curve_t) 0x000e)
+#define PSA_ECC_CURVE_SECP160K1 ((psa_ecc_curve_t) 0x000f)
+#define PSA_ECC_CURVE_SECP160R1 ((psa_ecc_curve_t) 0x0010)
+#define PSA_ECC_CURVE_SECP160R2 ((psa_ecc_curve_t) 0x0011)
+#define PSA_ECC_CURVE_SECP192K1 ((psa_ecc_curve_t) 0x0012)
+#define PSA_ECC_CURVE_SECP192R1 ((psa_ecc_curve_t) 0x0013)
+#define PSA_ECC_CURVE_SECP224K1 ((psa_ecc_curve_t) 0x0014)
+#define PSA_ECC_CURVE_SECP224R1 ((psa_ecc_curve_t) 0x0015)
+#define PSA_ECC_CURVE_SECP256K1 ((psa_ecc_curve_t) 0x0016)
+#define PSA_ECC_CURVE_SECP256R1 ((psa_ecc_curve_t) 0x0017)
+#define PSA_ECC_CURVE_SECP384R1 ((psa_ecc_curve_t) 0x0018)
+#define PSA_ECC_CURVE_SECP521R1 ((psa_ecc_curve_t) 0x0019)
+#define PSA_ECC_CURVE_BRAINPOOL_P256R1 ((psa_ecc_curve_t) 0x001a)
+#define PSA_ECC_CURVE_BRAINPOOL_P384R1 ((psa_ecc_curve_t) 0x001b)
+#define PSA_ECC_CURVE_BRAINPOOL_P512R1 ((psa_ecc_curve_t) 0x001c)
+#define PSA_ECC_CURVE_CURVE25519 ((psa_ecc_curve_t) 0x001d)
+#define PSA_ECC_CURVE_CURVE448 ((psa_ecc_curve_t) 0x001e)
+#define PSA_ECC_CURVE_FFDHE_2048 ((psa_ecc_curve_t) 0x0100)
+#define PSA_ECC_CURVE_FFDHE_3072 ((psa_ecc_curve_t) 0x0101)
+#define PSA_ECC_CURVE_FFDHE_4096 ((psa_ecc_curve_t) 0x0102)
+#define PSA_ECC_CURVE_FFDHE_6144 ((psa_ecc_curve_t) 0x0103)
+#define PSA_ECC_CURVE_FFDHE_8192 ((psa_ecc_curve_t) 0x0104)
+
+/** The block size of a block cipher.
+ *
+ * \param type A cipher key type (value of type #psa_key_type_t).
+ *
+ * \return The block size for a block cipher, or 1 for a stream cipher.
+ * The return value is undefined if \p type is not a supported
+ * cipher key type.
+ *
+ * \note It is possible to build stream cipher algorithms on top of a block
+ * cipher, for example CTR mode (#PSA_ALG_CTR).
+ * This macro only takes the key type into account, so it cannot be
+ * used to determine the size of the data that #psa_cipher_update()
+ * might buffer for future processing in general.
+ *
+ * \note This macro returns a compile-time constant if its argument is one.
+ *
+ * \warning This macro may evaluate its argument multiple times.
+ */
+#define PSA_BLOCK_CIPHER_BLOCK_SIZE(type) \
+ ( \
+ (type) == PSA_KEY_TYPE_AES ? 16 : \
+ (type) == PSA_KEY_TYPE_DES ? 8 : \
+ (type) == PSA_KEY_TYPE_CAMELLIA ? 16 : \
+ (type) == PSA_KEY_TYPE_ARC4 ? 1 : \
+ 0)
+
+/** \brief Encoding of a cryptographic algorithm.
+ *
+ * For algorithms that can be applied to multiple key types, this type
+ * does not encode the key type. For example, for symmetric ciphers
+ * based on a block cipher, #psa_algorithm_t encodes the block cipher
+ * mode and the padding mode while the block cipher itself is encoded
+ * via #psa_key_type_t.
+ */
+typedef uint32_t psa_algorithm_t;
+
+#define PSA_ALG_VENDOR_FLAG ((psa_algorithm_t)0x80000000)
+#define PSA_ALG_CATEGORY_MASK ((psa_algorithm_t)0x7f000000)
+#define PSA_ALG_CATEGORY_HASH ((psa_algorithm_t)0x01000000)
+#define PSA_ALG_CATEGORY_MAC ((psa_algorithm_t)0x02000000)
+#define PSA_ALG_CATEGORY_CIPHER ((psa_algorithm_t)0x04000000)
+#define PSA_ALG_CATEGORY_AEAD ((psa_algorithm_t)0x06000000)
+#define PSA_ALG_CATEGORY_SIGN ((psa_algorithm_t)0x10000000)
+#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION ((psa_algorithm_t)0x12000000)
+#define PSA_ALG_CATEGORY_KEY_AGREEMENT ((psa_algorithm_t)0x22000000)
+#define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t)0x30000000)
+
+#define PSA_ALG_IS_VENDOR_DEFINED(alg) \
+ (((alg) & PSA_ALG_VENDOR_FLAG) != 0)
+
+/** Whether the specified algorithm is a hash algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a hash algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_HASH(alg) \
+ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_HASH)
+
+/** Whether the specified algorithm is a MAC algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a MAC algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_MAC(alg) \
+ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_MAC)
+
+/** Whether the specified algorithm is a symmetric cipher algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a symmetric cipher algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_CIPHER(alg) \
+ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_CIPHER)
+
+/** Whether the specified algorithm is an authenticated encryption
+ * with associated data (AEAD) algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is an AEAD algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_AEAD(alg) \
+ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_AEAD)
+
+/** Whether the specified algorithm is a public-key signature algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a public-key signature algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_SIGN(alg) \
+ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_SIGN)
+
+/** Whether the specified algorithm is a public-key encryption algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a public-key encryption algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg) \
+ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION)
+
+/** Whether the specified algorithm is a key agreement algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a key agreement algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_KEY_AGREEMENT(alg) \
+ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_AGREEMENT)
+
+/** Whether the specified algorithm is a key derivation algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a key derivation algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_KEY_DERIVATION(alg) \
+ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION)
+
+#define PSA_ALG_HASH_MASK ((psa_algorithm_t)0x000000ff)
+#define PSA_ALG_MD2 ((psa_algorithm_t)0x01000001)
+#define PSA_ALG_MD4 ((psa_algorithm_t)0x01000002)
+#define PSA_ALG_MD5 ((psa_algorithm_t)0x01000003)
+#define PSA_ALG_RIPEMD160 ((psa_algorithm_t)0x01000004)
+#define PSA_ALG_SHA_1 ((psa_algorithm_t)0x01000005)
+/** SHA2-224 */
+#define PSA_ALG_SHA_224 ((psa_algorithm_t)0x01000008)
+/** SHA2-256 */
+#define PSA_ALG_SHA_256 ((psa_algorithm_t)0x01000009)
+/** SHA2-384 */
+#define PSA_ALG_SHA_384 ((psa_algorithm_t)0x0100000a)
+/** SHA2-512 */
+#define PSA_ALG_SHA_512 ((psa_algorithm_t)0x0100000b)
+/** SHA2-512/224 */
+#define PSA_ALG_SHA_512_224 ((psa_algorithm_t)0x0100000c)
+/** SHA2-512/256 */
+#define PSA_ALG_SHA_512_256 ((psa_algorithm_t)0x0100000d)
+/** SHA3-224 */
+#define PSA_ALG_SHA3_224 ((psa_algorithm_t)0x01000010)
+/** SHA3-256 */
+#define PSA_ALG_SHA3_256 ((psa_algorithm_t)0x01000011)
+/** SHA3-384 */
+#define PSA_ALG_SHA3_384 ((psa_algorithm_t)0x01000012)
+/** SHA3-512 */
+#define PSA_ALG_SHA3_512 ((psa_algorithm_t)0x01000013)
+
+#define PSA_ALG_MAC_SUBCATEGORY_MASK ((psa_algorithm_t)0x00c00000)
+#define PSA_ALG_HMAC_BASE ((psa_algorithm_t)0x02800000)
+/** Macro to build an HMAC algorithm.
+ *
+ * For example, #PSA_ALG_HMAC(#PSA_ALG_SHA_256) is HMAC-SHA-256.
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return The corresponding HMAC algorithm.
+ * \return Unspecified if \p alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_HMAC(hash_alg) \
+ (PSA_ALG_HMAC_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+
+#define PSA_ALG_HMAC_HASH(hmac_alg) \
+ (PSA_ALG_CATEGORY_HASH | ((hmac_alg) & PSA_ALG_HASH_MASK))
+
+/** Whether the specified algorithm is an HMAC algorithm.
+ *
+ * HMAC is a family of MAC algorithms that are based on a hash function.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is an HMAC algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_HMAC(alg) \
+ (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_MAC_SUBCATEGORY_MASK)) == \
+ PSA_ALG_HMAC_BASE)
+
+#define PSA_ALG_CIPHER_MAC_BASE ((psa_algorithm_t)0x02c00000)
+#define PSA_ALG_CBC_MAC ((psa_algorithm_t)0x02c00001)
+#define PSA_ALG_CMAC ((psa_algorithm_t)0x02c00002)
+#define PSA_ALG_GMAC ((psa_algorithm_t)0x02c00003)
+
+/** Whether the specified algorithm is a MAC algorithm based on a block cipher.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a MAC algorithm based on a block cipher, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_CIPHER_MAC(alg) \
+ (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_MAC_SUBCATEGORY_MASK)) == \
+ PSA_ALG_CIPHER_MAC_BASE)
+
+#define PSA_ALG_CIPHER_SUBCATEGORY_MASK ((psa_algorithm_t)0x00c00000)
+#define PSA_ALG_BLOCK_CIPHER_BASE ((psa_algorithm_t)0x04000000)
+#define PSA_ALG_BLOCK_CIPHER_MODE_MASK ((psa_algorithm_t)0x000000ff)
+#define PSA_ALG_BLOCK_CIPHER_PADDING_MASK ((psa_algorithm_t)0x003f0000)
+
+/** Use a block cipher mode without padding.
+ *
+ * This padding mode may only be used with messages whose lengths are a
+ * whole number of blocks for the chosen block cipher.
+ */
+#define PSA_ALG_BLOCK_CIPHER_PAD_NONE ((psa_algorithm_t)0x00000000)
+
+#define PSA_ALG_BLOCK_CIPHER_PAD_PKCS7 ((psa_algorithm_t)0x00010000)
+
+/** Whether the specified algorithm is a block cipher.
+ *
+ * A block cipher is a symmetric cipher that encrypts or decrypts messages
+ * by chopping them into fixed-size blocks. Processing a message requires
+ * applying a _padding mode_ to transform the message into one whose
+ * length is a whole number of blocks. To construct an algorithm
+ * identifier for a block cipher, apply a bitwise-or between the block
+ * cipher mode and the padding mode. For example, CBC with PKCS#7 padding
+ * is `PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_PKCS7`.
+ *
+ * The transformation applied to each block is determined by the key type.
+ * For example, to use AES-128-CBC-PKCS7, use the algorithm above with
+ * a key of type #PSA_KEY_TYPE_AES and a length of 128 bits (16 bytes).
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a block cipher algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier or if it is not a symmetric cipher algorithm.
+ */
+#define PSA_ALG_IS_BLOCK_CIPHER(alg) \
+ (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_CIPHER_SUBCATEGORY_MASK)) == \
+ PSA_ALG_BLOCK_CIPHER_BASE)
+
+/** The CBC block cipher mode.
+ */
+#define PSA_ALG_CBC_BASE ((psa_algorithm_t)0x04000001)
+#define PSA_ALG_CFB_BASE ((psa_algorithm_t)0x04000002)
+#define PSA_ALG_OFB_BASE ((psa_algorithm_t)0x04000003)
+#define PSA_ALG_XTS_BASE ((psa_algorithm_t)0x04000004)
+
+#define PSA_ALG_STREAM_CIPHER_BASE ((psa_algorithm_t)0x04800000)
+
+/** The CTR stream cipher mode.
+ *
+ * CTR is a stream cipher which is built from a block cipher. The
+ * underlying block cipher is determined by the key type. For example,
+ * to use AES-128-CTR, use this algorithm with
+ * a key of type #PSA_KEY_TYPE_AES and a length of 128 bits (16 bytes).
+ */
+#define PSA_ALG_CTR ((psa_algorithm_t)0x04800001)
+
+/** The ARC4 stream cipher algorithm.
+ */
+#define PSA_ALG_ARC4 ((psa_algorithm_t)0x04800002)
+
+/** Whether the specified algorithm is a stream cipher.
+ *
+ * A stream cipher is a symmetric cipher that encrypts or decrypts messages
+ * by applying a bitwise-xor with a stream of bytes that is generated
+ * from a key.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a stream cipher algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier or if it is not a symmetric cipher algorithm.
+ */
+#define PSA_ALG_IS_STREAM_CIPHER(alg) \
+ (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_CIPHER_SUBCATEGORY_MASK)) == \
+ PSA_ALG_STREAM_CIPHER_BASE)
+
+#define PSA_ALG_CCM ((psa_algorithm_t)0x06000001)
+#define PSA_ALG_GCM ((psa_algorithm_t)0x06000002)
+
+#define PSA_ALG_RSA_PKCS1V15_SIGN_BASE ((psa_algorithm_t)0x10020000)
+/** RSA PKCS#1 v1.5 signature with hashing.
+ *
+ * This is the signature scheme defined by RFC 8017
+ * (PKCS#1: RSA Cryptography Specifications) under the name
+ * RSASSA-PKCS1-v1_5.
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return The corresponding RSA PKCS#1 v1.5 signature algorithm.
+ * \return Unspecified if \p alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg) \
+ (PSA_ALG_RSA_PKCS1V15_SIGN_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+/** Raw PKCS#1 v1.5 signature.
+ *
+ * The input to this algorithm is the DigestInfo structure used by
+ * RFC 8017 (PKCS#1: RSA Cryptography Specifications), §9.2
+ * steps 3–6.
+ */
+#define PSA_ALG_RSA_PKCS1V15_SIGN_RAW PSA_ALG_RSA_PKCS1V15_SIGN_BASE
+#define PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PKCS1V15_SIGN_BASE)
+
+#define PSA_ALG_RSA_PSS_BASE ((psa_algorithm_t)0x10030000)
+/** RSA PSS signature with hashing.
+ *
+ * This is the signature scheme defined by RFC 8017
+ * (PKCS#1: RSA Cryptography Specifications) under the name
+ * RSASSA-PSS, with the message generation function MGF1, and with
+ * a salt length equal to the length of the hash. The specified
+ * hash algorithm is used to hash the input message, to create the
+ * salted hash, and for the mask generation.
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return The corresponding RSA PSS signature algorithm.
+ * \return Unspecified if \p alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_RSA_PSS(hash_alg) \
+ (PSA_ALG_RSA_PSS_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_IS_RSA_PSS(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_BASE)
+
+#define PSA_ALG_DSA_BASE ((psa_algorithm_t)0x10040000)
+/** DSA signature with hashing.
+ *
+ * This is the signature scheme defined by FIPS 186-4,
+ * with a random per-message secret number (*k*).
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return The corresponding DSA signature algorithm.
+ * \return Unspecified if \p alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_DSA(hash_alg) \
+ (PSA_ALG_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_DETERMINISTIC_DSA_BASE ((psa_algorithm_t)0x10050000)
+#define PSA_ALG_DSA_DETERMINISTIC_FLAG ((psa_algorithm_t)0x00010000)
+#define PSA_ALG_DETERMINISTIC_DSA(hash_alg) \
+ (PSA_ALG_DETERMINISTIC_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_IS_DSA(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_DSA_DETERMINISTIC_FLAG) == \
+ PSA_ALG_DSA_BASE)
+#define PSA_ALG_DSA_IS_DETERMINISTIC(alg) \
+ (((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0)
+#define PSA_ALG_IS_DETERMINISTIC_DSA(alg) \
+ (PSA_ALG_IS_DSA(alg) && PSA_ALG_DSA_IS_DETERMINISTIC(alg))
+#define PSA_ALG_IS_RANDOMIZED_DSA(alg) \
+ (PSA_ALG_IS_DSA(alg) && !PSA_ALG_DSA_IS_DETERMINISTIC(alg))
+
+#define PSA_ALG_ECDSA_BASE ((psa_algorithm_t)0x10060000)
+/** ECDSA signature with hashing.
+ *
+ * This is the ECDSA signature scheme defined by ANSI X9.62,
+ * with a random per-message secret number (*k*).
+ *
+ * The representation of the signature as a byte string consists of
+ * the concatentation of the signature values *r* and *s*. Each of
+ * *r* and *s* is encoded as an *N*-octet string, where *N* is the length
+ * of the base point of the curve in octets. Each value is represented
+ * in big-endian order (most significant octet first).
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return The corresponding ECDSA signature algorithm.
+ * \return Unspecified if \p alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_ECDSA(hash_alg) \
+ (PSA_ALG_ECDSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+/** ECDSA signature without hashing.
+ *
+ * This is the same signature scheme as #PSA_ALG_ECDSA(), but
+ * without specifying a hash algorithm. This algorithm may only be
+ * used to sign or verify a sequence of bytes that should be an
+ * already-calculated hash. Note that the input is padded with
+ * zeros on the left or truncated on the left as required to fit
+ * the curve size.
+ */
+#define PSA_ALG_ECDSA_ANY PSA_ALG_ECDSA_BASE
+#define PSA_ALG_DETERMINISTIC_ECDSA_BASE ((psa_algorithm_t)0x10070000)
+/** Deterministic ECDSA signature with hashing.
+ *
+ * This is the deterministic ECDSA signature scheme defined by RFC 6979.
+ *
+ * The representation of a signature is the same as with #PSA_ALG_ECDSA().
+ *
+ * Note that when this algorithm is used for verification, signatures
+ * made with randomized ECDSA (#PSA_ALG_ECDSA(\p hash_alg)) with the
+ * same private key are accepted. In other words,
+ * #PSA_ALG_DETERMINISTIC_ECDSA(\p hash_alg) differs from
+ * #PSA_ALG_ECDSA(\p hash_alg) only for signature, not for verification.
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return The corresponding deterministic ECDSA signature
+ * algorithm.
+ * \return Unspecified if \p alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_DETERMINISTIC_ECDSA(hash_alg) \
+ (PSA_ALG_DETERMINISTIC_ECDSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_IS_ECDSA(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_DSA_DETERMINISTIC_FLAG) == \
+ PSA_ALG_ECDSA_BASE)
+#define PSA_ALG_ECDSA_IS_DETERMINISTIC(alg) \
+ (((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0)
+#define PSA_ALG_IS_DETERMINISTIC_ECDSA(alg) \
+ (PSA_ALG_IS_ECDSA(alg) && PSA_ALG_ECDSA_IS_DETERMINISTIC(alg))
+#define PSA_ALG_IS_RANDOMIZED_ECDSA(alg) \
+ (PSA_ALG_IS_ECDSA(alg) && !PSA_ALG_ECDSA_IS_DETERMINISTIC(alg))
+
+/** Get the hash used by a hash-and-sign signature algorithm.
+ *
+ * A hash-and-sign algorithm is a signature algorithm which is
+ * composed of two phases: first a hashing phase which does not use
+ * the key and produces a hash of the input message, then a signing
+ * phase which only uses the hash and the key and not the message
+ * itself.
+ *
+ * \param alg A signature algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_SIGN(\p alg) is true).
+ *
+ * \return The underlying hash algorithm if \p alg is a hash-and-sign
+ * algorithm.
+ * \return 0 if \p alg is a signature algorithm that does not
+ * follow the hash-and-sign structure.
+ * \return Unspecified if \p alg is not a signature algorithm or
+ * if it is not supported by the implementation.
+ */
+#define PSA_ALG_SIGN_GET_HASH(alg) \
+ (PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \
+ PSA_ALG_IS_DSA(alg) || PSA_ALG_IS_ECDSA(alg) ? \
+ ((alg) & PSA_ALG_HASH_MASK) == 0 ? /*"raw" algorithm*/ 0 : \
+ ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH : \
+ 0)
+
+/** RSA PKCS#1 v1.5 encryption.
+ */
+#define PSA_ALG_RSA_PKCS1V15_CRYPT ((psa_algorithm_t)0x12020000)
+
+#define PSA_ALG_RSA_OAEP_BASE ((psa_algorithm_t)0x12030000)
+/** RSA OAEP encryption.
+ *
+ * This is the encryption scheme defined by RFC 8017
+ * (PKCS#1: RSA Cryptography Specifications) under the name
+ * RSAES-OAEP, with the message generation function MGF1.
+ *
+ * \param hash_alg The hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true) to use
+ * for MGF1.
+ *
+ * \return The corresponding RSA OAEP signature algorithm.
+ * \return Unspecified if \p alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_RSA_OAEP(hash_alg) \
+ (PSA_ALG_RSA_OAEP_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_IS_RSA_OAEP(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_OAEP_BASE)
+#define PSA_ALG_RSA_OAEP_GET_HASH(alg) \
+ (PSA_ALG_IS_RSA_OAEP(alg) ? \
+ ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH : \
+ 0)
+
+#define PSA_ALG_HKDF_BASE ((psa_algorithm_t)0x30000100)
+/** Macro to build an HKDF algorithm.
+ *
+ * For example, `PSA_ALG_HKDF(PSA_ALG_SHA256)` is HKDF using HMAC-SHA-256.
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return The corresponding HKDF algorithm.
+ * \return Unspecified if \p alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_HKDF(hash_alg) \
+ (PSA_ALG_HKDF_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+/** Whether the specified algorithm is an HKDF algorithm.
+ *
+ * HKDF is a family of key derivation algorithms that are based on a hash
+ * function and the HMAC construction.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \c alg is an HKDF algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \c alg is not a supported
+ * key derivation algorithm identifier.
+ */
+#define PSA_ALG_IS_HKDF(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HKDF_BASE)
+#define PSA_ALG_HKDF_GET_HASH(hkdf_alg) \
+ (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
+
+/**@}*/
+
+/** \defgroup key_management Key management
+ * @{
+ */
+
+/**
+ * \brief Import a key in binary format.
+ *
+ * This function supports any output from psa_export_key(). Refer to the
+ * documentation of psa_export_key() for the format for each key type.
+ *
+ * \param key Slot where the key will be stored. This must be a
+ * valid slot for a key of the chosen type. It must
+ * be unoccupied.
+ * \param type Key type (a \c PSA_KEY_TYPE_XXX value).
+ * \param[in] data Buffer containing the key data.
+ * \param data_length Size of the \p data buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * The key type or key size is not supported, either by the
+ * implementation in general or in this particular slot.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The key slot is invalid,
+ * or the key data is not correctly formatted.
+ * \retval #PSA_ERROR_OCCUPIED_SLOT
+ * There is already a key in the specified slot.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_INSUFFICIENT_STORAGE
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_import_key(psa_key_slot_t key,
+ psa_key_type_t type,
+ const uint8_t *data,
+ size_t data_length);
+
+/**
+ * \brief Destroy a key and restore the slot to its default state.
+ *
+ * This function destroys the content of the key slot from both volatile
+ * memory and, if applicable, non-volatile storage. Implementations shall
+ * make a best effort to ensure that any previous content of the slot is
+ * unrecoverable.
+ *
+ * This function also erases any metadata such as policies. It returns the
+ * specified slot to its default state.
+ *
+ * \param key The key slot to erase.
+ *
+ * \retval #PSA_SUCCESS
+ * The slot's content, if any, has been erased.
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * The slot holds content and cannot be erased because it is
+ * read-only, either due to a policy or due to physical restrictions.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The specified slot number does not designate a valid slot.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * There was an failure in communication with the cryptoprocessor.
+ * The key material may still be present in the cryptoprocessor.
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * The storage is corrupted. Implementations shall make a best effort
+ * to erase key material even in this stage, however applications
+ * should be aware that it may be impossible to guarantee that the
+ * key material is not recoverable in such cases.
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ * An unexpected condition which is not a storage corruption or
+ * a communication failure occurred. The cryptoprocessor may have
+ * been compromised.
+ */
+psa_status_t psa_destroy_key(psa_key_slot_t key);
+
+/**
+ * \brief Get basic metadata about a key.
+ *
+ * \param key Slot whose content is queried. This must
+ * be an occupied key slot.
+ * \param[out] type On success, the key type (a \c PSA_KEY_TYPE_XXX value).
+ * This may be a null pointer, in which case the key type
+ * is not written.
+ * \param[out] bits On success, the key size in bits.
+ * This may be a null pointer, in which case the key size
+ * is not written.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_EMPTY_SLOT
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_get_key_information(psa_key_slot_t key,
+ psa_key_type_t *type,
+ size_t *bits);
+
+/**
+ * \brief Export a key in binary format.
+ *
+ * The output of this function can be passed to psa_import_key() to
+ * create an equivalent object.
+ *
+ * If a key is created with psa_import_key() and then exported with
+ * this function, it is not guaranteed that the resulting data is
+ * identical: the implementation may choose a different representation
+ * of the same key if the format permits it.
+ *
+ * For standard key types, the output format is as follows:
+ *
+ * - For symmetric keys (including MAC keys), the format is the
+ * raw bytes of the key.
+ * - For DES, the key data consists of 8 bytes. The parity bits must be
+ * correct.
+ * - For Triple-DES, the format is the concatenation of the
+ * two or three DES keys.
+ * - For RSA key pairs (#PSA_KEY_TYPE_RSA_KEYPAIR), the format
+ * is the non-encrypted DER representation defined by PKCS\#1 (RFC 8017)
+ * as RSAPrivateKey.
+ * - For RSA public keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY), the format
+ * is the DER representation defined by RFC 5280 as SubjectPublicKeyInfo.
+ *
+ * \param key Slot whose content is to be exported. This must
+ * be an occupied key slot.
+ * \param[out] data Buffer where the key data is to be written.
+ * \param data_size Size of the \p data buffer in bytes.
+ * \param[out] data_length On success, the number of bytes
+ * that make up the key data.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_EMPTY_SLOT
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_export_key(psa_key_slot_t key,
+ uint8_t *data,
+ size_t data_size,
+ size_t *data_length);
+
+/**
+ * \brief Export a public key or the public part of a key pair in binary format.
+ *
+ * The output of this function can be passed to psa_import_key() to
+ * create an object that is equivalent to the public key.
+ *
+ * For standard key types, the output format is as follows:
+ *
+ * - For RSA keys (#PSA_KEY_TYPE_RSA_KEYPAIR or #PSA_KEY_TYPE_RSA_PUBLIC_KEY),
+ * the format is the DER representation of the public key defined by RFC 5280
+ * as SubjectPublicKeyInfo.
+ *
+ * \param key Slot whose content is to be exported. This must
+ * be an occupied key slot.
+ * \param[out] data Buffer where the key data is to be written.
+ * \param data_size Size of the \p data buffer in bytes.
+ * \param[out] data_length On success, the number of bytes
+ * that make up the key data.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_EMPTY_SLOT
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_export_public_key(psa_key_slot_t key,
+ uint8_t *data,
+ size_t data_size,
+ size_t *data_length);
+
+/**@}*/
+
+/** \defgroup policy Key policies
+ * @{
+ */
+
+/** \brief Encoding of permitted usage on a key. */
+typedef uint32_t psa_key_usage_t;
+
+/** Whether the key may be exported.
+ *
+ * A public key or the public part of a key pair may always be exported
+ * regardless of the value of this permission flag.
+ *
+ * If a key does not have export permission, implementations shall not
+ * allow the key to be exported in plain form from the cryptoprocessor,
+ * whether through psa_export_key() or through a proprietary interface.
+ * The key may however be exportable in a wrapped form, i.e. in a form
+ * where it is encrypted by another key.
+ */
+#define PSA_KEY_USAGE_EXPORT ((psa_key_usage_t)0x00000001)
+
+/** Whether the key may be used to encrypt a message.
+ *
+ * This flag allows the key to be used for a symmetric encryption operation,
+ * for an AEAD encryption-and-authentication operation,
+ * or for an asymmetric encryption operation,
+ * if otherwise permitted by the key's type and policy.
+ *
+ * For a key pair, this concerns the public key.
+ */
+#define PSA_KEY_USAGE_ENCRYPT ((psa_key_usage_t)0x00000100)
+
+/** Whether the key may be used to decrypt a message.
+ *
+ * This flag allows the key to be used for a symmetric decryption operation,
+ * for an AEAD decryption-and-verification operation,
+ * or for an asymmetric decryption operation,
+ * if otherwise permitted by the key's type and policy.
+ *
+ * For a key pair, this concerns the private key.
+ */
+#define PSA_KEY_USAGE_DECRYPT ((psa_key_usage_t)0x00000200)
+
+/** Whether the key may be used to sign a message.
+ *
+ * This flag allows the key to be used for a MAC calculation operation
+ * or for an asymmetric signature operation,
+ * if otherwise permitted by the key's type and policy.
+ *
+ * For a key pair, this concerns the private key.
+ */
+#define PSA_KEY_USAGE_SIGN ((psa_key_usage_t)0x00000400)
+
+/** Whether the key may be used to verify a message signature.
+ *
+ * This flag allows the key to be used for a MAC verification operation
+ * or for an asymmetric signature verification operation,
+ * if otherwise permitted by by the key's type and policy.
+ *
+ * For a key pair, this concerns the public key.
+ */
+#define PSA_KEY_USAGE_VERIFY ((psa_key_usage_t)0x00000800)
+
+/** Whether the key may be used to derive other keys.
+ */
+#define PSA_KEY_USAGE_DERIVE ((psa_key_usage_t)0x00001000)
+
+/** The type of the key policy data structure.
+ *
+ * This is an implementation-defined \c struct. Applications should not
+ * make any assumptions about the content of this structure except
+ * as directed by the documentation of a specific implementation. */
+typedef struct psa_key_policy_s psa_key_policy_t;
+
+/** \brief Initialize a key policy structure to a default that forbids all
+ * usage of the key.
+ *
+ * \param[out] policy The policy object to initialize.
+ */
+void psa_key_policy_init(psa_key_policy_t *policy);
+
+/** \brief Set the standard fields of a policy structure.
+ *
+ * Note that this function does not make any consistency check of the
+ * parameters. The values are only checked when applying the policy to
+ * a key slot with psa_set_key_policy().
+ *
+ * \param[out] policy The policy object to modify.
+ * \param usage The permitted uses for the key.
+ * \param alg The algorithm that the key may be used for.
+ */
+void psa_key_policy_set_usage(psa_key_policy_t *policy,
+ psa_key_usage_t usage,
+ psa_algorithm_t alg);
+
+/** \brief Retrieve the usage field of a policy structure.
+ *
+ * \param[in] policy The policy object to query.
+ *
+ * \return The permitted uses for a key with this policy.
+ */
+psa_key_usage_t psa_key_policy_get_usage(const psa_key_policy_t *policy);
+
+/** \brief Retrieve the algorithm field of a policy structure.
+ *
+ * \param[in] policy The policy object to query.
+ *
+ * \return The permitted algorithm for a key with this policy.
+ */
+psa_algorithm_t psa_key_policy_get_algorithm(const psa_key_policy_t *policy);
+
+/** \brief Set the usage policy on a key slot.
+ *
+ * This function must be called on an empty key slot, before importing,
+ * generating or creating a key in the slot. Changing the policy of an
+ * existing key is not permitted.
+ *
+ * Implementations may set restrictions on supported key policies
+ * depending on the key type and the key slot.
+ *
+ * \param key The key slot whose policy is to be changed.
+ * \param[in] policy The policy object to query.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_OCCUPIED_SLOT
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_set_key_policy(psa_key_slot_t key,
+ const psa_key_policy_t *policy);
+
+/** \brief Get the usage policy for a key slot.
+ *
+ * \param key The key slot whose policy is being queried.
+ * \param[out] policy On success, the key's policy.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_get_key_policy(psa_key_slot_t key,
+ psa_key_policy_t *policy);
+
+/**@}*/
+
+/** \defgroup persistence Key lifetime
+ * @{
+ */
+
+/** Encoding of key lifetimes.
+ */
+typedef uint32_t psa_key_lifetime_t;
+
+/** A volatile key slot retains its content as long as the application is
+ * running. It is guaranteed to be erased on a power reset.
+ */
+#define PSA_KEY_LIFETIME_VOLATILE ((psa_key_lifetime_t)0x00000000)
+
+/** A persistent key slot retains its content as long as it is not explicitly
+ * destroyed.
+ */
+#define PSA_KEY_LIFETIME_PERSISTENT ((psa_key_lifetime_t)0x00000001)
+
+/** A write-once key slot may not be modified once a key has been set.
+ * It will retain its content as long as the device remains operational.
+ */
+#define PSA_KEY_LIFETIME_WRITE_ONCE ((psa_key_lifetime_t)0x7fffffff)
+
+/** \brief Retrieve the lifetime of a key slot.
+ *
+ * The assignment of lifetimes to slots is implementation-dependent.
+ *
+ * \param key Slot to query.
+ * \param[out] lifetime On success, the lifetime value.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The key slot is invalid.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_get_key_lifetime(psa_key_slot_t key,
+ psa_key_lifetime_t *lifetime);
+
+/** \brief Change the lifetime of a key slot.
+ *
+ * Whether the lifetime of a key slot can be changed at all, and if so
+ * whether the lifetime of an occupied key slot can be changed, is
+ * implementation-dependent.
+ *
+ * \param key Slot whose lifetime is to be changed.
+ * \param lifetime The lifetime value to set for the given key slot.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The key slot is invalid,
+ * or the lifetime value is invalid.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * The implementation does not support the specified lifetime value,
+ * at least for the specified key slot.
+ * \retval #PSA_ERROR_OCCUPIED_SLOT
+ * The slot contains a key, and the implementation does not support
+ * changing the lifetime of an occupied slot.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_set_key_lifetime(psa_key_slot_t key,
+ psa_key_lifetime_t lifetime);
+
+/**@}*/
+
+/** \defgroup hash Message digests
+ * @{
+ */
+
+/** The type of the state data structure for multipart hash operations.
+ *
+ * This is an implementation-defined \c struct. Applications should not
+ * make any assumptions about the content of this structure except
+ * as directed by the documentation of a specific implementation. */
+typedef struct psa_hash_operation_s psa_hash_operation_t;
+
+/** The size of the output of psa_hash_finish(), in bytes.
+ *
+ * This is also the hash size that psa_hash_verify() expects.
+ *
+ * \param alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p alg) is true), or an HMAC algorithm
+ * (#PSA_ALG_HMAC(\c hash_alg) where \c hash_alg is a
+ * hash algorithm).
+ *
+ * \return The hash size for the specified hash algorithm.
+ * If the hash algorithm is not recognized, return 0.
+ * An implementation may return either 0 or the correct size
+ * for a hash algorithm that it recognizes, but does not support.
+ */
+#define PSA_HASH_SIZE(alg) \
+ ( \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_MD2 ? 16 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_MD4 ? 16 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_MD5 ? 16 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_RIPEMD160 ? 20 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA_1 ? 20 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA_224 ? 28 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA_256 ? 32 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA_384 ? 48 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA_512 ? 64 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA_512_224 ? 28 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA_512_256 ? 32 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA3_224 ? 28 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA3_256 ? 32 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA3_384 ? 48 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA3_512 ? 64 : \
+ 0)
+
+/** Start a multipart hash operation.
+ *
+ * The sequence of operations to calculate a hash (message digest)
+ * is as follows:
+ * -# Allocate an operation object which will be passed to all the functions
+ * listed here.
+ * -# Call psa_hash_setup() to specify the algorithm.
+ * -# Call psa_hash_update() zero, one or more times, passing a fragment
+ * of the message each time. The hash that is calculated is the hash
+ * of the concatenation of these messages in order.
+ * -# To calculate the hash, call psa_hash_finish().
+ * To compare the hash with an expected value, call psa_hash_verify().
+ *
+ * The application may call psa_hash_abort() at any time after the operation
+ * has been initialized with psa_hash_setup().
+ *
+ * After a successful call to psa_hash_setup(), the application must
+ * eventually terminate the operation. The following events terminate an
+ * operation:
+ * - A failed call to psa_hash_update().
+ * - A call to psa_hash_finish(), psa_hash_verify() or psa_hash_abort().
+ *
+ * \param[out] operation The operation object to use.
+ * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value
+ * such that #PSA_ALG_IS_HASH(\p alg) is true).
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not a hash algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_hash_setup(psa_hash_operation_t *operation,
+ psa_algorithm_t alg);
+
+/** Add a message fragment to a multipart hash operation.
+ *
+ * The application must call psa_hash_setup() before calling this function.
+ *
+ * If this function returns an error status, the operation becomes inactive.
+ *
+ * \param[in,out] operation Active hash operation.
+ * \param[in] input Buffer containing the message fragment to hash.
+ * \param input_length Size of the \p input buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (not started, or already completed).
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_hash_update(psa_hash_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length);
+
+/** Finish the calculation of the hash of a message.
+ *
+ * The application must call psa_hash_setup() before calling this function.
+ * This function calculates the hash of the message formed by concatenating
+ * the inputs passed to preceding calls to psa_hash_update().
+ *
+ * When this function returns, the operation becomes inactive.
+ *
+ * \warning Applications should not call this function if they expect
+ * a specific value for the hash. Call psa_hash_verify() instead.
+ * Beware that comparing integrity or authenticity data such as
+ * hash values with a function such as \c memcmp is risky
+ * because the time taken by the comparison may leak information
+ * about the hashed data which could allow an attacker to guess
+ * a valid hash and thereby bypass security controls.
+ *
+ * \param[in,out] operation Active hash operation.
+ * \param[out] hash Buffer where the hash is to be written.
+ * \param hash_size Size of the \p hash buffer in bytes.
+ * \param[out] hash_length On success, the number of bytes
+ * that make up the hash value. This is always
+ * #PSA_HASH_SIZE(\c alg) where \c alg is the
+ * hash algorithm that is calculated.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (not started, or already completed).
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p hash buffer is too small. You can determine a
+ * sufficient buffer size by calling #PSA_HASH_SIZE(\c alg)
+ * where \c alg is the hash algorithm that is calculated.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_hash_finish(psa_hash_operation_t *operation,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length);
+
+/** Finish the calculation of the hash of a message and compare it with
+ * an expected value.
+ *
+ * The application must call psa_hash_setup() before calling this function.
+ * This function calculates the hash of the message formed by concatenating
+ * the inputs passed to preceding calls to psa_hash_update(). It then
+ * compares the calculated hash with the expected hash passed as a
+ * parameter to this function.
+ *
+ * When this function returns, the operation becomes inactive.
+ *
+ * \note Implementations shall make the best effort to ensure that the
+ * comparison between the actual hash and the expected hash is performed
+ * in constant time.
+ *
+ * \param[in,out] operation Active hash operation.
+ * \param[in] hash Buffer containing the expected hash value.
+ * \param hash_length Size of the \p hash buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * The expected hash is identical to the actual hash of the message.
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ * The hash of the message was calculated successfully, but it
+ * differs from the expected hash.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (not started, or already completed).
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
+ const uint8_t *hash,
+ size_t hash_length);
+
+/** Abort a hash operation.
+ *
+ * Aborting an operation frees all associated resources except for the
+ * \p operation structure itself. Once aborted, the operation object
+ * can be reused for another operation by calling
+ * psa_hash_setup() again.
+ *
+ * You may call this function any time after the operation object has
+ * been initialized by any of the following methods:
+ * - A call to psa_hash_setup(), whether it succeeds or not.
+ * - Initializing the \c struct to all-bits-zero.
+ * - Initializing the \c struct to logical zeros, e.g.
+ * `psa_hash_operation_t operation = {0}`.
+ *
+ * In particular, calling psa_hash_abort() after the operation has been
+ * terminated by a call to psa_hash_abort(), psa_hash_finish() or
+ * psa_hash_verify() is safe and has no effect.
+ *
+ * \param[in,out] operation Initialized hash operation.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_BAD_STATE
+ * \p operation is not an active hash operation.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_hash_abort(psa_hash_operation_t *operation);
+
+/**@}*/
+
+/** \defgroup MAC Message authentication codes
+ * @{
+ */
+
+/** The type of the state data structure for multipart MAC operations.
+ *
+ * This is an implementation-defined \c struct. Applications should not
+ * make any assumptions about the content of this structure except
+ * as directed by the documentation of a specific implementation. */
+typedef struct psa_mac_operation_s psa_mac_operation_t;
+
+/** Start a multipart MAC calculation operation.
+ *
+ * This function sets up the calculation of the MAC
+ * (message authentication code) of a byte string.
+ * To verify the MAC of a message against an
+ * expected value, use psa_mac_verify_setup() instead.
+ *
+ * The sequence of operations to calculate a MAC is as follows:
+ * -# Allocate an operation object which will be passed to all the functions
+ * listed here.
+ * -# Call psa_mac_sign_setup() to specify the algorithm and key.
+ * The key remains associated with the operation even if the content
+ * of the key slot changes.
+ * -# Call psa_mac_update() zero, one or more times, passing a fragment
+ * of the message each time. The MAC that is calculated is the MAC
+ * of the concatenation of these messages in order.
+ * -# At the end of the message, call psa_mac_sign_finish() to finish
+ * calculating the MAC value and retrieve it.
+ *
+ * The application may call psa_mac_abort() at any time after the operation
+ * has been initialized with psa_mac_sign_setup().
+ *
+ * After a successful call to psa_mac_sign_setup(), the application must
+ * eventually terminate the operation through one of the following methods:
+ * - A failed call to psa_mac_update().
+ * - A call to psa_mac_sign_finish() or psa_mac_abort().
+ *
+ * \param[out] operation The operation object to use.
+ * \param key Slot containing the key to use for the operation.
+ * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value
+ * such that #PSA_ALG_IS_MAC(alg) is true).
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_EMPTY_SLOT
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not compatible with \p alg.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not a MAC algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation,
+ psa_key_slot_t key,
+ psa_algorithm_t alg);
+
+/** Start a multipart MAC verification operation.
+ *
+ * This function sets up the verification of the MAC
+ * (message authentication code) of a byte string against an expected value.
+ *
+ * The sequence of operations to verify a MAC is as follows:
+ * -# Allocate an operation object which will be passed to all the functions
+ * listed here.
+ * -# Call psa_mac_verify_setup() to specify the algorithm and key.
+ * The key remains associated with the operation even if the content
+ * of the key slot changes.
+ * -# Call psa_mac_update() zero, one or more times, passing a fragment
+ * of the message each time. The MAC that is calculated is the MAC
+ * of the concatenation of these messages in order.
+ * -# At the end of the message, call psa_mac_verify_finish() to finish
+ * calculating the actual MAC of the message and verify it against
+ * the expected value.
+ *
+ * The application may call psa_mac_abort() at any time after the operation
+ * has been initialized with psa_mac_verify_setup().
+ *
+ * After a successful call to psa_mac_verify_setup(), the application must
+ * eventually terminate the operation through one of the following methods:
+ * - A failed call to psa_mac_update().
+ * - A call to psa_mac_verify_finish() or psa_mac_abort().
+ *
+ * \param[out] operation The operation object to use.
+ * \param key Slot containing the key to use for the operation.
+ * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value
+ * such that #PSA_ALG_IS_MAC(\p alg) is true).
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_EMPTY_SLOT
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \c key is not compatible with \c alg.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \c alg is not supported or is not a MAC algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation,
+ psa_key_slot_t key,
+ psa_algorithm_t alg);
+
+/** Add a message fragment to a multipart MAC operation.
+ *
+ * The application must call psa_mac_sign_setup() or psa_mac_verify_setup()
+ * before calling this function.
+ *
+ * If this function returns an error status, the operation becomes inactive.
+ *
+ * \param[in,out] operation Active MAC operation.
+ * \param[in] input Buffer containing the message fragment to add to
+ * the MAC calculation.
+ * \param input_length Size of the \p input buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (not started, or already completed).
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_mac_update(psa_mac_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length);
+
+/** Finish the calculation of the MAC of a message.
+ *
+ * The application must call psa_mac_sign_setup() before calling this function.
+ * This function calculates the MAC of the message formed by concatenating
+ * the inputs passed to preceding calls to psa_mac_update().
+ *
+ * When this function returns, the operation becomes inactive.
+ *
+ * \warning Applications should not call this function if they expect
+ * a specific value for the MAC. Call psa_mac_verify_finish() instead.
+ * Beware that comparing integrity or authenticity data such as
+ * MAC values with a function such as \c memcmp is risky
+ * because the time taken by the comparison may leak information
+ * about the MAC value which could allow an attacker to guess
+ * a valid MAC and thereby bypass security controls.
+ *
+ * \param[in,out] operation Active MAC operation.
+ * \param[out] mac Buffer where the MAC value is to be written.
+ * \param mac_size Size of the \p mac buffer in bytes.
+ * \param[out] mac_length On success, the number of bytes
+ * that make up the MAC value. This is always
+ * #PSA_MAC_FINAL_SIZE(\c key_type, \c key_bits, \c alg)
+ * where \c key_type and \c key_bits are the type and
+ * bit-size respectively of the key and \c alg is the
+ * MAC algorithm that is calculated.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (not started, or already completed).
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p mac buffer is too small. You can determine a
+ * sufficient buffer size by calling PSA_MAC_FINAL_SIZE().
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation,
+ uint8_t *mac,
+ size_t mac_size,
+ size_t *mac_length);
+
+/** Finish the calculation of the MAC of a message and compare it with
+ * an expected value.
+ *
+ * The application must call psa_mac_verify_setup() before calling this function.
+ * This function calculates the MAC of the message formed by concatenating
+ * the inputs passed to preceding calls to psa_mac_update(). It then
+ * compares the calculated MAC with the expected MAC passed as a
+ * parameter to this function.
+ *
+ * When this function returns, the operation becomes inactive.
+ *
+ * \note Implementations shall make the best effort to ensure that the
+ * comparison between the actual MAC and the expected MAC is performed
+ * in constant time.
+ *
+ * \param[in,out] operation Active MAC operation.
+ * \param[in] mac Buffer containing the expected MAC value.
+ * \param mac_length Size of the \p mac buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * The expected MAC is identical to the actual MAC of the message.
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ * The MAC of the message was calculated successfully, but it
+ * differs from the expected MAC.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (not started, or already completed).
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation,
+ const uint8_t *mac,
+ size_t mac_length);
+
+/** Abort a MAC operation.
+ *
+ * Aborting an operation frees all associated resources except for the
+ * \p operation structure itself. Once aborted, the operation object
+ * can be reused for another operation by calling
+ * psa_mac_sign_setup() or psa_mac_verify_setup() again.
+ *
+ * You may call this function any time after the operation object has
+ * been initialized by any of the following methods:
+ * - A call to psa_mac_sign_setup() or psa_mac_verify_setup(), whether
+ * it succeeds or not.
+ * - Initializing the \c struct to all-bits-zero.
+ * - Initializing the \c struct to logical zeros, e.g.
+ * `psa_mac_operation_t operation = {0}`.
+ *
+ * In particular, calling psa_mac_abort() after the operation has been
+ * terminated by a call to psa_mac_abort(), psa_mac_sign_finish() or
+ * psa_mac_verify_finish() is safe and has no effect.
+ *
+ * \param[in,out] operation Initialized MAC operation.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_BAD_STATE
+ * \p operation is not an active MAC operation.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_mac_abort(psa_mac_operation_t *operation);
+
+/**@}*/
+
+/** \defgroup cipher Symmetric ciphers
+ * @{
+ */
+
+/** The type of the state data structure for multipart cipher operations.
+ *
+ * This is an implementation-defined \c struct. Applications should not
+ * make any assumptions about the content of this structure except
+ * as directed by the documentation of a specific implementation. */
+typedef struct psa_cipher_operation_s psa_cipher_operation_t;
+
+/** Set the key for a multipart symmetric encryption operation.
+ *
+ * The sequence of operations to encrypt a message with a symmetric cipher
+ * is as follows:
+ * -# Allocate an operation object which will be passed to all the functions
+ * listed here.
+ * -# Call psa_cipher_encrypt_setup() to specify the algorithm and key.
+ * The key remains associated with the operation even if the content
+ * of the key slot changes.
+ * -# Call either psa_cipher_generate_iv() or psa_cipher_set_iv() to
+ * generate or set the IV (initialization vector). You should use
+ * psa_cipher_generate_iv() unless the protocol you are implementing
+ * requires a specific IV value.
+ * -# Call psa_cipher_update() zero, one or more times, passing a fragment
+ * of the message each time.
+ * -# Call psa_cipher_finish().
+ *
+ * The application may call psa_cipher_abort() at any time after the operation
+ * has been initialized with psa_cipher_encrypt_setup().
+ *
+ * After a successful call to psa_cipher_encrypt_setup(), the application must
+ * eventually terminate the operation. The following events terminate an
+ * operation:
+ * - A failed call to psa_cipher_generate_iv(), psa_cipher_set_iv()
+ * or psa_cipher_update().
+ * - A call to psa_cipher_finish() or psa_cipher_abort().
+ *
+ * \param[out] operation The operation object to use.
+ * \param key Slot containing the key to use for the operation.
+ * \param alg The cipher algorithm to compute
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_CIPHER(\p alg) is true).
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_EMPTY_SLOT
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not compatible with \p alg.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not a cipher algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation,
+ psa_key_slot_t key,
+ psa_algorithm_t alg);
+
+/** Set the key for a multipart symmetric decryption operation.
+ *
+ * The sequence of operations to decrypt a message with a symmetric cipher
+ * is as follows:
+ * -# Allocate an operation object which will be passed to all the functions
+ * listed here.
+ * -# Call psa_cipher_decrypt_setup() to specify the algorithm and key.
+ * The key remains associated with the operation even if the content
+ * of the key slot changes.
+ * -# Call psa_cipher_update() with the IV (initialization vector) for the
+ * decryption. If the IV is prepended to the ciphertext, you can call
+ * psa_cipher_update() on a buffer containing the IV followed by the
+ * beginning of the message.
+ * -# Call psa_cipher_update() zero, one or more times, passing a fragment
+ * of the message each time.
+ * -# Call psa_cipher_finish().
+ *
+ * The application may call psa_cipher_abort() at any time after the operation
+ * has been initialized with psa_cipher_decrypt_setup().
+ *
+ * After a successful call to psa_cipher_decrypt_setup(), the application must
+ * eventually terminate the operation. The following events terminate an
+ * operation:
+ * - A failed call to psa_cipher_update().
+ * - A call to psa_cipher_finish() or psa_cipher_abort().
+ *
+ * \param[out] operation The operation object to use.
+ * \param key Slot containing the key to use for the operation.
+ * \param alg The cipher algorithm to compute
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_CIPHER(\p alg) is true).
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_EMPTY_SLOT
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not compatible with \p alg.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not a cipher algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation,
+ psa_key_slot_t key,
+ psa_algorithm_t alg);
+
+/** Generate an IV for a symmetric encryption operation.
+ *
+ * This function generates a random IV (initialization vector), nonce
+ * or initial counter value for the encryption operation as appropriate
+ * for the chosen algorithm, key type and key size.
+ *
+ * The application must call psa_cipher_encrypt_setup() before
+ * calling this function.
+ *
+ * If this function returns an error status, the operation becomes inactive.
+ *
+ * \param[in,out] operation Active cipher operation.
+ * \param[out] iv Buffer where the generated IV is to be written.
+ * \param iv_size Size of the \p iv buffer in bytes.
+ * \param[out] iv_length On success, the number of bytes of the
+ * generated IV.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (not started, or IV already set).
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p iv buffer is too small.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation,
+ unsigned char *iv,
+ size_t iv_size,
+ size_t *iv_length);
+
+/** Set the IV for a symmetric encryption or decryption operation.
+ *
+ * This function sets the random IV (initialization vector), nonce
+ * or initial counter value for the encryption or decryption operation.
+ *
+ * The application must call psa_cipher_encrypt_setup() before
+ * calling this function.
+ *
+ * If this function returns an error status, the operation becomes inactive.
+ *
+ * \note When encrypting, applications should use psa_cipher_generate_iv()
+ * instead of this function, unless implementing a protocol that requires
+ * a non-random IV.
+ *
+ * \param[in,out] operation Active cipher operation.
+ * \param[in] iv Buffer containing the IV to use.
+ * \param iv_length Size of the IV in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (not started, or IV already set).
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The size of \p iv is not acceptable for the chosen algorithm,
+ * or the chosen algorithm does not use an IV.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation,
+ const unsigned char *iv,
+ size_t iv_length);
+
+/** Encrypt or decrypt a message fragment in an active cipher operation.
+ *
+ * Before calling this function, you must:
+ * 1. Call either psa_cipher_encrypt_setup() or psa_cipher_decrypt_setup().
+ * The choice of setup function determines whether this function
+ * encrypts or decrypts its input.
+ * 2. If the algorithm requires an IV, call psa_cipher_generate_iv()
+ * (recommended when encrypting) or psa_cipher_set_iv().
+ *
+ * If this function returns an error status, the operation becomes inactive.
+ *
+ * \param[in,out] operation Active cipher operation.
+ * \param[in] input Buffer containing the message fragment to
+ * encrypt or decrypt.
+ * \param input_length Size of the \p input buffer in bytes.
+ * \param[out] output Buffer where the output is to be written.
+ * \param output_size Size of the \p output buffer in bytes.
+ * \param[out] output_length On success, the number of bytes
+ * that make up the returned output.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (not started, IV required but
+ * not set, or already completed).
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p output buffer is too small.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_cipher_update(psa_cipher_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length,
+ unsigned char *output,
+ size_t output_size,
+ size_t *output_length);
+
+/** Finish encrypting or decrypting a message in a cipher operation.
+ *
+ * The application must call psa_cipher_encrypt_setup() or
+ * psa_cipher_decrypt_setup() before calling this function. The choice
+ * of setup function determines whether this function encrypts or
+ * decrypts its input.
+ *
+ * This function finishes the encryption or decryption of the message
+ * formed by concatenating the inputs passed to preceding calls to
+ * psa_cipher_update().
+ *
+ * When this function returns, the operation becomes inactive.
+ *
+ * \param[in,out] operation Active cipher operation.
+ * \param[out] output Buffer where the output is to be written.
+ * \param output_size Size of the \p output buffer in bytes.
+ * \param[out] output_length On success, the number of bytes
+ * that make up the returned output.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (not started, IV required but
+ * not set, or already completed).
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p output buffer is too small.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length);
+
+/** Abort a cipher operation.
+ *
+ * Aborting an operation frees all associated resources except for the
+ * \p operation structure itself. Once aborted, the operation object
+ * can be reused for another operation by calling
+ * psa_cipher_encrypt_setup() or psa_cipher_decrypt_setup() again.
+ *
+ * You may call this function any time after the operation object has
+ * been initialized by any of the following methods:
+ * - A call to psa_cipher_encrypt_setup() or psa_cipher_decrypt_setup(),
+ * whether it succeeds or not.
+ * - Initializing the \c struct to all-bits-zero.
+ * - Initializing the \c struct to logical zeros, e.g.
+ * `psa_cipher_operation_t operation = {0}`.
+ *
+ * In particular, calling psa_cipher_abort() after the operation has been
+ * terminated by a call to psa_cipher_abort() or psa_cipher_finish()
+ * is safe and has no effect.
+ *
+ * \param[in,out] operation Initialized cipher operation.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_BAD_STATE
+ * \p operation is not an active cipher operation.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation);
+
+/**@}*/
+
+/** \defgroup aead Authenticated encryption with associated data (AEAD)
+ * @{
+ */
+
+/** The tag size for an AEAD algorithm, in bytes.
+ *
+ * \param alg An AEAD algorithm
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_AEAD(\p alg) is true).
+ *
+ * \return The tag size for the specified algorithm.
+ * If the AEAD algorithm does not have an identified
+ * tag that can be distinguished from the rest of
+ * the ciphertext, return 0.
+ * If the AEAD algorithm is not recognized, return 0.
+ * An implementation may return either 0 or a
+ * correct size for an AEAD algorithm that it
+ * recognizes, but does not support.
+ */
+#define PSA_AEAD_TAG_SIZE(alg) \
+ ((alg) == PSA_ALG_GCM ? 16 : \
+ (alg) == PSA_ALG_CCM ? 16 : \
+ 0)
+
+/** Process an authenticated encryption operation.
+ *
+ * \param key Slot containing the key to use.
+ * \param alg The AEAD algorithm to compute
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_AEAD(\p alg) is true).
+ * \param[in] nonce Nonce or IV to use.
+ * \param nonce_length Size of the \p nonce buffer in bytes.
+ * \param[in] additional_data Additional data that will be authenticated
+ * but not encrypted.
+ * \param additional_data_length Size of \p additional_data in bytes.
+ * \param[in] plaintext Data that will be authenticated and
+ * encrypted.
+ * \param plaintext_length Size of \p plaintext in bytes.
+ * \param[out] ciphertext Output buffer for the authenticated and
+ * encrypted data. The additional data is not
+ * part of this output. For algorithms where the
+ * encrypted data and the authentication tag
+ * are defined as separate outputs, the
+ * authentication tag is appended to the
+ * encrypted data.
+ * \param ciphertext_size Size of the \p ciphertext buffer in bytes.
+ * This must be at least
+ * #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\p alg,
+ * \p plaintext_length).
+ * \param[out] ciphertext_length On success, the size of the output
+ * in the \b ciphertext buffer.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_EMPTY_SLOT
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not compatible with \p alg.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not an AEAD algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_aead_encrypt(psa_key_slot_t key,
+ psa_algorithm_t alg,
+ const uint8_t *nonce,
+ size_t nonce_length,
+ const uint8_t *additional_data,
+ size_t additional_data_length,
+ const uint8_t *plaintext,
+ size_t plaintext_length,
+ uint8_t *ciphertext,
+ size_t ciphertext_size,
+ size_t *ciphertext_length);
+
+/** Process an authenticated decryption operation.
+ *
+ * \param key Slot containing the key to use.
+ * \param alg The AEAD algorithm to compute
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_AEAD(\p alg) is true).
+ * \param[in] nonce Nonce or IV to use.
+ * \param nonce_length Size of the \p nonce buffer in bytes.
+ * \param[in] additional_data Additional data that has been authenticated
+ * but not encrypted.
+ * \param additional_data_length Size of \p additional_data in bytes.
+ * \param[in] ciphertext Data that has been authenticated and
+ * encrypted. For algorithms where the
+ * encrypted data and the authentication tag
+ * are defined as separate inputs, the buffer
+ * must contain the encrypted data followed
+ * by the authentication tag.
+ * \param ciphertext_length Size of \p ciphertext in bytes.
+ * \param[out] plaintext Output buffer for the decrypted data.
+ * \param plaintext_size Size of the \p plaintext buffer in bytes.
+ * This must be at least
+ * #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\p alg,
+ * \p ciphertext_length).
+ * \param[out] plaintext_length On success, the size of the output
+ * in the \b plaintext buffer.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_EMPTY_SLOT
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ * The ciphertext is not authentic.
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not compatible with \p alg.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not an AEAD algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_aead_decrypt(psa_key_slot_t key,
+ psa_algorithm_t alg,
+ const uint8_t *nonce,
+ size_t nonce_length,
+ const uint8_t *additional_data,
+ size_t additional_data_length,
+ const uint8_t *ciphertext,
+ size_t ciphertext_length,
+ uint8_t *plaintext,
+ size_t plaintext_size,
+ size_t *plaintext_length);
+
+/**@}*/
+
+/** \defgroup asymmetric Asymmetric cryptography
+ * @{
+ */
+
+/**
+ * \brief ECDSA signature size for a given curve bit size
+ *
+ * \param curve_bits Curve size in bits.
+ * \return Signature size in bytes.
+ *
+ * \note This macro returns a compile-time constant if its argument is one.
+ */
+#define PSA_ECDSA_SIGNATURE_SIZE(curve_bits) \
+ (PSA_BITS_TO_BYTES(curve_bits) * 2)
+
+/**
+ * \brief Sign a hash or short message with a private key.
+ *
+ * Note that to perform a hash-and-sign signature algorithm, you must
+ * first calculate the hash by calling psa_hash_setup(), psa_hash_update()
+ * and psa_hash_finish(). Then pass the resulting hash as the \p hash
+ * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg)
+ * to determine the hash algorithm to use.
+ *
+ * \param key Key slot containing an asymmetric key pair.
+ * \param alg A signature algorithm that is compatible with
+ * the type of \p key.
+ * \param[in] hash The hash or message to sign.
+ * \param hash_length Size of the \p hash buffer in bytes.
+ * \param[out] signature Buffer where the signature is to be written.
+ * \param signature_size Size of the \p signature buffer in bytes.
+ * \param[out] signature_length On success, the number of bytes
+ * that make up the returned signature value.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p signature buffer is too small. You can
+ * determine a sufficient buffer size by calling
+ * #PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
+ * where \c key_type and \c key_bits are the type and bit-size
+ * respectively of \p key.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
+ */
+psa_status_t psa_asymmetric_sign(psa_key_slot_t key,
+ psa_algorithm_t alg,
+ const uint8_t *hash,
+ size_t hash_length,
+ uint8_t *signature,
+ size_t signature_size,
+ size_t *signature_length);
+
+/**
+ * \brief Verify the signature a hash or short message using a public key.
+ *
+ * Note that to perform a hash-and-sign signature algorithm, you must
+ * first calculate the hash by calling psa_hash_setup(), psa_hash_update()
+ * and psa_hash_finish(). Then pass the resulting hash as the \p hash
+ * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg)
+ * to determine the hash algorithm to use.
+ *
+ * \param key Key slot containing a public key or an
+ * asymmetric key pair.
+ * \param alg A signature algorithm that is compatible with
+ * the type of \p key.
+ * \param[in] hash The hash or message whose signature is to be
+ * verified.
+ * \param hash_length Size of the \p hash buffer in bytes.
+ * \param[in] signature Buffer containing the signature to verify.
+ * \param signature_length Size of the \p signature buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * The signature is valid.
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ * The calculation was perfomed successfully, but the passed
+ * signature is not a valid signature.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_asymmetric_verify(psa_key_slot_t key,
+ psa_algorithm_t alg,
+ const uint8_t *hash,
+ size_t hash_length,
+ const uint8_t *signature,
+ size_t signature_length);
+
+#define PSA_RSA_MINIMUM_PADDING_SIZE(alg) \
+ (PSA_ALG_IS_RSA_OAEP(alg) ? \
+ 2 * PSA_HASH_FINAL_SIZE(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1 : \
+ 11 /*PKCS#1v1.5*/)
+
+/**
+ * \brief Encrypt a short message with a public key.
+ *
+ * \param key Key slot containing a public key or an
+ * asymmetric key pair.
+ * \param alg An asymmetric encryption algorithm that is
+ * compatible with the type of \p key.
+ * \param[in] input The message to encrypt.
+ * \param input_length Size of the \p input buffer in bytes.
+ * \param[in] salt A salt or label, if supported by the
+ * encryption algorithm.
+ * If the algorithm does not support a
+ * salt, pass \c NULL.
+ * If the algorithm supports an optional
+ * salt and you do not want to pass a salt,
+ * pass \c NULL.
+ *
+ * - For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
+ * supported.
+ * \param salt_length Size of the \p salt buffer in bytes.
+ * If \p salt is \c NULL, pass 0.
+ * \param[out] output Buffer where the encrypted message is to
+ * be written.
+ * \param output_size Size of the \p output buffer in bytes.
+ * \param[out] output_length On success, the number of bytes
+ * that make up the returned output.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p output buffer is too small. You can
+ * determine a sufficient buffer size by calling
+ * #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
+ * where \c key_type and \c key_bits are the type and bit-size
+ * respectively of \p key.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
+ */
+psa_status_t psa_asymmetric_encrypt(psa_key_slot_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *salt,
+ size_t salt_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length);
+
+/**
+ * \brief Decrypt a short message with a private key.
+ *
+ * \param key Key slot containing an asymmetric key pair.
+ * \param alg An asymmetric encryption algorithm that is
+ * compatible with the type of \p key.
+ * \param[in] input The message to decrypt.
+ * \param input_length Size of the \p input buffer in bytes.
+ * \param[in] salt A salt or label, if supported by the
+ * encryption algorithm.
+ * If the algorithm does not support a
+ * salt, pass \c NULL.
+ * If the algorithm supports an optional
+ * salt and you do not want to pass a salt,
+ * pass \c NULL.
+ *
+ * - For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
+ * supported.
+ * \param salt_length Size of the \p salt buffer in bytes.
+ * If \p salt is \c NULL, pass 0.
+ * \param[out] output Buffer where the decrypted message is to
+ * be written.
+ * \param output_size Size of the \c output buffer in bytes.
+ * \param[out] output_length On success, the number of bytes
+ * that make up the returned output.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p output buffer is too small. You can
+ * determine a sufficient buffer size by calling
+ * #PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
+ * where \c key_type and \c key_bits are the type and bit-size
+ * respectively of \p key.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
+ * \retval #PSA_ERROR_INVALID_PADDING
+ */
+psa_status_t psa_asymmetric_decrypt(psa_key_slot_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *salt,
+ size_t salt_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length);
+
+/**@}*/
+
+/** \defgroup generators Generators
+ * @{
+ */
+
+/** The type of the state data structure for generators.
+ *
+ * Before calling any function on a generator, the application must
+ * initialize it by any of the following means:
+ * - Set the structure to all-bits-zero, for example:
+ * \code
+ * psa_crypto_generator_t generator;
+ * memset(&generator, 0, sizeof(generator));
+ * \endcode
+ * - Initialize the structure to logical zero values, for example:
+ * \code
+ * psa_crypto_generator_t generator = {0};
+ * \endcode
+ * - Initialize the structure to the initializer #PSA_CRYPTO_GENERATOR_INIT,
+ * for example:
+ * \code
+ * psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+ * \endcode
+ * - Assign the result of the function psa_crypto_generator_init()
+ * to the structure, for example:
+ * \code
+ * psa_crypto_generator_t generator;
+ * generator = psa_crypto_generator_init();
+ * \endcode
+ *
+ * This is an implementation-defined \c struct. Applications should not
+ * make any assumptions about the content of this structure except
+ * as directed by the documentation of a specific implementation.
+ */
+typedef struct psa_crypto_generator_s psa_crypto_generator_t;
+
+/** \def PSA_CRYPTO_GENERATOR_INIT
+ *
+ * This macro returns a suitable initializer for a generator object
+ * of type #psa_crypto_generator_t.
+ */
+#ifdef __DOXYGEN_ONLY__
+/* This is an example definition for documentation purposes.
+ * Implementations should define a suitable value in `crypto_struct.h`.
+ */
+#define PSA_CRYPTO_GENERATOR_INIT {0}
+#endif
+
+/** Return an initial value for a generator object.
+ */
+static psa_crypto_generator_t psa_crypto_generator_init(void);
+
+/** Retrieve the current capacity of a generator.
+ *
+ * The capacity of a generator is the maximum number of bytes that it can
+ * return. Reading *N* bytes from a generator reduces its capacity by *N*.
+ *
+ * \param[in] generator The generator to query.
+ * \param[out] capacity On success, the capacity of the generator.
+ *
+ * \retval PSA_SUCCESS
+ * \retval PSA_ERROR_BAD_STATE
+ * \retval PSA_ERROR_COMMUNICATION_FAILURE
+ */
+psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
+ size_t *capacity);
+
+/** Read some data from a generator.
+ *
+ * This function reads and returns a sequence of bytes from a generator.
+ * The data that is read is discarded from the generator. The generator's
+ * capacity is decreased by the number of bytes read.
+ *
+ * \param[in,out] generator The generator object to read from.
+ * \param[out] output Buffer where the generator output will be
+ * written.
+ * \param output_length Number of bytes to output.
+ *
+ * \retval PSA_SUCCESS
+ * \retval PSA_ERROR_INSUFFICIENT_CAPACITY
+ * There were fewer than \p output_length bytes
+ * in the generator. Note that in this case, no
+ * output is written to the output buffer.
+ * The generator's capacity is set to 0, thus
+ * subsequent calls to this function will not
+ * succeed, even with a smaller output buffer.
+ * \retval PSA_ERROR_BAD_STATE
+ * \retval PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval PSA_ERROR_HARDWARE_FAILURE
+ * \retval PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_generator_read(psa_crypto_generator_t *generator,
+ uint8_t *output,
+ size_t output_length);
+
+/** Create a symmetric key from data read from a generator.
+ *
+ * This function reads a sequence of bytes from a generator and imports
+ * these bytes as a key.
+ * The data that is read is discarded from the generator. The generator's
+ * capacity is decreased by the number of bytes read.
+ *
+ * This function is equivalent to calling #psa_generator_read and
+ * passing the resulting output to #psa_import_key, but
+ * if the implementation provides an isolation boundary then
+ * the key material is not exposed outside the isolation boundary.
+ *
+ * \param key Slot where the key will be stored. This must be a
+ * valid slot for a key of the chosen type. It must
+ * be unoccupied.
+ * \param type Key type (a \c PSA_KEY_TYPE_XXX value).
+ * This must be a symmetric key type.
+ * \param bits Key size in bits.
+ * \param[in,out] generator The generator object to read from.
+ *
+ * \retval PSA_SUCCESS
+ * Success.
+ * \retval PSA_ERROR_INSUFFICIENT_CAPACITY
+ * There were fewer than \p output_length bytes
+ * in the generator. Note that in this case, no
+ * output is written to the output buffer.
+ * The generator's capacity is set to 0, thus
+ * subsequent calls to this function will not
+ * succeed, even with a smaller output buffer.
+ * \retval PSA_ERROR_NOT_SUPPORTED
+ * The key type or key size is not supported, either by the
+ * implementation in general or in this particular slot.
+ * \retval PSA_ERROR_BAD_STATE
+ * \retval PSA_ERROR_INVALID_ARGUMENT
+ * The key slot is invalid.
+ * \retval PSA_ERROR_OCCUPIED_SLOT
+ * There is already a key in the specified slot.
+ * \retval PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval PSA_ERROR_INSUFFICIENT_STORAGE
+ * \retval PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval PSA_ERROR_HARDWARE_FAILURE
+ * \retval PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_generator_import_key(psa_key_slot_t key,
+ psa_key_type_t type,
+ size_t bits,
+ psa_crypto_generator_t *generator);
+
+/** Abort a generator.
+ *
+ * Once a generator has been aborted, its capacity is zero.
+ * Aborting a generator frees all associated resources except for the
+ * \c generator structure itself.
+ *
+ * This function may be called at any time as long as the generator
+ * object has been initialized to #PSA_CRYPTO_GENERATOR_INIT, to
+ * psa_crypto_generator_init() or a zero value. In particular, it is valid
+ * to call psa_generator_abort() twice, or to call psa_generator_abort()
+ * on a generator that has not been set up.
+ *
+ * Once aborted, the generator object may be called.
+ *
+ * \param[in,out] generator The generator to abort.
+ *
+ * \retval PSA_SUCCESS
+ * \retval PSA_ERROR_BAD_STATE
+ * \retval PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval PSA_ERROR_HARDWARE_FAILURE
+ * \retval PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_generator_abort(psa_crypto_generator_t *generator);
+
+/**@}*/
+
+/** \defgroup derivation Key derivation
+ * @{
+ */
+
+/** Set up a key derivation operation.
+ *
+ * A key derivation algorithm takes three inputs: a secret input \p key and
+ * two non-secret inputs \p label and p salt.
+ * The result of this function is a byte generator which can
+ * be used to produce keys and other cryptographic material.
+ *
+ * The role of \p label and \p salt is as follows:
+ * - For HKDF (#PSA_ALG_HKDF), \p salt is the salt used in the "extract" step
+ * and \p label is the info string used in the "expand" step.
+ *
+ * \param[in,out] generator The generator object to set up. It must
+ * have been initialized to .
+ * \param key Slot containing the secret key to use.
+ * \param alg The key derivation algorithm to compute
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_KEY_DERIVATION(\p alg) is true).
+ * \param[in] salt Salt to use.
+ * \param salt_length Size of the \p salt buffer in bytes.
+ * \param[in] label Label to use.
+ * \param label_length Size of the \p label buffer in bytes.
+ * \param capacity The maximum number of bytes that the
+ * generator will be able to provide.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_EMPTY_SLOT
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \c key is not compatible with \c alg,
+ * or \p capacity is too large for the specified algorithm and key.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \c alg is not supported or is not a key derivation algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_key_derivation(psa_crypto_generator_t *generator,
+ psa_key_slot_t key,
+ psa_algorithm_t alg,
+ const uint8_t *salt,
+ size_t salt_length,
+ const uint8_t *label,
+ size_t label_length,
+ size_t capacity);
+
+/**@}*/
+
+/** \defgroup random Random generation
+ * @{
+ */
+
+/**
+ * \brief Generate random bytes.
+ *
+ * \warning This function **can** fail! Callers MUST check the return status
+ * and MUST NOT use the content of the output buffer if the return
+ * status is not #PSA_SUCCESS.
+ *
+ * \note To generate a key, use psa_generate_key() instead.
+ *
+ * \param[out] output Output buffer for the generated data.
+ * \param output_size Number of bytes to generate and output.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_generate_random(uint8_t *output,
+ size_t output_size);
+
+/** Extra parameters for RSA key generation.
+ *
+ * You may pass a pointer to a structure of this type as the \c extra
+ * parameter to psa_generate_key().
+ */
+typedef struct {
+ uint32_t e; /**< Public exponent value. Default: 65537. */
+} psa_generate_key_extra_rsa;
+
+/**
+ * \brief Generate a key or key pair.
+ *
+ * \param key Slot where the key will be stored. This must be a
+ * valid slot for a key of the chosen type. It must
+ * be unoccupied.
+ * \param type Key type (a \c PSA_KEY_TYPE_XXX value).
+ * \param bits Key size in bits.
+ * \param[in] extra Extra parameters for key generation. The
+ * interpretation of this parameter depends on
+ * \p type. All types support \c NULL to use
+ * default parameters. Implementation that support
+ * the generation of vendor-specific key types
+ * that allow extra parameters shall document
+ * the format of these extra parameters and
+ * the default values. For standard parameters,
+ * the meaning of \p extra is as follows:
+ * - For a symmetric key type (a type such
+ * that #PSA_KEY_TYPE_IS_ASYMMETRIC(\p type) is
+ * false), \p extra must be \c NULL.
+ * - For an elliptic curve key type (a type
+ * such that #PSA_KEY_TYPE_IS_ECC(\p type) is
+ * false), \p extra must be \c NULL.
+ * - For an RSA key (\p type is
+ * #PSA_KEY_TYPE_RSA_KEYPAIR), \p extra is an
+ * optional #psa_generate_key_extra_rsa structure
+ * specifying the public exponent. The
+ * default public exponent used when \p extra
+ * is \c NULL is 65537.
+ * \param extra_size Size of the buffer that \p extra
+ * points to, in bytes. Note that if \p extra is
+ * \c NULL then \p extra_size must be zero.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_generate_key(psa_key_slot_t key,
+ psa_key_type_t type,
+ size_t bits,
+ const void *extra,
+ size_t extra_size);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+/* The file "crypto_sizes.h" contains definitions for size calculation
+ * macros whose definitions are implementation-specific. */
+#include "crypto_sizes.h"
+
+/* The file "crypto_struct.h" contains definitions for
+ * implementation-specific structs that are declared above. */
+#include "crypto_struct.h"
+
+/* The file "crypto_extra.h" contains vendor-specific definitions. This
+ * can include vendor-defined algorithms, extra functions, etc. */
+#include "crypto_extra.h"
+
+#endif /* PSA_CRYPTO_H */
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
new file mode 100644
index 0000000..c587eb2
--- /dev/null
+++ b/include/psa/crypto_extra.h
@@ -0,0 +1,51 @@
+/**
+ * \file psa/crypto_extra.h
+ *
+ * \brief PSA cryptography module: Mbed Crypto vendor extensions
+ *
+ * \note This file may not be included directly. Applications must
+ * include psa/crypto.h.
+ *
+ * This file is reserved for vendor-specific definitions.
+ */
+/*
+ * Copyright (C) 2018, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+#ifndef PSA_CRYPTO_EXTRA_H
+#define PSA_CRYPTO_EXTRA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Library deinitialization.
+ *
+ * This function clears all data associated with the PSA layer,
+ * including the whole key store.
+ *
+ * This is an Mbed Crypto extension.
+ */
+void mbedcrypto_psa_crypto_free( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PSA_CRYPTO_EXTRA_H */
diff --git a/include/psa/crypto_platform.h b/include/psa/crypto_platform.h
new file mode 100644
index 0000000..69ccd56
--- /dev/null
+++ b/include/psa/crypto_platform.h
@@ -0,0 +1,52 @@
+/**
+ * \file psa/crypto_platform.h
+ *
+ * \brief PSA cryptography module: Mbed Crypto platfom definitions
+ *
+ * \note This file may not be included directly. Applications must
+ * include psa/crypto.h.
+ *
+ * This file contains platform-dependent type definitions.
+ *
+ * In implementations with isolation between the application and the
+ * cryptography module, implementers should take care to ensure that
+ * the definitions that are exposed to applications match what the
+ * module implements.
+ */
+/*
+ * Copyright (C) 2018, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+#ifndef PSA_CRYPTO_PLATFORM_H
+#define PSA_CRYPTO_PLATFORM_H
+
+/* Include the Mbed Crypto configuration file, the way Mbed Crypto does it
+ * in each of its header files. */
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "../mbedcrypto/config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+/* PSA requires several types which C99 provides in stdint.h. */
+#include <stdint.h>
+
+/* Integral type representing a key slot number. */
+typedef uint16_t psa_key_slot_t;
+
+#endif /* PSA_CRYPTO_PLATFORM_H */
diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h
new file mode 100644
index 0000000..9a0ae59
--- /dev/null
+++ b/include/psa/crypto_sizes.h
@@ -0,0 +1,308 @@
+/**
+ * \file psa/crypto_sizes.h
+ *
+ * \brief PSA cryptography module: Mbed Crypto buffer size macros
+ *
+ * \note This file may not be included directly. Applications must
+ * include psa/crypto.h.
+ *
+ * This file contains the definitions of macros that are useful to
+ * compute buffer sizes. The signatures and semantics of these macros
+ * are standardized, but the definitions are not, because they depend on
+ * the available algorithms and, in some cases, on permitted tolerances
+ * on buffer sizes.
+ *
+ * In implementations with isolation between the application and the
+ * cryptography module, implementers should take care to ensure that
+ * the definitions that are exposed to applications match what the
+ * module implements.
+ *
+ * Macros that compute sizes whose values do not depend on the
+ * implementation are in crypto.h.
+ */
+/*
+ * Copyright (C) 2018, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+#ifndef PSA_CRYPTO_SIZES_H
+#define PSA_CRYPTO_SIZES_H
+
+/* Include the Mbed Crypto configuration file, the way Mbed Crypto does it
+ * in each of its header files. */
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "../mbedcrypto/config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+/** \def PSA_HASH_MAX_SIZE
+ *
+ * Maximum size of a hash.
+ *
+ * This macro must expand to a compile-time constant integer. This value
+ * should be the maximum size of a hash supported by the implementation,
+ * in bytes, and must be no smaller than this maximum.
+ */
+#if defined(MBEDCRYPTO_SHA512_C)
+#define PSA_HASH_MAX_SIZE 64
+#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 128
+#else
+#define PSA_HASH_MAX_SIZE 32
+#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 64
+#endif
+
+/** \def PSA_MAC_MAX_SIZE
+ *
+ * Maximum size of a MAC.
+ *
+ * This macro must expand to a compile-time constant integer. This value
+ * should be the maximum size of a MAC supported by the implementation,
+ * in bytes, and must be no smaller than this maximum.
+ */
+/* All non-HMAC MACs have a maximum size that's smaller than the
+ * minimum possible value of PSA_HASH_MAX_SIZE in this implementation. */
+#define PSA_MAC_MAX_SIZE PSA_HASH_MAX_SIZE
+
+/* The maximum size of an RSA key on this implementation, in bits.
+ * This is a vendor-specific macro.
+ *
+ * Mbed Crypto does not set a hard limit on the size of RSA keys: any key
+ * whose parameters fit in a bignum is accepted. However large keys can
+ * induce a large memory usage and long computation times. Unlike other
+ * auxiliary macros in this file and in crypto.h, which reflect how the
+ * library is configured, this macro defines how the library is
+ * configured. This implementation refuses to import or generate an
+ * RSA key whose size is larger than the value defined here.
+ *
+ * Note that an implementation may set different size limits for different
+ * operations, and does not need to accept all key sizes up to the limit. */
+#define PSA_VENDOR_RSA_MAX_KEY_BITS 4096
+
+/* The maximum size of an ECC key on this implementation, in bits.
+ * This is a vendor-specific macro. */
+#if defined(MBEDCRYPTO_ECP_DP_SECP521R1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 521
+#elif defined(MBEDCRYPTO_ECP_DP_BP512R1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 512
+#elif defined(MBEDCRYPTO_ECP_DP_CURVE448_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 448
+#elif defined(MBEDCRYPTO_ECP_DP_SECP384R1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 384
+#elif defined(MBEDCRYPTO_ECP_DP_BP384R1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 384
+#elif defined(MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 256
+#elif defined(MBEDCRYPTO_ECP_DP_SECP256K1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 256
+#elif defined(MBEDCRYPTO_ECP_DP_BP256R1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 256
+#elif defined(MBEDCRYPTO_ECP_DP_CURVE25519_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 255
+#elif defined(MBEDCRYPTO_ECP_DP_SECP224R1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 224
+#elif defined(MBEDCRYPTO_ECP_DP_SECP224K1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 224
+#elif defined(MBEDCRYPTO_ECP_DP_SECP192R1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 192
+#elif defined(MBEDCRYPTO_ECP_DP_SECP192K1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 192
+#else
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 0
+#endif
+
+/** \def PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE
+ *
+ * Maximum size of an asymmetric signature.
+ *
+ * This macro must expand to a compile-time constant integer. This value
+ * should be the maximum size of a MAC supported by the implementation,
+ * in bytes, and must be no smaller than this maximum.
+ */
+#define PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE \
+ PSA_BITS_TO_BYTES( \
+ PSA_VENDOR_RSA_MAX_KEY_BITS > PSA_VENDOR_ECC_MAX_CURVE_BITS ? \
+ PSA_VENDOR_RSA_MAX_KEY_BITS : \
+ PSA_VENDOR_ECC_MAX_CURVE_BITS \
+ )
+
+
+
+/** The size of the output of psa_mac_sign_finish(), in bytes.
+ *
+ * This is also the MAC size that psa_mac_verify_finish() expects.
+ *
+ * \param key_type The type of the MAC key.
+ * \param key_bits The size of the MAC key in bits.
+ * \param alg A MAC algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_MAC(alg) is true).
+ *
+ * \return The MAC size for the specified algorithm with
+ * the specified key parameters.
+ * \return 0 if the MAC algorithm is not recognized.
+ * \return Either 0 or the correct size for a MAC algorithm that
+ * the implementation recognizes, but does not support.
+ * \return Unspecified if the key parameters are not consistent
+ * with the algorithm.
+ */
+#define PSA_MAC_FINAL_SIZE(key_type, key_bits, alg) \
+ (PSA_ALG_IS_HMAC(alg) ? PSA_HASH_SIZE(PSA_ALG_HMAC_HASH(alg)) : \
+ PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) ? PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) : \
+ 0)
+
+/** The maximum size of the output of psa_aead_encrypt(), in bytes.
+ *
+ * If the size of the ciphertext buffer is at least this large, it is
+ * guaranteed that psa_aead_encrypt() will not fail due to an
+ * insufficient buffer size. Depending on the algorithm, the actual size of
+ * the ciphertext may be smaller.
+ *
+ * \param alg An AEAD algorithm
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_AEAD(alg) is true).
+ * \param plaintext_length Size of the plaintext in bytes.
+ *
+ * \return The AEAD ciphertext size for the specified
+ * algorithm.
+ * If the AEAD algorithm is not recognized, return 0.
+ * An implementation may return either 0 or a
+ * correct size for an AEAD algorithm that it
+ * recognizes, but does not support.
+ */
+#define PSA_AEAD_ENCRYPT_OUTPUT_SIZE(alg, plaintext_length) \
+ (PSA_AEAD_TAG_SIZE(alg) != 0 ? \
+ (plaintext_length) + PSA_AEAD_TAG_SIZE(alg) : \
+ 0)
+
+/** The maximum size of the output of psa_aead_decrypt(), in bytes.
+ *
+ * If the size of the plaintext buffer is at least this large, it is
+ * guaranteed that psa_aead_decrypt() will not fail due to an
+ * insufficient buffer size. Depending on the algorithm, the actual size of
+ * the plaintext may be smaller.
+ *
+ * \param alg An AEAD algorithm
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_AEAD(alg) is true).
+ * \param ciphertext_length Size of the plaintext in bytes.
+ *
+ * \return The AEAD ciphertext size for the specified
+ * algorithm.
+ * If the AEAD algorithm is not recognized, return 0.
+ * An implementation may return either 0 or a
+ * correct size for an AEAD algorithm that it
+ * recognizes, but does not support.
+ */
+#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length) \
+ (PSA_AEAD_TAG_SIZE(alg) != 0 ? \
+ (plaintext_length) - PSA_AEAD_TAG_SIZE(alg) : \
+ 0)
+
+/** Safe signature buffer size for psa_asymmetric_sign().
+ *
+ * This macro returns a safe buffer size for a signature using a key
+ * of the specified type and size, with the specified algorithm.
+ * Note that the actual size of the signature may be smaller
+ * (some algorithms produce a variable-size signature).
+ *
+ * \warning This function may call its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * \param key_type An asymmetric key type (this may indifferently be a
+ * key pair type or a public key type).
+ * \param key_bits The size of the key in bits.
+ * \param alg The signature algorithm.
+ *
+ * \return If the parameters are valid and supported, return
+ * a buffer size in bytes that guarantees that
+ * psa_asymmetric_sign() will not fail with
+ * #PSA_ERROR_BUFFER_TOO_SMALL.
+ * If the parameters are a valid combination that is not supported
+ * by the implementation, this macro either shall return either a
+ * sensible size or 0.
+ * If the parameters are not valid, the
+ * return value is unspecified.
+ */
+#define PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE(key_type, key_bits, alg) \
+ (PSA_KEY_TYPE_IS_RSA(key_type) ? ((void)alg, PSA_BITS_TO_BYTES(key_bits)) : \
+ PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_ECDSA_SIGNATURE_SIZE(key_bits) : \
+ ((void)alg, 0))
+
+/** Safe output buffer size for psa_asymmetric_encrypt().
+ *
+ * This macro returns a safe buffer size for a ciphertext produced using
+ * a key of the specified type and size, with the specified algorithm.
+ * Note that the actual size of the ciphertext may be smaller, depending
+ * on the algorithm.
+ *
+ * \warning This function may call its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * \param key_type An asymmetric key type (this may indifferently be a
+ * key pair type or a public key type).
+ * \param key_bits The size of the key in bits.
+ * \param alg The signature algorithm.
+ *
+ * \return If the parameters are valid and supported, return
+ * a buffer size in bytes that guarantees that
+ * psa_asymmetric_encrypt() will not fail with
+ * #PSA_ERROR_BUFFER_TOO_SMALL.
+ * If the parameters are a valid combination that is not supported
+ * by the implementation, this macro either shall return either a
+ * sensible size or 0.
+ * If the parameters are not valid, the
+ * return value is unspecified.
+ */
+#define PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(key_type, key_bits, alg) \
+ (PSA_KEY_TYPE_IS_RSA(key_type) ? \
+ ((void)alg, PSA_BITS_TO_BYTES(key_bits)) : \
+ 0)
+
+/** Safe output buffer size for psa_asymmetric_decrypt().
+ *
+ * This macro returns a safe buffer size for a ciphertext produced using
+ * a key of the specified type and size, with the specified algorithm.
+ * Note that the actual size of the ciphertext may be smaller, depending
+ * on the algorithm.
+ *
+ * \warning This function may call its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * \param key_type An asymmetric key type (this may indifferently be a
+ * key pair type or a public key type).
+ * \param key_bits The size of the key in bits.
+ * \param alg The signature algorithm.
+ *
+ * \return If the parameters are valid and supported, return
+ * a buffer size in bytes that guarantees that
+ * psa_asymmetric_decrypt() will not fail with
+ * #PSA_ERROR_BUFFER_TOO_SMALL.
+ * If the parameters are a valid combination that is not supported
+ * by the implementation, this macro either shall return either a
+ * sensible size or 0.
+ * If the parameters are not valid, the
+ * return value is unspecified.
+ */
+#define PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(key_type, key_bits, alg) \
+ (PSA_KEY_TYPE_IS_RSA(key_type) ? \
+ PSA_BITS_TO_BYTES(key_bits) - PSA_RSA_MINIMUM_PADDING_SIZE(alg) : \
+ 0)
+
+#endif /* PSA_CRYPTO_SIZES_H */
diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h
new file mode 100644
index 0000000..5769a0c
--- /dev/null
+++ b/include/psa/crypto_struct.h
@@ -0,0 +1,177 @@
+/**
+ * \file psa/crypto_struct.h
+ *
+ * \brief PSA cryptography module: Mbed Crypto structured type implementations
+ *
+ * \note This file may not be included directly. Applications must
+ * include psa/crypto.h.
+ *
+ * This file contains the definitions of some data structures with
+ * implementation-specific definitions.
+ *
+ * In implementations with isolation between the application and the
+ * cryptography module, it is expected that the front-end and the back-end
+ * would have different versions of this file.
+ */
+/*
+ * Copyright (C) 2018, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+#ifndef PSA_CRYPTO_STRUCT_H
+#define PSA_CRYPTO_STRUCT_H
+
+/* Include the Mbed Crypto configuration file, the way Mbed Crypto does it
+ * in each of its header files. */
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "../mbedcrypto/config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#include "mbedcrypto/cipher.h"
+#include "mbedcrypto/cmac.h"
+#include "mbedcrypto/gcm.h"
+#include "mbedcrypto/md.h"
+#include "mbedcrypto/md2.h"
+#include "mbedcrypto/md4.h"
+#include "mbedcrypto/md5.h"
+#include "mbedcrypto/ripemd160.h"
+#include "mbedcrypto/sha1.h"
+#include "mbedcrypto/sha256.h"
+#include "mbedcrypto/sha512.h"
+
+struct psa_hash_operation_s
+{
+ psa_algorithm_t alg;
+ union
+ {
+ unsigned dummy; /* Make the union non-empty even with no supported algorithms. */
+#if defined(MBEDCRYPTO_MD2_C)
+ mbedcrypto_md2_context md2;
+#endif
+#if defined(MBEDCRYPTO_MD4_C)
+ mbedcrypto_md4_context md4;
+#endif
+#if defined(MBEDCRYPTO_MD5_C)
+ mbedcrypto_md5_context md5;
+#endif
+#if defined(MBEDCRYPTO_RIPEMD160_C)
+ mbedcrypto_ripemd160_context ripemd160;
+#endif
+#if defined(MBEDCRYPTO_SHA1_C)
+ mbedcrypto_sha1_context sha1;
+#endif
+#if defined(MBEDCRYPTO_SHA256_C)
+ mbedcrypto_sha256_context sha256;
+#endif
+#if defined(MBEDCRYPTO_SHA512_C)
+ mbedcrypto_sha512_context sha512;
+#endif
+ } ctx;
+};
+
+
+typedef struct
+{
+ /** The hash context. */
+ struct psa_hash_operation_s hash_ctx;
+ /** The HMAC part of the context. */
+ uint8_t opad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
+} psa_hmac_internal_data;
+
+
+struct psa_mac_operation_s
+{
+ psa_algorithm_t alg;
+ unsigned int key_set : 1;
+ unsigned int iv_required : 1;
+ unsigned int iv_set : 1;
+ unsigned int has_input : 1;
+ unsigned int is_sign : 1;
+ uint8_t mac_size;
+ union
+ {
+ unsigned dummy; /* Make the union non-empty even with no supported algorithms. */
+#if defined(MBEDCRYPTO_MD_C)
+ psa_hmac_internal_data hmac;
+#endif
+#if defined(MBEDCRYPTO_CMAC_C)
+ mbedcrypto_cipher_context_t cmac;
+#endif
+ } ctx;
+};
+
+struct psa_cipher_operation_s
+{
+ psa_algorithm_t alg;
+ unsigned int key_set : 1;
+ unsigned int iv_required : 1;
+ unsigned int iv_set : 1;
+ uint8_t iv_size;
+ uint8_t block_size;
+ union
+ {
+ mbedcrypto_cipher_context_t cipher;
+ } ctx;
+};
+
+typedef struct
+{
+ uint8_t *info;
+ size_t info_length;
+ psa_hmac_internal_data hmac;
+ uint8_t prk[PSA_HASH_MAX_SIZE];
+ uint8_t output_block[PSA_HASH_MAX_SIZE];
+#if PSA_HASH_MAX_SIZE > 0xff
+#error "PSA_HASH_MAX_SIZE does not fit in uint8_t"
+#endif
+ uint8_t offset_in_block;
+ uint8_t block_number;
+} psa_hkdf_generator_t;
+
+struct psa_crypto_generator_s
+{
+ psa_algorithm_t alg;
+ size_t capacity;
+ union
+ {
+ struct
+ {
+ uint8_t *data;
+ size_t size;
+ } buffer;
+#if defined(MBEDCRYPTO_MD_C)
+ psa_hkdf_generator_t hkdf;
+#endif
+ } ctx;
+};
+
+#define PSA_CRYPTO_GENERATOR_INIT {0, 0, {{0, 0}}}
+static inline struct psa_crypto_generator_s psa_crypto_generator_init( void )
+{
+ const struct psa_crypto_generator_s v = PSA_CRYPTO_GENERATOR_INIT;
+ return( v );
+}
+
+struct psa_key_policy_s
+{
+ psa_key_usage_t usage;
+ psa_algorithm_t alg;
+};
+
+#endif /* PSA_CRYPTO_STRUCT_H */