Add SHA1, SHA256, AES CBC and etc. tests for MBed-TLS, modified kconfig to enable selection of

whether to compile test code when build for board ok1052-c.
This commit is contained in:
Ruoqing He 2022-10-04 03:37:35 -07:00
parent 4167f1f0f9
commit 7079f86acb
157 changed files with 33847 additions and 40227 deletions

View File

@ -24,5 +24,11 @@ endif
menuconfig MBEDTLS
bool "using mbedtls"
default n
select MBEDTLS_ENABLE
if MBEDTLS
menuconfig ENABLE_MBEDTLS_TEST
bool "enable test"
default n
endif
endmenu

View File

@ -1,5 +1,14 @@
SRC_FILES := aes.c aria.c asn1parse.c asn1write.c base64.c bignum.c certs.c cipher.c cmac.c ctr_drbg.c dhm.c ecp.c \
entropy.c files.txt md5.c md.c oid.c pem.c pk.c pkcs12.c pkcs5.c pkparse.c rsa.c rsa_internal.c sha1.c \
sha256.c ssl_cli.c ssl_srv.c ssl_tls.c
SRC_FILES := aes.c aesni.c arc4.c asn1parse.c asn1write.c base64.c bignum.c blowfish.c camellia.c \
ccm.c certs.c cipher.c cipher_wrap.c cmac.c ctr_drbg.c debug.c des.c dhm.c ecdh.c ecdsa.c ecjpake.c \
ecp.c ecp_curves.c entropy.c entropy_poll.c error.c gcm.c havege.c hmac_drbg.c md2.c md4.c md5.c md.c \
md_wrap.c memory_buffer_alloc.c net_sockets.c oid.c padlock.c pem.c pk.c pkcs11.c pkcs12.c pkcs5.c \
pkparse.c pk_wrap.c pkwrite.c platform.c ripemd160.c rsa.c rsa_internal.c sha1.c sha256.c sha512.c \
ssl_cache.c ssl_ciphersuites.c ssl_cli.c ssl_cookie.c ssl_srv.c ssl_ticket.c ssl_tls.c threading.c \
version.c version_features.c x509.c x509_create.c x509_crl.c x509_csr.c \
x509write_crt.c x509write_csr.c xtea.c # timing_alt.c tls_hardware.c
ifeq ($(CONFIG_ENABLE_MBEDTLS_TEST), y)
SRC_FILES += test.c
endif
include $(KERNEL_ROOT)/compiler.mk

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,7 @@
/**
* \file aes.h
*
* \brief This file contains AES definitions and functions.
*
* The Advanced Encryption Standard (AES) specifies a FIPS-approved
* \brief The Advanced Encryption Standard (AES) specifies a FIPS-approved
* cryptographic algorithm that can be used to protect electronic
* data.
*
@ -13,13 +11,7 @@
* <em>ISO/IEC 18033-2:2006: Information technology -- Security
* techniques -- Encryption algorithms -- Part 2: Asymmetric
* ciphers</em>.
*
* The AES-XTS block mode is standardized by NIST SP 800-38E
* <https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-38e.pdf>
* and described in detail by IEEE P1619
* <https://ieeexplore.ieee.org/servlet/opac?punumber=4375278>.
*/
/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*
@ -58,13 +50,8 @@
#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
/* Error codes in range 0x0021-0x0025 */
#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021 /**< Invalid input data. */
/* MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE is deprecated and should not be used. */
/* Error codes in range 0x0023-0x0025 */
#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE -0x0023 /**< Feature not available. For example, an unsupported AES key size. */
/* MBEDTLS_ERR_AES_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_AES_HW_ACCEL_FAILED -0x0025 /**< AES hardware accelerator failed. */
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
@ -72,34 +59,21 @@
#define inline __inline
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_AES_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief The AES context-type definition.
*/
#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
#define MBEDTLS_AES_128_EXPANDED_KEY_SIZE_IN_WORDS 44
#endif
typedef struct mbedtls_aes_context
typedef struct
{
int nr; /*!< The number of rounds. */
uint32_t *rk; /*!< AES round keys. */
#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
uint32_t frk[8]; /*!< Fake AES round keys. */
#endif
#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
uint32_t hash; /*!< hash of the set key */
#endif
#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) && !defined(MBEDTLS_PADLOCK_C)
uint32_t buf[MBEDTLS_AES_128_EXPANDED_KEY_SIZE_IN_WORDS]; /*!< Unaligned data buffer for expanded key only */
#else /* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
uint32_t buf[68]; /*!< Unaligned data buffer. This buffer can
hold 32 extra Bytes, which can be used for
one of the following purposes:
@ -108,34 +82,16 @@ typedef struct mbedtls_aes_context
<li>Simplifying key expansion in the 256-bit
case by generating an extra round key.
</li></ul> */
#endif /* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
}
mbedtls_aes_context;
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/**
* \brief The AES XTS context-type definition.
*/
typedef struct mbedtls_aes_xts_context
{
mbedtls_aes_context crypt; /*!< The AES context to use for AES block
encryption or decryption. */
mbedtls_aes_context tweak; /*!< The AES context used for tweak
computation. */
} mbedtls_aes_xts_context;
#endif /* MBEDTLS_CIPHER_MODE_XTS */
#else /* MBEDTLS_AES_ALT */
#include "aes_alt.h"
#endif /* MBEDTLS_AES_ALT */
/**
* \brief This function initializes the specified AES context.
*
* It must be the first API called before using
* the context.
*
* \param ctx The AES context to initialize. This must not be \c NULL.
* \param ctx The AES context to initialize.
*/
void mbedtls_aes_init( mbedtls_aes_context *ctx );
@ -143,47 +99,21 @@ void mbedtls_aes_init( mbedtls_aes_context *ctx );
* \brief This function releases and clears the specified AES context.
*
* \param ctx The AES context to clear.
* If this is \c NULL, this function does nothing.
* Otherwise, the context must have been at least initialized.
*/
void mbedtls_aes_free( mbedtls_aes_context *ctx );
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/**
* \brief This function initializes the specified AES XTS context.
*
* It must be the first API called before using
* the context.
*
* \param ctx The AES XTS context to initialize. This must not be \c NULL.
*/
void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx );
/**
* \brief This function releases and clears the specified AES XTS context.
*
* \param ctx The AES XTS context to clear.
* If this is \c NULL, this function does nothing.
* Otherwise, the context must have been at least initialized.
*/
void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx );
#endif /* MBEDTLS_CIPHER_MODE_XTS */
/**
* \brief This function sets the encryption key.
*
* \param ctx The AES context to which the key should be bound.
* It must be initialized.
* \param key The encryption key.
* This must be a readable buffer of size \p keybits bits.
* \param keybits The size of data passed in bits. Valid options are:
* <ul><li>128 bits</li>
* <li>192 bits</li>
* <li>256 bits</li></ul>
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH or
* #MBEDTLS_ERR_PLATFORM_FAULT_DETECTED on failure.
* \return \c 0 on success or #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
* on failure.
*/
int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits );
@ -192,63 +122,17 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
* \brief This function sets the decryption key.
*
* \param ctx The AES context to which the key should be bound.
* It must be initialized.
* \param key The decryption key.
* This must be a readable buffer of size \p keybits bits.
* \param keybits The size of data passed. Valid options are:
* <ul><li>128 bits</li>
* <li>192 bits</li>
* <li>256 bits</li></ul>
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH or
* #MBEDTLS_ERR_PLATFORM_FAULT_DETECTED on failure.
* \return \c 0 on success, or #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
*/
int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits );
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/**
* \brief This function prepares an XTS context for encryption and
* sets the encryption key.
*
* \param ctx The AES XTS context to which the key should be bound.
* It must be initialized.
* \param key The encryption key. This is comprised of the XTS key1
* concatenated with the XTS key2.
* This must be a readable buffer of size \p keybits bits.
* \param keybits The size of \p key passed in bits. Valid options are:
* <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
* <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
*/
int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
const unsigned char *key,
unsigned int keybits );
/**
* \brief This function prepares an XTS context for decryption and
* sets the decryption key.
*
* \param ctx The AES XTS context to which the key should be bound.
* It must be initialized.
* \param key The decryption key. This is comprised of the XTS key1
* concatenated with the XTS key2.
* This must be a readable buffer of size \p keybits bits.
* \param keybits The size of \p key passed in bits. Valid options are:
* <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
* <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
*/
int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
const unsigned char *key,
unsigned int keybits );
#endif /* MBEDTLS_CIPHER_MODE_XTS */
/**
* \brief This function performs an AES single-block encryption or
* decryption operation.
@ -262,13 +146,10 @@ int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
* call to this API with the same context.
*
* \param ctx The AES context to use for encryption or decryption.
* It must be initialized and bound to a key.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT.
* \param input The buffer holding the input data.
* It must be readable and at least \c 16 Bytes long.
* \param output The buffer where the output data will be written.
* It must be writeable and at least \c 16 Bytes long.
* \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.
*/
@ -291,8 +172,8 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
* mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called
* before the first call to this API with the same context.
*
* \note This function operates on full blocks, that is, the input size
* must be a multiple of the AES block size of \c 16 Bytes.
* \note 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
@ -303,20 +184,15 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
*
*
* \param ctx The AES context to use for encryption or decryption.
* It must be initialized and bound to a key.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT.
* \param length The length of the input data in Bytes. This must be a
* multiple of the block size (\c 16 Bytes).
* multiple of the block size (16 Bytes).
* \param iv Initialization vector (updated after use).
* It must be a readable and writeable buffer of \c 16 Bytes.
* \param input The buffer holding the input data.
* It must be readable and of size \p length Bytes.
* \param output The buffer holding the output data.
* It must be writeable and of size \p length Bytes.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
* \return \c 0 on success, or #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
* on failure.
*/
int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
@ -327,50 +203,6 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/**
* \brief This function performs an AES-XTS encryption or decryption
* operation for an entire XTS data unit.
*
* AES-XTS encrypts or decrypts blocks based on their location as
* defined by a data unit number. The data unit number must be
* provided by \p data_unit.
*
* NIST SP 800-38E limits the maximum size of a data unit to 2^20
* AES blocks. If the data unit is larger than this, this function
* returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH.
*
* \param ctx The AES XTS context to use for AES XTS operations.
* It must be initialized and bound to a key.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT.
* \param length The length of a data unit in Bytes. This can be any
* length between 16 bytes and 2^24 bytes inclusive
* (between 1 and 2^20 block cipher blocks).
* \param data_unit The address of the data unit encoded as an array of 16
* bytes in little-endian format. For disk encryption, this
* is typically the index of the block device sector that
* contains the data.
* \param input The buffer holding the input data (which is an entire
* data unit). This function reads \p length Bytes from \p
* input.
* \param output The buffer holding the output data (which is an entire
* data unit). This function writes \p length Bytes to \p
* output.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is
* smaller than an AES block in size (16 Bytes) or if \p
* length is larger than 2^20 blocks (16 MiB).
*/
int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
int mode,
size_t length,
const unsigned char data_unit[16],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_XTS */
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/**
* \brief This function performs an AES-CFB128 encryption or decryption
@ -396,18 +228,13 @@ int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
*
*
* \param ctx The AES context to use for encryption or decryption.
* It must be initialized and bound to a key.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT.
* \param length The length of the input data in Bytes.
* \param length The length of the input data.
* \param iv_off The offset in IV (updated after use).
* It must point to a valid \c size_t.
* \param iv The initialization vector (updated after use).
* It must be a readable and writeable buffer of \c 16 Bytes.
* \param input The buffer holding the input data.
* It must be readable and of size \p length Bytes.
* \param output The buffer holding the output data.
* It must be writeable and of size \p length Bytes.
*
* \return \c 0 on success.
*/
@ -442,16 +269,12 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
*
*
* \param ctx The AES context to use for encryption or decryption.
* It must be initialized and bound to a key.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT
* \param length The length of the input data.
* \param iv The initialization vector (updated after use).
* It must be a readable and writeable buffer of \c 16 Bytes.
* \param input The buffer holding the input data.
* It must be readable and of size \p length Bytes.
* \param output The buffer holding the output data.
* It must be writeable and of size \p length Bytes.
*
* \return \c 0 on success.
*/
@ -463,61 +286,6 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
unsigned char *output );
#endif /*MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_OFB)
/**
* \brief This function performs an AES-OFB (Output Feedback Mode)
* encryption or decryption operation.
*
* For OFB, you must set up the context with
* mbedtls_aes_setkey_enc(), regardless of whether you are
* performing an encryption or decryption operation. This is
* because OFB mode uses the same key schedule for encryption and
* decryption.
*
* The OFB operation is identical for encryption or decryption,
* therefore no operation mode needs to be specified.
*
* \note Upon exit, the content of iv, the Initialisation Vector, is
* updated so that you can call the same function again on the next
* block(s) of data and get the same result as if it was encrypted
* in one call. This allows a "streaming" usage, by initialising
* iv_off to 0 before the first call, and preserving its value
* between calls.
*
* For non-streaming use, the iv should be initialised on each call
* to a unique value, and iv_off set to 0 on each call.
*
* If you need to retain the contents of the initialisation vector,
* you must either save it manually or use the cipher module
* instead.
*
* \warning For the OFB mode, the initialisation vector must be unique
* every encryption operation. Reuse of an initialisation vector
* will compromise security.
*
* \param ctx The AES context to use for encryption or decryption.
* It must be initialized and bound to a key.
* \param length The length of the input data.
* \param iv_off The offset in IV (updated after use).
* It must point to a valid \c size_t.
* \param iv The initialization vector (updated after use).
* It must be a readable and writeable buffer of \c 16 Bytes.
* \param input The buffer holding the input data.
* It must be readable and of size \p length Bytes.
* \param output The buffer holding the output data.
* It must be writeable and of size \p length Bytes.
*
* \return \c 0 on success.
*/
int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
size_t length,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_OFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/**
* \brief This function performs an AES-CTR encryption or decryption
@ -532,68 +300,20 @@ int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
* must use the context initialized with mbedtls_aes_setkey_enc()
* for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT.
*
* \warning You must never reuse a nonce value with the same key. Doing so
* would void the encryption for the two messages encrypted with
* the same nonce and key.
*
* There are two common strategies for managing nonces with CTR:
*
* 1. You can handle everything as a single message processed over
* successive calls to this function. In that case, you want to
* set \p nonce_counter and \p nc_off to 0 for the first call, and
* then preserve the values of \p nonce_counter, \p nc_off and \p
* stream_block across calls to this function as they will be
* updated by this function.
*
* With this strategy, you must not encrypt more than 2**128
* blocks of data with the same key.
*
* 2. You can encrypt separate messages by dividing the \p
* nonce_counter buffer in two areas: the first one used for a
* per-message nonce, handled by yourself, and the second one
* updated by this function internally.
*
* For example, you might reserve the first 12 bytes for the
* per-message nonce, and the last 4 bytes for internal use. In that
* case, before calling this function on a new message you need to
* set the first 12 bytes of \p nonce_counter to your chosen nonce
* value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
* stream_block to be ignored). That way, you can encrypt at most
* 2**96 messages of up to 2**32 blocks each with the same key.
*
* The per-message nonce (or information sufficient to reconstruct
* it) needs to be communicated with the ciphertext and must be unique.
* The recommended way to ensure uniqueness is to use a message
* counter. An alternative is to generate random nonces, but this
* limits the number of messages that can be securely encrypted:
* for example, with 96-bit random nonces, you should not encrypt
* more than 2**32 messages with the same key.
*
* Note that for both stategies, sizes are measured in blocks and
* that an AES block is 16 bytes.
*
* \warning Upon return, \p stream_block contains sensitive data. Its
* content must not be written to insecure storage and should be
* securely discarded as soon as it's no longer needed.
* \warning You must keep the maximum use of your counter in mind.
*
* \param ctx The AES context to use for encryption or decryption.
* It must be initialized and bound to a key.
* \param length The length of the input data.
* \param nc_off The offset in the current \p stream_block, for
* resuming within the current cipher stream. The
* offset pointer should be 0 at the start of a stream.
* It must point to a valid \c size_t.
* \param nonce_counter The 128-bit nonce and counter.
* It must be a readable-writeable buffer of \c 16 Bytes.
* \param stream_block The saved stream block for resuming. This is
* overwritten by the function.
* It must be a readable-writeable buffer of \c 16 Bytes.
* \param input The buffer holding the input data.
* It must be readable and of size \p length Bytes.
* \param output The buffer holding the output data.
* It must be writeable and of size \p length Bytes.
*
* \return \c 0 on success.
* \return \c 0 on success.
*/
int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
size_t length,
@ -614,7 +334,6 @@ int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
* \param output The output (ciphertext) block.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_PLATFORM_FAULT_DETECTED in case of error.
*/
int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
@ -630,7 +349,6 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
* \param output The output (plaintext) block.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_PLATFORM_FAULT_DETECTED in case of error.
*/
int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
@ -646,7 +364,7 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
* \brief Deprecated internal AES block encryption function
* without return value.
*
* \deprecated Superseded by mbedtls_internal_aes_encrypt()
* \deprecated Superseded by mbedtls_aes_encrypt_ext() in 2.5.0.
*
* \param ctx The AES context to use for encryption.
* \param input Plaintext block.
@ -660,7 +378,7 @@ MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
* \brief Deprecated internal AES block decryption function
* without return value.
*
* \deprecated Superseded by mbedtls_internal_aes_decrypt()
* \deprecated Superseded by mbedtls_aes_decrypt_ext() in 2.5.0.
*
* \param ctx The AES context to use for decryption.
* \param input Ciphertext block.
@ -673,18 +391,25 @@ MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_AES_ALT */
#include "aes_alt.h"
#endif /* MBEDTLS_AES_ALT */
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
* \return \c 0 on success, or \c 1 on failure.
*/
int mbedtls_aes_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,464 @@
/*
* AES-NI support 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 TLS (https://tls.mbed.org)
*/
/*
* [AES-WP] http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-aes-instructions-set
* [CLMUL-WP] http://software.intel.com/en-us/articles/intel-carry-less-multiplication-instruction-and-its-usage-for-computing-the-gcm-mode/
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_AESNI_C)
#include "aesni.h"
#include <string.h>
#ifndef asm
#define asm __asm
#endif
#if defined(MBEDTLS_HAVE_X86_64)
/*
* AES-NI support detection routine
*/
int mbedtls_aesni_has_support( unsigned int what )
{
static int done = 0;
static unsigned int c = 0;
if( ! done )
{
asm( "movl $1, %%eax \n\t"
"cpuid \n\t"
: "=c" (c)
:
: "eax", "ebx", "edx" );
done = 1;
}
return( ( c & what ) != 0 );
}
/*
* Binutils needs to be at least 2.19 to support AES-NI instructions.
* Unfortunately, a lot of users have a lower version now (2014-04).
* Emit bytecode directly in order to support "old" version of gas.
*
* Opcodes from the Intel architecture reference manual, vol. 3.
* We always use registers, so we don't need prefixes for memory operands.
* Operand macros are in gas order (src, dst) as opposed to Intel order
* (dst, src) in order to blend better into the surrounding assembly code.
*/
#define AESDEC ".byte 0x66,0x0F,0x38,0xDE,"
#define AESDECLAST ".byte 0x66,0x0F,0x38,0xDF,"
#define AESENC ".byte 0x66,0x0F,0x38,0xDC,"
#define AESENCLAST ".byte 0x66,0x0F,0x38,0xDD,"
#define AESIMC ".byte 0x66,0x0F,0x38,0xDB,"
#define AESKEYGENA ".byte 0x66,0x0F,0x3A,0xDF,"
#define PCLMULQDQ ".byte 0x66,0x0F,0x3A,0x44,"
#define xmm0_xmm0 "0xC0"
#define xmm0_xmm1 "0xC8"
#define xmm0_xmm2 "0xD0"
#define xmm0_xmm3 "0xD8"
#define xmm0_xmm4 "0xE0"
#define xmm1_xmm0 "0xC1"
#define xmm1_xmm2 "0xD1"
/*
* AES-NI AES-ECB block en(de)cryption
*/
int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] )
{
asm( "movdqu (%3), %%xmm0 \n\t" // load input
"movdqu (%1), %%xmm1 \n\t" // load round key 0
"pxor %%xmm1, %%xmm0 \n\t" // round 0
"add $16, %1 \n\t" // point to next round key
"subl $1, %0 \n\t" // normal rounds = nr - 1
"test %2, %2 \n\t" // mode?
"jz 2f \n\t" // 0 = decrypt
"1: \n\t" // encryption loop
"movdqu (%1), %%xmm1 \n\t" // load round key
AESENC xmm1_xmm0 "\n\t" // do round
"add $16, %1 \n\t" // point to next round key
"subl $1, %0 \n\t" // loop
"jnz 1b \n\t"
"movdqu (%1), %%xmm1 \n\t" // load round key
AESENCLAST xmm1_xmm0 "\n\t" // last round
"jmp 3f \n\t"
"2: \n\t" // decryption loop
"movdqu (%1), %%xmm1 \n\t"
AESDEC xmm1_xmm0 "\n\t" // do round
"add $16, %1 \n\t"
"subl $1, %0 \n\t"
"jnz 2b \n\t"
"movdqu (%1), %%xmm1 \n\t" // load round key
AESDECLAST xmm1_xmm0 "\n\t" // last round
"3: \n\t"
"movdqu %%xmm0, (%4) \n\t" // export output
:
: "r" (ctx->nr), "r" (ctx->rk), "r" (mode), "r" (input), "r" (output)
: "memory", "cc", "xmm0", "xmm1" );
return( 0 );
}
/*
* GCM multiplication: c = a times b in GF(2^128)
* Based on [CLMUL-WP] algorithms 1 (with equation 27) and 5.
*/
void mbedtls_aesni_gcm_mult( unsigned char c[16],
const unsigned char a[16],
const unsigned char b[16] )
{
unsigned char aa[16], bb[16], cc[16];
size_t i;
/* The inputs are in big-endian order, so byte-reverse them */
for( i = 0; i < 16; i++ )
{
aa[i] = a[15 - i];
bb[i] = b[15 - i];
}
asm( "movdqu (%0), %%xmm0 \n\t" // a1:a0
"movdqu (%1), %%xmm1 \n\t" // b1:b0
/*
* Caryless multiplication xmm2:xmm1 = xmm0 * xmm1
* using [CLMUL-WP] algorithm 1 (p. 13).
*/
"movdqa %%xmm1, %%xmm2 \n\t" // copy of b1:b0
"movdqa %%xmm1, %%xmm3 \n\t" // same
"movdqa %%xmm1, %%xmm4 \n\t" // same
PCLMULQDQ xmm0_xmm1 ",0x00 \n\t" // a0*b0 = c1:c0
PCLMULQDQ xmm0_xmm2 ",0x11 \n\t" // a1*b1 = d1:d0
PCLMULQDQ xmm0_xmm3 ",0x10 \n\t" // a0*b1 = e1:e0
PCLMULQDQ xmm0_xmm4 ",0x01 \n\t" // a1*b0 = f1:f0
"pxor %%xmm3, %%xmm4 \n\t" // e1+f1:e0+f0
"movdqa %%xmm4, %%xmm3 \n\t" // same
"psrldq $8, %%xmm4 \n\t" // 0:e1+f1
"pslldq $8, %%xmm3 \n\t" // e0+f0:0
"pxor %%xmm4, %%xmm2 \n\t" // d1:d0+e1+f1
"pxor %%xmm3, %%xmm1 \n\t" // c1+e0+f1:c0
/*
* Now shift the result one bit to the left,
* taking advantage of [CLMUL-WP] eq 27 (p. 20)
*/
"movdqa %%xmm1, %%xmm3 \n\t" // r1:r0
"movdqa %%xmm2, %%xmm4 \n\t" // r3:r2
"psllq $1, %%xmm1 \n\t" // r1<<1:r0<<1
"psllq $1, %%xmm2 \n\t" // r3<<1:r2<<1
"psrlq $63, %%xmm3 \n\t" // r1>>63:r0>>63
"psrlq $63, %%xmm4 \n\t" // r3>>63:r2>>63
"movdqa %%xmm3, %%xmm5 \n\t" // r1>>63:r0>>63
"pslldq $8, %%xmm3 \n\t" // r0>>63:0
"pslldq $8, %%xmm4 \n\t" // r2>>63:0
"psrldq $8, %%xmm5 \n\t" // 0:r1>>63
"por %%xmm3, %%xmm1 \n\t" // r1<<1|r0>>63:r0<<1
"por %%xmm4, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1
"por %%xmm5, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1|r1>>63
/*
* Now reduce modulo the GCM polynomial x^128 + x^7 + x^2 + x + 1
* using [CLMUL-WP] algorithm 5 (p. 20).
* Currently xmm2:xmm1 holds x3:x2:x1:x0 (already shifted).
*/
/* Step 2 (1) */
"movdqa %%xmm1, %%xmm3 \n\t" // x1:x0
"movdqa %%xmm1, %%xmm4 \n\t" // same
"movdqa %%xmm1, %%xmm5 \n\t" // same
"psllq $63, %%xmm3 \n\t" // x1<<63:x0<<63 = stuff:a
"psllq $62, %%xmm4 \n\t" // x1<<62:x0<<62 = stuff:b
"psllq $57, %%xmm5 \n\t" // x1<<57:x0<<57 = stuff:c
/* Step 2 (2) */
"pxor %%xmm4, %%xmm3 \n\t" // stuff:a+b
"pxor %%xmm5, %%xmm3 \n\t" // stuff:a+b+c
"pslldq $8, %%xmm3 \n\t" // a+b+c:0
"pxor %%xmm3, %%xmm1 \n\t" // x1+a+b+c:x0 = d:x0
/* Steps 3 and 4 */
"movdqa %%xmm1,%%xmm0 \n\t" // d:x0
"movdqa %%xmm1,%%xmm4 \n\t" // same
"movdqa %%xmm1,%%xmm5 \n\t" // same
"psrlq $1, %%xmm0 \n\t" // e1:x0>>1 = e1:e0'
"psrlq $2, %%xmm4 \n\t" // f1:x0>>2 = f1:f0'
"psrlq $7, %%xmm5 \n\t" // g1:x0>>7 = g1:g0'
"pxor %%xmm4, %%xmm0 \n\t" // e1+f1:e0'+f0'
"pxor %%xmm5, %%xmm0 \n\t" // e1+f1+g1:e0'+f0'+g0'
// e0'+f0'+g0' is almost e0+f0+g0, ex\tcept for some missing
// bits carried from d. Now get those\t bits back in.
"movdqa %%xmm1,%%xmm3 \n\t" // d:x0
"movdqa %%xmm1,%%xmm4 \n\t" // same
"movdqa %%xmm1,%%xmm5 \n\t" // same
"psllq $63, %%xmm3 \n\t" // d<<63:stuff
"psllq $62, %%xmm4 \n\t" // d<<62:stuff
"psllq $57, %%xmm5 \n\t" // d<<57:stuff
"pxor %%xmm4, %%xmm3 \n\t" // d<<63+d<<62:stuff
"pxor %%xmm5, %%xmm3 \n\t" // missing bits of d:stuff
"psrldq $8, %%xmm3 \n\t" // 0:missing bits of d
"pxor %%xmm3, %%xmm0 \n\t" // e1+f1+g1:e0+f0+g0
"pxor %%xmm1, %%xmm0 \n\t" // h1:h0
"pxor %%xmm2, %%xmm0 \n\t" // x3+h1:x2+h0
"movdqu %%xmm0, (%2) \n\t" // done
:
: "r" (aa), "r" (bb), "r" (cc)
: "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" );
/* Now byte-reverse the outputs */
for( i = 0; i < 16; i++ )
c[i] = cc[15 - i];
return;
}
/*
* Compute decryption round keys from encryption round keys
*/
void mbedtls_aesni_inverse_key( unsigned char *invkey,
const unsigned char *fwdkey, int nr )
{
unsigned char *ik = invkey;
const unsigned char *fk = fwdkey + 16 * nr;
memcpy( ik, fk, 16 );
for( fk -= 16, ik += 16; fk > fwdkey; fk -= 16, ik += 16 )
asm( "movdqu (%0), %%xmm0 \n\t"
AESIMC xmm0_xmm0 "\n\t"
"movdqu %%xmm0, (%1) \n\t"
:
: "r" (fk), "r" (ik)
: "memory", "xmm0" );
memcpy( ik, fk, 16 );
}
/*
* Key expansion, 128-bit case
*/
static void aesni_setkey_enc_128( unsigned char *rk,
const unsigned char *key )
{
asm( "movdqu (%1), %%xmm0 \n\t" // copy the original key
"movdqu %%xmm0, (%0) \n\t" // as round key 0
"jmp 2f \n\t" // skip auxiliary routine
/*
* Finish generating the next round key.
*
* On entry xmm0 is r3:r2:r1:r0 and xmm1 is X:stuff:stuff:stuff
* with X = rot( sub( r3 ) ) ^ RCON.
*
* On exit, xmm0 is r7:r6:r5:r4
* with r4 = X + r0, r5 = r4 + r1, r6 = r5 + r2, r7 = r6 + r3
* and those are written to the round key buffer.
*/
"1: \n\t"
"pshufd $0xff, %%xmm1, %%xmm1 \n\t" // X:X:X:X
"pxor %%xmm0, %%xmm1 \n\t" // X+r3:X+r2:X+r1:r4
"pslldq $4, %%xmm0 \n\t" // r2:r1:r0:0
"pxor %%xmm0, %%xmm1 \n\t" // X+r3+r2:X+r2+r1:r5:r4
"pslldq $4, %%xmm0 \n\t" // etc
"pxor %%xmm0, %%xmm1 \n\t"
"pslldq $4, %%xmm0 \n\t"
"pxor %%xmm1, %%xmm0 \n\t" // update xmm0 for next time!
"add $16, %0 \n\t" // point to next round key
"movdqu %%xmm0, (%0) \n\t" // write it
"ret \n\t"
/* Main "loop" */
"2: \n\t"
AESKEYGENA xmm0_xmm1 ",0x01 \n\tcall 1b \n\t"
AESKEYGENA xmm0_xmm1 ",0x02 \n\tcall 1b \n\t"
AESKEYGENA xmm0_xmm1 ",0x04 \n\tcall 1b \n\t"
AESKEYGENA xmm0_xmm1 ",0x08 \n\tcall 1b \n\t"
AESKEYGENA xmm0_xmm1 ",0x10 \n\tcall 1b \n\t"
AESKEYGENA xmm0_xmm1 ",0x20 \n\tcall 1b \n\t"
AESKEYGENA xmm0_xmm1 ",0x40 \n\tcall 1b \n\t"
AESKEYGENA xmm0_xmm1 ",0x80 \n\tcall 1b \n\t"
AESKEYGENA xmm0_xmm1 ",0x1B \n\tcall 1b \n\t"
AESKEYGENA xmm0_xmm1 ",0x36 \n\tcall 1b \n\t"
:
: "r" (rk), "r" (key)
: "memory", "cc", "0" );
}
/*
* Key expansion, 192-bit case
*/
static void aesni_setkey_enc_192( unsigned char *rk,
const unsigned char *key )
{
asm( "movdqu (%1), %%xmm0 \n\t" // copy original round key
"movdqu %%xmm0, (%0) \n\t"
"add $16, %0 \n\t"
"movq 16(%1), %%xmm1 \n\t"
"movq %%xmm1, (%0) \n\t"
"add $8, %0 \n\t"
"jmp 2f \n\t" // skip auxiliary routine
/*
* Finish generating the next 6 quarter-keys.
*
* On entry xmm0 is r3:r2:r1:r0, xmm1 is stuff:stuff:r5:r4
* and xmm2 is stuff:stuff:X:stuff with X = rot( sub( r3 ) ) ^ RCON.
*
* On exit, xmm0 is r9:r8:r7:r6 and xmm1 is stuff:stuff:r11:r10
* and those are written to the round key buffer.
*/
"1: \n\t"
"pshufd $0x55, %%xmm2, %%xmm2 \n\t" // X:X:X:X
"pxor %%xmm0, %%xmm2 \n\t" // X+r3:X+r2:X+r1:r4
"pslldq $4, %%xmm0 \n\t" // etc
"pxor %%xmm0, %%xmm2 \n\t"
"pslldq $4, %%xmm0 \n\t"
"pxor %%xmm0, %%xmm2 \n\t"
"pslldq $4, %%xmm0 \n\t"
"pxor %%xmm2, %%xmm0 \n\t" // update xmm0 = r9:r8:r7:r6
"movdqu %%xmm0, (%0) \n\t"
"add $16, %0 \n\t"
"pshufd $0xff, %%xmm0, %%xmm2 \n\t" // r9:r9:r9:r9
"pxor %%xmm1, %%xmm2 \n\t" // stuff:stuff:r9+r5:r10
"pslldq $4, %%xmm1 \n\t" // r2:r1:r0:0
"pxor %%xmm2, %%xmm1 \n\t" // xmm1 = stuff:stuff:r11:r10
"movq %%xmm1, (%0) \n\t"
"add $8, %0 \n\t"
"ret \n\t"
"2: \n\t"
AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x80 \n\tcall 1b \n\t"
:
: "r" (rk), "r" (key)
: "memory", "cc", "0" );
}
/*
* Key expansion, 256-bit case
*/
static void aesni_setkey_enc_256( unsigned char *rk,
const unsigned char *key )
{
asm( "movdqu (%1), %%xmm0 \n\t"
"movdqu %%xmm0, (%0) \n\t"
"add $16, %0 \n\t"
"movdqu 16(%1), %%xmm1 \n\t"
"movdqu %%xmm1, (%0) \n\t"
"jmp 2f \n\t" // skip auxiliary routine
/*
* Finish generating the next two round keys.
*
* On entry xmm0 is r3:r2:r1:r0, xmm1 is r7:r6:r5:r4 and
* xmm2 is X:stuff:stuff:stuff with X = rot( sub( r7 )) ^ RCON
*
* On exit, xmm0 is r11:r10:r9:r8 and xmm1 is r15:r14:r13:r12
* and those have been written to the output buffer.
*/
"1: \n\t"
"pshufd $0xff, %%xmm2, %%xmm2 \n\t"
"pxor %%xmm0, %%xmm2 \n\t"
"pslldq $4, %%xmm0 \n\t"
"pxor %%xmm0, %%xmm2 \n\t"
"pslldq $4, %%xmm0 \n\t"
"pxor %%xmm0, %%xmm2 \n\t"
"pslldq $4, %%xmm0 \n\t"
"pxor %%xmm2, %%xmm0 \n\t"
"add $16, %0 \n\t"
"movdqu %%xmm0, (%0) \n\t"
/* Set xmm2 to stuff:Y:stuff:stuff with Y = subword( r11 )
* and proceed to generate next round key from there */
AESKEYGENA xmm0_xmm2 ",0x00 \n\t"
"pshufd $0xaa, %%xmm2, %%xmm2 \n\t"
"pxor %%xmm1, %%xmm2 \n\t"
"pslldq $4, %%xmm1 \n\t"
"pxor %%xmm1, %%xmm2 \n\t"
"pslldq $4, %%xmm1 \n\t"
"pxor %%xmm1, %%xmm2 \n\t"
"pslldq $4, %%xmm1 \n\t"
"pxor %%xmm2, %%xmm1 \n\t"
"add $16, %0 \n\t"
"movdqu %%xmm1, (%0) \n\t"
"ret \n\t"
/*
* Main "loop" - Generating one more key than necessary,
* see definition of mbedtls_aes_context.buf
*/
"2: \n\t"
AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t"
:
: "r" (rk), "r" (key)
: "memory", "cc", "0" );
}
/*
* Key expansion, wrapper
*/
int mbedtls_aesni_setkey_enc( unsigned char *rk,
const unsigned char *key,
size_t bits )
{
switch( bits )
{
case 128: aesni_setkey_enc_128( rk, key ); break;
case 192: aesni_setkey_enc_192( rk, key ); break;
case 256: aesni_setkey_enc_256( rk, key ); break;
default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
}
return( 0 );
}
#endif /* MBEDTLS_HAVE_X86_64 */
#endif /* MBEDTLS_AESNI_C */

View File

@ -2,9 +2,6 @@
* \file aesni.h
*
* \brief AES-NI for hardware AES acceleration on some Intel processors
*
* \warning These functions are only for internal use by other library
* functions; you must not call them directly.
*/
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
@ -51,10 +48,7 @@ extern "C" {
#endif
/**
* \brief Internal function to detect the AES-NI feature in CPUs.
*
* \note This function is only for internal use by other library
* functions; you must not call it directly.
* \brief AES-NI features detection routine
*
* \param what The feature to detect
* (MBEDTLS_AESNI_AES or MBEDTLS_AESNI_CLMUL)
@ -64,10 +58,7 @@ extern "C" {
int mbedtls_aesni_has_support( unsigned int what );
/**
* \brief Internal AES-NI AES-ECB block encryption and decryption
*
* \note This function is only for internal use by other library
* functions; you must not call it directly.
* \brief AES-NI AES-ECB block en(de)cryption
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
@ -77,15 +68,12 @@ int mbedtls_aesni_has_support( unsigned int what );
* \return 0 on success (cannot fail)
*/
int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
int mode,
const unsigned char input[16],
unsigned char output[16] );
/**
* \brief Internal GCM multiplication: c = a * b in GF(2^128)
*
* \note This function is only for internal use by other library
* functions; you must not call it directly.
* \brief GCM multiplication: c = a * b in GF(2^128)
*
* \param c Result
* \param a First operand
@ -95,29 +83,21 @@ int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx,
* elements of GF(2^128) as per the GCM spec.
*/
void mbedtls_aesni_gcm_mult( unsigned char c[16],
const unsigned char a[16],
const unsigned char b[16] );
const unsigned char a[16],
const unsigned char b[16] );
/**
* \brief Internal round key inversion. This function computes
* decryption round keys from the encryption round keys.
*
* \note This function is only for internal use by other library
* functions; you must not call it directly.
* \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 mbedtls_aesni_inverse_key( unsigned char *invkey,
const unsigned char *fwdkey,
int nr );
const unsigned char *fwdkey, int nr );
/**
* \brief Internal key expansion for encryption
*
* \note This function is only for internal use by other library
* functions; you must not call it directly.
* \brief Perform key expansion (for encryption)
*
* \param rk Destination buffer where the round keys are written
* \param key Encryption key
@ -126,8 +106,8 @@ void mbedtls_aesni_inverse_key( unsigned char *invkey,
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
*/
int mbedtls_aesni_setkey_enc( unsigned char *rk,
const unsigned char *key,
size_t bits );
const unsigned char *key,
size_t bits );
#ifdef __cplusplus
}

View File

@ -0,0 +1,205 @@
/*
* An implementation of the ARCFOUR algorithm
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The ARCFOUR algorithm was publicly disclosed on 94/09.
*
* http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_ARC4_C)
#include "arc4.h"
#include <string.h>
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#if !defined(MBEDTLS_ARC4_ALT)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
}
void mbedtls_arc4_init( mbedtls_arc4_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_arc4_context ) );
}
void mbedtls_arc4_free( mbedtls_arc4_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_zeroize( ctx, sizeof( mbedtls_arc4_context ) );
}
/*
* ARC4 key schedule
*/
void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key,
unsigned int keylen )
{
int i, j, a;
unsigned int k;
unsigned char *m;
ctx->x = 0;
ctx->y = 0;
m = ctx->m;
for( i = 0; i < 256; i++ )
m[i] = (unsigned char) i;
j = k = 0;
for( i = 0; i < 256; i++, k++ )
{
if( k >= keylen ) k = 0;
a = m[i];
j = ( j + a + key[k] ) & 0xFF;
m[i] = m[j];
m[j] = (unsigned char) a;
}
}
/*
* ARC4 cipher function
*/
int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input,
unsigned char *output )
{
int x, y, a, b;
size_t i;
unsigned char *m;
x = ctx->x;
y = ctx->y;
m = ctx->m;
for( i = 0; i < length; i++ )
{
x = ( x + 1 ) & 0xFF; a = m[x];
y = ( y + a ) & 0xFF; b = m[y];
m[x] = (unsigned char) b;
m[y] = (unsigned char) a;
output[i] = (unsigned char)
( input[i] ^ m[(unsigned char)( a + b )] );
}
ctx->x = x;
ctx->y = y;
return( 0 );
}
#endif /* !MBEDTLS_ARC4_ALT */
#if defined(MBEDTLS_SELF_TEST)
/*
* ARC4 tests vectors as posted by Eric Rescorla in sep. 1994:
*
* http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0
*/
static const unsigned char arc4_test_key[3][8] =
{
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
};
static const unsigned char arc4_test_pt[3][8] =
{
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
};
static const unsigned char arc4_test_ct[3][8] =
{
{ 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 },
{ 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 },
{ 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A }
};
/*
* Checkup routine
*/
int mbedtls_arc4_self_test( int verbose )
{
int i, ret = 0;
unsigned char ibuf[8];
unsigned char obuf[8];
mbedtls_arc4_context ctx;
mbedtls_arc4_init( &ctx );
for( i = 0; i < 3; i++ )
{
if( verbose != 0 )
mbedtls_printf( " ARC4 test #%d: ", i + 1 );
memcpy( ibuf, arc4_test_pt[i], 8 );
mbedtls_arc4_setup( &ctx, arc4_test_key[i], 8 );
mbedtls_arc4_crypt( &ctx, 8, ibuf, obuf );
if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit;
}
if( verbose != 0 )
mbedtls_printf( "passed\n" );
}
if( verbose != 0 )
mbedtls_printf( "\n" );
exit:
mbedtls_arc4_free( &ctx );
return( ret );
}
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_ARC4_C */

View File

@ -36,17 +36,16 @@
#include <stddef.h>
/* MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED -0x0019 /**< ARC4 hardware accelerator failed. */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_ARC4_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief ARC4 context structure
*
@ -54,7 +53,7 @@ extern "C" {
* security risk. We recommend considering stronger ciphers instead.
*
*/
typedef struct mbedtls_arc4_context
typedef struct
{
int x; /*!< permutation index */
int y; /*!< permutation index */
@ -62,10 +61,6 @@ typedef struct mbedtls_arc4_context
}
mbedtls_arc4_context;
#else /* MBEDTLS_ARC4_ALT */
#include "arc4_alt.h"
#endif /* MBEDTLS_ARC4_ALT */
/**
* \brief Initialize ARC4 context
*
@ -123,7 +118,17 @@ void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key,
int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input,
unsigned char *output );
#if defined(MBEDTLS_SELF_TEST)
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_ARC4_ALT */
#include "arc4_alt.h"
#endif /* MBEDTLS_ARC4_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Checkup routine
@ -137,8 +142,6 @@ int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned
*/
int mbedtls_arc4_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,370 +0,0 @@
/**
* \file aria.h
*
* \brief ARIA block cipher
*
* The ARIA algorithm is a symmetric block cipher that can encrypt and
* decrypt information. It is defined by the Korean Agency for
* Technology and Standards (KATS) in <em>KS X 1213:2004</em> (in
* Korean, but see http://210.104.33.10/ARIA/index-e.html in English)
* and also described by the IETF in <em>RFC 5794</em>.
*/
/* 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 TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ARIA_H
#define MBEDTLS_ARIA_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#include "platform_util.h"
#define MBEDTLS_ARIA_ENCRYPT 1 /**< ARIA encryption. */
#define MBEDTLS_ARIA_DECRYPT 0 /**< ARIA decryption. */
#define MBEDTLS_ARIA_BLOCKSIZE 16 /**< ARIA block size in bytes. */
#define MBEDTLS_ARIA_MAX_ROUNDS 16 /**< Maxiumum number of rounds in ARIA. */
#define MBEDTLS_ARIA_MAX_KEYSIZE 32 /**< Maximum size of an ARIA key in bytes. */
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#define MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x005C )
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#define MBEDTLS_ERR_ARIA_BAD_INPUT_DATA -0x005C /**< Bad input data. */
#define MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH -0x005E /**< Invalid data input length. */
/* MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE is deprecated and should not be used.
*/
#define MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE -0x005A /**< Feature not available. For example, an unsupported ARIA key size. */
/* MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED -0x0058 /**< ARIA hardware accelerator failed. */
#if !defined(MBEDTLS_ARIA_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief The ARIA context-type definition.
*/
typedef struct mbedtls_aria_context
{
unsigned char nr; /*!< The number of rounds (12, 14 or 16) */
/*! The ARIA round keys. */
uint32_t rk[MBEDTLS_ARIA_MAX_ROUNDS + 1][MBEDTLS_ARIA_BLOCKSIZE / 4];
}
mbedtls_aria_context;
#else /* MBEDTLS_ARIA_ALT */
#include "aria_alt.h"
#endif /* MBEDTLS_ARIA_ALT */
/**
* \brief This function initializes the specified ARIA context.
*
* It must be the first API called before using
* the context.
*
* \param ctx The ARIA context to initialize. This must not be \c NULL.
*/
void mbedtls_aria_init( mbedtls_aria_context *ctx );
/**
* \brief This function releases and clears the specified ARIA context.
*
* \param ctx The ARIA context to clear. This may be \c NULL, in which
* case this function returns immediately. If it is not \c NULL,
* it must point to an initialized ARIA context.
*/
void mbedtls_aria_free( mbedtls_aria_context *ctx );
/**
* \brief This function sets the encryption key.
*
* \param ctx The ARIA context to which the key should be bound.
* This must be initialized.
* \param key The encryption key. This must be a readable buffer
* of size \p keybits Bits.
* \param keybits The size of \p key 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 negative error code on failure.
*/
int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx,
const unsigned char *key,
unsigned int keybits );
/**
* \brief This function sets the decryption key.
*
* \param ctx The ARIA context to which the key should be bound.
* This must be initialized.
* \param key The decryption key. This must be a readable buffer
* of size \p keybits Bits.
* \param keybits The size of data passed. Valid options are:
* <ul><li>128 bits</li>
* <li>192 bits</li>
* <li>256 bits</li></ul>
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx,
const unsigned char *key,
unsigned int keybits );
/**
* \brief This function performs an ARIA single-block encryption or
* decryption operation.
*
* It performs encryption or decryption (depending on whether
* the key was set for encryption on decryption) on the input
* data buffer defined in the \p input parameter.
*
* mbedtls_aria_init(), and either mbedtls_aria_setkey_enc() or
* mbedtls_aria_setkey_dec() must be called before the first
* call to this API with the same context.
*
* \param ctx The ARIA context to use for encryption or decryption.
* This must be initialized and bound to a key.
* \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.
* \return A negative error code on failure.
*/
int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE],
unsigned char output[MBEDTLS_ARIA_BLOCKSIZE] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief This function performs an ARIA-CBC encryption or decryption operation
* on full blocks.
*
* It performs the operation defined in the \p mode
* parameter (encrypt/decrypt), on the input data buffer defined in
* the \p input parameter.
*
* It can be called as many times as needed, until all the input
* data is processed. mbedtls_aria_init(), and either
* mbedtls_aria_setkey_enc() or mbedtls_aria_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 ARIA 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 ARIA context to use for encryption or decryption.
* This must be initialized and bound to a key.
* \param mode The mode of operation. This must be either
* #MBEDTLS_ARIA_ENCRYPT for encryption, or
* #MBEDTLS_ARIA_DECRYPT for decryption.
* \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).
* This must be a readable buffer of size 16 Bytes.
* \param input The buffer holding the input data. This must
* be a readable buffer of length \p length Bytes.
* \param output The buffer holding the output data. This must
* be a writable buffer of length \p length Bytes.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx,
int mode,
size_t length,
unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/**
* \brief This function performs an ARIA-CFB128 encryption or decryption
* operation.
*
* It performs the operation defined in the \p mode
* parameter (encrypt or decrypt), on the input data buffer
* defined in the \p input parameter.
*
* For CFB, you must set up the context with mbedtls_aria_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 ARIA context to use for encryption or decryption.
* This must be initialized and bound to a key.
* \param mode The mode of operation. This must be either
* #MBEDTLS_ARIA_ENCRYPT for encryption, or
* #MBEDTLS_ARIA_DECRYPT for decryption.
* \param length The length of the input data \p input in Bytes.
* \param iv_off The offset in IV (updated after use).
* This must not be larger than 15.
* \param iv The initialization vector (updated after use).
* This must be a readable buffer of size 16 Bytes.
* \param input The buffer holding the input data. This must
* be a readable buffer of length \p length Bytes.
* \param output The buffer holding the output data. This must
* be a writable buffer of length \p length Bytes.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/**
* \brief This function performs an ARIA-CTR encryption or decryption
* operation.
*
* This function performs the operation defined in the \p mode
* parameter (encrypt/decrypt), on the input data buffer
* defined in the \p input parameter.
*
* Due to the nature of CTR, you must use the same key schedule
* for both encryption and decryption operations. Therefore, you
* must use the context initialized with mbedtls_aria_setkey_enc()
* for both #MBEDTLS_ARIA_ENCRYPT and #MBEDTLS_ARIA_DECRYPT.
*
* \warning You must never reuse a nonce value with the same key. Doing so
* would void the encryption for the two messages encrypted with
* the same nonce and key.
*
* There are two common strategies for managing nonces with CTR:
*
* 1. You can handle everything as a single message processed over
* successive calls to this function. In that case, you want to
* set \p nonce_counter and \p nc_off to 0 for the first call, and
* then preserve the values of \p nonce_counter, \p nc_off and \p
* stream_block across calls to this function as they will be
* updated by this function.
*
* With this strategy, you must not encrypt more than 2**128
* blocks of data with the same key.
*
* 2. You can encrypt separate messages by dividing the \p
* nonce_counter buffer in two areas: the first one used for a
* per-message nonce, handled by yourself, and the second one
* updated by this function internally.
*
* For example, you might reserve the first 12 bytes for the
* per-message nonce, and the last 4 bytes for internal use. In that
* case, before calling this function on a new message you need to
* set the first 12 bytes of \p nonce_counter to your chosen nonce
* value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
* stream_block to be ignored). That way, you can encrypt at most
* 2**96 messages of up to 2**32 blocks each with the same key.
*
* The per-message nonce (or information sufficient to reconstruct
* it) needs to be communicated with the ciphertext and must be unique.
* The recommended way to ensure uniqueness is to use a message
* counter. An alternative is to generate random nonces, but this
* limits the number of messages that can be securely encrypted:
* for example, with 96-bit random nonces, you should not encrypt
* more than 2**32 messages with the same key.
*
* Note that for both stategies, sizes are measured in blocks and
* that an ARIA block is 16 bytes.
*
* \warning Upon return, \p stream_block contains sensitive data. Its
* content must not be written to insecure storage and should be
* securely discarded as soon as it's no longer needed.
*
* \param ctx The ARIA context to use for encryption or decryption.
* This must be initialized and bound to a key.
* \param length The length of the input data \p input in Bytes.
* \param nc_off The offset in Bytes in the current \p stream_block,
* for resuming within the current cipher stream. The
* offset pointer should be \c 0 at the start of a
* stream. This must not be larger than \c 15 Bytes.
* \param nonce_counter The 128-bit nonce and counter. This must point to
* a read/write buffer of length \c 16 bytes.
* \param stream_block The saved stream block for resuming. This must
* point to a read/write buffer of length \c 16 bytes.
* This is overwritten by the function.
* \param input The buffer holding the input data. This must
* be a readable buffer of length \p length Bytes.
* \param output The buffer holding the output data. This must
* be a writable buffer of length \p length Bytes.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE],
unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CTR */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine.
*
* \return \c 0 on success, or \c 1 on failure.
*/
int mbedtls_aria_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* aria.h */

View File

@ -31,7 +31,6 @@
#endif
#include <stddef.h>
#include <stdint.h>
#if defined(MBEDTLS_BIGNUM_C)
#include "bignum.h"
@ -90,18 +89,6 @@
#define MBEDTLS_ASN1_CONSTRUCTED 0x20
#define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80
/* Slightly smaller way to check if tag is a string tag
* compared to canonical implementation. */
#define MBEDTLS_ASN1_IS_STRING_TAG( tag ) \
( ( tag ) < 32u && ( \
( ( 1u << ( tag ) ) & ( ( 1u << MBEDTLS_ASN1_BMP_STRING ) | \
( 1u << MBEDTLS_ASN1_UTF8_STRING ) | \
( 1u << MBEDTLS_ASN1_T61_STRING ) | \
( 1u << MBEDTLS_ASN1_IA5_STRING ) | \
( 1u << MBEDTLS_ASN1_UNIVERSAL_STRING ) | \
( 1u << MBEDTLS_ASN1_PRINTABLE_STRING ) | \
( 1u << MBEDTLS_ASN1_BIT_STRING ) ) ) != 0 ) )
/*
* 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",
@ -130,11 +117,7 @@
*/
#define MBEDTLS_OID_CMP(oid_str, oid_buf) \
( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) || \
mbedtls_platform_memequal( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 )
#define MBEDTLS_OID_CMP_RAW(oid_str, oid_buf, oid_buf_len) \
( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf_len) ) || \
mbedtls_platform_memequal( (oid_str), (oid_buf), (oid_buf_len) ) != 0 )
memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 )
#ifdef __cplusplus
extern "C" {
@ -277,97 +260,20 @@ int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end
size_t *len );
/**
* \brief Free a heap-allocated linked list presentation of
* an ASN.1 sequence, including the first element.
* \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>"
* Updated the pointer to immediately behind the full sequence tag.
*
* \param seq The address of the first sequence component. This may
* be \c NULL, in which case this functions returns
* immediately.
*/
void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq );
/**
* \brief This function parses and splits an ASN.1 "SEQUENCE OF <tag>"
* and updates the source buffer pointer to immediately behind
* the full sequence.
*
* \param p The address of the pointer to the beginning of the
* ASN.1 SEQUENCE OF structure, including ASN.1 tag+length header.
* On success, `*p` is advanced to point to the first byte
* following the parsed ASN.1 sequence.
* \param end The end of the ASN.1 input buffer starting at \p p. This is
* used for bounds checking.
* \param cur The address at which to store the first entry in the parsed
* sequence. Further entries are heap-allocated and referenced
* from \p cur.
* \param tag The common tag of the entries in the ASN.1 sequence.
*
* \note Ownership for the heap-allocated elements \c cur->next,
* \c cur->next->next, ..., is passed to the caller. It
* is hence the caller's responsibility to free them when
* no longer needed, and mbedtls_asn1_sequence_free() can
* be used for that, passing \c cur->next as the \c seq
* argument (or \p cur if \p cur itself was heap-allocated
* by the caller).
* \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 mbedtls_asn1_get_sequence_of( unsigned char **p,
const unsigned char *end,
mbedtls_asn1_sequence *cur,
int tag );
/**
* \brief Traverse an ASN.1 SEQUENCE container and
* call a callback for each entry.
*
* \warning This function is still experimental and may change
* at any time.
*
* \param p The address of the pointer to the beginning of
* the ASN.1 SEQUENCE header. This is updated to
* point to the end of the ASN.1 SEQUENCE container
* on a successful invocation.
* \param end The end of the ASN.1 SEQUENCE container.
* \param tag_must_mask A mask to be applied to the ASN.1 tags found within
* the SEQUENCE before comparing to \p tag_must_value.
* \param tag_must_val The required value of each ASN.1 tag found in the
* SEQUENCE, after masking with \p tag_must_mask.
* Mismatching tags lead to an error.
* For example, a value of \c 0 for both \p tag_must_mask
* and \p tag_must_val means that every tag is allowed,
* while a value of \c 0xFF for \p tag_must_mask means
* that \p tag_must_val is the only allowed tag.
* \param tag_may_mask A mask to be applied to the ASN.1 tags found within
* the SEQUENCE before comparing to \p tag_may_value.
* \param tag_may_val The desired value of each ASN.1 tag found in the
* SEQUENCE, after masking with \p tag_may_mask.
* Mismatching tags will be silently ignored.
* For example, a value of \c 0 for \p tag_may_mask and
* \p tag_may_val means that any tag will be considered,
* while a value of \c 0xFF for \p tag_may_mask means
* that all tags with value different from \p tag_may_val
* will be ignored.
* \param cb The callback to trigger for each component
* in the ASN.1 SEQUENCE. If the callback returns
* a non-zero value, the function stops immediately,
* forwarding the callback's return value.
* \param ctx The context to be passed to the callback \p cb.
*
* \return \c 0 if successful the entire ASN.1 SEQUENCE
* was traversed without parsing or callback errors.
* \return A negative ASN.1 error code on a parsing failure.
* \return A non-zero error code forwarded from the callback
* \p cb in case the latter returns a non-zero value.
*/
int mbedtls_asn1_traverse_sequence_of(
unsigned char **p,
const unsigned char *end,
uint8_t tag_must_mask, uint8_t tag_must_val,
uint8_t tag_may_mask, uint8_t tag_may_val,
int (*cb)( void *ctx, int tag,
unsigned char* start, size_t len ),
void *ctx );
int tag);
#if defined(MBEDTLS_BIGNUM_C)
/**

View File

@ -28,7 +28,6 @@
#if defined(MBEDTLS_ASN1_PARSE_C)
#include "asn1.h"
#include "platform_util.h"
#include <string.h>
@ -44,6 +43,11 @@
#define mbedtls_free free
#endif
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
}
/*
* ASN.1 DER decoding routines
*/
@ -229,103 +233,6 @@ int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end
return( 0 );
}
void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq )
{
while( seq != NULL )
{
mbedtls_asn1_sequence *next = seq->next;
mbedtls_platform_zeroize( seq, sizeof( *seq ) );
mbedtls_free( seq );
seq = next;
}
}
/*
* Traverse an ASN.1 "SEQUENCE OF <tag>"
* and call a callback for each entry found.
*/
int mbedtls_asn1_traverse_sequence_of(
unsigned char **p,
const unsigned char *end,
uint8_t tag_must_mask, uint8_t tag_must_val,
uint8_t tag_may_mask, uint8_t tag_may_val,
int (*cb)( void *ctx, int tag,
unsigned char *start, size_t len ),
void *ctx )
{
int ret;
size_t len;
/* Get main sequence tag */
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
return( ret );
}
if( *p + len != end )
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
while( *p < end )
{
unsigned char const tag = *(*p)++;
if( ( tag & tag_must_mask ) != tag_must_val )
return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
if( ( ret = mbedtls_asn1_get_len( p, end, &len ) ) != 0 )
return( ret );
if( ( tag & tag_may_mask ) == tag_may_val )
{
if( cb != NULL )
{
ret = cb( ctx, tag, *p, len );
if( ret != 0 )
return( ret );
}
}
*p += len;
}
return( 0 );
}
typedef struct
{
int tag;
mbedtls_asn1_sequence *cur;
} asn1_get_sequence_of_cb_ctx_t;
static int asn1_get_sequence_of_cb( void *ctx,
int tag,
unsigned char *start,
size_t len )
{
asn1_get_sequence_of_cb_ctx_t *cb_ctx =
(asn1_get_sequence_of_cb_ctx_t *) ctx;
mbedtls_asn1_sequence *cur =
cb_ctx->cur;
if( cur->buf.p != NULL )
{
cur->next =
mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
if( cur->next == NULL )
return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
cur = cur->next;
}
cur->buf.p = start;
cur->buf.len = len;
cur->buf.tag = tag;
cb_ctx->cur = cur;
return( 0 );
}
/*
@ -336,11 +243,49 @@ int mbedtls_asn1_get_sequence_of( unsigned char **p,
mbedtls_asn1_sequence *cur,
int tag)
{
asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
mbedtls_platform_memset( cur, 0, sizeof( mbedtls_asn1_sequence ) );
return( mbedtls_asn1_traverse_sequence_of(
p, end, 0xFF, tag, 0, 0,
asn1_get_sequence_of_cb, &cb_ctx ) );
int ret;
size_t len;
mbedtls_asn1_buf *buf;
/* Get main sequence tag */
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
return( ret );
if( *p + len != end )
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
while( *p < end )
{
buf = &(cur->buf);
buf->tag = **p;
if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
return( ret );
buf->p = *p;
*p += buf->len;
/* Allocate and assign next pointer */
if( *p < end )
{
cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1,
sizeof( mbedtls_asn1_sequence ) );
if( cur->next == NULL )
return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
cur = cur->next;
}
}
/* Set final sequence entry's next pointer to NULL */
cur->next = NULL;
if( *p != end )
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
return( 0 );
}
int mbedtls_asn1_get_alg( unsigned char **p,
@ -354,18 +299,21 @@ int mbedtls_asn1_get_alg( unsigned char **p,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
return( ret );
if( ( end - *p ) < 1 )
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
alg->tag = **p;
end = *p + len;
if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 )
return( ret );
alg->tag = MBEDTLS_ASN1_OID;
alg->p = *p;
*p += alg->len;
if( *p == end )
{
mbedtls_platform_zeroize( params, sizeof(mbedtls_asn1_buf) );
mbedtls_zeroize( params, sizeof(mbedtls_asn1_buf) );
return( 0 );
}
@ -410,7 +358,7 @@ void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur )
mbedtls_free( cur->oid.p );
mbedtls_free( cur->val.p );
mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) );
mbedtls_zeroize( cur, sizeof( mbedtls_asn1_named_data ) );
}
void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head )
@ -431,7 +379,7 @@ mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *
while( list != NULL )
{
if( list->oid.len == len &&
mbedtls_platform_memequal( list->oid.p, oid, len ) == 0 )
memcmp( list->oid.p, oid, len ) == 0 )
{
break;
}

View File

@ -28,7 +28,6 @@
#if defined(MBEDTLS_ASN1_WRITE_C)
#include "asn1write.h"
#include "platform_util.h"
#include <string.h>
@ -124,7 +123,7 @@ int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
len = size;
(*p) -= len;
mbedtls_platform_memcpy( *p, buf, len );
memcpy( *p, buf, len );
return( (int) len );
}
@ -237,6 +236,9 @@ int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val )
int ret;
size_t len = 0;
// DER format assumes 2s complement for numbers, so the leftmost bit
// should be 0 for positive numbers and 1 for negative numbers.
//
if( *p - start < 1 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
@ -258,37 +260,34 @@ int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val )
return( (int) len );
}
int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start, int tag,
const char *text, size_t text_len )
int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start,
const char *text, size_t text_len )
{
int ret;
size_t len = 0;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
(const unsigned char *) text, text_len ) );
(const unsigned char *) text, text_len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, tag ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_PRINTABLE_STRING ) );
return( (int) len );
}
int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start,
const char *text, size_t text_len )
{
return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_UTF8_STRING, text, text_len) );
}
int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start,
const char *text, size_t text_len )
{
return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_PRINTABLE_STRING, text, text_len) );
}
int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start,
const char *text, size_t text_len )
{
return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_IA5_STRING, text, text_len) );
int ret;
size_t len = 0;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
(const unsigned char *) text, text_len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_IA5_STRING ) );
return( (int) len );
}
int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
@ -312,7 +311,7 @@ int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
byte_len--;
*--( *p ) = buf[byte_len] & ~( ( 0x1 << unused_bits ) - 1 );
( *p ) -= byte_len;
mbedtls_platform_memcpy( *p, buf, byte_len );
memcpy( *p, buf, byte_len );
}
/* Write unused bits */
@ -348,7 +347,7 @@ static mbedtls_asn1_named_data *asn1_find_named_data(
while( list != NULL )
{
if( list->oid.len == len &&
mbedtls_platform_memequal( list->oid.p, oid, len ) == 0 )
memcmp( list->oid.p, oid, len ) == 0 )
{
break;
}
@ -384,7 +383,7 @@ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(
return( NULL );
}
mbedtls_platform_memcpy( cur->oid.p, oid, oid_len );
memcpy( cur->oid.p, oid, oid_len );
cur->val.len = val_len;
cur->val.p = mbedtls_calloc( 1, val_len );
@ -415,7 +414,7 @@ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(
}
if( val != NULL )
mbedtls_platform_memcpy( cur->val.p, val, val_len );
memcpy( cur->val.p, val, val_len );
return( cur );
}

View File

@ -32,239 +32,161 @@
#include "asn1.h"
#define MBEDTLS_ASN1_CHK_ADD(g, f) \
do \
{ \
if( ( ret = (f) ) < 0 ) \
return( ret ); \
else \
(g) += ret; \
} while( 0 )
#define MBEDTLS_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.
* \brief Write a length field in ASN.1 format
* Note: function works backwards in data buffer
*
* \note This 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
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param len The length value to write.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start,
size_t len );
/**
* \brief Write an ASN.1 tag in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param tag The tag to write.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start,
unsigned char tag );
int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len );
/**
* \brief Write raw buffer data.
* \brief Write a ASN.1 tag in ASN.1 format
* Note: function works backwards in data buffer
*
* \note This 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
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param buf The data buffer to write.
* \param size The length of the data buffer.
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start,
unsigned char tag );
/**
* \brief Write raw buffer data
* Note: function works backwards in data buffer
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
* \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 mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t size );
const unsigned char *buf, size_t size );
#if defined(MBEDTLS_BIGNUM_C)
/**
* \brief Write a arbitrary-precision number (#MBEDTLS_ASN1_INTEGER)
* in ASN.1 format.
* \brief Write a big number (MBEDTLS_ASN1_INTEGER) in ASN.1 format
* Note: function works backwards in data buffer
*
* \note This 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
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param X The MPI to write.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start,
const mbedtls_mpi *X );
int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedtls_mpi *X );
#endif /* MBEDTLS_BIGNUM_C */
/**
* \brief Write a NULL tag (#MBEDTLS_ASN1_NULL) with zero data
* in ASN.1 format.
* \brief Write a NULL tag (MBEDTLS_ASN1_NULL) with zero data in ASN.1 format
* Note: function works backwards in data buffer
*
* \note This function works backwards in data buffer.
* \param p reference to current position pointer
* \param start start of the buffer (for bounds-checking)
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start );
/**
* \brief Write an OID tag (#MBEDTLS_ASN1_OID) and data
* in ASN.1 format.
* \brief Write an OID tag (MBEDTLS_ASN1_OID) and data in ASN.1 format
* Note: function works backwards in data buffer
*
* \note This 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
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param oid The OID to write.
* \param oid_len The length of the OID.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len );
const char *oid, size_t oid_len );
/**
* \brief Write an AlgorithmIdentifier sequence in ASN.1 format.
* \brief Write an AlgorithmIdentifier sequence in ASN.1 format
* Note: function works backwards in data buffer
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param oid The OID of the algorithm to write.
* \param oid_len The length of the algorithm's OID.
* \param par_len The length of the parameters, which must be already written.
* \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 number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_algorithm_identifier( unsigned char **p,
unsigned char *start,
const char *oid, size_t oid_len,
size_t par_len );
int mbedtls_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 (#MBEDTLS_ASN1_BOOLEAN) and value
* in ASN.1 format.
* \brief Write a boolean tag (MBEDTLS_ASN1_BOOLEAN) and value in ASN.1 format
* Note: function works backwards in data buffer
*
* \note This 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
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param boolean The boolean value to write, either \c 0 or \c 1.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start,
int boolean );
int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolean );
/**
* \brief Write an int tag (#MBEDTLS_ASN1_INTEGER) and value
* in ASN.1 format.
* \brief Write an int tag (MBEDTLS_ASN1_INTEGER) and value in ASN.1 format
* Note: function works backwards in data buffer
*
* \note This 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
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param val The integer value to write.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val );
/**
* \brief Write a string in ASN.1 format using a specific
* string encoding tag.
* \note This function works backwards in data buffer.
* \brief Write a printable string tag (MBEDTLS_ASN1_PRINTABLE_STRING) and
* value in ASN.1 format
* Note: function works backwards in data buffer
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param tag The string encoding tag to write, e.g.
* #MBEDTLS_ASN1_UTF8_STRING.
* \param text The string to write.
* \param text_len The length of \p text in bytes (which might
* be strictly larger than the number of characters).
* \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 number of bytes written to \p p on success.
* \return A negative error code on failure.
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start,
int tag, const char *text,
size_t text_len );
int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start,
const char *text, size_t text_len );
/**
* \brief Write a string in ASN.1 format using the PrintableString
* string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING).
* \brief Write an IA5 string tag (MBEDTLS_ASN1_IA5_STRING) and
* value in ASN.1 format
* Note: function works backwards in data buffer
*
* \note This 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
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param text The string to write.
* \param text_len The length of \p text in bytes (which might
* be strictly larger than the number of characters).
*
* \return The number of bytes written to \p p on success.
* \return A negative error code on failure.
*/
int mbedtls_asn1_write_printable_string( unsigned char **p,
unsigned char *start,
const char *text, size_t text_len );
/**
* \brief Write a UTF8 string in ASN.1 format using the UTF8String
* string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING).
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param text The string to write.
* \param text_len The length of \p text in bytes (which might
* be strictly larger than the number of characters).
*
* \return The number of bytes written to \p p on success.
* \return A negative error code on failure.
*/
int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start,
const char *text, size_t text_len );
/**
* \brief Write a string in ASN.1 format using the IA5String
* string encoding tag (#MBEDTLS_ASN1_IA5_STRING).
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param text The string to write.
* \param text_len The length of \p text in bytes (which might
* be strictly larger than the number of characters).
*
* \return The number of bytes written to \p p on success.
* \return A negative error code on failure.
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start,
const char *text, size_t text_len );
const char *text, size_t text_len );
/**
* \brief Write a bitstring tag (#MBEDTLS_ASN1_BIT_STRING) and
@ -281,7 +203,7 @@ int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start,
* \return A negative error code on failure.
*/
int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t bits );
const unsigned char *buf, size_t bits );
/**
* \brief Write an octet string tag (#MBEDTLS_ASN1_OCTET_STRING)
@ -289,16 +211,15 @@ int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param buf The buffer holding the data to write.
* \param size The length of the data buffer \p buf.
* \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 number of bytes written to \p p on success.
* \return A negative error code on failure.
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t size );
const unsigned char *buf, size_t size );
/**
* \brief Create or find a specific named_data entry for writing in a
@ -306,16 +227,15 @@ int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
* a new entry is added to the head of the list.
* Warning: Destructive behaviour for the val data!
*
* \param list The 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 The size of the OID.
* \param val The data to store (can be \c NULL if you want to fill
* it by hand).
* \param val_len The minimum length of the data buffer needed.
* \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 A pointer to the new / existing entry on success.
* \return \c NULL if if there was a memory allocation error.
* \return NULL if if there was a memory allocation error, or a pointer
* to the new / existing entry.
*/
mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **list,
const char *oid, size_t oid_len,

View File

@ -260,7 +260,7 @@ int mbedtls_base64_self_test( int verbose )
src = base64_test_dec;
if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 ||
memcmp( base64_test_enc, buffer, 88 ) != 0 )
memcmp( base64_test_enc, buffer, 88 ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
@ -274,7 +274,7 @@ int mbedtls_base64_self_test( int verbose )
src = base64_test_enc;
if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 ||
memcmp( base64_test_dec, buffer, 64 ) != 0 )
memcmp( base64_test_dec, buffer, 64 ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );

View File

@ -81,7 +81,6 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
const unsigned char *src, size_t slen );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
@ -89,8 +88,6 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
*/
int mbedtls_base64_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,656 @@
/*
* Blowfish implementation
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The Blowfish block cipher was designed by Bruce Schneier in 1993.
* http://www.schneier.com/blowfish.html
* http://en.wikipedia.org/wiki/Blowfish_%28cipher%29
*
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_BLOWFISH_C)
#include "blowfish.h"
#include <string.h>
#if !defined(MBEDTLS_BLOWFISH_ALT)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
}
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(n,b,i) \
{ \
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
| ( (uint32_t) (b)[(i) + 3] ); \
}
#endif
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
}
#endif
static const uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2] = {
0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL,
0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L,
0x9216D5D9L, 0x8979FB1BL
};
/* declarations of data at the end of this file */
static const uint32_t S[4][256];
static uint32_t F( mbedtls_blowfish_context *ctx, uint32_t x )
{
unsigned short a, b, c, d;
uint32_t y;
d = (unsigned short)(x & 0xFF);
x >>= 8;
c = (unsigned short)(x & 0xFF);
x >>= 8;
b = (unsigned short)(x & 0xFF);
x >>= 8;
a = (unsigned short)(x & 0xFF);
y = ctx->S[0][a] + ctx->S[1][b];
y = y ^ ctx->S[2][c];
y = y + ctx->S[3][d];
return( y );
}
static void blowfish_enc( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr )
{
uint32_t Xl, Xr, temp;
short i;
Xl = *xl;
Xr = *xr;
for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS; ++i )
{
Xl = Xl ^ ctx->P[i];
Xr = F( ctx, Xl ) ^ Xr;
temp = Xl;
Xl = Xr;
Xr = temp;
}
temp = Xl;
Xl = Xr;
Xr = temp;
Xr = Xr ^ ctx->P[MBEDTLS_BLOWFISH_ROUNDS];
Xl = Xl ^ ctx->P[MBEDTLS_BLOWFISH_ROUNDS + 1];
*xl = Xl;
*xr = Xr;
}
static void blowfish_dec( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr )
{
uint32_t Xl, Xr, temp;
short i;
Xl = *xl;
Xr = *xr;
for( i = MBEDTLS_BLOWFISH_ROUNDS + 1; i > 1; --i )
{
Xl = Xl ^ ctx->P[i];
Xr = F( ctx, Xl ) ^ Xr;
temp = Xl;
Xl = Xr;
Xr = temp;
}
temp = Xl;
Xl = Xr;
Xr = temp;
Xr = Xr ^ ctx->P[1];
Xl = Xl ^ ctx->P[0];
*xl = Xl;
*xr = Xr;
}
void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_blowfish_context ) );
}
void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_zeroize( ctx, sizeof( mbedtls_blowfish_context ) );
}
/*
* Blowfish key schedule
*/
int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, const unsigned char *key,
unsigned int keybits )
{
unsigned int i, j, k;
uint32_t data, datal, datar;
if( keybits < MBEDTLS_BLOWFISH_MIN_KEY_BITS || keybits > MBEDTLS_BLOWFISH_MAX_KEY_BITS ||
( keybits % 8 ) )
{
return( MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH );
}
keybits >>= 3;
for( i = 0; i < 4; i++ )
{
for( j = 0; j < 256; j++ )
ctx->S[i][j] = S[i][j];
}
j = 0;
for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; ++i )
{
data = 0x00000000;
for( k = 0; k < 4; ++k )
{
data = ( data << 8 ) | key[j++];
if( j >= keybits )
j = 0;
}
ctx->P[i] = P[i] ^ data;
}
datal = 0x00000000;
datar = 0x00000000;
for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; i += 2 )
{
blowfish_enc( ctx, &datal, &datar );
ctx->P[i] = datal;
ctx->P[i + 1] = datar;
}
for( i = 0; i < 4; i++ )
{
for( j = 0; j < 256; j += 2 )
{
blowfish_enc( ctx, &datal, &datar );
ctx->S[i][j] = datal;
ctx->S[i][j + 1] = datar;
}
}
return( 0 );
}
/*
* Blowfish-ECB block encryption/decryption
*/
int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
int mode,
const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE],
unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] )
{
uint32_t X0, X1;
GET_UINT32_BE( X0, input, 0 );
GET_UINT32_BE( X1, input, 4 );
if( mode == MBEDTLS_BLOWFISH_DECRYPT )
{
blowfish_dec( ctx, &X0, &X1 );
}
else /* MBEDTLS_BLOWFISH_ENCRYPT */
{
blowfish_enc( ctx, &X0, &X1 );
}
PUT_UINT32_BE( X0, output, 0 );
PUT_UINT32_BE( X1, output, 4 );
return( 0 );
}
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/*
* Blowfish-CBC buffer encryption/decryption
*/
int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx,
int mode,
size_t length,
unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
const unsigned char *input,
unsigned char *output )
{
int i;
unsigned char temp[MBEDTLS_BLOWFISH_BLOCKSIZE];
if( length % MBEDTLS_BLOWFISH_BLOCKSIZE )
return( MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH );
if( mode == MBEDTLS_BLOWFISH_DECRYPT )
{
while( length > 0 )
{
memcpy( temp, input, MBEDTLS_BLOWFISH_BLOCKSIZE );
mbedtls_blowfish_crypt_ecb( ctx, mode, input, output );
for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE;i++ )
output[i] = (unsigned char)( output[i] ^ iv[i] );
memcpy( iv, temp, MBEDTLS_BLOWFISH_BLOCKSIZE );
input += MBEDTLS_BLOWFISH_BLOCKSIZE;
output += MBEDTLS_BLOWFISH_BLOCKSIZE;
length -= MBEDTLS_BLOWFISH_BLOCKSIZE;
}
}
else
{
while( length > 0 )
{
for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE; i++ )
output[i] = (unsigned char)( input[i] ^ iv[i] );
mbedtls_blowfish_crypt_ecb( ctx, mode, output, output );
memcpy( iv, output, MBEDTLS_BLOWFISH_BLOCKSIZE );
input += MBEDTLS_BLOWFISH_BLOCKSIZE;
output += MBEDTLS_BLOWFISH_BLOCKSIZE;
length -= MBEDTLS_BLOWFISH_BLOCKSIZE;
}
}
return( 0 );
}
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/*
* Blowfish CFB buffer encryption/decryption
*/
int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
const unsigned char *input,
unsigned char *output )
{
int c;
size_t n = *iv_off;
if( mode == MBEDTLS_BLOWFISH_DECRYPT )
{
while( length-- )
{
if( n == 0 )
mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv );
c = *input++;
*output++ = (unsigned char)( c ^ iv[n] );
iv[n] = (unsigned char) c;
n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE;
}
}
else
{
while( length-- )
{
if( n == 0 )
mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv );
iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE;
}
}
*iv_off = n;
return( 0 );
}
#endif /*MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/*
* Blowfish CTR buffer encryption/decryption
*/
int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[MBEDTLS_BLOWFISH_BLOCKSIZE],
unsigned char stream_block[MBEDTLS_BLOWFISH_BLOCKSIZE],
const unsigned char *input,
unsigned char *output )
{
int c, i;
size_t n = *nc_off;
while( length-- )
{
if( n == 0 ) {
mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, nonce_counter,
stream_block );
for( i = MBEDTLS_BLOWFISH_BLOCKSIZE; i > 0; i-- )
if( ++nonce_counter[i - 1] != 0 )
break;
}
c = *input++;
*output++ = (unsigned char)( c ^ stream_block[n] );
n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE;
}
*nc_off = n;
return( 0 );
}
#endif /* MBEDTLS_CIPHER_MODE_CTR */
static const uint32_t S[4][256] = {
{ 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L,
0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L,
0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L,
0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL,
0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL,
0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L,
0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL,
0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL,
0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L,
0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L,
0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL,
0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL,
0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL,
0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L,
0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L,
0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L,
0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L,
0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L,
0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL,
0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L,
0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L,
0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L,
0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L,
0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL,
0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L,
0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL,
0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL,
0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L,
0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL,
0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L,
0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL,
0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L,
0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L,
0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL,
0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L,
0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L,
0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL,
0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L,
0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL,
0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L,
0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L,
0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL,
0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L,
0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L,
0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L,
0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L,
0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L,
0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL,
0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL,
0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L,
0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L,
0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L,
0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L,
0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL,
0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L,
0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL,
0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL,
0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L,
0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L,
0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L,
0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L,
0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L,
0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L,
0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL },
{ 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L,
0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L,
0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L,
0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL,
0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L,
0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L,
0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL,
0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L,
0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L,
0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L,
0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL,
0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL,
0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L,
0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L,
0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L,
0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L,
0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL,
0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL,
0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL,
0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L,
0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL,
0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L,
0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L,
0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL,
0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL,
0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L,
0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL,
0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L,
0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL,
0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL,
0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L,
0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L,
0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L,
0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L,
0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L,
0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L,
0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L,
0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL,
0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L,
0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL,
0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L,
0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L,
0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L,
0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L,
0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L,
0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L,
0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L,
0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L,
0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L,
0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L,
0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L,
0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L,
0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L,
0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L,
0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L,
0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L,
0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL,
0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL,
0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L,
0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL,
0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L,
0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L,
0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L,
0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L },
{ 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L,
0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L,
0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL,
0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L,
0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L,
0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L,
0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL,
0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL,
0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL,
0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L,
0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L,
0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL,
0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L,
0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL,
0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L,
0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL,
0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L,
0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL,
0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L,
0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL,
0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L,
0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L,
0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL,
0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L,
0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L,
0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L,
0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L,
0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL,
0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L,
0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL,
0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L,
0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL,
0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L,
0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL,
0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL,
0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL,
0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L,
0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L,
0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL,
0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL,
0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL,
0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL,
0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL,
0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L,
0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L,
0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L,
0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L,
0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL,
0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL,
0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L,
0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L,
0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L,
0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L,
0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L,
0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L,
0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L,
0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L,
0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L,
0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L,
0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL,
0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L,
0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL,
0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L,
0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L },
{ 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL,
0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL,
0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL,
0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L,
0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L,
0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L,
0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L,
0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L,
0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L,
0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L,
0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L,
0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L,
0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L,
0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L,
0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L,
0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL,
0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL,
0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L,
0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL,
0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL,
0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL,
0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L,
0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL,
0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL,
0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L,
0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L,
0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L,
0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L,
0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL,
0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL,
0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L,
0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L,
0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L,
0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL,
0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L,
0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L,
0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L,
0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL,
0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L,
0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L,
0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L,
0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL,
0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL,
0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L,
0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L,
0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L,
0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L,
0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL,
0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L,
0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL,
0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL,
0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L,
0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L,
0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL,
0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L,
0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL,
0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L,
0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL,
0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L,
0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L,
0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL,
0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L,
0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL,
0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L }
};
#endif /* !MBEDTLS_BLOWFISH_ALT */
#endif /* MBEDTLS_BLOWFISH_C */

View File

@ -33,8 +33,6 @@
#include <stddef.h>
#include <stdint.h>
#include "platform_util.h"
#define MBEDTLS_BLOWFISH_ENCRYPT 1
#define MBEDTLS_BLOWFISH_DECRYPT 0
#define MBEDTLS_BLOWFISH_MAX_KEY_BITS 448
@ -42,87 +40,63 @@
#define MBEDTLS_BLOWFISH_ROUNDS 16 /**< Rounds to use. When increasing this value, make sure to extend the initialisation vectors */
#define MBEDTLS_BLOWFISH_BLOCKSIZE 8 /* Blowfish uses 64 bit blocks */
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#define MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x0016 )
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#define MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA -0x0016 /**< Bad input data. */
#define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */
/* MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED is deprecated and should not be used.
*/
#define MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH -0x0016 /**< Invalid key length. */
#define MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED -0x0017 /**< Blowfish hardware accelerator failed. */
#ifdef __cplusplus
extern "C" {
#endif
#define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */
#if !defined(MBEDTLS_BLOWFISH_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Blowfish context structure
*/
typedef struct mbedtls_blowfish_context
typedef struct
{
uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2]; /*!< Blowfish round keys */
uint32_t S[4][256]; /*!< key dependent S-boxes */
}
mbedtls_blowfish_context;
#else /* MBEDTLS_BLOWFISH_ALT */
#include "blowfish_alt.h"
#endif /* MBEDTLS_BLOWFISH_ALT */
/**
* \brief Initialize a Blowfish context.
* \brief Initialize Blowfish context
*
* \param ctx The Blowfish context to be initialized.
* This must not be \c NULL.
* \param ctx Blowfish context to be initialized
*/
void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx );
/**
* \brief Clear a Blowfish context.
* \brief Clear Blowfish context
*
* \param ctx The Blowfish context to be cleared.
* This may be \c NULL, in which case this function
* returns immediately. If it is not \c NULL, it must
* point to an initialized Blowfish context.
* \param ctx Blowfish context to be cleared
*/
void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx );
/**
* \brief Perform a Blowfish key schedule operation.
* \brief Blowfish key schedule
*
* \param ctx The Blowfish context to perform the key schedule on.
* \param key The encryption key. This must be a readable buffer of
* length \p keybits Bits.
* \param keybits The length of \p key in Bits. This must be between
* \c 32 and \c 448 and a multiple of \c 8.
* \param ctx Blowfish context to be initialized
* \param key encryption key
* \param keybits must be between 32 and 448 bits
*
* \return \c 0 if successful.
* \return A negative error code on failure.
* \return 0 if successful, or MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH
*/
int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, const unsigned char *key,
unsigned int keybits );
/**
* \brief Perform a Blowfish-ECB block encryption/decryption operation.
* \brief Blowfish-ECB block encryption/decryption
*
* \param ctx The Blowfish context to use. This must be initialized
* and bound to a key.
* \param mode The mode of operation. Possible values are
* #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or
* #MBEDTLS_BLOWFISH_DECRYPT for decryption.
* \param input The input block. This must be a readable buffer
* of size \c 8 Bytes.
* \param output The output block. This must be a writable buffer
* of size \c 8 Bytes.
* \param ctx Blowfish context
* \param mode MBEDTLS_BLOWFISH_ENCRYPT or MBEDTLS_BLOWFISH_DECRYPT
* \param input 8-byte input block
* \param output 8-byte output block
*
* \return \c 0 if successful.
* \return A negative error code on failure.
* \return 0 if successful
*/
int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
int mode,
@ -131,7 +105,9 @@ int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief Perform a Blowfish-CBC buffer encryption/decryption operation.
* \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
@ -141,22 +117,15 @@ int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx The Blowfish context to use. This must be initialized
* and bound to a key.
* \param mode The mode of operation. Possible values are
* #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or
* #MBEDTLS_BLOWFISH_DECRYPT for decryption.
* \param length The length of the input data in Bytes. This must be
* multiple of \c 8.
* \param iv The initialization vector. This must be a read/write buffer
* of length \c 8 Bytes. It is updated by this function.
* \param input The input data. This must be a readable buffer of length
* \p length Bytes.
* \param output The output data. This must be a writable buffer of length
* \p length Bytes.
* \param ctx Blowfish context
* \param mode MBEDTLS_BLOWFISH_ENCRYPT or MBEDTLS_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 \c 0 if successful.
* \return A negative error code on failure.
* \return 0 if successful, or
* MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH
*/
int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx,
int mode,
@ -168,7 +137,7 @@ int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx,
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/**
* \brief Perform a Blowfish CFB buffer encryption/decryption operation.
* \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
@ -178,25 +147,15 @@ int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx,
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx The Blowfish context to use. This must be initialized
* and bound to a key.
* \param mode The mode of operation. Possible values are
* #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or
* #MBEDTLS_BLOWFISH_DECRYPT for decryption.
* \param length The length of the input data in Bytes.
* \param iv_off The offset in the initialiation vector.
* The value pointed to must be smaller than \c 8 Bytes.
* It is updated by this function to support the aforementioned
* streaming usage.
* \param iv The initialization vector. This must be a read/write buffer
* of size \c 8 Bytes. It is updated after use.
* \param input The input data. This must be a readable buffer of length
* \p length Bytes.
* \param output The output data. This must be a writable buffer of length
* \p length Bytes.
* \param ctx Blowfish context
* \param mode MBEDTLS_BLOWFISH_ENCRYPT or MBEDTLS_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 \c 0 if successful.
* \return A negative error code on failure.
* \return 0 if successful
*/
int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx,
int mode,
@ -209,67 +168,22 @@ int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx,
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/**
* \brief Perform a Blowfish-CTR buffer encryption/decryption operation.
* \brief Blowfish-CTR buffer encryption/decryption
*
* \warning You must never reuse a nonce value with the same key. Doing so
* would void the encryption for the two messages encrypted with
* the same nonce and key.
* Warning: You have to keep the maximum use of your counter in mind!
*
* There are two common strategies for managing nonces with CTR:
*
* 1. You can handle everything as a single message processed over
* successive calls to this function. In that case, you want to
* set \p nonce_counter and \p nc_off to 0 for the first call, and
* then preserve the values of \p nonce_counter, \p nc_off and \p
* stream_block across calls to this function as they will be
* updated by this function.
*
* With this strategy, you must not encrypt more than 2**64
* blocks of data with the same key.
*
* 2. You can encrypt separate messages by dividing the \p
* nonce_counter buffer in two areas: the first one used for a
* per-message nonce, handled by yourself, and the second one
* updated by this function internally.
*
* For example, you might reserve the first 4 bytes for the
* per-message nonce, and the last 4 bytes for internal use. In that
* case, before calling this function on a new message you need to
* set the first 4 bytes of \p nonce_counter to your chosen nonce
* value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
* stream_block to be ignored). That way, you can encrypt at most
* 2**32 messages of up to 2**32 blocks each with the same key.
*
* The per-message nonce (or information sufficient to reconstruct
* it) needs to be communicated with the ciphertext and must be unique.
* The recommended way to ensure uniqueness is to use a message
* counter.
*
* Note that for both stategies, sizes are measured in blocks and
* that a Blowfish block is 8 bytes.
*
* \warning Upon return, \p stream_block contains sensitive data. Its
* content must not be written to insecure storage and should be
* securely discarded as soon as it's no longer needed.
*
* \param ctx The Blowfish context to use. This must be initialized
* and bound to a key.
* \param length The length of the input data in Bytes.
* \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
* should be \c 0 at the start of a stream and must be
* smaller than \c 8. It is updated by this function.
* \param nonce_counter The 64-bit nonce and counter. This must point to a
* read/write buffer of length \c 8 Bytes.
* \param stream_block The saved stream-block for resuming. This must point to
* a read/write buffer of length \c 8 Bytes.
* \param input The input data. This must be a readable buffer of
* length \p length Bytes.
* \param output The output data. This must be a writable buffer of
* length \p length Bytes.
* 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 \c 0 if successful.
* \return A negative error code on failure.
* \return 0 if successful
*/
int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx,
size_t length,
@ -284,4 +198,8 @@ int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx,
}
#endif
#else /* MBEDTLS_BLOWFISH_ALT */
#include "blowfish_alt.h"
#endif /* MBEDTLS_BLOWFISH_ALT */
#endif /* blowfish.h */

View File

@ -571,8 +571,9 @@
#endif /* TriCore */
/*
* Note, 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.
* 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
@ -642,24 +643,6 @@
"r6", "r7", "r8", "r9", "cc" \
);
#elif (__ARM_ARCH >= 6) && \
defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)
#define MULADDC_INIT \
asm(
#define MULADDC_CORE \
"ldr r0, [%0], #4 \n\t" \
"ldr r1, [%1] \n\t" \
"umaal r1, %2, %3, r0 \n\t" \
"str r1, [%1], #4 \n\t"
#define MULADDC_STOP \
: "=r" (s), "=r" (d), "=r" (c) \
: "r" (b), "0" (s), "1" (d), "2" (c) \
: "r0", "r1", "memory" \
);
#else
#define MULADDC_INIT \

File diff suppressed because it is too large Load Diff

View File

@ -33,107 +33,78 @@
#include <stddef.h>
#include <stdint.h>
#include "platform_util.h"
#define MBEDTLS_CAMELLIA_ENCRYPT 1
#define MBEDTLS_CAMELLIA_DECRYPT 0
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#define MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x0024 )
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#define MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA -0x0024 /**< Bad input data. */
#define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 /**< Invalid data input length. */
/* MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED is deprecated and should not be used.
*/
#define MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH -0x0024 /**< Invalid key length. */
#define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 /**< Invalid data input length. */
#define MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED -0x0027 /**< Camellia hardware accelerator failed. */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_CAMELLIA_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief CAMELLIA context structure
*/
typedef struct mbedtls_camellia_context
typedef struct
{
int nr; /*!< number of rounds */
uint32_t rk[68]; /*!< CAMELLIA round keys */
}
mbedtls_camellia_context;
#else /* MBEDTLS_CAMELLIA_ALT */
#include "camellia_alt.h"
#endif /* MBEDTLS_CAMELLIA_ALT */
/**
* \brief Initialize a CAMELLIA context.
* \brief Initialize CAMELLIA context
*
* \param ctx The CAMELLIA context to be initialized.
* This must not be \c NULL.
* \param ctx CAMELLIA context to be initialized
*/
void mbedtls_camellia_init( mbedtls_camellia_context *ctx );
/**
* \brief Clear a CAMELLIA context.
* \brief Clear CAMELLIA context
*
* \param ctx The CAMELLIA context to be cleared. This may be \c NULL,
* in which case this function returns immediately. If it is not
* \c NULL, it must be initialized.
* \param ctx CAMELLIA context to be cleared
*/
void mbedtls_camellia_free( mbedtls_camellia_context *ctx );
/**
* \brief Perform a CAMELLIA key schedule operation for encryption.
* \brief CAMELLIA key schedule (encryption)
*
* \param ctx The CAMELLIA context to use. This must be initialized.
* \param key The encryption key to use. This must be a readable buffer
* of size \p keybits Bits.
* \param keybits The length of \p key in Bits. This must be either \c 128,
* \c 192 or \c 256.
* \param ctx CAMELLIA context to be initialized
* \param key encryption key
* \param keybits must be 128, 192 or 256
*
* \return \c 0 if successful.
* \return A negative error code on failure.
* \return 0 if successful, or MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH
*/
int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx,
const unsigned char *key,
unsigned int keybits );
int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, const unsigned char *key,
unsigned int keybits );
/**
* \brief Perform a CAMELLIA key schedule operation for decryption.
* \brief CAMELLIA key schedule (decryption)
*
* \param ctx The CAMELLIA context to use. This must be initialized.
* \param key The decryption key. This must be a readable buffer
* of size \p keybits Bits.
* \param keybits The length of \p key in Bits. This must be either \c 128,
* \c 192 or \c 256.
* \param ctx CAMELLIA context to be initialized
* \param key decryption key
* \param keybits must be 128, 192 or 256
*
* \return \c 0 if successful.
* \return A negative error code on failure.
* \return 0 if successful, or MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH
*/
int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx,
const unsigned char *key,
unsigned int keybits );
int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx, const unsigned char *key,
unsigned int keybits );
/**
* \brief Perform a CAMELLIA-ECB block encryption/decryption operation.
* \brief CAMELLIA-ECB block encryption/decryption
*
* \param ctx The CAMELLIA context to use. This must be initialized
* and bound to a key.
* \param mode The mode of operation. This must be either
* #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
* \param input The input block. This must be a readable buffer
* of size \c 16 Bytes.
* \param output The output block. This must be a writable buffer
* of size \c 16 Bytes.
* \param ctx CAMELLIA context
* \param mode MBEDTLS_CAMELLIA_ENCRYPT or MBEDTLS_CAMELLIA_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return \c 0 if successful.
* \return A negative error code on failure.
* \return 0 if successful
*/
int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
int mode,
@ -142,7 +113,9 @@ int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief Perform a CAMELLIA-CBC buffer encryption/decryption operation.
* \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
@ -152,22 +125,15 @@ int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx The CAMELLIA context to use. This must be initialized
* and bound to a key.
* \param mode The mode of operation. This must be either
* #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
* \param length The length in Bytes of the input data \p input.
* This must be a multiple of \c 16 Bytes.
* \param iv The initialization vector. This must be a read/write buffer
* of length \c 16 Bytes. It is updated to allow streaming
* use as explained above.
* \param input The buffer holding the input data. This must point to a
* readable buffer of length \p length Bytes.
* \param output The buffer holding the output data. This must point to a
* writable buffer of length \p length Bytes.
* \param ctx CAMELLIA context
* \param mode MBEDTLS_CAMELLIA_ENCRYPT or MBEDTLS_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 \c 0 if successful.
* \return A negative error code on failure.
* \return 0 if successful, or
* MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH
*/
int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
int mode,
@ -179,14 +145,11 @@ int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/**
* \brief Perform a CAMELLIA-CFB128 buffer encryption/decryption
* operation.
* \brief CAMELLIA-CFB128 buffer encryption/decryption
*
* \note Due to the nature of CFB mode, you should use the same
* key for both encryption and decryption. In particular, calls
* to this function should be preceded by a key-schedule via
* mbedtls_camellia_setkey_enc() regardless of whether \p mode
* is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
* Note: Due to the nature of CFB you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* mbedtls_camellia_setkey_enc() for both MBEDTLS_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
@ -196,24 +159,16 @@ int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx The CAMELLIA context to use. This must be initialized
* and bound to a key.
* \param mode The mode of operation. This must be either
* #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
* \param length The length of the input data \p input. Any value is allowed.
* \param iv_off The current offset in the IV. This must be smaller
* than \c 16 Bytes. It is updated after this call to allow
* the aforementioned streaming usage.
* \param iv The initialization vector. This must be a read/write buffer
* of length \c 16 Bytes. It is updated after this call to
* allow the aforementioned streaming usage.
* \param input The buffer holding the input data. This must be a readable
* buffer of size \p length Bytes.
* \param output The buffer to hold the output data. This must be a writable
* buffer of length \p length Bytes.
* \param ctx CAMELLIA context
* \param mode MBEDTLS_CAMELLIA_ENCRYPT or MBEDTLS_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 \c 0 if successful.
* \return A negative error code on failure.
* \return 0 if successful, or
* MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH
*/
int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx,
int mode,
@ -226,78 +181,26 @@ int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx,
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/**
* \brief Perform a CAMELLIA-CTR buffer encryption/decryption operation.
* \brief CAMELLIA-CTR buffer encryption/decryption
*
* *note Due to the nature of CTR mode, you should use the same
* key for both encryption and decryption. In particular, calls
* to this function should be preceded by a key-schedule via
* mbedtls_camellia_setkey_enc() regardless of whether \p mode
* is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
* Warning: You have to keep the maximum use of your counter in mind!
*
* \warning You must never reuse a nonce value with the same key. Doing so
* would void the encryption for the two messages encrypted with
* the same nonce and key.
* Note: Due to the nature of CTR you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* mbedtls_camellia_setkey_enc() for both MBEDTLS_CAMELLIA_ENCRYPT and MBEDTLS_CAMELLIA_DECRYPT.
*
* There are two common strategies for managing nonces with CTR:
*
* 1. You can handle everything as a single message processed over
* successive calls to this function. In that case, you want to
* set \p nonce_counter and \p nc_off to 0 for the first call, and
* then preserve the values of \p nonce_counter, \p nc_off and \p
* stream_block across calls to this function as they will be
* updated by this function.
*
* With this strategy, you must not encrypt more than 2**128
* blocks of data with the same key.
*
* 2. You can encrypt separate messages by dividing the \p
* nonce_counter buffer in two areas: the first one used for a
* per-message nonce, handled by yourself, and the second one
* updated by this function internally.
*
* For example, you might reserve the first \c 12 Bytes for the
* per-message nonce, and the last \c 4 Bytes for internal use.
* In that case, before calling this function on a new message you
* need to set the first \c 12 Bytes of \p nonce_counter to your
* chosen nonce value, the last four to \c 0, and \p nc_off to \c 0
* (which will cause \p stream_block to be ignored). That way, you
* can encrypt at most \c 2**96 messages of up to \c 2**32 blocks
* each with the same key.
*
* The per-message nonce (or information sufficient to reconstruct
* it) needs to be communicated with the ciphertext and must be
* unique. The recommended way to ensure uniqueness is to use a
* message counter. An alternative is to generate random nonces,
* but this limits the number of messages that can be securely
* encrypted: for example, with 96-bit random nonces, you should
* not encrypt more than 2**32 messages with the same key.
*
* Note that for both stategies, sizes are measured in blocks and
* that a CAMELLIA block is \c 16 Bytes.
*
* \warning Upon return, \p stream_block contains sensitive data. Its
* content must not be written to insecure storage and should be
* securely discarded as soon as it's no longer needed.
*
* \param ctx The CAMELLIA context to use. This must be initialized
* and bound to a key.
* \param length The length of the input data \p input in Bytes.
* Any value is allowed.
* \param nc_off The offset in the current \p stream_block (for resuming
* \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 \c 0 at the start of a stream. It is updated
* at the end of this call.
* \param nonce_counter The 128-bit nonce and counter. This must be a read/write
* buffer of length \c 16 Bytes.
* \param stream_block The saved stream-block for resuming. This must be a
* read/write buffer of length \c 16 Bytes.
* \param input The input data stream. This must be a readable buffer of
* size \p length Bytes.
* \param output The output data stream. This must be a writable buffer
* of size \p length Bytes.
* 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 \c 0 if successful.
* \return A negative error code on failure.
* \return 0 if successful
*/
int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx,
size_t length,
@ -308,7 +211,17 @@ int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CTR */
#if defined(MBEDTLS_SELF_TEST)
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_CAMELLIA_ALT */
#include "camellia_alt.h"
#endif /* MBEDTLS_CAMELLIA_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Checkup routine
@ -317,8 +230,6 @@ int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx,
*/
int mbedtls_camellia_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,479 @@
/*
* NIST SP800-38C compliant CCM implementation
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* Definition of CCM:
* http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
* RFC 3610 "Counter with CBC-MAC (CCM)"
*
* Related:
* RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_CCM_C)
#include "ccm.h"
#include <string.h>
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
#if defined(MBEDTLS_PLATFORM_C)
#include "platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
#if !defined(MBEDTLS_CCM_ALT)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
}
#define CCM_ENCRYPT 0
#define CCM_DECRYPT 1
/*
* Initialize context
*/
void mbedtls_ccm_init( mbedtls_ccm_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_ccm_context ) );
}
int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
mbedtls_cipher_id_t cipher,
const unsigned char *key,
unsigned int keybits )
{
int ret;
const mbedtls_cipher_info_t *cipher_info;
cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
if( cipher_info == NULL )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
if( cipher_info->block_size != 16 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
mbedtls_cipher_free( &ctx->cipher_ctx );
if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
return( ret );
if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
MBEDTLS_ENCRYPT ) ) != 0 )
{
return( ret );
}
return( 0 );
}
/*
* Free context
*/
void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
{
mbedtls_cipher_free( &ctx->cipher_ctx );
mbedtls_zeroize( ctx, sizeof( mbedtls_ccm_context ) );
}
/*
* Macros for common operations.
* Results in smaller compiled code than static inline functions.
*/
/*
* Update the CBC-MAC state in y using a block in b
* (Always using b as the source helps the compiler optimise a bit better.)
*/
#define UPDATE_CBC_MAC \
for( i = 0; i < 16; i++ ) \
y[i] ^= b[i]; \
\
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \
return( ret );
/*
* Encrypt or decrypt a partial block with CTR
* Warning: using b for temporary storage! src and dst must not be b!
* This avoids allocating one more 16 bytes buffer while allowing src == dst.
*/
#define CTR_CRYPT( dst, src, len ) \
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, 16, b, &olen ) ) != 0 ) \
return( ret ); \
\
for( i = 0; i < len; i++ ) \
dst[i] = src[i] ^ b[i];
/*
* Authenticated encryption or decryption
*/
static int ccm_auth_crypt( mbedtls_ccm_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,
unsigned char *tag, size_t tag_len )
{
int ret;
unsigned char i;
unsigned char q;
size_t len_left, olen;
unsigned char b[16];
unsigned char y[16];
unsigned char ctr[16];
const unsigned char *src;
unsigned char *dst;
/*
* Check length requirements: SP800-38C A.1
* Additional requirement: a < 2^16 - 2^8 to simplify the code.
* 'length' checked later (when writing it to the first block)
*/
if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
/* Also implies q is within bounds */
if( iv_len < 7 || iv_len > 13 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
if( add_len > 0xFF00 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
q = 16 - 1 - (unsigned char) iv_len;
/*
* First block B_0:
* 0 .. 0 flags
* 1 .. iv_len nonce (aka iv)
* iv_len+1 .. 15 length
*
* With flags as (bits):
* 7 0
* 6 add present?
* 5 .. 3 (t - 2) / 2
* 2 .. 0 q - 1
*/
b[0] = 0;
b[0] |= ( add_len > 0 ) << 6;
b[0] |= ( ( tag_len - 2 ) / 2 ) << 3;
b[0] |= q - 1;
memcpy( b + 1, iv, iv_len );
for( i = 0, len_left = length; i < q; i++, len_left >>= 8 )
b[15-i] = (unsigned char)( len_left & 0xFF );
if( len_left > 0 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
/* Start CBC-MAC with first block */
memset( y, 0, 16 );
UPDATE_CBC_MAC;
/*
* If there is additional data, update CBC-MAC with
* add_len, add, 0 (padding to a block boundary)
*/
if( add_len > 0 )
{
size_t use_len;
len_left = add_len;
src = add;
memset( b, 0, 16 );
b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF );
b[1] = (unsigned char)( ( add_len ) & 0xFF );
use_len = len_left < 16 - 2 ? len_left : 16 - 2;
memcpy( b + 2, src, use_len );
len_left -= use_len;
src += use_len;
UPDATE_CBC_MAC;
while( len_left > 0 )
{
use_len = len_left > 16 ? 16 : len_left;
memset( b, 0, 16 );
memcpy( b, src, use_len );
UPDATE_CBC_MAC;
len_left -= use_len;
src += use_len;
}
}
/*
* Prepare counter block for encryption:
* 0 .. 0 flags
* 1 .. iv_len nonce (aka iv)
* iv_len+1 .. 15 counter (initially 1)
*
* With flags as (bits):
* 7 .. 3 0
* 2 .. 0 q - 1
*/
ctr[0] = q - 1;
memcpy( ctr + 1, iv, iv_len );
memset( ctr + 1 + iv_len, 0, q );
ctr[15] = 1;
/*
* Authenticate and {en,de}crypt the message.
*
* The only difference between encryption and decryption is
* the respective order of authentication and {en,de}cryption.
*/
len_left = length;
src = input;
dst = output;
while( len_left > 0 )
{
size_t use_len = len_left > 16 ? 16 : len_left;
if( mode == CCM_ENCRYPT )
{
memset( b, 0, 16 );
memcpy( b, src, use_len );
UPDATE_CBC_MAC;
}
CTR_CRYPT( dst, src, use_len );
if( mode == CCM_DECRYPT )
{
memset( b, 0, 16 );
memcpy( b, dst, use_len );
UPDATE_CBC_MAC;
}
dst += use_len;
src += use_len;
len_left -= use_len;
/*
* Increment counter.
* No need to check for overflow thanks to the length check above.
*/
for( i = 0; i < q; i++ )
if( ++ctr[15-i] != 0 )
break;
}
/*
* Authentication: reset counter and crypt/mask internal tag
*/
for( i = 0; i < q; i++ )
ctr[15-i] = 0;
CTR_CRYPT( y, y, 16 );
memcpy( tag, y, tag_len );
return( 0 );
}
/*
* Authenticated encryption
*/
int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *iv, size_t iv_len,
const unsigned char *add, size_t add_len,
const unsigned char *input, unsigned char *output,
unsigned char *tag, size_t tag_len )
{
return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len,
add, add_len, input, output, tag, tag_len ) );
}
/*
* Authenticated decryption
*/
int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
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 )
{
int ret;
unsigned char check_tag[16];
unsigned char i;
int diff;
if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length,
iv, iv_len, add, add_len,
input, output, check_tag, tag_len ) ) != 0 )
{
return( ret );
}
/* Check tag in "constant-time" */
for( diff = 0, i = 0; i < tag_len; i++ )
diff |= tag[i] ^ check_tag[i];
if( diff != 0 )
{
mbedtls_zeroize( output, length );
return( MBEDTLS_ERR_CCM_AUTH_FAILED );
}
return( 0 );
}
#endif /* !MBEDTLS_CCM_ALT */
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
/*
* Examples 1 to 3 from SP800-38C Appendix C
*/
#define NB_TESTS 3
#define CCM_SELFTEST_PT_MAX_LEN 24
#define CCM_SELFTEST_CT_MAX_LEN 32
/*
* The data is the same for all tests, only the used length changes
*/
static const unsigned char key[] = {
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
};
static const unsigned char iv[] = {
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b
};
static const unsigned char ad[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13
};
static const unsigned char msg[CCM_SELFTEST_PT_MAX_LEN] = {
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
};
static const size_t iv_len [NB_TESTS] = { 7, 8, 12 };
static const size_t add_len[NB_TESTS] = { 8, 16, 20 };
static const size_t msg_len[NB_TESTS] = { 4, 16, 24 };
static const size_t tag_len[NB_TESTS] = { 4, 6, 8 };
static const unsigned char res[NB_TESTS][CCM_SELFTEST_CT_MAX_LEN] = {
{ 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d },
{ 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62,
0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d,
0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd },
{ 0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a,
0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b,
0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5,
0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 }
};
int mbedtls_ccm_self_test( int verbose )
{
mbedtls_ccm_context ctx;
/*
* Some hardware accelerators require the input and output buffers
* would be in RAM, because the flash is not accessible.
* Use buffers on the stack to hold the test vectors data.
*/
unsigned char plaintext[CCM_SELFTEST_PT_MAX_LEN];
unsigned char ciphertext[CCM_SELFTEST_CT_MAX_LEN];
size_t i;
int ret;
mbedtls_ccm_init( &ctx );
if( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( " CCM: setup failed" );
return( 1 );
}
for( i = 0; i < NB_TESTS; i++ )
{
if( verbose != 0 )
mbedtls_printf( " CCM-AES #%u: ", (unsigned int) i + 1 );
memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
memset( ciphertext, 0, CCM_SELFTEST_CT_MAX_LEN );
memcpy( plaintext, msg, msg_len[i] );
ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len[i],
iv, iv_len[i], ad, add_len[i],
plaintext, ciphertext,
ciphertext + msg_len[i], tag_len[i] );
if( ret != 0 ||
memcmp( ciphertext, res[i], msg_len[i] + tag_len[i] ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i],
iv, iv_len[i], ad, add_len[i],
ciphertext, plaintext,
ciphertext + msg_len[i], tag_len[i] );
if( ret != 0 ||
memcmp( plaintext, msg, msg_len[i] ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
mbedtls_printf( "passed\n" );
}
mbedtls_ccm_free( &ctx );
if( verbose != 0 )
mbedtls_printf( "\n" );
return( 0 );
}
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
#endif /* MBEDTLS_CCM_C */

View File

@ -1,11 +1,8 @@
/**
* \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.
* \brief 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>
@ -14,18 +11,6 @@
* <li>Nonce - A unique value that is assigned to the payload and the
* associated data.</li></ul>
*
* Definition of CCM:
* http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
* RFC 3610 "Counter with CBC-MAC (CCM)"
*
* Related:
* RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
*
* Definition of CCM*:
* IEEE 802.15.4 - IEEE Standard for Local and metropolitan area networks
* Integer representation is fixed most-significant-octet-first order and
* the representation of octets is most-significant-bit-first order. This is
* consistent with RFC 3610.
*/
/*
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
@ -59,38 +44,31 @@
#define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to the function. */
#define MBEDTLS_ERR_CCM_AUTH_FAILED -0x000F /**< Authenticated decryption failed. */
/* MBEDTLS_ERR_CCM_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_CCM_HW_ACCEL_FAILED -0x0011 /**< CCM hardware accelerator failed. */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_CCM_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief The CCM context-type definition. The CCM context is passed
* to the APIs called.
*/
typedef struct mbedtls_ccm_context
{
typedef struct {
mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */
}
mbedtls_ccm_context;
#else /* MBEDTLS_CCM_ALT */
#include "ccm_alt.h"
#endif /* MBEDTLS_CCM_ALT */
/**
* \brief This function initializes the specified CCM context,
* to make references valid, and prepare the context
* for mbedtls_ccm_setkey() or mbedtls_ccm_free().
*
* \param ctx The CCM context to initialize. This must not be \c NULL.
* \param ctx The CCM context to initialize.
*/
void mbedtls_ccm_init( mbedtls_ccm_context *ctx );
@ -98,14 +76,12 @@ void mbedtls_ccm_init( mbedtls_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. This must be an initialized
* context.
* \param ctx The CCM context to initialize.
* \param cipher The 128-bit block cipher to use.
* \param key The encryption key. This must not be \c NULL.
* \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.
* \return \c 0 on success, or a cipher-specific error code.
*/
int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
mbedtls_cipher_id_t cipher,
@ -116,96 +92,36 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
* \brief This function releases and clears the specified CCM context
* and underlying cipher sub-context.
*
* \param ctx The CCM context to clear. If this is \c NULL, the function
* has no effect. Otherwise, this must be initialized.
* \param ctx The CCM context to clear.
*/
void mbedtls_ccm_free( mbedtls_ccm_context *ctx );
/**
* \brief This function encrypts a buffer using CCM.
*
* \note The tag is written to a separate buffer. To concatenate
* the \p tag with the \p output, as done in <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. This must be
* initialized and bound to a key.
* \param ctx The CCM context to use for encryption.
* \param length The length of the input data in Bytes.
* \param iv The initialization vector (nonce). This must be a readable
* buffer of at least \p iv_len Bytes.
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
* or 13. The length L of the message length field is
* 15 - \p iv_len.
* \param add The additional data field. If \p add_len is greater than
* zero, \p add must be a readable buffer of at least that
* length.
* \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.
* This must be less than `2^16 - 2^8`.
* \param input The buffer holding the input data. If \p length is greater
* than zero, \p input must be a readable buffer of at least
* that length.
* \param output The buffer holding the output data. If \p length is greater
* than zero, \p output must be a writable buffer of at least
* that length.
* \param tag The buffer holding the authentication field. This must be a
* readable buffer of at least \p tag_len Bytes.
* \param tag_len The length of the authentication field to generate 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 mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *iv, size_t iv_len,
const unsigned char *add, size_t add_len,
const unsigned char *input, unsigned char *output,
unsigned char *tag, size_t tag_len );
/**
* \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.
*
* \note When using this function in a variable tag length context,
* the tag length has to be encoded into the \p iv passed to
* this function.
*
* \param ctx The CCM context to use for encryption. This must be
* initialized and bound to a key.
* \param length The length of the input data in Bytes.
* \param iv The initialization vector (nonce). This must be a readable
* buffer of at least \p iv_len Bytes.
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
* or 13. The length L of the message length field is
* 15 - \p iv_len.
* \param add The additional data field. This must be a readable buffer of
* at least \p add_len Bytes.
* \param add_len The length of additional data in Bytes.
* This must be less than 2^16 - 2^8.
* \param input The buffer holding the input data. If \p length is greater
* than zero, \p input must be a readable buffer of at least
* that length.
* \param output The buffer holding the output data. If \p length is greater
* than zero, \p output must be a writable buffer of at least
* that length.
* \param tag The buffer holding the authentication field. This must be a
* readable buffer of at least \p tag_len Bytes.
* \param tag_len The length of the authentication field to generate in Bytes:
* 0, 4, 6, 8, 10, 12, 14 or 16.
*
* \warning Passing \c 0 as \p tag_len means that the message is no
* longer authenticated.
*
* \return \c 0 on success.
* \return A CCM or cipher-specific error code on failure.
*/
int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *iv, size_t iv_len,
const unsigned char *add, size_t add_len,
const unsigned char *input, unsigned char *output,
@ -215,32 +131,22 @@ int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
* \brief This function performs a CCM authenticated decryption of a
* buffer.
*
* \param ctx The CCM context to use for decryption. This must be
* initialized and bound to a key.
* \param ctx The CCM context to use for decryption.
* \param length The length of the input data in Bytes.
* \param iv The initialization vector (nonce). This must be a readable
* buffer of at least \p iv_len Bytes.
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
* or 13. The length L of the message length field is
* 15 - \p iv_len.
* \param add The additional data field. This must be a readable buffer
* of at least that \p add_len 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.
* This must be less than 2^16 - 2^8.
* \param input The buffer holding the input data. If \p length is greater
* than zero, \p input must be a readable buffer of at least
* that length.
* \param output The buffer holding the output data. If \p length is greater
* than zero, \p output must be a writable buffer of at least
* that length.
* \param tag The buffer holding the authentication field. This must be a
* readable buffer of at least \p tag_len Bytes.
* \param tag_len The length of the authentication field to generate 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 #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match.
* \return A cipher-specific error code on calculation failure.
* \return 0 if successful and authenticated, or
* #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match.
*/
int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *iv, size_t iv_len,
@ -248,57 +154,23 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *input, unsigned char *output,
const unsigned char *tag, size_t tag_len );
/**
* \brief This function performs a CCM* authenticated decryption of a
* buffer.
*
* \note When using this function in a variable tag length context,
* the tag length has to be decoded from \p iv and passed to
* this function as \p tag_len. (\p tag needs to be adjusted
* accordingly.)
*
* \param ctx The CCM context to use for decryption. This must be
* initialized and bound to a key.
* \param length The length of the input data in Bytes.
* \param iv The initialization vector (nonce). This must be a readable
* buffer of at least \p iv_len Bytes.
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
* or 13. The length L of the message length field is
* 15 - \p iv_len.
* \param add The additional data field. This must be a readable buffer of
* at least that \p add_len Bytes.
* \param add_len The length of additional data in Bytes.
* This must be less than 2^16 - 2^8.
* \param input The buffer holding the input data. If \p length is greater
* than zero, \p input must be a readable buffer of at least
* that length.
* \param output The buffer holding the output data. If \p length is greater
* than zero, \p output must be a writable buffer of at least
* that length.
* \param tag The buffer holding the authentication field. This must be a
* readable buffer of at least \p tag_len Bytes.
* \param tag_len The length of the authentication field in Bytes.
* 0, 4, 6, 8, 10, 12, 14 or 16.
*
* \warning Passing \c 0 as \p tag_len means that the message is nos
* longer authenticated.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match.
* \return A cipher-specific error code on calculation failure.
*/
int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *iv, size_t iv_len,
const unsigned char *add, size_t add_len,
const unsigned char *input, unsigned char *output,
const unsigned char *tag, size_t tag_len );
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_CCM_ALT */
#include "ccm_alt.h"
#endif /* MBEDTLS_CCM_ALT */
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
/**
* \brief The CCM checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
* \return \c 0 on success, or \c 1 on failure.
*/
int mbedtls_ccm_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */

File diff suppressed because it is too large Load Diff

View File

@ -36,214 +36,68 @@
extern "C" {
#endif
/* List of all PEM-encoded CA certificates, terminated by NULL;
* PEM encoded if MBEDTLS_PEM_PARSE_C is enabled, DER encoded
* otherwise. */
extern const char * mbedtls_test_cas[];
extern const size_t mbedtls_test_cas_len[];
/* List of all DER-encoded CA certificates, terminated by NULL */
extern const unsigned char * mbedtls_test_cas_der[];
extern const size_t mbedtls_test_cas_der_len[];
#if defined(MBEDTLS_PEM_PARSE_C)
/* Concatenation of all CA certificates in PEM format if available */
extern const char mbedtls_test_cas_pem[];
extern const size_t mbedtls_test_cas_pem_len;
#endif /* MBEDTLS_PEM_PARSE_C */
#endif
/* List of all CA certificates, terminated by NULL */
extern const char * mbedtls_test_cas[];
extern const size_t mbedtls_test_cas_len[];
/*
* CA test certificates
* Convenience for users who just want a certificate:
* RSA by default, or ECDSA if RSA is not available
*/
extern const char mbedtls_test_ca_crt_ec_pem[];
extern const char mbedtls_test_ca_key_ec_pem[];
extern const char mbedtls_test_ca_pwd_ec_pem[];
extern const char mbedtls_test_ca_key_rsa_pem[];
extern const char mbedtls_test_ca_pwd_rsa_pem[];
extern const char mbedtls_test_ca_crt_rsa_sha1_pem[];
extern const char mbedtls_test_ca_crt_rsa_sha256_pem[];
extern const unsigned char mbedtls_test_ca_crt_ec_der[];
extern const unsigned char mbedtls_test_ca_key_ec_der[];
extern const unsigned char mbedtls_test_ca_key_rsa_der[];
extern const unsigned char mbedtls_test_ca_crt_rsa_sha1_der[];
extern const unsigned char mbedtls_test_ca_crt_rsa_sha256_der[];
extern const size_t mbedtls_test_ca_crt_ec_pem_len;
extern const size_t mbedtls_test_ca_key_ec_pem_len;
extern const size_t mbedtls_test_ca_pwd_ec_pem_len;
extern const size_t mbedtls_test_ca_key_rsa_pem_len;
extern const size_t mbedtls_test_ca_pwd_rsa_pem_len;
extern const size_t mbedtls_test_ca_crt_rsa_sha1_pem_len;
extern const size_t mbedtls_test_ca_crt_rsa_sha256_pem_len;
extern const size_t mbedtls_test_ca_crt_ec_der_len;
extern const size_t mbedtls_test_ca_key_ec_der_len;
extern const size_t mbedtls_test_ca_pwd_ec_der_len;
extern const size_t mbedtls_test_ca_key_rsa_der_len;
extern const size_t mbedtls_test_ca_pwd_rsa_der_len;
extern const size_t mbedtls_test_ca_crt_rsa_sha1_der_len;
extern const size_t mbedtls_test_ca_crt_rsa_sha256_der_len;
/* Config-dependent dispatch between PEM and DER encoding
* (PEM if enabled, otherwise DER) */
extern const char mbedtls_test_ca_crt_ec[];
extern const char mbedtls_test_ca_key_ec[];
extern const char mbedtls_test_ca_pwd_ec[];
extern const char mbedtls_test_ca_key_rsa[];
extern const char mbedtls_test_ca_pwd_rsa[];
extern const char mbedtls_test_ca_crt_rsa_sha1[];
extern const char mbedtls_test_ca_crt_rsa_sha256[];
extern const size_t mbedtls_test_ca_crt_ec_len;
extern const size_t mbedtls_test_ca_key_ec_len;
extern const size_t mbedtls_test_ca_pwd_ec_len;
extern const size_t mbedtls_test_ca_key_rsa_len;
extern const size_t mbedtls_test_ca_pwd_rsa_len;
extern const size_t mbedtls_test_ca_crt_rsa_sha1_len;
extern const size_t mbedtls_test_ca_crt_rsa_sha256_len;
/* Config-dependent dispatch between SHA-1 and SHA-256
* (SHA-256 if enabled, otherwise SHA-1) */
extern const char mbedtls_test_ca_crt_rsa[];
extern const size_t mbedtls_test_ca_crt_rsa_len;
/* Config-dependent dispatch between EC and RSA
* (RSA if enabled, otherwise EC) */
extern const char * mbedtls_test_ca_crt;
extern const char * mbedtls_test_ca_key;
extern const char * mbedtls_test_ca_pwd;
extern const size_t mbedtls_test_ca_crt_len;
extern const char * mbedtls_test_ca_key;
extern const size_t mbedtls_test_ca_key_len;
extern const char * mbedtls_test_ca_pwd;
extern const size_t mbedtls_test_ca_pwd_len;
/*
* Server test certificates
*/
extern const char mbedtls_test_srv_crt_ec_pem[];
extern const char mbedtls_test_srv_key_ec_pem[];
extern const char mbedtls_test_srv_pwd_ec_pem[];
extern const char mbedtls_test_srv_key_rsa_pem[];
extern const char mbedtls_test_srv_pwd_rsa_pem[];
extern const char mbedtls_test_srv_crt_rsa_sha1_pem[];
extern const char mbedtls_test_srv_crt_rsa_sha256_pem[];
extern const unsigned char mbedtls_test_srv_crt_ec_der[];
extern const unsigned char mbedtls_test_srv_key_ec_der[];
extern const unsigned char mbedtls_test_srv_key_rsa_der[];
extern const unsigned char mbedtls_test_srv_crt_rsa_sha1_der[];
extern const unsigned char mbedtls_test_srv_crt_rsa_sha256_der[];
extern const size_t mbedtls_test_srv_crt_ec_pem_len;
extern const size_t mbedtls_test_srv_key_ec_pem_len;
extern const size_t mbedtls_test_srv_pwd_ec_pem_len;
extern const size_t mbedtls_test_srv_key_rsa_pem_len;
extern const size_t mbedtls_test_srv_pwd_rsa_pem_len;
extern const size_t mbedtls_test_srv_crt_rsa_sha1_pem_len;
extern const size_t mbedtls_test_srv_crt_rsa_sha256_pem_len;
extern const size_t mbedtls_test_srv_crt_ec_der_len;
extern const size_t mbedtls_test_srv_key_ec_der_len;
extern const size_t mbedtls_test_srv_pwd_ec_der_len;
extern const size_t mbedtls_test_srv_key_rsa_der_len;
extern const size_t mbedtls_test_srv_pwd_rsa_der_len;
extern const size_t mbedtls_test_srv_crt_rsa_sha1_der_len;
extern const size_t mbedtls_test_srv_crt_rsa_sha256_der_len;
/* Config-dependent dispatch between PEM and DER encoding
* (PEM if enabled, otherwise DER) */
extern const char mbedtls_test_srv_crt_ec[];
extern const char mbedtls_test_srv_key_ec[];
extern const char mbedtls_test_srv_pwd_ec[];
extern const char mbedtls_test_srv_key_rsa[];
extern const char mbedtls_test_srv_pwd_rsa[];
extern const char mbedtls_test_srv_crt_rsa_sha1[];
extern const char mbedtls_test_srv_crt_rsa_sha256[];
extern const size_t mbedtls_test_srv_crt_ec_len;
extern const size_t mbedtls_test_srv_key_ec_len;
extern const size_t mbedtls_test_srv_pwd_ec_len;
extern const size_t mbedtls_test_srv_key_rsa_len;
extern const size_t mbedtls_test_srv_pwd_rsa_len;
extern const size_t mbedtls_test_srv_crt_rsa_sha1_len;
extern const size_t mbedtls_test_srv_crt_rsa_sha256_len;
/* Config-dependent dispatch between SHA-1 and SHA-256
* (SHA-256 if enabled, otherwise SHA-1) */
extern const char mbedtls_test_srv_crt_rsa[];
extern const size_t mbedtls_test_srv_crt_rsa_len;
/* Config-dependent dispatch between EC and RSA
* (RSA if enabled, otherwise EC) */
extern const char * mbedtls_test_srv_crt;
extern const char * mbedtls_test_srv_key;
extern const char * mbedtls_test_srv_pwd;
extern const size_t mbedtls_test_srv_crt_len;
extern const char * mbedtls_test_srv_key;
extern const size_t mbedtls_test_srv_key_len;
extern const size_t mbedtls_test_srv_pwd_len;
/*
* Client test certificates
*/
extern const char mbedtls_test_cli_crt_ec_pem[];
extern const char mbedtls_test_cli_key_ec_pem[];
extern const char mbedtls_test_cli_pwd_ec_pem[];
extern const char mbedtls_test_cli_key_rsa_pem[];
extern const char mbedtls_test_cli_pwd_rsa_pem[];
extern const char mbedtls_test_cli_crt_rsa_pem[];
extern const unsigned char mbedtls_test_cli_crt_ec_der[];
extern const unsigned char mbedtls_test_cli_key_ec_der[];
extern const unsigned char mbedtls_test_cli_key_rsa_der[];
extern const unsigned char mbedtls_test_cli_crt_rsa_der[];
extern const size_t mbedtls_test_cli_crt_ec_pem_len;
extern const size_t mbedtls_test_cli_key_ec_pem_len;
extern const size_t mbedtls_test_cli_pwd_ec_pem_len;
extern const size_t mbedtls_test_cli_key_rsa_pem_len;
extern const size_t mbedtls_test_cli_pwd_rsa_pem_len;
extern const size_t mbedtls_test_cli_crt_rsa_pem_len;
extern const size_t mbedtls_test_cli_crt_ec_der_len;
extern const size_t mbedtls_test_cli_key_ec_der_len;
extern const size_t mbedtls_test_cli_key_rsa_der_len;
extern const size_t mbedtls_test_cli_crt_rsa_der_len;
/* Config-dependent dispatch between PEM and DER encoding
* (PEM if enabled, otherwise DER) */
extern const char mbedtls_test_cli_crt_ec[];
extern const char mbedtls_test_cli_key_ec[];
extern const char mbedtls_test_cli_pwd_ec[];
extern const char mbedtls_test_cli_key_rsa[];
extern const char mbedtls_test_cli_pwd_rsa[];
extern const char mbedtls_test_cli_crt_rsa[];
extern const size_t mbedtls_test_cli_crt_ec_len;
extern const size_t mbedtls_test_cli_key_ec_len;
extern const size_t mbedtls_test_cli_pwd_ec_len;
extern const size_t mbedtls_test_cli_key_rsa_len;
extern const size_t mbedtls_test_cli_pwd_rsa_len;
extern const size_t mbedtls_test_cli_crt_rsa_len;
/* Config-dependent dispatch between EC and RSA
* (RSA if enabled, otherwise EC) */
extern const char * mbedtls_test_cli_crt;
extern const char * mbedtls_test_cli_key;
extern const char * mbedtls_test_cli_pwd;
extern const size_t mbedtls_test_cli_crt_len;
extern const char * mbedtls_test_cli_key;
extern const size_t mbedtls_test_cli_key_len;
extern const size_t mbedtls_test_cli_pwd_len;
#if defined(MBEDTLS_ECDSA_C)
extern const char mbedtls_test_ca_crt_ec[];
extern const size_t mbedtls_test_ca_crt_ec_len;
extern const char mbedtls_test_ca_key_ec[];
extern const size_t mbedtls_test_ca_key_ec_len;
extern const char mbedtls_test_ca_pwd_ec[];
extern const size_t mbedtls_test_ca_pwd_ec_len;
extern const char mbedtls_test_srv_crt_ec[];
extern const size_t mbedtls_test_srv_crt_ec_len;
extern const char mbedtls_test_srv_key_ec[];
extern const size_t mbedtls_test_srv_key_ec_len;
extern const char mbedtls_test_cli_crt_ec[];
extern const size_t mbedtls_test_cli_crt_ec_len;
extern const char mbedtls_test_cli_key_ec[];
extern const size_t mbedtls_test_cli_key_ec_len;
#endif
#if defined(MBEDTLS_RSA_C)
extern const char mbedtls_test_ca_crt_rsa[];
extern const size_t mbedtls_test_ca_crt_rsa_len;
extern const char mbedtls_test_ca_key_rsa[];
extern const size_t mbedtls_test_ca_key_rsa_len;
extern const char mbedtls_test_ca_pwd_rsa[];
extern const size_t mbedtls_test_ca_pwd_rsa_len;
extern const char mbedtls_test_srv_crt_rsa[];
extern const size_t mbedtls_test_srv_crt_rsa_len;
extern const char mbedtls_test_srv_key_rsa[];
extern const size_t mbedtls_test_srv_key_rsa_len;
extern const char mbedtls_test_cli_crt_rsa[];
extern const size_t mbedtls_test_cli_crt_rsa_len;
extern const char mbedtls_test_cli_key_rsa[];
extern const size_t mbedtls_test_cli_key_rsa_len;
#endif
#ifdef __cplusplus
}

View File

@ -1,226 +0,0 @@
/**
* \file chacha20.h
*
* \brief This file contains ChaCha20 definitions and functions.
*
* ChaCha20 is a stream cipher that can encrypt and decrypt
* information. ChaCha was created by Daniel Bernstein as a variant of
* its Salsa cipher https://cr.yp.to/chacha/chacha-20080128.pdf
* ChaCha20 is the variant with 20 rounds, that was also standardized
* in RFC 7539.
*
* \author Daniel King <damaki.gh@gmail.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 TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CHACHA20_H
#define MBEDTLS_CHACHA20_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stdint.h>
#include <stddef.h>
#define MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA -0x0051 /**< Invalid input parameter(s). */
/* MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE is deprecated and should not be
* used. */
#define MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE -0x0053 /**< Feature not available. For example, s part of the API is not implemented. */
/* MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED is deprecated and should not be used.
*/
#define MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED -0x0055 /**< Chacha20 hardware accelerator failed. */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_CHACHA20_ALT)
typedef struct mbedtls_chacha20_context
{
uint32_t state[16]; /*! The state (before round operations). */
uint8_t keystream8[64]; /*! Leftover keystream bytes. */
size_t keystream_bytes_used; /*! Number of keystream bytes already used. */
}
mbedtls_chacha20_context;
#else /* MBEDTLS_CHACHA20_ALT */
#include "chacha20_alt.h"
#endif /* MBEDTLS_CHACHA20_ALT */
/**
* \brief This function initializes the specified ChaCha20 context.
*
* It must be the first API called before using
* the context.
*
* It is usually followed by calls to
* \c mbedtls_chacha20_setkey() and
* \c mbedtls_chacha20_starts(), then one or more calls to
* to \c mbedtls_chacha20_update(), and finally to
* \c mbedtls_chacha20_free().
*
* \param ctx The ChaCha20 context to initialize.
* This must not be \c NULL.
*/
void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx );
/**
* \brief This function releases and clears the specified
* ChaCha20 context.
*
* \param ctx The ChaCha20 context to clear. This may be \c NULL,
* in which case this function is a no-op. If it is not
* \c NULL, it must point to an initialized context.
*
*/
void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx );
/**
* \brief This function sets the encryption/decryption key.
*
* \note After using this function, you must also call
* \c mbedtls_chacha20_starts() to set a nonce before you
* start encrypting/decrypting data with
* \c mbedtls_chacha_update().
*
* \param ctx The ChaCha20 context to which the key should be bound.
* It must be initialized.
* \param key The encryption/decryption key. This must be \c 32 Bytes
* in length.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or key is NULL.
*/
int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
const unsigned char key[32] );
/**
* \brief This function sets the nonce and initial counter value.
*
* \note A ChaCha20 context can be re-used with the same key by
* calling this function to change the nonce.
*
* \warning You must never use the same nonce twice with the same key.
* This would void any confidentiality guarantees for the
* messages encrypted with the same nonce and key.
*
* \param ctx The ChaCha20 context to which the nonce should be bound.
* It must be initialized and bound to a key.
* \param nonce The nonce. This must be \c 12 Bytes in size.
* \param counter The initial counter value. This is usually \c 0.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or nonce is
* NULL.
*/
int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
const unsigned char nonce[12],
uint32_t counter );
/**
* \brief This function encrypts or decrypts data.
*
* Since ChaCha20 is a stream cipher, the same operation is
* used for encrypting and decrypting data.
*
* \note The \p input and \p output pointers must either be equal or
* point to non-overlapping buffers.
*
* \note \c mbedtls_chacha20_setkey() and
* \c mbedtls_chacha20_starts() must be called at least once
* to setup the context before this function can be called.
*
* \note This function can be called multiple times in a row in
* order to encrypt of decrypt data piecewise with the same
* key and nonce.
*
* \param ctx The ChaCha20 context to use for encryption or decryption.
* It must be initialized and bound to a key and nonce.
* \param size The length of the input data in Bytes.
* \param input The buffer holding the input data.
* This pointer can be \c NULL if `size == 0`.
* \param output The buffer holding the output data.
* This must be able to hold \p size Bytes.
* This pointer can be \c NULL if `size == 0`.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
size_t size,
const unsigned char *input,
unsigned char *output );
/**
* \brief This function encrypts or decrypts data with ChaCha20 and
* the given key and nonce.
*
* Since ChaCha20 is a stream cipher, the same operation is
* used for encrypting and decrypting data.
*
* \warning You must never use the same (key, nonce) pair more than
* once. This would void any confidentiality guarantees for
* the messages encrypted with the same nonce and key.
*
* \note The \p input and \p output pointers must either be equal or
* point to non-overlapping buffers.
*
* \param key The encryption/decryption key.
* This must be \c 32 Bytes in length.
* \param nonce The nonce. This must be \c 12 Bytes in size.
* \param counter The initial counter value. This is usually \c 0.
* \param size The length of the input data in Bytes.
* \param input The buffer holding the input data.
* This pointer can be \c NULL if `size == 0`.
* \param output The buffer holding the output data.
* This must be able to hold \p size Bytes.
* This pointer can be \c NULL if `size == 0`.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_chacha20_crypt( const unsigned char key[32],
const unsigned char nonce[12],
uint32_t counter,
size_t size,
const unsigned char* input,
unsigned char* output );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief The ChaCha20 checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
*/
int mbedtls_chacha20_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CHACHA20_H */

View File

@ -1,358 +0,0 @@
/**
* \file chachapoly.h
*
* \brief This file contains the AEAD-ChaCha20-Poly1305 definitions and
* functions.
*
* ChaCha20-Poly1305 is an algorithm for Authenticated Encryption
* with Associated Data (AEAD) that can be used to encrypt and
* authenticate data. It is based on ChaCha20 and Poly1305 by Daniel
* Bernstein and was standardized in RFC 7539.
*
* \author Daniel King <damaki.gh@gmail.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 TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CHACHAPOLY_H
#define MBEDTLS_CHACHAPOLY_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
/* for shared error codes */
#include "poly1305.h"
#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x0054 /**< The requested operation is not permitted in the current state. */
#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED -0x0056 /**< Authenticated decryption failed: data was not authentic. */
#ifdef __cplusplus
extern "C" {
#endif
typedef enum
{
MBEDTLS_CHACHAPOLY_ENCRYPT, /**< The mode value for performing encryption. */
MBEDTLS_CHACHAPOLY_DECRYPT /**< The mode value for performing decryption. */
}
mbedtls_chachapoly_mode_t;
#if !defined(MBEDTLS_CHACHAPOLY_ALT)
#include "chacha20.h"
typedef struct mbedtls_chachapoly_context
{
mbedtls_chacha20_context chacha20_ctx; /**< The ChaCha20 context. */
mbedtls_poly1305_context poly1305_ctx; /**< The Poly1305 context. */
uint64_t aad_len; /**< The length (bytes) of the Additional Authenticated Data. */
uint64_t ciphertext_len; /**< The length (bytes) of the ciphertext. */
int state; /**< The current state of the context. */
mbedtls_chachapoly_mode_t mode; /**< Cipher mode (encrypt or decrypt). */
}
mbedtls_chachapoly_context;
#else /* !MBEDTLS_CHACHAPOLY_ALT */
#include "chachapoly_alt.h"
#endif /* !MBEDTLS_CHACHAPOLY_ALT */
/**
* \brief This function initializes the specified ChaCha20-Poly1305 context.
*
* It must be the first API called before using
* the context. It must be followed by a call to
* \c mbedtls_chachapoly_setkey() before any operation can be
* done, and to \c mbedtls_chachapoly_free() once all
* operations with that context have been finished.
*
* In order to encrypt or decrypt full messages at once, for
* each message you should make a single call to
* \c mbedtls_chachapoly_crypt_and_tag() or
* \c mbedtls_chachapoly_auth_decrypt().
*
* In order to encrypt messages piecewise, for each
* message you should make a call to
* \c mbedtls_chachapoly_starts(), then 0 or more calls to
* \c mbedtls_chachapoly_update_aad(), then 0 or more calls to
* \c mbedtls_chachapoly_update(), then one call to
* \c mbedtls_chachapoly_finish().
*
* \warning Decryption with the piecewise API is discouraged! Always
* use \c mbedtls_chachapoly_auth_decrypt() when possible!
*
* If however this is not possible because the data is too
* large to fit in memory, you need to:
*
* - call \c mbedtls_chachapoly_starts() and (if needed)
* \c mbedtls_chachapoly_update_aad() as above,
* - call \c mbedtls_chachapoly_update() multiple times and
* ensure its output (the plaintext) is NOT used in any other
* way than placing it in temporary storage at this point,
* - call \c mbedtls_chachapoly_finish() to compute the
* authentication tag and compared it in constant time to the
* tag received with the ciphertext.
*
* If the tags are not equal, you must immediately discard
* all previous outputs of \c mbedtls_chachapoly_update(),
* otherwise you can now safely use the plaintext.
*
* \param ctx The ChachaPoly context to initialize. Must not be \c NULL.
*/
void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx );
/**
* \brief This function releases and clears the specified
* ChaCha20-Poly1305 context.
*
* \param ctx The ChachaPoly context to clear. This may be \c NULL, in which
* case this function is a no-op.
*/
void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx );
/**
* \brief This function sets the ChaCha20-Poly1305
* symmetric encryption key.
*
* \param ctx The ChaCha20-Poly1305 context to which the key should be
* bound. This must be initialized.
* \param key The \c 256 Bit (\c 32 Bytes) key.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
const unsigned char key[32] );
/**
* \brief This function starts a ChaCha20-Poly1305 encryption or
* decryption operation.
*
* \warning You must never use the same nonce twice with the same key.
* This would void any confidentiality and authenticity
* guarantees for the messages encrypted with the same nonce
* and key.
*
* \note If the context is being used for AAD only (no data to
* encrypt or decrypt) then \p mode can be set to any value.
*
* \warning Decryption with the piecewise API is discouraged, see the
* warning on \c mbedtls_chachapoly_init().
*
* \param ctx The ChaCha20-Poly1305 context. This must be initialized
* and bound to a key.
* \param nonce The nonce/IV to use for the message.
* This must be a redable buffer of length \c 12 Bytes.
* \param mode The operation to perform: #MBEDTLS_CHACHAPOLY_ENCRYPT or
* #MBEDTLS_CHACHAPOLY_DECRYPT (discouraged, see warning).
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx,
const unsigned char nonce[12],
mbedtls_chachapoly_mode_t mode );
/**
* \brief This function feeds additional data to be authenticated
* into an ongoing ChaCha20-Poly1305 operation.
*
* The Additional Authenticated Data (AAD), also called
* Associated Data (AD) is only authenticated but not
* encrypted nor included in the encrypted output. It is
* usually transmitted separately from the ciphertext or
* computed locally by each party.
*
* \note This function is called before data is encrypted/decrypted.
* I.e. call this function to process the AAD before calling
* \c mbedtls_chachapoly_update().
*
* You may call this function multiple times to process
* an arbitrary amount of AAD. It is permitted to call
* this function 0 times, if no AAD is used.
*
* This function cannot be called any more if data has
* been processed by \c mbedtls_chachapoly_update(),
* or if the context has been finished.
*
* \warning Decryption with the piecewise API is discouraged, see the
* warning on \c mbedtls_chachapoly_init().
*
* \param ctx The ChaCha20-Poly1305 context. This must be initialized
* and bound to a key.
* \param aad_len The length in Bytes of the AAD. The length has no
* restrictions.
* \param aad Buffer containing the AAD.
* This pointer can be \c NULL if `aad_len == 0`.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
* if \p ctx or \p aad are NULL.
* \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
* if the operations has not been started or has been
* finished, or if the AAD has been finished.
*/
int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx,
const unsigned char *aad,
size_t aad_len );
/**
* \brief Thus function feeds data to be encrypted or decrypted
* into an on-going ChaCha20-Poly1305
* operation.
*
* The direction (encryption or decryption) depends on the
* mode that was given when calling
* \c mbedtls_chachapoly_starts().
*
* You may call this function multiple times to process
* an arbitrary amount of data. It is permitted to call
* this function 0 times, if no data is to be encrypted
* or decrypted.
*
* \warning Decryption with the piecewise API is discouraged, see the
* warning on \c mbedtls_chachapoly_init().
*
* \param ctx The ChaCha20-Poly1305 context to use. This must be initialized.
* \param len The length (in bytes) of the data to encrypt or decrypt.
* \param input The buffer containing the data to encrypt or decrypt.
* This pointer can be \c NULL if `len == 0`.
* \param output The buffer to where the encrypted or decrypted data is
* written. This must be able to hold \p len bytes.
* This pointer can be \c NULL if `len == 0`.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
* if the operation has not been started or has been
* finished.
* \return Another negative error code on other kinds of failure.
*/
int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,
size_t len,
const unsigned char *input,
unsigned char *output );
/**
* \brief This function finished the ChaCha20-Poly1305 operation and
* generates the MAC (authentication tag).
*
* \param ctx The ChaCha20-Poly1305 context to use. This must be initialized.
* \param mac The buffer to where the 128-bit (16 bytes) MAC is written.
*
* \warning Decryption with the piecewise API is discouraged, see the
* warning on \c mbedtls_chachapoly_init().
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
* if the operation has not been started or has been
* finished.
* \return Another negative error code on other kinds of failure.
*/
int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
unsigned char mac[16] );
/**
* \brief This function performs a complete ChaCha20-Poly1305
* authenticated encryption with the previously-set key.
*
* \note Before using this function, you must set the key with
* \c mbedtls_chachapoly_setkey().
*
* \warning You must never use the same nonce twice with the same key.
* This would void any confidentiality and authenticity
* guarantees for the messages encrypted with the same nonce
* and key.
*
* \param ctx The ChaCha20-Poly1305 context to use (holds the key).
* This must be initialized.
* \param length The length (in bytes) of the data to encrypt or decrypt.
* \param nonce The 96-bit (12 bytes) nonce/IV to use.
* \param aad The buffer containing the additional authenticated
* data (AAD). This pointer can be \c NULL if `aad_len == 0`.
* \param aad_len The length (in bytes) of the AAD data to process.
* \param input The buffer containing the data to encrypt or decrypt.
* This pointer can be \c NULL if `ilen == 0`.
* \param output The buffer to where the encrypted or decrypted data
* is written. This pointer can be \c NULL if `ilen == 0`.
* \param tag The buffer to where the computed 128-bit (16 bytes) MAC
* is written. This must not be \c NULL.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx,
size_t length,
const unsigned char nonce[12],
const unsigned char *aad,
size_t aad_len,
const unsigned char *input,
unsigned char *output,
unsigned char tag[16] );
/**
* \brief This function performs a complete ChaCha20-Poly1305
* authenticated decryption with the previously-set key.
*
* \note Before using this function, you must set the key with
* \c mbedtls_chachapoly_setkey().
*
* \param ctx The ChaCha20-Poly1305 context to use (holds the key).
* \param length The length (in Bytes) of the data to decrypt.
* \param nonce The \c 96 Bit (\c 12 bytes) nonce/IV to use.
* \param aad The buffer containing the additional authenticated data (AAD).
* This pointer can be \c NULL if `aad_len == 0`.
* \param aad_len The length (in bytes) of the AAD data to process.
* \param tag The buffer holding the authentication tag.
* This must be a readable buffer of length \c 16 Bytes.
* \param input The buffer containing the data to decrypt.
* This pointer can be \c NULL if `ilen == 0`.
* \param output The buffer to where the decrypted data is written.
* This pointer can be \c NULL if `ilen == 0`.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED
* if the data was not authentic.
* \return Another negative error code on other kinds of failure.
*/
int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx,
size_t length,
const unsigned char nonce[12],
const unsigned char *aad,
size_t aad_len,
const unsigned char tag[16],
const unsigned char *input,
unsigned char *output );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief The ChaCha20-Poly1305 checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
*/
int mbedtls_chachapoly_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CHACHAPOLY_H */

View File

@ -4,7 +4,7 @@
* \brief Consistency checks for configuration options
*/
/*
* Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
* 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
@ -74,16 +74,6 @@
#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_CTR_DRBG_C) && defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) && !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
#error "MBEDTLS_CTR_DRBG_C and MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH defined, but MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is not defined"
#endif
#if defined(MBEDTLS_AES_128_BIT_MASKED) && ( !defined(MBEDTLS_AES_SCA_COUNTERMEASURES) || \
!defined(MBEDTLS_AES_ONLY_ENCRYPT) || \
!defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) )
#error "MBEDTLS_AES_128_BIT_MASKED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_DHM_C) && !defined(MBEDTLS_BIGNUM_C)
#error "MBEDTLS_DHM_C defined, but not all prerequisites"
#endif
@ -97,56 +87,6 @@
#error "MBEDTLS_CMAC_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_CONF_SINGLE_EC) && \
( !defined(MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID) || \
( defined(MBEDTLS_USE_TINYCRYPT) && \
!defined(MBEDTLS_SSL_CONF_SINGLE_UECC_GRP_ID) ) || \
( defined(MBEDTLS_ECP_C) && \
!defined(MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID) ) )
#error "MBEDTLS_SSL_CONF_SINGLE_EC defined, but not all prerequesites"
#endif
#if defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) && \
( !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID) || \
!defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID) )
#error "MBEDTLS_SSL_CONF_SINGLE_SIG_HASH defined, but not all prerequesites"
#endif
#if defined(MBEDTLS_USE_TINYCRYPT) && defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
#error "MBEDTLS_USE_TINYCRYPT defined, but it cannot be defined with MBEDTLS_NO_64BIT_MULTIPLICATION"
#endif
#if defined(MBEDTLS_USE_TINYCRYPT) && !defined(MBEDTLS_SHA256_C)
#error "MBEDTLS_USE_TINYCRYPT defined, but not MBEDTLS_SHA256_C"
#endif
#if defined(MBEDTLS_USE_TINYCRYPT) && \
!( defined(MBEDTLS_SSL_CONF_SINGLE_EC) && \
MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID == 23 && \
MBEDTLS_SSL_CONF_SINGLE_UECC_GRP_ID == MBEDTLS_UECC_DP_SECP256R1 )
#error "MBEDTLS_USE_TINYCRYPT requires the use of MBEDTLS_SSL_CONF_SINGLE_UECC_GRP_ID to hardcode the choice of Secp256r1"
#endif
#if defined(MBEDTLS_USE_TINYCRYPT) && defined(MBEDTLS_ECP_C)
#error "MBEDTLS_USE_TINYCRYPT and MBEDTLS_ECP_C cannot be used simultaneously"
#endif
#if defined(MBEDTLS_USE_TINYCRYPT) && \
!defined(MBEDTLS_SSL_CONF_RNG)
#error "MBEDTLS_USE_TINYCRYPT defined, but not all prerequesites"
#endif
#if defined(MBEDTLS_OPTIMIZE_TINYCRYPT_ASM) && \
( !defined(MBEDTLS_HAVE_ASM) || \
!defined(MBEDTLS_USE_TINYCRYPT) )
#error "MBEDTLS_OPTIMIZE_TINYCRYPT_ASM defined, but not all prerequesites"
#endif
#if defined(MBEDTLS_NIST_KW_C) && \
( !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_CIPHER_C) )
#error "MBEDTLS_NIST_KW_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C)
#error "MBEDTLS_ECDH_C defined, but not all prerequisites"
#endif
@ -163,22 +103,11 @@
#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_RESTARTABLE) && \
( defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) || \
defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) || \
defined(MBEDTLS_ECDSA_SIGN_ALT) || \
defined(MBEDTLS_ECDSA_VERIFY_ALT) || \
defined(MBEDTLS_ECDSA_GENKEY_ALT) || \
defined(MBEDTLS_ECP_INTERNAL_ALT) || \
defined(MBEDTLS_ECP_ALT) )
#error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative ECP implementation"
#endif
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C)
#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \
#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \
!defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \
@ -189,27 +118,10 @@
!defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) && \
!defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) ) )
!defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) )
#error "MBEDTLS_ECP_C defined, but not all prerequisites"
#endif
#if ( defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) && \
!defined(MBEDTLS_ECP_C)
#error "At least one ECP curve enabled, but not all prerequesites"
#endif
#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C)
#error "MBEDTLS_PK_PARSE_C defined, but not all prerequesites"
#endif
@ -283,23 +195,17 @@
#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_HKDF_C) && !defined(MBEDTLS_MD_C)
#error "MBEDTLS_HKDF_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C)
#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \
( !( defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_USE_TINYCRYPT) ) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) )
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
( !( defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_USE_TINYCRYPT) ) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) )
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites"
#endif
@ -308,7 +214,7 @@
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \
!(defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_USE_TINYCRYPT) )
!defined(MBEDTLS_ECDH_C)
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites"
#endif
@ -318,17 +224,14 @@
#error "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
( !( defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_USE_TINYCRYPT) ) || \
!defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) || \
!defined(MBEDTLS_PKCS1_V15) )
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
( !( defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_USE_TINYCRYPT) ) || \
!( defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_USE_TINYCRYPT) ) || \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites"
#endif
@ -351,27 +254,11 @@
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) && \
!defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) && \
( !defined(MBEDTLS_SHA256_C) && \
!defined(MBEDTLS_SHA512_C) && \
!defined(MBEDTLS_SHA1_C) )
#error "MBEDTLS_SSL_KEEP_PEER_CERTIFICATE defined, but not all prerequesites"
#endif
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_MEMORY_BACKTRACE) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
#error "MBEDTLS_MEMORY_BACKTRACE defined, but not all prerequesites"
#endif
#if defined(MBEDTLS_MEMORY_DEBUG) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequesites"
#endif
#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
#endif
@ -384,10 +271,8 @@
#error "MBEDTLS_PEM_WRITE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PK_C) && \
( !defined(MBEDTLS_RSA_C) && \
!defined(MBEDTLS_ECP_C) && \
!defined(MBEDTLS_USE_TINYCRYPT) )
#if defined(MBEDTLS_PK_C) && \
( !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C) )
#error "MBEDTLS_PK_C defined, but not all prerequisites"
#endif
@ -631,23 +516,6 @@
#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
#endif
#if (defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \
!(defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) )
#error "One or more versions of the TLS protocol are enabled " \
"but no key exchange methods defined with MBEDTLS_KEY_EXCHANGE_xxxx"
#endif
#if defined(MBEDTLS_SSL_PROTO_DTLS) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
@ -670,28 +538,7 @@
#if defined(MBEDTLS_SSL_TLS_C) && (!defined(MBEDTLS_SSL_PROTO_SSL3) && \
!defined(MBEDTLS_SSL_PROTO_TLS1) && !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2))
#error "MBEDTLS_SSL_TLS_C defined, but no protocol version is active"
#endif
/* PROTO_TLS is not a documented option so far, but still check for conflicts
* involving it, in preparation for making it the documented option later */
#if defined(MBEDTLS_SSL_PROTO_TLS) && defined(MBEDTLS_SSL_PROTO_NO_TLS)
#error "MBEDTLS_SSL_PROTO_TLS and MBEDTLS_SSL_PROTO_NO_TLS both defined"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && \
( defined(MBEDTLS_SSL_PROTO_NO_TLS) && !defined(MBEDTLS_SSL_PROTO_DTLS) )
#error "MBEDTLS_SSL_TLS_C defined, but neither TLS or DTLS is active"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) && \
defined(MBEDTLS_ARC4_C)
#error "MBEDTLS_ARC4_C cannot be defined with MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS on"
#endif
#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY) && !defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) && \
defined(MBEDTLS_ARC4_C)
#error "MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY requires MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS to be defined."
#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \
@ -724,49 +571,6 @@
#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_CONF_MIN_MINOR_VER) || \
defined(MBEDTLS_SSL_CONF_MAX_MINOR_VER) || \
defined(MBEDTLS_SSL_CONF_MIN_MAJOR_VER) || \
defined(MBEDTLS_SSL_CONF_MAX_MAJOR_VER)
#if !( defined(MBEDTLS_SSL_CONF_MIN_MINOR_VER) && \
defined(MBEDTLS_SSL_CONF_MAX_MINOR_VER) && \
defined(MBEDTLS_SSL_CONF_MIN_MAJOR_VER) && \
defined(MBEDTLS_SSL_CONF_MAX_MAJOR_VER) )
#error "MBEDTLS_SSL_CONF_MIN_MINOR_VER, MBEDTLS_SSL_CONF_MAX_MINOR_VER, MBEDTLS_SSL_CONF_MIN_MAJOR_VER, MBEDTLS_SSL_CONF_MAX_MAJOR_VER must be defined simultaneously"
#endif
#endif
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
#error "MBEDTLS_SSL_DTLS_CONNECTION_ID defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
defined(MBEDTLS_SSL_CID_IN_LEN_MAX) && \
MBEDTLS_SSL_CID_IN_LEN_MAX > 255
#error "MBEDTLS_SSL_CID_IN_LEN_MAX too large (max 255)"
#endif
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
defined(MBEDTLS_SSL_CID_OUT_LEN_MAX) && \
MBEDTLS_SSL_CID_OUT_LEN_MAX > 255
#error "MBEDTLS_SSL_CID_OUT_LEN_MAX too large (max 255)"
#endif
#if ( defined(MBEDTLS_SSL_CONF_CID_LEN) && \
!defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID) ) || \
( !defined(MBEDTLS_SSL_CONF_CID_LEN) && \
defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID) )
#error "MBEDTLS_SSL_CONF_CID_LEN and MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID must be defined simultaneously"
#endif
#if ( defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) && \
!defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) ) || \
( !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) && \
defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) )
#error "MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN and MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX must be defined simultaneously"
#endif
#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites"
@ -786,32 +590,6 @@
#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites"
#endif
#if ( defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) && \
!defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET) ) || \
( !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) && \
defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET) )
#error "MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET and MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET must be defined together."
#endif
#if ( defined(MBEDTLS_SSL_CONF_SEND) && \
!( defined(MBEDTLS_SSL_CONF_RECV) && \
defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT) ) ) || \
( defined(MBEDTLS_SSL_CONF_RECV) && \
!( defined(MBEDTLS_SSL_CONF_SEND) && \
defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT) ) ) || \
( defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT) && \
!( defined(MBEDTLS_SSL_CONF_SEND) && \
defined(MBEDTLS_SSL_CONF_RECV) ) )
#error "MBEDTLS_SSL_CONF_SEND/RECV/RECV_TIMEOUT must be defined simultaneously"
#endif
#if ( defined(MBEDTLS_SSL_CONF_GET_TIMER) && \
!defined(MBEDTLS_SSL_CONF_SET_TIMER) ) || \
( !defined(MBEDTLS_SSL_CONF_GET_TIMER) && \
defined(MBEDTLS_SSL_CONF_SET_TIMER) )
#error "MBEDTLS_SSL_CONF_GET_TIMER and MBEDTLS_SSL_CONF_SET_TIMER must be defined together."
#endif
#if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C)
#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites"
#endif
@ -826,16 +604,6 @@
#error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \
defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION)
#error "MBEDTLS_SSL_SESSION_TICKETS cannot be defined with MBEDTLS_SSL_NO_SESSION_RESUMPTION"
#endif
#if !defined(MBEDTLS_SSL_NO_SESSION_CACHE) && \
defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION)
#error "MBEDTLS_SSL_NO_SESSION_CACHE needs to be defined with MBEDTLS_SSL_NO_SESSION_RESUMPTION"
#endif
#if defined(MBEDTLS_THREADING_PTHREAD)
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites"
@ -843,113 +611,6 @@
#define MBEDTLS_THREADING_IMPL
#endif
/* Ensure that precisely one hash is enabled. */
#if defined(MBEDTLS_MD_SINGLE_HASH)
#if defined(MBEDTLS_SHA256_C)
#define MBEDTLS_SHA256_ENABLED 1
#else
#define MBEDTLS_SHA256_ENABLED 0
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA256_NO_SHA224)
#define MBEDTLS_SHA224_ENABLED 1
#else
#define MBEDTLS_SHA224_ENABLED 0
#endif /* MBEDTLS_SHA256_C && !MBEDTLS_SHA256_NO_SHA224 */
#if defined(MBEDTLS_SHA512_C)
#define MBEDTLS_SHA512_ENABLED 2
#else
#define MBEDTLS_SHA512_ENABLED 0
#endif /* MBEDTLS_SHA512_C */
#if defined(MBEDTLS_SHA1_C)
#define MBEDTLS_SHA1_ENABLED 1
#else
#define MBEDTLS_SHA1_ENABLED 0
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_MD2_C)
#define MBEDTLS_MD2_ENABLED 1
#else
#define MBEDTLS_MD2_ENABLED 0
#endif /* MBEDTLS_MD2_C */
#if defined(MBEDTLS_MD4_C)
#define MBEDTLS_MD4_ENABLED 1
#else
#define MBEDTLS_MD4_ENABLED 0
#endif /* MBEDTLS_MD4_C */
#if defined(MBEDTLS_MD5_C)
#define MBEDTLS_MD5_ENABLED 1
#else
#define MBEDTLS_MD5_ENABLED 0
#endif /* MBEDTLS_MD5_C */
#if defined(MBEDTLS_RIPEMD160_C)
#define MBEDTLS_RIPEMD160_ENABLED 1
#else
#define MBEDTLS_RIPEMD160_ENABLED 0
#endif /* MBEDTLS_RIPEMD160_C */
#define MBEDTLS_HASHES_ENABLED \
( MBEDTLS_MD2_ENABLED + \
MBEDTLS_MD4_ENABLED + \
MBEDTLS_MD5_ENABLED + \
MBEDTLS_RIPEMD160_ENABLED + \
MBEDTLS_SHA1_ENABLED + \
MBEDTLS_SHA256_ENABLED + \
MBEDTLS_SHA512_ENABLED )
#if MBEDTLS_HASHES_ENABLED != 1
#error "MBEDTLS_MD_SINGLE_HASH must be used with precisely one hash algorithm enabled."
#endif
#undef MBEDTLS_HASHES_ENABLED
#endif /* MBEDTLS_MD_SINGLE_HASH */
#if defined(MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION) && !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
#error "MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION can only be used with MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
#endif
#if defined(MBEDTLS_SSL_EARLY_KEY_COMPUTATION) && !defined(MBEDTLS_USE_TINYCRYPT)
#error "MBEDTLS_SSL_EARLY_KEY_COMPUTATION can only be used with MBEDTLS_USE_TINYCRYPT"
#endif
/*
* Note: the dependency on TinyCrypt is reflected in several ways in the code:
*
* 1. We only define the various MBEDTLS_PK_INFO_{TYPE}_{FIELD} macros for
* TYPE == ECKEY, resolving to the TinyCrypt version.
* 2. In pk_init() and pk_free() we assume that zeroization is a proper way
* to init/free the context, which is true of mbedtls_uecc_keypair, but
* might not always hold otherwise (think hardware-accelerated ECP_ALT).
* 3. We rely on the fact that MBEDTLS_ECP_RESTARTABLE is disabled - code
* paths (and pk_info fields) that are guarded by this are currently not
* handled by the internal abstraction layers enabling PK_SINGLE_TYPE.
*
* If this dependency is ever removed, the above points need to be addressed
* in the code.
*/
#if defined(MBEDTLS_PK_SINGLE_TYPE) && !defined(MBEDTLS_USE_TINYCRYPT)
#error "MBEDTLS_PK_SINGLE_TYPE can only be used with MBEDTLS_USE_TINYCRYPT"
#endif
/* Note: code paths that depend on MBEDTLS_PK_RSA_ALT_SUPPORT are not ported
* to the internal abstraction layers that enable PK_SINGLE_TYPE. */
#if defined(MBEDTLS_PK_SINGLE_TYPE) && defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
#error "MBEDTLS_PK_SINGLE_TYPE is not compatible with MBEDTLS_PK_RSA_ALT_SUPPORT"
#endif
/* This is to avoid a situation where RSA is available, but not through the PK
* layer, which might surprise user code. */
#if defined(MBEDTLS_PK_SINGLE_TYPE) && defined(MBEDTLS_RSA_C)
#error "MBEDTLS_PK_SINGLE_TYPE is not compatible with MBEDTLS_RSA_C"
#endif
#if defined(MBEDTLS_THREADING_ALT)
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites"
@ -966,10 +627,9 @@
#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_USE_C) && \
( !defined(MBEDTLS_OID_C) || \
!defined(MBEDTLS_ASN1_PARSE_C) || \
!defined(MBEDTLS_PK_PARSE_C) )
#if defined(MBEDTLS_X509_USE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \
!defined(MBEDTLS_PK_PARSE_C) )
#error "MBEDTLS_X509_USE_C defined, but not all prerequisites"
#endif
@ -979,10 +639,6 @@
#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_CERTS_C) && !defined(MBEDTLS_X509_USE_C)
#error "MBEDTLS_CERTS_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites"
#endif
@ -1003,11 +659,6 @@
#error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CRT_REMOVE_TIME) && \
defined(MBEDTLS_HAVE_TIME_DATE)
#error "MBEDTLS_X509_CRT_REMOVE_TIME and MBEDTLS_HAVE_TIME_DATE cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_HAVE_INT32) && defined(MBEDTLS_HAVE_INT64)
#error "MBEDTLS_HAVE_INT32 and MBEDTLS_HAVE_INT64 cannot be defined simultaneously"
#endif /* MBEDTLS_HAVE_INT32 && MBEDTLS_HAVE_INT64 */
@ -1020,7 +671,7 @@
/*
* Avoid warning from -pedantic. This is a convenient place for this
* workaround since this is included by every single file before the
* #if defined(MBEDTLS_xxx_C) that results in empty translation units.
* #if defined(MBEDTLS_xxx_C) that results in emtpy translation units.
*/
typedef int mbedtls_iso_c_forbids_empty_translation_units;

View File

@ -33,16 +33,10 @@
#include "cipher.h"
#include "cipher_internal.h"
#include "platform_util.h"
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#if defined(MBEDTLS_CHACHAPOLY_C)
#include "chachapoly.h"
#endif
#if defined(MBEDTLS_GCM_C)
#include "gcm.h"
#endif
@ -51,10 +45,6 @@
#include "ccm.h"
#endif
#if defined(MBEDTLS_CHACHA20_C)
#include "chacha20.h"
#endif
#if defined(MBEDTLS_CMAC_C)
#include "cmac.h"
#endif
@ -66,30 +56,10 @@
#define mbedtls_free free
#endif
#define CIPHER_VALIDATE_RET( cond ) \
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA )
#define CIPHER_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
/* Compare the contents of two buffers in constant time.
* Returns 0 if the contents are bitwise identical, otherwise returns
* a non-zero value.
* This is currently only used by GCM and ChaCha20+Poly1305.
*/
static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, size_t len )
{
const unsigned char *p1 = (const unsigned char*) v1;
const unsigned char *p2 = (const unsigned char*) v2;
size_t i;
unsigned char diff;
for( diff = 0, i = 0; i < len; i++ )
diff |= p1[i] ^ p2[i];
return( (int)diff );
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
}
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
static int supported_init = 0;
@ -156,7 +126,6 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_ciph
void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx )
{
CIPHER_VALIDATE( ctx != NULL );
memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
}
@ -168,8 +137,7 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
#if defined(MBEDTLS_CMAC_C)
if( ctx->cmac_ctx )
{
mbedtls_platform_zeroize( ctx->cmac_ctx,
sizeof( mbedtls_cmac_context_t ) );
mbedtls_zeroize( ctx->cmac_ctx, sizeof( mbedtls_cmac_context_t ) );
mbedtls_free( ctx->cmac_ctx );
}
#endif
@ -177,17 +145,15 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
if( ctx->cipher_ctx )
ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx );
mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
mbedtls_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
}
int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info )
{
CIPHER_VALIDATE_RET( ctx != NULL );
if( cipher_info == NULL )
if( NULL == cipher_info || NULL == ctx )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
mbedtls_platform_memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
ctx->operation = MBEDTLS_OPERATION_NONE;
memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) )
return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
@ -208,16 +174,10 @@ int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_in
return( 0 );
}
int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
const unsigned char *key,
int key_bitlen,
const mbedtls_operation_t operation )
int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key,
int key_bitlen, const mbedtls_operation_t operation )
{
CIPHER_VALIDATE_RET( ctx != NULL );
CIPHER_VALIDATE_RET( key != NULL );
CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT ||
operation == MBEDTLS_DECRYPT );
if( ctx->cipher_info == NULL )
if( NULL == ctx || NULL == ctx->cipher_info )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 &&
@ -230,34 +190,34 @@ int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
ctx->operation = operation;
/*
* For OFB, CFB and CTR mode always use the encryption key schedule
* For CFB and CTR mode always use the encryption key schedule
*/
if( MBEDTLS_ENCRYPT == operation ||
MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
MBEDTLS_MODE_CTR == ctx->cipher_info->mode )
{
return( ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
ctx->key_bitlen ) );
return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
ctx->key_bitlen );
}
if( MBEDTLS_DECRYPT == operation )
return( ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
ctx->key_bitlen ) );
return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
ctx->key_bitlen );
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
const unsigned char *iv,
size_t iv_len )
const unsigned char *iv, size_t iv_len )
{
size_t actual_iv_size;
CIPHER_VALIDATE_RET( ctx != NULL );
CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
if( ctx->cipher_info == NULL )
if( NULL == ctx || NULL == ctx->cipher_info )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
else if( NULL == iv && iv_len != 0 )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
if( NULL == iv && iv_len == 0 )
ctx->iv_size = 0;
/* avoid buffer overflow in ctx->iv */
if( iv_len > MBEDTLS_MAX_IV_LENGTH )
@ -273,22 +233,9 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
if( actual_iv_size > iv_len )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
#if defined(MBEDTLS_CHACHA20_C)
if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
{
if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx,
iv,
0U ) ) /* Initial counter value */
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
}
#endif
if ( actual_iv_size != 0 )
{
mbedtls_platform_memcpy( ctx->iv, iv, actual_iv_size );
memcpy( ctx->iv, iv, actual_iv_size );
ctx->iv_size = actual_iv_size;
}
@ -297,8 +244,7 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
{
CIPHER_VALIDATE_RET( ctx != NULL );
if( ctx->cipher_info == NULL )
if( NULL == ctx || NULL == ctx->cipher_info )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
ctx->unprocessed_len = 0;
@ -306,67 +252,36 @@ int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
return( 0 );
}
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
#if defined(MBEDTLS_GCM_C)
int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
const unsigned char *ad, size_t ad_len )
{
CIPHER_VALIDATE_RET( ctx != NULL );
CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
if( ctx->cipher_info == NULL )
if( NULL == ctx || NULL == ctx->cipher_info )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
{
return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
ctx->iv, ctx->iv_size, ad, ad_len ) );
return mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
ctx->iv, ctx->iv_size, ad, ad_len );
}
#endif
#if defined(MBEDTLS_CHACHAPOLY_C)
if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
{
int result;
mbedtls_chachapoly_mode_t mode;
mode = ( ctx->operation == MBEDTLS_ENCRYPT )
? MBEDTLS_CHACHAPOLY_ENCRYPT
: MBEDTLS_CHACHAPOLY_DECRYPT;
result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context *) ctx->cipher_ctx,
ctx->iv,
mode );
if ( result != 0 )
return( result );
return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context *) ctx->cipher_ctx,
ad, ad_len ) );
}
#endif
return( 0 );
}
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
#endif /* MBEDTLS_GCM_C */
int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
size_t ilen, unsigned char *output, size_t *olen )
{
int ret;
size_t block_size;
size_t block_size = 0;
CIPHER_VALIDATE_RET( ctx != NULL );
CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
CIPHER_VALIDATE_RET( output != NULL );
CIPHER_VALIDATE_RET( olen != NULL );
if( ctx->cipher_info == NULL )
if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
*olen = 0;
block_size = mbedtls_cipher_get_block_size( ctx );
if ( 0 == block_size )
{
return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
}
if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB )
{
@ -388,19 +303,15 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM )
{
*olen = ilen;
return( mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
output ) );
return mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
output );
}
#endif
#if defined(MBEDTLS_CHACHAPOLY_C)
if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 )
if ( 0 == block_size )
{
*olen = ilen;
return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context *) ctx->cipher_ctx,
ilen, input, output ) );
return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
}
#endif
if( input == output &&
( ctx->unprocessed_len != 0 || ilen % block_size ) )
@ -423,7 +334,7 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
( ctx->operation == MBEDTLS_ENCRYPT &&
ilen < block_size - ctx->unprocessed_len ) )
{
mbedtls_platform_memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
ilen );
ctx->unprocessed_len += ilen;
@ -437,7 +348,7 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
{
copy_len = block_size - ctx->unprocessed_len;
mbedtls_platform_memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
copy_len );
if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
@ -460,6 +371,11 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
*/
if( 0 != ilen )
{
if( 0 == block_size )
{
return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
}
/* Encryption: only cache partial blocks
* Decryption w/ padding: always keep at least one whole block
* Decryption w/o padding: only cache partial blocks
@ -472,7 +388,7 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
copy_len = block_size;
}
mbedtls_platform_memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
copy_len );
ctx->unprocessed_len += copy_len;
@ -513,21 +429,6 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
}
#endif /* MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_OFB)
if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB )
{
if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx,
ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) )
{
return( ret );
}
*olen = ilen;
return( 0 );
}
#endif /* MBEDTLS_CIPHER_MODE_OFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR )
{
@ -544,27 +445,6 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
}
#endif /* MBEDTLS_CIPHER_MODE_CTR */
#if defined(MBEDTLS_CIPHER_MODE_XTS)
if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS )
{
if( ctx->unprocessed_len > 0 ) {
/* We can only process an entire data unit at a time. */
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
}
ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx,
ctx->operation, ilen, ctx->iv, input, output );
if( ret != 0 )
{
return( ret );
}
*olen = ilen;
return( 0 );
}
#endif /* MBEDTLS_CIPHER_MODE_XTS */
#if defined(MBEDTLS_CIPHER_MODE_STREAM)
if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM )
{
@ -592,7 +472,7 @@ static void add_pkcs_padding( unsigned char *output, size_t output_len,
size_t data_len )
{
size_t padding_len = output_len - data_len;
uint_fast8_t i;
unsigned char i;
for( i = 0; i < padding_len; i++ )
output[data_len + i] = (unsigned char) padding_len;
@ -602,7 +482,7 @@ static int get_pkcs_padding( unsigned char *input, size_t input_len,
size_t *data_len )
{
size_t i, pad_idx;
uint_fast8_t padding_len, bad = 0;
unsigned char padding_len, bad = 0;
if( NULL == input || NULL == data_len )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
@ -632,7 +512,7 @@ static void add_one_and_zeros_padding( unsigned char *output,
size_t output_len, size_t data_len )
{
size_t padding_len = output_len - data_len;
uint_fast8_t i = 0;
unsigned char i = 0;
output[data_len] = 0x80;
for( i = 1; i < padding_len; i++ )
@ -643,7 +523,7 @@ static int get_one_and_zeros_padding( unsigned char *input, size_t input_len,
size_t *data_len )
{
size_t i;
uint_fast8_t done = 0, prev_done, bad;
unsigned char done = 0, prev_done, bad;
if( NULL == input || NULL == data_len )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
@ -671,7 +551,7 @@ static void add_zeros_and_len_padding( unsigned char *output,
size_t output_len, size_t data_len )
{
size_t padding_len = output_len - data_len;
uint_fast8_t i = 0;
unsigned char i = 0;
for( i = 1; i < padding_len; i++ )
output[data_len + i - 1] = 0x00;
@ -758,30 +638,19 @@ static int get_no_padding( unsigned char *input, size_t input_len,
int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
unsigned char *output, size_t *olen )
{
CIPHER_VALIDATE_RET( ctx != NULL );
CIPHER_VALIDATE_RET( output != NULL );
CIPHER_VALIDATE_RET( olen != NULL );
if( ctx->cipher_info == NULL )
if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
*olen = 0;
if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
MBEDTLS_MODE_CTR == ctx->cipher_info->mode ||
MBEDTLS_MODE_GCM == ctx->cipher_info->mode ||
MBEDTLS_MODE_XTS == ctx->cipher_info->mode ||
MBEDTLS_MODE_STREAM == ctx->cipher_info->mode )
{
return( 0 );
}
if ( ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) ||
( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) )
{
return( 0 );
}
if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode )
{
if( ctx->unprocessed_len != 0 )
@ -831,8 +700,8 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
/* Set output size for decryption */
if( MBEDTLS_DECRYPT == ctx->operation )
return( ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
olen ) );
return ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
olen );
/* Set output size for encryption */
*olen = mbedtls_cipher_get_block_size( ctx );
@ -846,12 +715,10 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
}
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
mbedtls_cipher_padding_t mode )
int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode )
{
CIPHER_VALIDATE_RET( ctx != NULL );
if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
if( NULL == ctx ||
MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
@ -895,35 +762,18 @@ int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
}
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
#if defined(MBEDTLS_GCM_C)
int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
unsigned char *tag, size_t tag_len )
{
CIPHER_VALIDATE_RET( ctx != NULL );
CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
if( ctx->cipher_info == NULL )
if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
if( MBEDTLS_ENCRYPT != ctx->operation )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
tag, tag_len ) );
#endif
#if defined(MBEDTLS_CHACHAPOLY_C)
if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
{
/* Don't allow truncated MAC for Poly1305 */
if ( tag_len != 16U )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
return( mbedtls_chachapoly_finish( (mbedtls_chachapoly_context *) ctx->cipher_ctx,
tag ) );
}
#endif
return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len );
return( 0 );
}
@ -931,22 +781,20 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
const unsigned char *tag, size_t tag_len )
{
unsigned char check_tag[16];
int ret;
CIPHER_VALIDATE_RET( ctx != NULL );
CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
if( MBEDTLS_DECRYPT != ctx->operation )
if( NULL == ctx || NULL == ctx->cipher_info ||
MBEDTLS_DECRYPT != ctx->operation )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
{
unsigned char check_tag[16];
size_t i;
int diff;
if( tag_len > sizeof( check_tag ) )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
@ -957,38 +805,18 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
}
/* Check the tag in "constant-time" */
if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
for( diff = 0, i = 0; i < tag_len; i++ )
diff |= tag[i] ^ check_tag[i];
if( diff != 0 )
return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
return( 0 );
}
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_CHACHAPOLY_C)
if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
{
/* Don't allow truncated MAC for Poly1305 */
if ( tag_len != sizeof( check_tag ) )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context *) ctx->cipher_ctx,
check_tag );
if ( ret != 0 )
{
return( ret );
}
/* Check the tag in "constant-time" */
if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
return( 0 );
}
#endif /* MBEDTLS_CHACHAPOLY_C */
return( 0 );
}
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
#endif /* MBEDTLS_GCM_C */
/*
* Packet-oriented wrapper for non-AEAD modes
@ -1001,12 +829,6 @@ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
int ret;
size_t finish_olen;
CIPHER_VALIDATE_RET( ctx != NULL );
CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
CIPHER_VALIDATE_RET( output != NULL );
CIPHER_VALIDATE_RET( olen != NULL );
if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
return( ret );
@ -1035,14 +857,6 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
unsigned char *output, size_t *olen,
unsigned char *tag, size_t tag_len )
{
CIPHER_VALIDATE_RET( ctx != NULL );
CIPHER_VALIDATE_RET( iv != NULL );
CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
CIPHER_VALIDATE_RET( output != NULL );
CIPHER_VALIDATE_RET( olen != NULL );
CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
{
@ -1061,21 +875,6 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
tag, tag_len ) );
}
#endif /* MBEDTLS_CCM_C */
#if defined(MBEDTLS_CHACHAPOLY_C)
if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
{
/* ChachaPoly has fixed length nonce and MAC (tag) */
if ( ( iv_len != ctx->cipher_info->iv_size ) ||
( tag_len != 16U ) )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
*olen = ilen;
return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx,
ilen, iv, ad, ad_len, input, output, tag ) );
}
#endif /* MBEDTLS_CHACHAPOLY_C */
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
}
@ -1090,14 +889,6 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
unsigned char *output, size_t *olen,
const unsigned char *tag, size_t tag_len )
{
CIPHER_VALIDATE_RET( ctx != NULL );
CIPHER_VALIDATE_RET( iv != NULL );
CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
CIPHER_VALIDATE_RET( output != NULL );
CIPHER_VALIDATE_RET( olen != NULL );
CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
{
@ -1130,28 +921,6 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
return( ret );
}
#endif /* MBEDTLS_CCM_C */
#if defined(MBEDTLS_CHACHAPOLY_C)
if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
{
int ret;
/* ChachaPoly has fixed length nonce and MAC (tag) */
if ( ( iv_len != ctx->cipher_info->iv_size ) ||
( tag_len != 16U ) )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
*olen = ilen;
ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen,
iv, ad, ad_len, tag, input, output );
if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED )
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
return( ret );
}
#endif /* MBEDTLS_CHACHAPOLY_C */
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
}

View File

@ -1,9 +1,7 @@
/**
* \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.
* \brief The generic cipher wrapper.
*
* \author Adriaan de Jong <dejong@fox-it.com>
*/
@ -36,9 +34,8 @@
#endif
#include <stddef.h>
#include "platform_util.h"
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C)
#define MBEDTLS_CIPHER_MODE_AEAD
#endif
@ -46,8 +43,7 @@
#define MBEDTLS_CIPHER_MODE_WITH_PADDING
#endif
#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \
defined(MBEDTLS_CHACHA20_C)
#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
#define MBEDTLS_CIPHER_MODE_STREAM
#endif
@ -63,8 +59,6 @@
#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */
#define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */
#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 /**< The context is invalid. For example, because it was freed. */
/* MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED -0x6400 /**< Cipher hardware accelerator failed. */
#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length. */
@ -75,122 +69,93 @@ extern "C" {
#endif
/**
* \brief Supported cipher types.
* \brief An enumeration of supported ciphers.
*
* \warning RC4 and DES are considered weak ciphers and their use
* constitutes a security risk. Arm recommends considering stronger
* \warning ARC4 and DES are considered weak ciphers and their use
* constitutes a security risk. We recommend considering stronger
* ciphers instead.
*/
typedef enum {
MBEDTLS_CIPHER_ID_NONE = 0, /**< Placeholder to mark the end of cipher ID lists. */
MBEDTLS_CIPHER_ID_NULL, /**< The identity cipher, treated as a stream cipher. */
MBEDTLS_CIPHER_ID_AES, /**< The AES cipher. */
MBEDTLS_CIPHER_ID_DES, /**< The DES cipher. */
MBEDTLS_CIPHER_ID_3DES, /**< The Triple DES cipher. */
MBEDTLS_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */
MBEDTLS_CIPHER_ID_BLOWFISH, /**< The Blowfish cipher. */
MBEDTLS_CIPHER_ID_ARC4, /**< The RC4 cipher. */
MBEDTLS_CIPHER_ID_ARIA, /**< The Aria cipher. */
MBEDTLS_CIPHER_ID_CHACHA20, /**< The ChaCha20 cipher. */
MBEDTLS_CIPHER_ID_NONE = 0,
MBEDTLS_CIPHER_ID_NULL,
MBEDTLS_CIPHER_ID_AES,
MBEDTLS_CIPHER_ID_DES,
MBEDTLS_CIPHER_ID_3DES,
MBEDTLS_CIPHER_ID_CAMELLIA,
MBEDTLS_CIPHER_ID_BLOWFISH,
MBEDTLS_CIPHER_ID_ARC4,
} mbedtls_cipher_id_t;
/**
* \brief Supported {cipher type, cipher mode} pairs.
* \brief An enumeration of supported (cipher, mode) pairs.
*
* \warning RC4 and DES are considered weak ciphers and their use
* constitutes a security risk. Arm recommends considering stronger
* \warning ARC4 and DES are considered weak ciphers and their use
* constitutes a security risk. We recommend considering stronger
* ciphers instead.
*/
typedef enum {
MBEDTLS_CIPHER_NONE = 0, /**< Placeholder to mark the end of cipher-pair lists. */
MBEDTLS_CIPHER_NULL, /**< The identity stream cipher. */
MBEDTLS_CIPHER_AES_128_ECB, /**< AES cipher with 128-bit ECB mode. */
MBEDTLS_CIPHER_AES_192_ECB, /**< AES cipher with 192-bit ECB mode. */
MBEDTLS_CIPHER_AES_256_ECB, /**< AES cipher with 256-bit ECB mode. */
MBEDTLS_CIPHER_AES_128_CBC, /**< AES cipher with 128-bit CBC mode. */
MBEDTLS_CIPHER_AES_192_CBC, /**< AES cipher with 192-bit CBC mode. */
MBEDTLS_CIPHER_AES_256_CBC, /**< AES cipher with 256-bit CBC mode. */
MBEDTLS_CIPHER_AES_128_CFB128, /**< AES cipher with 128-bit CFB128 mode. */
MBEDTLS_CIPHER_AES_192_CFB128, /**< AES cipher with 192-bit CFB128 mode. */
MBEDTLS_CIPHER_AES_256_CFB128, /**< AES cipher with 256-bit CFB128 mode. */
MBEDTLS_CIPHER_AES_128_CTR, /**< AES cipher with 128-bit CTR mode. */
MBEDTLS_CIPHER_AES_192_CTR, /**< AES cipher with 192-bit CTR mode. */
MBEDTLS_CIPHER_AES_256_CTR, /**< AES cipher with 256-bit CTR mode. */
MBEDTLS_CIPHER_AES_128_GCM, /**< AES cipher with 128-bit GCM mode. */
MBEDTLS_CIPHER_AES_192_GCM, /**< AES cipher with 192-bit GCM mode. */
MBEDTLS_CIPHER_AES_256_GCM, /**< AES cipher with 256-bit GCM mode. */
MBEDTLS_CIPHER_CAMELLIA_128_ECB, /**< Camellia cipher with 128-bit ECB mode. */
MBEDTLS_CIPHER_CAMELLIA_192_ECB, /**< Camellia cipher with 192-bit ECB mode. */
MBEDTLS_CIPHER_CAMELLIA_256_ECB, /**< Camellia cipher with 256-bit ECB mode. */
MBEDTLS_CIPHER_CAMELLIA_128_CBC, /**< Camellia cipher with 128-bit CBC mode. */
MBEDTLS_CIPHER_CAMELLIA_192_CBC, /**< Camellia cipher with 192-bit CBC mode. */
MBEDTLS_CIPHER_CAMELLIA_256_CBC, /**< Camellia cipher with 256-bit CBC mode. */
MBEDTLS_CIPHER_CAMELLIA_128_CFB128, /**< Camellia cipher with 128-bit CFB128 mode. */
MBEDTLS_CIPHER_CAMELLIA_192_CFB128, /**< Camellia cipher with 192-bit CFB128 mode. */
MBEDTLS_CIPHER_CAMELLIA_256_CFB128, /**< Camellia cipher with 256-bit CFB128 mode. */
MBEDTLS_CIPHER_CAMELLIA_128_CTR, /**< Camellia cipher with 128-bit CTR mode. */
MBEDTLS_CIPHER_CAMELLIA_192_CTR, /**< Camellia cipher with 192-bit CTR mode. */
MBEDTLS_CIPHER_CAMELLIA_256_CTR, /**< Camellia cipher with 256-bit CTR mode. */
MBEDTLS_CIPHER_CAMELLIA_128_GCM, /**< Camellia cipher with 128-bit GCM mode. */
MBEDTLS_CIPHER_CAMELLIA_192_GCM, /**< Camellia cipher with 192-bit GCM mode. */
MBEDTLS_CIPHER_CAMELLIA_256_GCM, /**< Camellia cipher with 256-bit GCM mode. */
MBEDTLS_CIPHER_DES_ECB, /**< DES cipher with ECB mode. */
MBEDTLS_CIPHER_DES_CBC, /**< DES cipher with CBC mode. */
MBEDTLS_CIPHER_DES_EDE_ECB, /**< DES cipher with EDE ECB mode. */
MBEDTLS_CIPHER_DES_EDE_CBC, /**< DES cipher with EDE CBC mode. */
MBEDTLS_CIPHER_DES_EDE3_ECB, /**< DES cipher with EDE3 ECB mode. */
MBEDTLS_CIPHER_DES_EDE3_CBC, /**< DES cipher with EDE3 CBC mode. */
MBEDTLS_CIPHER_BLOWFISH_ECB, /**< Blowfish cipher with ECB mode. */
MBEDTLS_CIPHER_BLOWFISH_CBC, /**< Blowfish cipher with CBC mode. */
MBEDTLS_CIPHER_BLOWFISH_CFB64, /**< Blowfish cipher with CFB64 mode. */
MBEDTLS_CIPHER_BLOWFISH_CTR, /**< Blowfish cipher with CTR mode. */
MBEDTLS_CIPHER_ARC4_128, /**< RC4 cipher with 128-bit mode. */
MBEDTLS_CIPHER_AES_128_CCM, /**< AES cipher with 128-bit CCM mode. */
MBEDTLS_CIPHER_AES_192_CCM, /**< AES cipher with 192-bit CCM mode. */
MBEDTLS_CIPHER_AES_256_CCM, /**< AES cipher with 256-bit CCM mode. */
MBEDTLS_CIPHER_CAMELLIA_128_CCM, /**< Camellia cipher with 128-bit CCM mode. */
MBEDTLS_CIPHER_CAMELLIA_192_CCM, /**< Camellia cipher with 192-bit CCM mode. */
MBEDTLS_CIPHER_CAMELLIA_256_CCM, /**< Camellia cipher with 256-bit CCM mode. */
MBEDTLS_CIPHER_ARIA_128_ECB, /**< Aria cipher with 128-bit key and ECB mode. */
MBEDTLS_CIPHER_ARIA_192_ECB, /**< Aria cipher with 192-bit key and ECB mode. */
MBEDTLS_CIPHER_ARIA_256_ECB, /**< Aria cipher with 256-bit key and ECB mode. */
MBEDTLS_CIPHER_ARIA_128_CBC, /**< Aria cipher with 128-bit key and CBC mode. */
MBEDTLS_CIPHER_ARIA_192_CBC, /**< Aria cipher with 192-bit key and CBC mode. */
MBEDTLS_CIPHER_ARIA_256_CBC, /**< Aria cipher with 256-bit key and CBC mode. */
MBEDTLS_CIPHER_ARIA_128_CFB128, /**< Aria cipher with 128-bit key and CFB-128 mode. */
MBEDTLS_CIPHER_ARIA_192_CFB128, /**< Aria cipher with 192-bit key and CFB-128 mode. */
MBEDTLS_CIPHER_ARIA_256_CFB128, /**< Aria cipher with 256-bit key and CFB-128 mode. */
MBEDTLS_CIPHER_ARIA_128_CTR, /**< Aria cipher with 128-bit key and CTR mode. */
MBEDTLS_CIPHER_ARIA_192_CTR, /**< Aria cipher with 192-bit key and CTR mode. */
MBEDTLS_CIPHER_ARIA_256_CTR, /**< Aria cipher with 256-bit key and CTR mode. */
MBEDTLS_CIPHER_ARIA_128_GCM, /**< Aria cipher with 128-bit key and GCM mode. */
MBEDTLS_CIPHER_ARIA_192_GCM, /**< Aria cipher with 192-bit key and GCM mode. */
MBEDTLS_CIPHER_ARIA_256_GCM, /**< Aria cipher with 256-bit key and GCM mode. */
MBEDTLS_CIPHER_ARIA_128_CCM, /**< Aria cipher with 128-bit key and CCM mode. */
MBEDTLS_CIPHER_ARIA_192_CCM, /**< Aria cipher with 192-bit key and CCM mode. */
MBEDTLS_CIPHER_ARIA_256_CCM, /**< Aria cipher with 256-bit key and CCM mode. */
MBEDTLS_CIPHER_AES_128_OFB, /**< AES 128-bit cipher in OFB mode. */
MBEDTLS_CIPHER_AES_192_OFB, /**< AES 192-bit cipher in OFB mode. */
MBEDTLS_CIPHER_AES_256_OFB, /**< AES 256-bit cipher in OFB mode. */
MBEDTLS_CIPHER_AES_128_XTS, /**< AES 128-bit cipher in XTS block mode. */
MBEDTLS_CIPHER_AES_256_XTS, /**< AES 256-bit cipher in XTS block mode. */
MBEDTLS_CIPHER_CHACHA20, /**< ChaCha20 stream cipher. */
MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< ChaCha20-Poly1305 AEAD cipher. */
MBEDTLS_CIPHER_NONE = 0,
MBEDTLS_CIPHER_NULL,
MBEDTLS_CIPHER_AES_128_ECB,
MBEDTLS_CIPHER_AES_192_ECB,
MBEDTLS_CIPHER_AES_256_ECB,
MBEDTLS_CIPHER_AES_128_CBC,
MBEDTLS_CIPHER_AES_192_CBC,
MBEDTLS_CIPHER_AES_256_CBC,
MBEDTLS_CIPHER_AES_128_CFB128,
MBEDTLS_CIPHER_AES_192_CFB128,
MBEDTLS_CIPHER_AES_256_CFB128,
MBEDTLS_CIPHER_AES_128_CTR,
MBEDTLS_CIPHER_AES_192_CTR,
MBEDTLS_CIPHER_AES_256_CTR,
MBEDTLS_CIPHER_AES_128_GCM,
MBEDTLS_CIPHER_AES_192_GCM,
MBEDTLS_CIPHER_AES_256_GCM,
MBEDTLS_CIPHER_CAMELLIA_128_ECB,
MBEDTLS_CIPHER_CAMELLIA_192_ECB,
MBEDTLS_CIPHER_CAMELLIA_256_ECB,
MBEDTLS_CIPHER_CAMELLIA_128_CBC,
MBEDTLS_CIPHER_CAMELLIA_192_CBC,
MBEDTLS_CIPHER_CAMELLIA_256_CBC,
MBEDTLS_CIPHER_CAMELLIA_128_CFB128,
MBEDTLS_CIPHER_CAMELLIA_192_CFB128,
MBEDTLS_CIPHER_CAMELLIA_256_CFB128,
MBEDTLS_CIPHER_CAMELLIA_128_CTR,
MBEDTLS_CIPHER_CAMELLIA_192_CTR,
MBEDTLS_CIPHER_CAMELLIA_256_CTR,
MBEDTLS_CIPHER_CAMELLIA_128_GCM,
MBEDTLS_CIPHER_CAMELLIA_192_GCM,
MBEDTLS_CIPHER_CAMELLIA_256_GCM,
MBEDTLS_CIPHER_DES_ECB,
MBEDTLS_CIPHER_DES_CBC,
MBEDTLS_CIPHER_DES_EDE_ECB,
MBEDTLS_CIPHER_DES_EDE_CBC,
MBEDTLS_CIPHER_DES_EDE3_ECB,
MBEDTLS_CIPHER_DES_EDE3_CBC,
MBEDTLS_CIPHER_BLOWFISH_ECB,
MBEDTLS_CIPHER_BLOWFISH_CBC,
MBEDTLS_CIPHER_BLOWFISH_CFB64,
MBEDTLS_CIPHER_BLOWFISH_CTR,
MBEDTLS_CIPHER_ARC4_128,
MBEDTLS_CIPHER_AES_128_CCM,
MBEDTLS_CIPHER_AES_192_CCM,
MBEDTLS_CIPHER_AES_256_CCM,
MBEDTLS_CIPHER_CAMELLIA_128_CCM,
MBEDTLS_CIPHER_CAMELLIA_192_CCM,
MBEDTLS_CIPHER_CAMELLIA_256_CCM,
} mbedtls_cipher_type_t;
/** Supported cipher modes. */
typedef enum {
MBEDTLS_MODE_NONE = 0, /**< None. */
MBEDTLS_MODE_ECB, /**< The ECB cipher mode. */
MBEDTLS_MODE_CBC, /**< The CBC cipher mode. */
MBEDTLS_MODE_CFB, /**< The CFB cipher mode. */
MBEDTLS_MODE_OFB, /**< The OFB cipher mode. */
MBEDTLS_MODE_CTR, /**< The CTR cipher mode. */
MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */
MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */
MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */
MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */
MBEDTLS_MODE_CHACHAPOLY, /**< The ChaCha-Poly cipher mode. */
MBEDTLS_MODE_NONE = 0,
MBEDTLS_MODE_ECB,
MBEDTLS_MODE_CBC,
MBEDTLS_MODE_CFB,
MBEDTLS_MODE_OFB, /* Unused! */
MBEDTLS_MODE_CTR,
MBEDTLS_MODE_GCM,
MBEDTLS_MODE_STREAM,
MBEDTLS_MODE_CCM,
} mbedtls_cipher_mode_t;
/** Supported cipher padding types. */
@ -198,8 +163,8 @@ typedef enum {
MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default). */
MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding. */
MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding. */
MBEDTLS_PADDING_ZEROS, /**< Zero padding (not reversible). */
MBEDTLS_PADDING_NONE, /**< Never pad (full blocks only). */
MBEDTLS_PADDING_ZEROS, /**< zero padding (not reversible). */
MBEDTLS_PADDING_NONE, /**< never pad (full blocks only). */
} mbedtls_cipher_padding_t;
/** Type of operation. */
@ -239,8 +204,7 @@ typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t;
* Cipher information. Allows calling cipher functions
* in a generic way.
*/
typedef struct mbedtls_cipher_info_t
{
typedef struct {
/** Full cipher identifier. For example,
* MBEDTLS_CIPHER_AES_256_CBC.
*/
@ -264,10 +228,7 @@ typedef struct mbedtls_cipher_info_t
*/
unsigned int iv_size;
/** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and
* MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the
* cipher supports variable IV or variable key sizes, respectively.
*/
/** Flags to set. For example, if the cipher supports variable IV sizes or variable key sizes. */
int flags;
/** The block size, in Bytes. */
@ -281,19 +242,18 @@ typedef struct mbedtls_cipher_info_t
/**
* Generic cipher context.
*/
typedef struct mbedtls_cipher_context_t
{
/** Operation that the key of the context has been
* initialized for.
*/
mbedtls_operation_t operation;
typedef struct {
/** Information about the associated cipher. */
const mbedtls_cipher_info_t *cipher_info;
/** Key length to use. */
int key_bitlen;
/** Operation that the key of the context has been
* initialized for.
*/
mbedtls_operation_t operation;
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
/** Padding functions to use, if relevant for
* the specific cipher mode.
@ -302,9 +262,15 @@ typedef struct mbedtls_cipher_context_t
int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len );
#endif
/** Buffer for input that has not been processed yet. */
unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH];
/** Number of Bytes that have not been processed yet. */
size_t unprocessed_len;
/** Current IV or NONCE_COUNTER for CTR-mode. */
unsigned char iv[MBEDTLS_MAX_IV_LENGTH];
/** IV size in Bytes, for ciphers with variable-length IVs. */
size_t iv_size;
@ -315,13 +281,6 @@ typedef struct mbedtls_cipher_context_t
/** CMAC-specific context. */
mbedtls_cmac_context_t *cmac_ctx;
#endif
/** Buffer for input that has not been processed yet. */
unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH];
/** Current IV or NONCE_COUNTER for CTR-mode, data unit (or sector) number
* for XTS-mode. */
unsigned char iv[MBEDTLS_MAX_IV_LENGTH];
} mbedtls_cipher_context_t;
/**
@ -337,12 +296,10 @@ const int *mbedtls_cipher_list( void );
* \brief This function retrieves the cipher-information
* structure associated with the given cipher name.
*
* \param cipher_name Name of the cipher to search for. This must not be
* \c NULL.
* \param cipher_name Name of the cipher to search for.
*
* \return The cipher information structure associated with the
* given \p cipher_name.
* \return \c NULL if the associated cipher information is not found.
* given \p cipher_name, or NULL if not found.
*/
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name );
@ -353,8 +310,7 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher
* \param cipher_type Type of the cipher to search for.
*
* \return The cipher information structure associated with the
* given \p cipher_type.
* \return \c NULL if the associated cipher information is not found.
* given \p cipher_type, or NULL if not found.
*/
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type );
@ -369,8 +325,7 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher
* \param mode The cipher mode. For example, #MBEDTLS_MODE_CBC.
*
* \return The cipher information structure associated with the
* given \p cipher_id.
* \return \c NULL if the associated cipher information is not found.
* given \p cipher_id, or NULL if not found.
*/
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
int key_bitlen,
@ -378,8 +333,6 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_ciph
/**
* \brief This function initializes a \p cipher_context as NONE.
*
* \param ctx The context to be initialized. This must not be \c NULL.
*/
void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
@ -387,10 +340,6 @@ void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
* \brief This function frees and clears the cipher-specific
* context of \p ctx. Freeing \p ctx itself remains the
* responsibility of the caller.
*
* \param ctx The context to be freed. If this is \c NULL, the
* function has no effect, otherwise this must point to an
* initialized context.
*/
void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx );
@ -400,35 +349,31 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx );
* structure with the appropriate values. It also clears
* the structure.
*
* \param ctx The context to initialize. This must be initialized.
* \param ctx The context to initialize. May not be NULL.
* \param cipher_info The cipher to use.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
* cipher-specific context fails.
* \return \c 0 on success,
* #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on parameter failure,
* #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
* cipher-specific context failed.
*
* \internal Currently, the function also clears the structure.
* In future versions, the caller will be required to call
* mbedtls_cipher_init() on the structure first.
*/
int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
const mbedtls_cipher_info_t *cipher_info );
int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info );
/**
* \brief This function returns the block size of the given cipher.
*
* \param ctx The context of the cipher. This must be initialized.
* \param ctx The context of the cipher. Must be initialized.
*
* \return The block size of the underlying cipher.
* \return \c 0 if \p ctx has not been initialized.
* \return The size of the blocks of the cipher, or zero if \p ctx
* has not been initialized.
*/
static inline unsigned int mbedtls_cipher_get_block_size(
const mbedtls_cipher_context_t *ctx )
static inline unsigned int mbedtls_cipher_get_block_size( const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
if( ctx->cipher_info == NULL )
if( NULL == ctx || NULL == ctx->cipher_info )
return 0;
return ctx->cipher_info->block_size;
@ -438,16 +383,14 @@ static inline unsigned int mbedtls_cipher_get_block_size(
* \brief This function returns the mode of operation for
* the cipher. For example, MBEDTLS_MODE_CBC.
*
* \param ctx The context of the cipher. This must be initialized.
* \param ctx The context of the cipher. Must be initialized.
*
* \return The mode of operation.
* \return #MBEDTLS_MODE_NONE if \p ctx has not been initialized.
* \return The mode of operation, or #MBEDTLS_MODE_NONE if
* \p ctx has not been initialized.
*/
static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode(
const mbedtls_cipher_context_t *ctx )
static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, MBEDTLS_MODE_NONE );
if( ctx->cipher_info == NULL )
if( NULL == ctx || NULL == ctx->cipher_info )
return MBEDTLS_MODE_NONE;
return ctx->cipher_info->mode;
@ -457,17 +400,15 @@ static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode(
* \brief This function returns the size of the IV or nonce
* of the cipher, in Bytes.
*
* \param ctx The context of the cipher. This must be initialized.
* \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.
* \return <ul><li>If no IV has been set: the recommended IV size.
* 0 for ciphers not using IV or nonce.</li>
* <li>If IV has already been set: the actual size.</li></ul>
*/
static inline int mbedtls_cipher_get_iv_size(
const mbedtls_cipher_context_t *ctx )
static inline int mbedtls_cipher_get_iv_size( const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
if( ctx->cipher_info == NULL )
if( NULL == ctx || NULL == ctx->cipher_info )
return 0;
if( ctx->iv_size != 0 )
@ -479,17 +420,14 @@ static inline int mbedtls_cipher_get_iv_size(
/**
* \brief This function returns the type of the given cipher.
*
* \param ctx The context of the cipher. This must be initialized.
* \param ctx The context of the cipher. Must be initialized.
*
* \return The type of the cipher.
* \return #MBEDTLS_CIPHER_NONE if \p ctx has not been initialized.
* \return The type of the cipher, or #MBEDTLS_CIPHER_NONE if
* \p ctx has not been initialized.
*/
static inline mbedtls_cipher_type_t mbedtls_cipher_get_type(
const mbedtls_cipher_context_t *ctx )
static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET(
ctx != NULL, MBEDTLS_CIPHER_NONE );
if( ctx->cipher_info == NULL )
if( NULL == ctx || NULL == ctx->cipher_info )
return MBEDTLS_CIPHER_NONE;
return ctx->cipher_info->type;
@ -499,16 +437,14 @@ static inline mbedtls_cipher_type_t mbedtls_cipher_get_type(
* \brief This function returns the name of the given cipher
* as a string.
*
* \param ctx The context of the cipher. This must be initialized.
* \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.
* \return The name of the cipher, or NULL if \p ctx has not
* been not initialized.
*/
static inline const char *mbedtls_cipher_get_name(
const mbedtls_cipher_context_t *ctx )
static inline const char *mbedtls_cipher_get_name( const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
if( ctx->cipher_info == NULL )
if( NULL == ctx || NULL == ctx->cipher_info )
return 0;
return ctx->cipher_info->name;
@ -517,18 +453,15 @@ static inline const char *mbedtls_cipher_get_name(
/**
* \brief This function returns the key length of the cipher.
*
* \param ctx The context of the cipher. This must be initialized.
* \param ctx The context of the cipher. Must be initialized.
*
* \return The key length of the cipher in bits.
* \return #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been
* \return The key length of the cipher in bits, or
* #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been
* initialized.
*/
static inline int mbedtls_cipher_get_key_bitlen(
const mbedtls_cipher_context_t *ctx )
static inline int mbedtls_cipher_get_key_bitlen( const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET(
ctx != NULL, MBEDTLS_KEY_LENGTH_NONE );
if( ctx->cipher_info == NULL )
if( NULL == ctx || NULL == ctx->cipher_info )
return MBEDTLS_KEY_LENGTH_NONE;
return (int) ctx->cipher_info->key_bitlen;
@ -537,17 +470,15 @@ static inline int mbedtls_cipher_get_key_bitlen(
/**
* \brief This function returns the operation of the given cipher.
*
* \param ctx The context of the cipher. This must be initialized.
* \param ctx The context of the cipher. Must be initialized.
*
* \return The type of operation: #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
* \return #MBEDTLS_OPERATION_NONE if \p ctx has not been initialized.
* \return The type of operation: #MBEDTLS_ENCRYPT or
* #MBEDTLS_DECRYPT, or #MBEDTLS_OPERATION_NONE if \p ctx
* has not been initialized.
*/
static inline mbedtls_operation_t mbedtls_cipher_get_operation(
const mbedtls_cipher_context_t *ctx )
static inline mbedtls_operation_t mbedtls_cipher_get_operation( const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET(
ctx != NULL, MBEDTLS_OPERATION_NONE );
if( ctx->cipher_info == NULL )
if( NULL == ctx || NULL == ctx->cipher_info )
return MBEDTLS_OPERATION_NONE;
return ctx->operation;
@ -556,23 +487,20 @@ static inline mbedtls_operation_t mbedtls_cipher_get_operation(
/**
* \brief This function sets the key to use with the given context.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a cipher information structure.
* \param key The key to use. This must be a readable buffer of at
* least \p key_bitlen Bits.
* \param key_bitlen The key length to use, in Bits.
* \param ctx The generic cipher context. May not be NULL. Must have
* been initialized using mbedtls_cipher_info_from_type()
* or mbedtls_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:
* #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return A cipher-specific error code on failure.
* \returns \c 0 on success, #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if
* parameter verification fails, or a cipher-specific
* error code.
*/
int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
const unsigned char *key,
int key_bitlen,
const mbedtls_operation_t operation );
int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key,
int key_bitlen, const mbedtls_operation_t operation );
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
/**
@ -581,71 +509,59 @@ int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
*
* The default passing mode is PKCS7 padding.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a cipher information structure.
* \param ctx The generic cipher context.
* \param mode The padding mode.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
* if the selected padding mode is not supported.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode
* \returns \c 0 on success, #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
* if the selected padding mode is not supported, or
* #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode
* does not support padding.
*/
int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
mbedtls_cipher_padding_t mode );
int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode );
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
/**
* \brief This function sets the initialization vector (IV)
* or nonce.
*
* \note Some ciphers do not use IVs nor nonce. For these
* ciphers, this function has no effect.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a cipher information structure.
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. This
* must be a readable buffer of at least \p iv_len Bytes.
* \param 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 #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \returns \c 0 on success, or #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
*
* \note Some ciphers do not use IVs nor nonce. For these
* ciphers, this function has no effect.
*/
int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
const unsigned char *iv,
size_t iv_len );
const unsigned char *iv, size_t iv_len );
/**
* \brief This function resets the cipher state.
*
* \param ctx The generic cipher context. This must be initialized.
* \param ctx The generic cipher context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \returns \c 0 on success, #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
* if parameter verification fails.
*/
int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
#if defined(MBEDTLS_GCM_C)
/**
* \brief This function adds additional data for AEAD ciphers.
* Currently supported with GCM and ChaCha20+Poly1305.
* This must be called exactly once, after
* mbedtls_cipher_reset().
* Only supported with GCM. Must be called
* exactly once, after mbedtls_cipher_reset().
*
* \param ctx The generic cipher context. This must be initialized.
* \param ad The additional data to use. This must be a readable
* buffer of at least \p ad_len Bytes.
* \param ad_len the Length of \p ad Bytes.
* \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.
* \return \c 0 on success, or a specific error code on failure.
*/
int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
const unsigned char *ad, size_t ad_len );
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
#endif /* MBEDTLS_GCM_C */
/**
* \brief The generic cipher update function. It encrypts or
@ -657,29 +573,25 @@ int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
* Exception: For MBEDTLS_MODE_ECB, expects a single block
* in size. For example, 16 Bytes for AES.
*
* \note If the underlying cipher is used in GCM mode, all calls
* to this function, except for the last one before
* mbedtls_cipher_finish(), must have \p ilen as a
* multiple of the block size of the cipher.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a key.
* \param input The buffer holding the input data. This must be a
* readable buffer of at least \p ilen Bytes.
* \param 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. This must be able to
* hold at least `ilen + block_size`. This must not be the
* same buffer as \p input.
* \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. This must not be
* \c NULL.
* actual number of Bytes written.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an
* unsupported mode for a cipher.
* \return A cipher-specific error code on failure.
* \returns \c 0 on success, #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if
* parameter verification fails,
* #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an
* unsupported mode for a cipher, or a cipher-specific
* error code.
*
* \note If the underlying cipher is GCM, all calls to this
* function, except the last one before
* mbedtls_cipher_finish(). Must have \p ilen as a
* multiple of the block_size.
*/
int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
size_t ilen, unsigned char *output, size_t *olen );
@ -690,94 +602,78 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
* contained in it is padded to the size of
* the last block, and written to the \p output buffer.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a key.
* \param output The buffer to write data to. This needs to be a writable
* buffer of at least \p block_size Bytes.
* \param 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.
* This may not be \c NULL.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
* expecting a full block but not receiving one.
* \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
* while decrypting.
* \return A cipher-specific error code on failure.
* \returns \c 0 on success, #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if
* parameter verification fails,
* #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption
* expected a full block but was not provided one,
* #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
* while decrypting, or a cipher-specific error code
* on failure for any other reason.
*/
int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
unsigned char *output, size_t *olen );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
#if defined(MBEDTLS_GCM_C)
/**
* \brief This function writes a tag for AEAD ciphers.
* Currently supported with GCM and ChaCha20+Poly1305.
* This must be called after mbedtls_cipher_finish().
* Only supported with GCM.
* Must be called after mbedtls_cipher_finish().
*
* \param ctx The generic cipher context. This must be initialized,
* bound to a key, and have just completed a cipher
* operation through mbedtls_cipher_finish() the tag for
* which should be written.
* \param tag The buffer to write the tag to. This must be a writable
* buffer of at least \p tag_len Bytes.
* \param 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.
* \return \c 0 on success, or a specific error code on failure.
*/
int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
unsigned char *tag, size_t tag_len );
/**
* \brief This function checks the tag for AEAD ciphers.
* Currently supported with GCM and ChaCha20+Poly1305.
* This must be called after mbedtls_cipher_finish().
* Only supported with GCM.
* Must be called after mbedtls_cipher_finish().
*
* \param ctx The generic cipher context. This must be initialized.
* \param tag The buffer holding the tag. This must be a readable
* buffer of at least \p tag_len Bytes.
* \param 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.
* \return \c 0 on success, or a specific error code on failure.
*/
int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
const unsigned char *tag, size_t tag_len );
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
#endif /* MBEDTLS_GCM_C */
/**
* \brief The generic all-in-one encryption/decryption function,
* for all ciphers except AEAD constructs.
*
* \param ctx The generic cipher context. This must be initialized.
* \param ctx The generic cipher context.
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
* This must be a readable buffer of at least \p iv_len
* Bytes.
* \param iv_len The IV length for ciphers with variable-size IV.
* This parameter is discarded by ciphers with fixed-size
* IV.
* \param input The buffer holding the input data. This must be a
* readable buffer of at least \p ilen Bytes.
* \param ilen The length of the input data in Bytes.
* \param output The buffer for the output data. This must be able to
* hold at least `ilen + block_size`. This must not be the
* same buffer as \p input.
* \param 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. This must not be
* \c NULL.
* 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 #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
* expecting a full block but not receiving one.
* \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
* while decrypting.
* \return A cipher-specific error code on failure.
* \returns \c 0 on success, or
* #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or
* #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption
* expected a full block but was not provided one, or
* #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
* while decrypting, or a cipher-specific error code on
* failure for any other reason.
*/
int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,
@ -788,32 +684,24 @@ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
/**
* \brief The generic autenticated encryption (AEAD) function.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a key.
* \param ctx The generic cipher context.
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
* This must be a readable buffer of at least \p iv_len
* Bytes.
* \param iv_len The IV length for ciphers with variable-size IV.
* This parameter is discarded by ciphers with fixed-size IV.
* \param ad The additional data to authenticate. This must be a
* readable buffer of at least \p ad_len Bytes.
* \param ad The additional data to authenticate.
* \param ad_len The length of \p ad.
* \param input The buffer holding the input data. This must be a
* readable buffer of at least \p ilen Bytes.
* \param input The buffer holding the input data.
* \param ilen The length of the input data.
* \param output The buffer for the output data. This must be able to
* hold at least \p ilen Bytes.
* \param 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. This must not be
* \c NULL.
* \param tag The buffer for the authentication tag. This must be a
* writable buffer of at least \p tag_len Bytes.
* 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 #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return A cipher-specific error code on failure.
* \returns \c 0 on success, or
* #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or
* a cipher-specific error code.
*/
int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,
@ -825,37 +713,29 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
/**
* \brief The generic autenticated decryption (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 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.
*
* \returns \c 0 on success, or
* #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or
* #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic,
* or a cipher-specific error code on failure for any other reason.
*
* \note If the data is not authentic, then the output buffer
* is zeroed out to prevent the unauthentic plaintext being
* used, making this interface safer.
*
* \param ctx The generic cipher context. This must be initialized and
* and bound to a key.
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
* This must be a readable buffer of at least \p iv_len
* Bytes.
* \param iv_len The IV length for ciphers with variable-size IV.
* This parameter is discarded by ciphers with fixed-size IV.
* \param ad The additional data to be authenticated. This must be a
* readable buffer of at least \p ad_len Bytes.
* \param ad_len The length of \p ad.
* \param input The buffer holding the input data. This must be a
* readable buffer of at least \p ilen Bytes.
* \param ilen The length of the input data.
* \param output The buffer for the output data.
* This must be able to hold at least \p ilen Bytes.
* \param olen The length of the output data, to be updated with the
* actual number of Bytes written. This must not be
* \c NULL.
* \param tag The buffer holding the authentication tag. This must be
* a readable buffer of at least \p tag_len Bytes.
* \param tag_len The length of the authentication tag.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic.
* \return A cipher-specific error code on failure.
*/
int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,

View File

@ -64,14 +64,6 @@ struct mbedtls_cipher_base_t
unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_OFB)
/** Encrypt using OFB (Full length) */
int (*ofb_func)( void *ctx, size_t length, size_t *iv_off,
unsigned char *iv,
const unsigned char *input,
unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/** Encrypt using CTR */
int (*ctr_func)( void *ctx, size_t length, size_t *nc_off,
@ -79,13 +71,6 @@ struct mbedtls_cipher_base_t
const unsigned char *input, unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/** Encrypt or decrypt using XTS. */
int (*xts_func)( void *ctx, mbedtls_operation_t mode, size_t length,
const unsigned char data_unit[16],
const unsigned char *input, unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_STREAM)
/** Encrypt using STREAM */
int (*stream_func)( void *ctx, size_t length,

File diff suppressed because it is too large Load Diff

View File

@ -49,7 +49,6 @@
#if defined(MBEDTLS_CMAC_C)
#include "cmac.h"
#include "platform_util.h"
#include <string.h>
@ -68,6 +67,11 @@
#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
}
/*
* Multiplication by u in the Galois field of GF(2^n)
*
@ -140,7 +144,7 @@ static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx,
unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX];
size_t olen, block_size;
mbedtls_platform_zeroize( L, sizeof( L ) );
mbedtls_zeroize( L, sizeof( L ) );
block_size = ctx->cipher_info->block_size;
@ -158,7 +162,7 @@ static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx,
goto exit;
exit:
mbedtls_platform_zeroize( L, sizeof( L ) );
mbedtls_zeroize( L, sizeof( L ) );
return( ret );
}
@ -234,7 +238,7 @@ int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
ctx->cmac_ctx = cmac_ctx;
mbedtls_platform_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) );
mbedtls_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) );
return 0;
}
@ -260,7 +264,7 @@ int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
if( cmac_ctx->unprocessed_len > 0 &&
ilen > block_size - cmac_ctx->unprocessed_len )
{
mbedtls_platform_memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
input,
block_size - cmac_ctx->unprocessed_len );
@ -297,7 +301,7 @@ int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
/* If there is data left over that wasn't aligned to a block */
if( ilen > 0 )
{
mbedtls_platform_memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
input,
ilen );
cmac_ctx->unprocessed_len += ilen;
@ -326,8 +330,8 @@ int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
block_size = ctx->cipher_info->block_size;
state = cmac_ctx->state;
mbedtls_platform_zeroize( K1, sizeof( K1 ) );
mbedtls_platform_zeroize( K2, sizeof( K2 ) );
mbedtls_zeroize( K1, sizeof( K1 ) );
mbedtls_zeroize( K2, sizeof( K2 ) );
cmac_generate_subkeys( ctx, K1, K2 );
last_block = cmac_ctx->unprocessed_block;
@ -352,19 +356,19 @@ int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
goto exit;
}
mbedtls_platform_memcpy( output, state, block_size );
memcpy( output, state, block_size );
exit:
/* Wipe the generated keys on the stack, and any other transients to avoid
* side channel leakage */
mbedtls_platform_zeroize( K1, sizeof( K1 ) );
mbedtls_platform_zeroize( K2, sizeof( K2 ) );
mbedtls_zeroize( K1, sizeof( K1 ) );
mbedtls_zeroize( K2, sizeof( K2 ) );
cmac_ctx->unprocessed_len = 0;
mbedtls_platform_zeroize( cmac_ctx->unprocessed_block,
sizeof( cmac_ctx->unprocessed_block ) );
mbedtls_zeroize( cmac_ctx->unprocessed_block,
sizeof( cmac_ctx->unprocessed_block ) );
mbedtls_platform_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX );
mbedtls_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX );
return( ret );
}
@ -379,10 +383,10 @@ int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx )
/* Reset the internal state */
cmac_ctx->unprocessed_len = 0;
mbedtls_platform_zeroize( cmac_ctx->unprocessed_block,
sizeof( cmac_ctx->unprocessed_block ) );
mbedtls_platform_zeroize( cmac_ctx->state,
sizeof( cmac_ctx->state ) );
mbedtls_zeroize( cmac_ctx->unprocessed_block,
sizeof( cmac_ctx->unprocessed_block ) );
mbedtls_zeroize( cmac_ctx->state,
sizeof( cmac_ctx->state ) );
return( 0 );
}
@ -446,11 +450,11 @@ int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
if( key_length == MBEDTLS_AES_BLOCK_SIZE )
{
/* Use key as is */
mbedtls_platform_memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE );
memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE );
}
else
{
mbedtls_platform_memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE );
memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE );
ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key,
key_length, int_key );
@ -462,7 +466,7 @@ int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
output );
exit:
mbedtls_platform_zeroize( int_key, sizeof( int_key ) );
mbedtls_zeroize( int_key, sizeof( int_key ) );
return( ret );
}
@ -902,7 +906,7 @@ static int test_aes128_cmac_prf( int verbose )
mbedtls_printf( " AES CMAC 128 PRF #%u: ", i );
ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output );
if( ret != 0 ||
memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 )
memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 )
{
if( verbose != 0 )

View File

@ -1,10 +1,8 @@
/**
* \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>.
* \brief The Cipher-based Message Authentication Code (CMAC) Mode for
* Authentication.
*/
/*
* Copyright (C) 2015-2018, Arm Limited (or its affiliates), All Rights Reserved
@ -40,16 +38,15 @@
extern "C" {
#endif
/* MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED -0x007A /**< CMAC hardware accelerator failed. */
#define MBEDTLS_AES_BLOCK_SIZE 16
#define MBEDTLS_DES3_BLOCK_SIZE 8
#if defined(MBEDTLS_AES_C)
#define MBEDTLS_CIPHER_BLKSIZE_MAX 16 /**< The longest block used by CMAC is that of AES. */
#define MBEDTLS_CIPHER_BLKSIZE_MAX 16 /* The longest block used by CMAC is that of AES. */
#else
#define MBEDTLS_CIPHER_BLKSIZE_MAX 8 /**< The longest block used by CMAC is that of 3DES. */
#define MBEDTLS_CIPHER_BLKSIZE_MAX 8 /* The longest block used by CMAC is that of 3DES. */
#endif
#if !defined(MBEDTLS_CMAC_ALT)
@ -70,25 +67,22 @@ struct mbedtls_cmac_context_t
size_t unprocessed_len;
};
#else /* !MBEDTLS_CMAC_ALT */
#include "cmac_alt.h"
#endif /* !MBEDTLS_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: MBEDTLS_CIPHER_AES_128_ECB,
* MBEDTLS_CIPHER_AES_192_ECB, MBEDTLS_CIPHER_AES_256_ECB,
* or MBEDTLS_CIPHER_DES_EDE3_ECB.
* as one of the following types:<ul>
* <li>MBEDTLS_CIPHER_AES_128_ECB</li>
* <li>MBEDTLS_CIPHER_AES_192_ECB</li>
* <li>MBEDTLS_CIPHER_AES_256_ECB</li>
* <li>MBEDTLS_CIPHER_DES_EDE3_ECB</li></ul>
* \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.
* \return \c 0 on success, or a cipher-specific error code.
*/
int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
const unsigned char *key, size_t keybits );
@ -105,9 +99,8 @@ int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
* \param input The buffer holding the input data.
* \param ilen The length of the input data.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
* if parameter verification fails.
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA
* if parameter verification fails.
*/
int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
const unsigned char *input, size_t ilen );
@ -123,8 +116,7 @@ int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
* \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 #MBEDTLS_ERR_MD_BAD_INPUT_DATA
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA
* if parameter verification fails.
*/
int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
@ -140,8 +132,7 @@ int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
*
* \param ctx The cipher context used for the CMAC operation.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA
* if parameter verification fails.
*/
int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx );
@ -164,8 +155,7 @@ int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx );
* \param ilen The length of the input data.
* \param output The buffer for the generic CMAC result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA
* if parameter verification fails.
*/
int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
@ -196,12 +186,23 @@ int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_len,
unsigned char output[16] );
#endif /* MBEDTLS_AES_C */
#ifdef __cplusplus
}
#endif
#else /* !MBEDTLS_CMAC_ALT */
#include "cmac_alt.h"
#endif /* !MBEDTLS_CMAC_ALT */
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_SELF_TEST) && ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) )
/**
* \brief The CMAC checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
* \return \c 0 on success, or \c 1 on failure.
*/
int mbedtls_cmac_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST && ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */

View File

@ -1384,8 +1384,7 @@
#define SSL_ANTI_REPLAY_ENABLED MBEDTLS_SSL_ANTI_REPLAY_ENABLED
#define SSL_ARC4_DISABLED MBEDTLS_SSL_ARC4_DISABLED
#define SSL_ARC4_ENABLED MBEDTLS_SSL_ARC4_ENABLED
#define SSL_BUFFER_LEN ( ( ( MBEDTLS_SSL_IN_BUFFER_LEN ) < ( MBEDTLS_SSL_OUT_BUFFER_LEN ) ) \
? ( MBEDTLS_SSL_IN_BUFFER_LEN ) : ( MBEDTLS_SSL_OUT_BUFFER_LEN ) )
#define SSL_BUFFER_LEN MBEDTLS_SSL_BUFFER_LEN
#define SSL_CACHE_DEFAULT_MAX_ENTRIES MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES
#define SSL_CACHE_DEFAULT_TIMEOUT MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT
#define SSL_CBC_RECORD_SPLITTING_DISABLED MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED
@ -2231,7 +2230,7 @@
#define rsa_rsassa_pss_verify_ext mbedtls_rsa_rsassa_pss_verify_ext
#define rsa_self_test mbedtls_rsa_self_test
#define rsa_set_padding mbedtls_rsa_set_padding
#define safer_memcmp mbedtls_platform_memequal
#define safer_memcmp mbedtls_ssl_safer_memcmp
#define set_alarm mbedtls_set_alarm
#define sha1 mbedtls_sha1
#define sha1_context mbedtls_sha1_context

File diff suppressed because it is too large Load Diff

View File

@ -1,47 +0,0 @@
/*
* CRC-16/ARC implementation, generated using pycrc v0.9.2, https://pycrc.org.
*
* Used options: --model=crc-16 --algorithm=tbl --generate=h --std=C89 --table-idx-width 4
*
* Copyright (C) 2006-2020, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CRC_H
#define MBEDTLS_CRC_H
#include <stdlib.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Update the crc value with new data.
*
* \param[in] crc The current crc value.
* \param[in] data Pointer to a buffer of \a data_len bytes.
* \param[in] data_len Number of bytes in the \a data buffer.
* \return The updated crc value.
*/
uint16_t mbedtls_crc_update( uint16_t crc, const void *data, size_t data_len );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CRC_H */

View File

@ -33,7 +33,6 @@
#if defined(MBEDTLS_CTR_DRBG_C)
#include "ctr_drbg.h"
#include "platform_util.h"
#include <string.h>
@ -50,18 +49,73 @@
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/*
* CTR_DRBG context initialization
*/
void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
{
mbedtls_platform_memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &ctx->mutex );
#endif
}
/*
* Non-public function wrapped by mbedtls_ctr_drbg_seed(). Necessary to allow
* NIST tests to succeed (which require known length fixed entropy)
*/
int mbedtls_ctr_drbg_seed_entropy_len(
mbedtls_ctr_drbg_context *ctx,
int (*f_entropy)(void *, unsigned char *, size_t),
void *p_entropy,
const unsigned char *custom,
size_t len,
size_t entropy_len )
{
int ret;
unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
mbedtls_aes_init( &ctx->aes_ctx );
ctx->f_entropy = f_entropy;
ctx->p_entropy = p_entropy;
ctx->entropy_len = entropy_len;
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
/*
* Initialize with an empty key
*/
if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
return( ret );
}
if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
{
return( ret );
}
return( 0 );
}
int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
int (*f_entropy)(void *, unsigned char *, size_t),
void *p_entropy,
const unsigned char *custom,
size_t len )
{
return( mbedtls_ctr_drbg_seed_entropy_len( ctx, f_entropy, p_entropy, custom, len,
MBEDTLS_CTR_DRBG_ENTROPY_LEN ) );
}
void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
{
if( ctx == NULL )
@ -71,7 +125,7 @@ void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
mbedtls_mutex_free( &ctx->mutex );
#endif
mbedtls_aes_free( &ctx->aes_ctx );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
mbedtls_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
}
void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance )
@ -106,7 +160,7 @@ static int block_cipher_df( unsigned char *output,
if( data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
mbedtls_platform_memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 );
memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 );
mbedtls_aes_init( &aes_ctx );
/*
@ -123,7 +177,7 @@ static int block_cipher_df( unsigned char *output,
*p++ = ( data_len ) & 0xff;
p += 3;
*p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
mbedtls_platform_memcpy( p, data, data_len );
memcpy( p, data, data_len );
p[data_len] = 0x80;
buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
@ -142,7 +196,7 @@ static int block_cipher_df( unsigned char *output,
for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
{
p = buf;
mbedtls_platform_memset( chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE );
memset( chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE );
use_len = buf_len;
while( use_len > 0 )
@ -159,7 +213,7 @@ static int block_cipher_df( unsigned char *output,
}
}
mbedtls_platform_memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE );
memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE );
/*
* Update IV
@ -183,7 +237,7 @@ static int block_cipher_df( unsigned char *output,
{
goto exit;
}
mbedtls_platform_memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE );
memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE );
p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
}
exit:
@ -191,29 +245,21 @@ exit:
/*
* tidy up the stack
*/
mbedtls_platform_zeroize( buf, sizeof( buf ) );
mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
mbedtls_platform_zeroize( key, sizeof( key ) );
mbedtls_platform_zeroize( chain, sizeof( chain ) );
mbedtls_zeroize( buf, sizeof( buf ) );
mbedtls_zeroize( tmp, sizeof( tmp ) );
mbedtls_zeroize( key, sizeof( key ) );
mbedtls_zeroize( chain, sizeof( chain ) );
if( 0 != ret )
{
/*
* wipe partial seed from memory
*/
mbedtls_platform_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN );
mbedtls_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN );
}
return( ret );
}
/* CTR_DRBG_Update (SP 800-90A &sect;10.2.1.2)
* ctr_drbg_update_internal(ctx, provided_data)
* implements
* CTR_DRBG_Update(provided_data, Key, V)
* with inputs and outputs
* ctx->aes_ctx = Key
* ctx->counter = V
*/
static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] )
{
@ -222,7 +268,7 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
int i, j;
int ret = 0;
mbedtls_platform_memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
{
@ -250,25 +296,13 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
*/
if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
goto exit;
mbedtls_platform_memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );
memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );
exit:
mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
mbedtls_zeroize( tmp, sizeof( tmp ) );
return( ret );
}
/* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
* mbedtls_ctr_drbg_update(ctx, additional, add_len)
* implements
* CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
* security_strength) -> initial_working_state
* with inputs
* ctx->counter = all-bits-0
* ctx->aes_ctx = context from all-bits-0 key
* additional[:add_len] = entropy_input || nonce || personalization_string
* and with outputs
* ctx = initial_working_state
*/
int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional,
size_t add_len )
@ -285,11 +319,11 @@ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
goto exit;
exit:
mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
mbedtls_zeroize( add_input, sizeof( add_input ) );
return( ret );
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
/* Deprecated function, kept for backward compatibility. */
void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional,
size_t add_len )
@ -300,20 +334,7 @@ void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
(void) mbedtls_ctr_drbg_update_ret( ctx, additional, add_len );
}
#endif /* MBEDTLS_DEPRECATED_REMOVED */
/* CTR_DRBG_Reseed with derivation function (SP 800-90A &sect;10.2.1.4.2)
* mbedtls_ctr_drbg_reseed(ctx, additional, len)
* implements
* CTR_DRBG_Reseed(working_state, entropy_input, additional_input)
* -> new_working_state
* with inputs
* ctx contains working_state
* additional[:len] = additional_input
* and entropy_input comes from calling ctx->f_entropy
* and with output
* ctx contains new_working_state
*/
int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional, size_t len )
{
@ -325,7 +346,7 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
mbedtls_platform_memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );
memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );
/*
* Gather entropy_len bytes of entropy to seed state
@ -343,7 +364,7 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
*/
if( additional && len )
{
mbedtls_platform_memcpy( seed + seedlen, additional, len );
memcpy( seed + seedlen, additional, len );
seedlen += len;
}
@ -361,86 +382,10 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
ctx->reseed_counter = 1;
exit:
mbedtls_platform_zeroize( seed, sizeof( seed ) );
mbedtls_zeroize( seed, sizeof( seed ) );
return( ret );
}
/* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
* mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len)
* implements
* CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
* security_strength) -> initial_working_state
* with inputs
* custom[:len] = nonce || personalization_string
* where entropy_input comes from f_entropy for ctx->entropy_len bytes
* and with outputs
* ctx = initial_working_state
*/
int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
int (*f_entropy)(void *, unsigned char *, size_t),
void *p_entropy,
const unsigned char *custom,
size_t len )
{
int ret;
unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
mbedtls_aes_init( &ctx->aes_ctx );
ctx->f_entropy = f_entropy;
ctx->p_entropy = p_entropy;
if( ctx->entropy_len == 0 )
ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
/*
* Initialize with an empty key
*/
if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
return( ret );
}
if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
{
return( ret );
}
return( 0 );
}
/* Backward compatibility wrapper */
int mbedtls_ctr_drbg_seed_entropy_len(
mbedtls_ctr_drbg_context *ctx,
int (*f_entropy)(void *, unsigned char *, size_t), void *p_entropy,
const unsigned char *custom, size_t len,
size_t entropy_len )
{
mbedtls_ctr_drbg_set_entropy_len( ctx, entropy_len );
return( mbedtls_ctr_drbg_seed( ctx, f_entropy, p_entropy, custom, len ) );
}
/* CTR_DRBG_Generate with derivation function (SP 800-90A &sect;10.2.1.5.2)
* mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len)
* implements
* CTR_DRBG_Reseed(working_state, entropy_input, additional[:add_len])
* -> working_state_after_reseed
* if required, then
* CTR_DRBG_Generate(working_state_after_reseed,
* requested_number_of_bits, additional_input)
* -> status, returned_bits, new_working_state
* with inputs
* ctx contains working_state
* requested_number_of_bits = 8 * output_len
* additional[:add_len] = additional_input
* and entropy_input comes from calling ctx->f_entropy
* and with outputs
* status = SUCCESS (this function does the reseed internally)
* returned_bits = output[:output_len]
* ctx contains new_working_state
*/
int mbedtls_ctr_drbg_random_with_add( void *p_rng,
unsigned char *output, size_t output_len,
const unsigned char *additional, size_t add_len )
@ -459,7 +404,7 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT )
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
mbedtls_platform_memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
if( ctx->reseed_counter > ctx->reseed_interval ||
ctx->prediction_resistance )
@ -499,7 +444,7 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
/*
* Copy random block to destination
*/
mbedtls_platform_memcpy( p, tmp, use_len );
memcpy( p, tmp, use_len );
p += use_len;
output_len -= use_len;
}
@ -510,9 +455,9 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
ctx->reseed_counter++;
exit:
mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
return( ret );
mbedtls_zeroize( add_input, sizeof( add_input ) );
mbedtls_zeroize( tmp, sizeof( tmp ) );
return( 0 );
}
int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
@ -554,7 +499,7 @@ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char
ret = 0;
exit:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
mbedtls_zeroize( buf, sizeof( buf ) );
fclose( f );
return( ret );
@ -563,36 +508,35 @@ exit:
int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
{
int ret = 0;
FILE *f = NULL;
FILE *f;
size_t n;
unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
unsigned char c;
if( ( f = fopen( path, "rb" ) ) == NULL )
return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
n = fread( buf, 1, sizeof( buf ), f );
if( fread( &c, 1, 1, f ) != 0 )
{
ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
goto exit;
}
if( n == 0 || ferror( f ) )
{
ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
goto exit;
}
fclose( f );
f = NULL;
fseek( f, 0, SEEK_END );
n = (size_t) ftell( f );
fseek( f, 0, SEEK_SET );
ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n );
exit:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
if( f != NULL )
if( n > MBEDTLS_CTR_DRBG_MAX_INPUT )
{
fclose( f );
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
}
if( fread( buf, 1, n, f ) != n )
ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
else
ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n );
fclose( f );
mbedtls_zeroize( buf, sizeof( buf ) );
if( ret != 0 )
return( ret );
return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) );
}
#endif /* MBEDTLS_FS_IO */
@ -673,11 +617,8 @@ int mbedtls_ctr_drbg_self_test( int verbose )
mbedtls_printf( " CTR_DRBG (PR = TRUE) : " );
test_offset = 0;
mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
CHK( mbedtls_ctr_drbg_seed( &ctx,
ctr_drbg_self_test_entropy,
(void *) entropy_source_pr,
nonce_pers_pr, 16 ) );
CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
(void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) );
mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
@ -697,11 +638,8 @@ int mbedtls_ctr_drbg_self_test( int verbose )
mbedtls_ctr_drbg_init( &ctx );
test_offset = 0;
mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
CHK( mbedtls_ctr_drbg_seed( &ctx,
ctr_drbg_self_test_entropy,
(void *) entropy_source_nopr,
nonce_pers_nopr, 16 ) );
CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
(void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );

View File

@ -1,44 +1,13 @@
/**
* \file ctr_drbg.h
*
* \brief This file contains definitions and functions for the
* CTR_DRBG pseudorandom generator.
* \brief CTR_DRBG is based on AES-256, as defined in <em>NIST SP 800-90A:
* Recommendation for Random Number Generation Using Deterministic
* Random Bit Generators</em>.
*
* 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 TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128
* (if \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled at compile time)
* as the underlying block cipher, with a derivation function.
* The initial seeding grabs #MBEDTLS_CTR_DRBG_ENTROPY_LEN bytes of entropy.
* See the documentation of mbedtls_ctr_drbg_seed() for more details.
*
* Based on NIST SP 800-90A §10.2.1 table 3 and NIST SP 800-57 part 1 table 2,
* here are the security strengths achieved in typical configuration:
* - 256 bits under the default configuration of the library, with AES-256
* and with #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more.
* - 256 bits if AES-256 is used, #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set
* to 32 or more, and the DRBG is initialized with an explicit
* nonce in the \c custom parameter to mbedtls_ctr_drbg_seed().
* - 128 bits if AES-256 is used but #MBEDTLS_CTR_DRBG_ENTROPY_LEN is
* between 24 and 47 and the DRBG is not initialized with an explicit
* nonce (see mbedtls_ctr_drbg_seed()).
* - 128 bits if AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled)
* and #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set to 24 or more (which is
* always the case unless it is explicitly set to a different value
* in config.h).
*
* Note that the value of #MBEDTLS_CTR_DRBG_ENTROPY_LEN defaults to:
* - \c 48 if the module \c MBEDTLS_SHA512_C is enabled and the symbol
* \c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled at compile time.
* This is the default configuration of the library.
* - \c 32 if the module \c MBEDTLS_SHA512_C is disabled at compile time.
* - \c 32 if \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled at compile time.
*/
/*
* Copyright (C) 2006-2019, Arm Limited (or its affiliates), All Rights Reserved
* 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
@ -76,24 +45,12 @@
#define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038 /**< The input (entropy + additional data) is too large. */
#define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A /**< Read or write error in file. */
#if !defined(MBEDTLS_CTR_DRBG_BLOCKSIZE)
#define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< The block size used by the cipher. */
#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
#define MBEDTLS_CTR_DRBG_KEYSIZE 16
/**< The key size in bytes used by the cipher.
*
* Compile-time choice: 16 bytes (128 bits)
* because #MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled.
*/
#else
#define MBEDTLS_CTR_DRBG_KEYSIZE 32
/**< The key size in bytes used by the cipher.
*
* Compile-time choice: 32 bytes (256 bits)
* because \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled.
*/
#endif
#if !defined(MBEDTLS_CTR_DRBG_KEYSIZE)
#define MBEDTLS_CTR_DRBG_KEYSIZE 32 /**< The key size used by the cipher. */
#endif
#define MBEDTLS_CTR_DRBG_KEYBITS ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 ) /**< The key size for the DRBG operation, in bits. */
#define MBEDTLS_CTR_DRBG_SEEDLEN ( MBEDTLS_CTR_DRBG_KEYSIZE + MBEDTLS_CTR_DRBG_BLOCKSIZE ) /**< The seed length, calculated as (counter + AES key). */
@ -106,31 +63,21 @@
* \{
*/
/** \def MBEDTLS_CTR_DRBG_ENTROPY_LEN
*
* \brief The amount of entropy used per seed by default, in bytes.
*/
#if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN)
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
/** This is 48 bytes because the entropy module uses SHA-512
* (\c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled).
*/
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48
#else /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */
/** This is 32 bytes because the entropy module uses SHA-256
* (the SHA512 module is disabled or
* \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled).
/**< The amount of entropy used per seed by default:
* <ul><li>48 with SHA-512.</li>
* <li>32 with SHA-256.</li></ul>
*/
#if !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
/** \warning To achieve a 256-bit security strength, you must pass a nonce
* to mbedtls_ctr_drbg_seed().
*/
#endif /* !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) */
#else
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32
#endif /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */
#endif /* !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) */
/**< 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(MBEDTLS_CTR_DRBG_RESEED_INTERVAL)
#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000
@ -149,7 +96,7 @@
#if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT)
#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384
/**< The maximum size of seed or reseed buffer in bytes. */
/**< The maximum size of seed or reseed buffer. */
#endif
/* \} name SECTION: Module settings */
@ -166,7 +113,7 @@ extern "C" {
/**
* \brief The CTR_DRBG context structure.
*/
typedef struct mbedtls_ctr_drbg_context
typedef struct
{
unsigned char counter[16]; /*!< The counter (V). */
int reseed_counter; /*!< The reseed counter. */
@ -207,71 +154,20 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
* \brief This function seeds and sets up the CTR_DRBG
* entropy source for future reseeds.
*
* A typical choice for the \p f_entropy and \p p_entropy parameters is
* to use the entropy module:
* - \p f_entropy is mbedtls_entropy_func();
* - \p p_entropy is an instance of ::mbedtls_entropy_context initialized
* with mbedtls_entropy_init() (which registers the platform's default
* entropy sources).
* \note Personalization data can be provided in addition to the more generic
* entropy source, to make this instantiation as unique as possible.
*
* The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default.
* You can override it by calling mbedtls_ctr_drbg_set_entropy_len().
*
* You can provide a personalization string in addition to the
* entropy source, to make this instantiation as unique as possible.
*
* \note The _seed_material_ value passed to the derivation
* function in the CTR_DRBG Instantiate Process
* described in NIST SP 800-90A §10.2.1.3.2
* is the concatenation of the string obtained from
* calling \p f_entropy and the \p custom string.
* The origin of the nonce depends on the value of
* the entropy length relative to the security strength.
* - If the entropy length is at least 1.5 times the
* security strength then the nonce is taken from the
* string obtained with \p f_entropy.
* - If the entropy length is less than the security
* strength, then the nonce is taken from \p custom.
* In this case, for compliance with SP 800-90A,
* you must pass a unique value of \p custom at
* each invocation. See SP 800-90A §8.6.7 for more
* details.
*/
#if MBEDTLS_CTR_DRBG_ENTROPY_LEN < MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
/** \warning When #MBEDTLS_CTR_DRBG_ENTROPY_LEN is less than
* #MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2, to achieve the
* maximum security strength permitted by CTR_DRBG,
* you must pass a value of \p custom that is a nonce:
* this value must never be repeated in subsequent
* runs of the same application or on a different
* device.
*/
#endif
/**
* \param ctx The CTR_DRBG context to seed.
* It must have been initialized with
* mbedtls_ctr_drbg_init().
* After a successful call to mbedtls_ctr_drbg_seed(),
* you may not call mbedtls_ctr_drbg_seed() again on
* the same context unless you call
* mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init()
* again first.
* \param f_entropy The entropy callback, taking as arguments the
* \p p_entropy context, the buffer to fill, and the
* length of the buffer.
* \p f_entropy is always called with a buffer size
* equal to the entropy length.
* \param p_entropy The entropy context to pass to \p f_entropy.
* \param custom The personalization string.
* This can be \c NULL, in which case the personalization
* string is empty regardless of the value of \p len.
* \param len The length of the personalization string.
* This must be at most
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
* - #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
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 #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
* \return \c 0 on success, or
* #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
*/
int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
int (*f_entropy)(void *, unsigned char *, size_t),
@ -291,8 +187,7 @@ void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx );
* The default value is off.
*
* \note If enabled, entropy is gathered at the beginning of
* every call to mbedtls_ctr_drbg_random_with_add()
* or mbedtls_ctr_drbg_random().
* every call to mbedtls_ctr_drbg_random_with_add().
* Only use this if your entropy source has sufficient
* throughput.
*
@ -304,37 +199,18 @@ void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
/**
* \brief This function sets the amount of entropy grabbed on each
* seed or reseed.
*
* The default value is #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
*
* \note The security strength of CTR_DRBG is bounded by the
* entropy length. Thus:
* - When using AES-256
* (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled,
* which is the default),
* \p len must be at least 32 (in bytes)
* to achieve a 256-bit strength.
* - When using AES-128
* (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled)
* \p len must be at least 16 (in bytes)
* to achieve a 128-bit strength.
* seed or reseed. The default value is
* #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
*
* \param ctx The CTR_DRBG context.
* \param len The amount of entropy to grab, in bytes.
* This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
* \param len The amount of entropy to grab.
*/
void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
size_t len );
/**
* \brief This function sets the reseed interval.
*
* The reseed interval is the number of calls to mbedtls_ctr_drbg_random()
* or mbedtls_ctr_drbg_random_with_add() after which the entropy function
* is called again.
*
* The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL.
* The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL.
*
* \param ctx The CTR_DRBG context.
* \param interval The reseed interval.
@ -347,62 +223,67 @@ void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
* extracts data from the entropy source.
*
* \param ctx The CTR_DRBG context.
* \param additional Additional data to add to the state. Can be \c NULL.
* \param additional Additional data to add to the state. Can be NULL.
* \param len The length of the additional data.
* This must be less than
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len
* where \c entropy_len is the entropy length
* configured for the context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
* \return \c 0 on success, or
* #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
*/
int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional, size_t len );
/**
* \brief This function updates the state of the CTR_DRBG context.
* \brief This function updates the state of the CTR_DRBG context.
*
* \param ctx The CTR_DRBG context.
* \param additional The data to update the state with. This must not be
* \c NULL unless \p add_len is \c 0.
* \param add_len Length of \p additional in bytes. This must be at
* most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
* \param ctx The CTR_DRBG context.
* \param additional The data to update the state with.
* \param add_len Length of \p additional in bytes. This must be at
* most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if
* \p add_len is more than
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
* \return An error from the underlying AES cipher on failure.
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if
* \p add_len is more than
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
* \return An error from the underlying AES cipher on failure.
*/
int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional,
size_t add_len );
/**
* \brief This function updates the state of the CTR_DRBG context.
*
* \warning This function cannot report errors. You should use
* mbedtls_ctr_drbg_update_ret() instead.
*
* \note If \p add_len is greater than
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, only the first
* #MBEDTLS_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 mbedtls_ctr_drbg_update( mbedtls_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.
*
* This function automatically reseeds if the reseed counter is exceeded
* or prediction resistance is enabled.
* \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
* #mbedtls_ctr_drbg_context structure.
* \param output The buffer to fill.
* \param output_len The length of the buffer in bytes.
* \param additional Additional data to update. Can be \c NULL, in which
* case the additional data is empty regardless of
* the value of \p add_len.
* \param add_len The length of the additional data
* if \p additional is not \c NULL.
* This must be less than #MBEDTLS_CTR_DRBG_MAX_INPUT
* and less than
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len
* where \c entropy_len is the entropy length
* configured for the context.
* \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 #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
* \return \c 0 on success, or
* #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
* #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
*/
int mbedtls_ctr_drbg_random_with_add( void *p_rng,
@ -412,51 +293,20 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
/**
* \brief This function uses CTR_DRBG to generate random data.
*
* This function automatically reseeds if the reseed counter is exceeded
* or prediction resistance is enabled.
*
* \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
* #mbedtls_ctr_drbg_context structure.
* \param output The buffer to fill.
* \param output_len The length of the buffer in bytes.
* \param output_len The length of the buffer.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
* \return \c 0 on success, or
* #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
* #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
*/
int mbedtls_ctr_drbg_random( void *p_rng,
unsigned char *output, size_t output_len );
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief This function updates the state of the CTR_DRBG context.
*
* \deprecated Superseded by mbedtls_ctr_drbg_update_ret()
* in 2.16.0.
*
* \note If \p add_len is greater than
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, only the first
* #MBEDTLS_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.
*/
MBEDTLS_DEPRECATED void mbedtls_ctr_drbg_update(
mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional,
size_t add_len );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_FS_IO)
/**
* \brief This function writes a seed file.
@ -464,9 +314,9 @@ MBEDTLS_DEPRECATED void mbedtls_ctr_drbg_update(
* \param ctx The CTR_DRBG context.
* \param path The name of the file.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on reseed
* \return \c 0 on success,
* #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error, or
* #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on
* failure.
*/
int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
@ -478,28 +328,21 @@ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char
* \param ctx The CTR_DRBG context.
* \param path The name of the file.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on
* reseed failure.
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if the existing
* seed file is too large.
* \return \c 0 on success,
* #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error,
* #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
* #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG on failure.
*/
int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
#endif /* MBEDTLS_FS_IO */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief The CTR_DRBG checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
* \return \c 0 on success, or \c 1 on failure.
*/
int mbedtls_ctr_drbg_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
/* Internal functions (do not call directly) */
int mbedtls_ctr_drbg_seed_entropy_len( mbedtls_ctr_drbg_context *,
int (*)(void *, unsigned char *, size_t), void *,

View File

@ -0,0 +1,368 @@
/*
* Debugging routines
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_DEBUG_C)
#if defined(MBEDTLS_PLATFORM_C)
#include "platform.h"
#else
#include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
#define mbedtls_time_t time_t
#define mbedtls_snprintf snprintf
#endif
#include "debug.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#define DEBUG_BUF_SIZE 512
static int debug_threshold = 0;
void mbedtls_debug_set_threshold( int threshold )
{
debug_threshold = threshold;
}
/*
* All calls to f_dbg must be made via this function
*/
static inline void debug_send_line( const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *str )
{
/*
* If in a threaded environment, we need a thread identifier.
* Since there is no portable way to get one, use the address of the ssl
* context instead, as it shouldn't be shared between threads.
*/
#if defined(MBEDTLS_THREADING_C)
char idstr[20 + DEBUG_BUF_SIZE]; /* 0x + 16 nibbles + ': ' */
mbedtls_snprintf( idstr, sizeof( idstr ), "%p: %s", (void*)ssl, str );
ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, idstr );
#else
ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, str );
#endif
}
void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *format, ... )
{
va_list argp;
char str[DEBUG_BUF_SIZE];
int ret;
if( NULL == ssl || NULL == ssl->conf || NULL == ssl->conf->f_dbg || level > debug_threshold )
return;
va_start( argp, format );
#if defined(_WIN32)
#if defined(_TRUNCATE) && !defined(__MINGW32__)
ret = _vsnprintf_s( str, DEBUG_BUF_SIZE, _TRUNCATE, format, argp );
#else
ret = _vsnprintf( str, DEBUG_BUF_SIZE, format, argp );
if( ret < 0 || (size_t) ret == DEBUG_BUF_SIZE )
{
str[DEBUG_BUF_SIZE-1] = '\0';
ret = -1;
}
#endif
#else
ret = vsnprintf( str, DEBUG_BUF_SIZE, format, argp );
#endif
va_end( argp );
if( ret >= 0 && ret < DEBUG_BUF_SIZE - 1 )
{
str[ret] = '\n';
str[ret + 1] = '\0';
}
debug_send_line( ssl, level, file, line, str );
}
void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, int ret )
{
char str[DEBUG_BUF_SIZE];
if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
return;
/*
* With non-blocking I/O and examples that just retry immediately,
* the logs would be quickly flooded with WANT_READ, so ignore that.
* Don't ignore WANT_WRITE however, since is is usually rare.
*/
if( ret == MBEDTLS_ERR_SSL_WANT_READ )
return;
mbedtls_snprintf( str, sizeof( str ), "%s() returned %d (-0x%04x)\n",
text, ret, -ret );
debug_send_line( ssl, level, file, line, str );
}
void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level,
const char *file, int line, const char *text,
const unsigned char *buf, size_t len )
{
char str[DEBUG_BUF_SIZE];
char txt[17];
size_t i, idx = 0;
if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
return;
mbedtls_snprintf( str + idx, sizeof( str ) - idx, "dumping '%s' (%u bytes)\n",
text, (unsigned int) len );
debug_send_line( ssl, level, file, line, str );
idx = 0;
memset( txt, 0, sizeof( txt ) );
for( i = 0; i < len; i++ )
{
if( i >= 4096 )
break;
if( i % 16 == 0 )
{
if( i > 0 )
{
mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %s\n", txt );
debug_send_line( ssl, level, file, line, str );
idx = 0;
memset( txt, 0, sizeof( txt ) );
}
idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, "%04x: ",
(unsigned int) i );
}
idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x",
(unsigned int) buf[i] );
txt[i % 16] = ( buf[i] > 31 && buf[i] < 127 ) ? buf[i] : '.' ;
}
if( len > 0 )
{
for( /* i = i */; i % 16 != 0; i++ )
idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " " );
mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %s\n", txt );
debug_send_line( ssl, level, file, line, str );
}
}
#if defined(MBEDTLS_ECP_C)
void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_ecp_point *X )
{
char str[DEBUG_BUF_SIZE];
if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
return;
mbedtls_snprintf( str, sizeof( str ), "%s(X)", text );
mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->X );
mbedtls_snprintf( str, sizeof( str ), "%s(Y)", text );
mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->Y );
}
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_BIGNUM_C)
void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_mpi *X )
{
char str[DEBUG_BUF_SIZE];
int j, k, zeros = 1;
size_t i, n, idx = 0;
if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || X == NULL || level > debug_threshold )
return;
for( n = X->n - 1; n > 0; n-- )
if( X->p[n] != 0 )
break;
for( j = ( sizeof(mbedtls_mpi_uint) << 3 ) - 1; j >= 0; j-- )
if( ( ( X->p[n] >> j ) & 1 ) != 0 )
break;
mbedtls_snprintf( str + idx, sizeof( str ) - idx, "value of '%s' (%d bits) is:\n",
text, (int) ( ( n * ( sizeof(mbedtls_mpi_uint) << 3 ) ) + j + 1 ) );
debug_send_line( ssl, level, file, line, str );
idx = 0;
for( i = n + 1, j = 0; i > 0; i-- )
{
if( zeros && X->p[i - 1] == 0 )
continue;
for( k = sizeof( mbedtls_mpi_uint ) - 1; k >= 0; k-- )
{
if( zeros && ( ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF ) == 0 )
continue;
else
zeros = 0;
if( j % 16 == 0 )
{
if( j > 0 )
{
mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" );
debug_send_line( ssl, level, file, line, str );
idx = 0;
}
}
idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x", (unsigned int)
( X->p[i - 1] >> ( k << 3 ) ) & 0xFF );
j++;
}
}
if( zeros == 1 )
idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " 00" );
mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" );
debug_send_line( ssl, level, file, line, str );
}
#endif /* MBEDTLS_BIGNUM_C */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
static void debug_print_pk( const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_pk_context *pk )
{
size_t i;
mbedtls_pk_debug_item items[MBEDTLS_PK_DEBUG_MAX_ITEMS];
char name[16];
memset( items, 0, sizeof( items ) );
if( mbedtls_pk_debug( pk, items ) != 0 )
{
debug_send_line( ssl, level, file, line,
"invalid PK context\n" );
return;
}
for( i = 0; i < MBEDTLS_PK_DEBUG_MAX_ITEMS; i++ )
{
if( items[i].type == MBEDTLS_PK_DEBUG_NONE )
return;
mbedtls_snprintf( name, sizeof( name ), "%s%s", text, items[i].name );
name[sizeof( name ) - 1] = '\0';
if( items[i].type == MBEDTLS_PK_DEBUG_MPI )
mbedtls_debug_print_mpi( ssl, level, file, line, name, items[i].value );
else
#if defined(MBEDTLS_ECP_C)
if( items[i].type == MBEDTLS_PK_DEBUG_ECP )
mbedtls_debug_print_ecp( ssl, level, file, line, name, items[i].value );
else
#endif
debug_send_line( ssl, level, file, line,
"should not happen\n" );
}
}
static void debug_print_line_by_line( const mbedtls_ssl_context *ssl, int level,
const char *file, int line, const char *text )
{
char str[DEBUG_BUF_SIZE];
const char *start, *cur;
start = text;
for( cur = text; *cur != '\0'; cur++ )
{
if( *cur == '\n' )
{
size_t len = cur - start + 1;
if( len > DEBUG_BUF_SIZE - 1 )
len = DEBUG_BUF_SIZE - 1;
memcpy( str, start, len );
str[len] = '\0';
debug_send_line( ssl, level, file, line, str );
start = cur + 1;
}
}
}
void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_x509_crt *crt )
{
char str[DEBUG_BUF_SIZE];
int i = 0;
if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || crt == NULL || level > debug_threshold )
return;
while( crt != NULL )
{
char buf[1024];
mbedtls_snprintf( str, sizeof( str ), "%s #%d:\n", text, ++i );
debug_send_line( ssl, level, file, line, str );
mbedtls_x509_crt_info( buf, sizeof( buf ) - 1, "", crt );
debug_print_line_by_line( ssl, level, file, line, buf );
debug_print_pk( ssl, level, file, line, "crt->", &crt->pk );
crt = crt->next;
}
}
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#endif /* MBEDTLS_DEBUG_C */

View File

@ -36,10 +36,6 @@
#include "ecp.h"
#endif
#if defined(MBEDTLS_ECDH_C)
#include "ecdh.h"
#endif
#if defined(MBEDTLS_DEBUG_C)
#define MBEDTLS_DEBUG_STRIP_PARENS( ... ) __VA_ARGS__
@ -65,17 +61,8 @@
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if !defined(MBEDTLS_X509_REMOVE_INFO)
#define MBEDTLS_SSL_DEBUG_CRT( level, text, crt ) \
mbedtls_debug_print_crt( ssl, level, __FILE__, __LINE__, text, crt )
#else
#define MBEDTLS_SSL_DEBUG_CRT( level, text, crt ) do { } while( 0 )
#endif /* !MBEDTLS_X509_REMOVE_INFO */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_ECDH_C)
#define MBEDTLS_SSL_DEBUG_ECDH( level, ecdh, attr ) \
mbedtls_debug_printf_ecdh( ssl, level, __FILE__, __LINE__, ecdh, attr )
#endif
#else /* MBEDTLS_DEBUG_C */
@ -86,7 +73,6 @@
#define MBEDTLS_SSL_DEBUG_MPI( level, text, X ) do { } while( 0 )
#define MBEDTLS_SSL_DEBUG_ECP( level, text, X ) do { } while( 0 )
#define MBEDTLS_SSL_DEBUG_CRT( level, text, crt ) do { } while( 0 )
#define MBEDTLS_SSL_DEBUG_ECDH( level, ecdh, attr ) do { } while( 0 )
#endif /* MBEDTLS_DEBUG_C */
@ -214,7 +200,7 @@ void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level,
const char *text, const mbedtls_ecp_point *X );
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_INFO)
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/**
* \brief Print a X.509 certificate structure to the debug output. This
* function is always used through the MBEDTLS_SSL_DEBUG_CRT() macro,
@ -235,38 +221,9 @@ void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level,
const char *text, const mbedtls_x509_crt *crt );
#endif
#if defined(MBEDTLS_ECDH_C)
typedef enum
{
MBEDTLS_DEBUG_ECDH_Q,
MBEDTLS_DEBUG_ECDH_QP,
MBEDTLS_DEBUG_ECDH_Z,
} mbedtls_debug_ecdh_attr;
/**
* \brief Print a field of the ECDH structure in the SSL context to the debug
* output. This function is always used through the
* MBEDTLS_SSL_DEBUG_ECDH() macro, which supplies the ssl context, file
* and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param ecdh the ECDH context
* \param attr the identifier of the attribute being output
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_printf_ecdh( const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const mbedtls_ecdh_context *ecdh,
mbedtls_debug_ecdh_attr attr );
#endif
#ifdef __cplusplus
}
#endif
#endif /* debug.h */

File diff suppressed because it is too large Load Diff

View File

@ -42,20 +42,18 @@
#define MBEDTLS_DES_DECRYPT 0
#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */
/* MBEDTLS_ERR_DES_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_DES_HW_ACCEL_FAILED -0x0033 /**< DES hardware accelerator failed. */
#define MBEDTLS_DES_KEY_SIZE 8
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_DES_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief DES context structure
*
@ -63,7 +61,7 @@ extern "C" {
* security risk. We recommend considering stronger ciphers
* instead.
*/
typedef struct mbedtls_des_context
typedef struct
{
uint32_t sk[32]; /*!< DES subkeys */
}
@ -72,16 +70,12 @@ mbedtls_des_context;
/**
* \brief Triple-DES context structure
*/
typedef struct mbedtls_des3_context
typedef struct
{
uint32_t sk[96]; /*!< 3DES subkeys */
}
mbedtls_des3_context;
#else /* MBEDTLS_DES_ALT */
#include "des_alt.h"
#endif /* MBEDTLS_DES_ALT */
/**
* \brief Initialize DES context
*
@ -337,8 +331,17 @@ int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
*/
void mbedtls_des_setkey( uint32_t SK[32],
const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
#ifdef __cplusplus
}
#endif
#if defined(MBEDTLS_SELF_TEST)
#else /* MBEDTLS_DES_ALT */
#include "des_alt.h"
#endif /* MBEDTLS_DES_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Checkup routine
@ -347,8 +350,6 @@ void mbedtls_des_setkey( uint32_t SK[32],
*/
int mbedtls_des_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif

View File

@ -36,7 +36,6 @@
#if defined(MBEDTLS_DHM_C)
#include "dhm.h"
#include "platform_util.h"
#include <string.h>
@ -59,11 +58,10 @@
#endif
#if !defined(MBEDTLS_DHM_ALT)
#define DHM_VALIDATE_RET( cond ) \
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_DHM_BAD_INPUT_DATA )
#define DHM_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/*
* helper to validate the mbedtls_mpi size and import it
@ -126,8 +124,7 @@ cleanup:
void mbedtls_dhm_init( mbedtls_dhm_context *ctx )
{
DHM_VALIDATE( ctx != NULL );
mbedtls_platform_memset( ctx, 0, sizeof( mbedtls_dhm_context ) );
memset( ctx, 0, sizeof( mbedtls_dhm_context ) );
}
/*
@ -138,9 +135,6 @@ int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
const unsigned char *end )
{
int ret;
DHM_VALIDATE_RET( ctx != NULL );
DHM_VALIDATE_RET( p != NULL && *p != NULL );
DHM_VALIDATE_RET( end != NULL );
if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 ||
( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 ||
@ -166,10 +160,6 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
int ret, count = 0;
size_t n1, n2, n3;
unsigned char *p;
DHM_VALIDATE_RET( ctx != NULL );
DHM_VALIDATE_RET( output != NULL );
DHM_VALIDATE_RET( olen != NULL );
DHM_VALIDATE_RET( f_rng != NULL );
if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
@ -240,9 +230,9 @@ int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
const mbedtls_mpi *G )
{
int ret;
DHM_VALIDATE_RET( ctx != NULL );
DHM_VALIDATE_RET( P != NULL );
DHM_VALIDATE_RET( G != NULL );
if( ctx == NULL || P == NULL || G == NULL )
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
@ -261,10 +251,8 @@ int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
const unsigned char *input, size_t ilen )
{
int ret;
DHM_VALIDATE_RET( ctx != NULL );
DHM_VALIDATE_RET( input != NULL );
if( ilen < 1 || ilen > ctx->len )
if( ctx == NULL || ilen < 1 || ilen > ctx->len )
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
@ -282,11 +270,8 @@ int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
void *p_rng )
{
int ret, count = 0;
DHM_VALIDATE_RET( ctx != NULL );
DHM_VALIDATE_RET( output != NULL );
DHM_VALIDATE_RET( f_rng != NULL );
if( olen < 1 || olen > ctx->len )
if( ctx == NULL || olen < 1 || olen > ctx->len )
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
@ -398,11 +383,8 @@ int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
{
int ret;
mbedtls_mpi GYb;
DHM_VALIDATE_RET( ctx != NULL );
DHM_VALIDATE_RET( output != NULL );
DHM_VALIDATE_RET( olen != NULL );
if( output_size < ctx->len )
if( ctx == NULL || output_size < ctx->len )
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
@ -449,21 +431,13 @@ cleanup:
*/
void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_mpi_free( &ctx->pX ); mbedtls_mpi_free( &ctx->Vf );
mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->RP );
mbedtls_mpi_free( &ctx->K ); mbedtls_mpi_free( &ctx->GY );
mbedtls_mpi_free( &ctx->GX ); mbedtls_mpi_free( &ctx->X );
mbedtls_mpi_free( &ctx->G ); mbedtls_mpi_free( &ctx->P );
mbedtls_mpi_free( &ctx->pX );
mbedtls_mpi_free( &ctx->Vf );
mbedtls_mpi_free( &ctx->Vi );
mbedtls_mpi_free( &ctx->RP );
mbedtls_mpi_free( &ctx->K );
mbedtls_mpi_free( &ctx->GY );
mbedtls_mpi_free( &ctx->GX );
mbedtls_mpi_free( &ctx->X );
mbedtls_mpi_free( &ctx->G );
mbedtls_mpi_free( &ctx->P );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
mbedtls_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
}
#if defined(MBEDTLS_ASN1_PARSE_C)
@ -478,12 +452,7 @@ int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
unsigned char *p, *end;
#if defined(MBEDTLS_PEM_PARSE_C)
mbedtls_pem_context pem;
#endif /* MBEDTLS_PEM_PARSE_C */
DHM_VALIDATE_RET( dhm != NULL );
DHM_VALIDATE_RET( dhmin != NULL );
#if defined(MBEDTLS_PEM_PARSE_C)
mbedtls_pem_init( &pem );
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
@ -606,7 +575,7 @@ static int load_file( const char *path, unsigned char **buf, size_t *n )
{
fclose( f );
mbedtls_platform_zeroize( *buf, *n + 1 );
mbedtls_zeroize( *buf, *n + 1 );
mbedtls_free( *buf );
return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
@ -630,15 +599,13 @@ int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
int ret;
size_t n;
unsigned char *buf;
DHM_VALIDATE_RET( dhm != NULL );
DHM_VALIDATE_RET( path != NULL );
if( ( ret = load_file( path, &buf, &n ) ) != 0 )
return( ret );
ret = mbedtls_dhm_parse_dhm( dhm, buf, n );
mbedtls_platform_zeroize( buf, n );
mbedtls_zeroize( buf, n );
mbedtls_free( buf );
return( ret );
@ -649,28 +616,12 @@ int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PEM_PARSE_C)
static const char mbedtls_test_dhm_params[] =
"-----BEGIN DH PARAMETERS-----\r\n"
"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
"-----END DH PARAMETERS-----\r\n";
#else /* MBEDTLS_PEM_PARSE_C */
static const char mbedtls_test_dhm_params[] = {
0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44,
0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d,
0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3,
0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1,
0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18,
0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a,
0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1,
0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6,
0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64,
0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8,
0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f,
0x49, 0x75, 0xb3, 0x02, 0x01, 0x02 };
#endif /* MBEDTLS_PEM_PARSE_C */
static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params );

View File

@ -1,13 +1,7 @@
/**
* \file dhm.h
*
* \brief This file contains Diffie-Hellman-Merkle (DHM) key exchange
* definitions and functions.
*
* Diffie-Hellman-Merkle (DHM) key exchange is defined in
* <em>RFC-2631: Diffie-Hellman Key Agreement Method</em> and
* <em>Public-Key Cryptography Standards (PKCS) #3: Diffie
* Hellman Key Agreement Standard</em>.
* \brief Diffie-Hellman-Merkle key exchange.
*
* <em>RFC-3526: More Modular Exponential (MODP) Diffie-Hellman groups for
* Internet Key Exchange (IKE)</em> defines a number of standardized
@ -71,6 +65,7 @@
#include MBEDTLS_CONFIG_FILE
#endif
#include "bignum.h"
#if !defined(MBEDTLS_DHM_ALT)
/*
* DHM Error codes
@ -84,22 +79,17 @@
#define MBEDTLS_ERR_DHM_INVALID_FORMAT -0x3380 /**< The ASN.1 data is not formatted correctly. */
#define MBEDTLS_ERR_DHM_ALLOC_FAILED -0x3400 /**< Allocation of memory failed. */
#define MBEDTLS_ERR_DHM_FILE_IO_ERROR -0x3480 /**< Read or write of file failed. */
/* MBEDTLS_ERR_DHM_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_DHM_HW_ACCEL_FAILED -0x3500 /**< DHM hardware accelerator failed. */
#define MBEDTLS_ERR_DHM_SET_GROUP_FAILED -0x3580 /**< Setting the modulus and generator failed. */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_DHM_ALT)
/**
* \brief The DHM context structure.
*/
typedef struct mbedtls_dhm_context
typedef struct
{
size_t len; /*!< The size of \p P in Bytes. */
mbedtls_mpi P; /*!< The prime modulus. */
@ -115,10 +105,6 @@ typedef struct mbedtls_dhm_context
}
mbedtls_dhm_context;
#else /* MBEDTLS_DHM_ALT */
#include "dhm_alt.h"
#endif /* MBEDTLS_DHM_ALT */
/**
* \brief This function initializes the DHM context.
*
@ -127,15 +113,9 @@ mbedtls_dhm_context;
void mbedtls_dhm_init( mbedtls_dhm_context *ctx );
/**
* \brief This function parses the DHM parameters in a
* TLS ServerKeyExchange handshake message
* (DHM modulus, generator, and public key).
* \brief This function parses the ServerKeyExchange parameters.
*
* \note In a TLS handshake, this is the how the client
* sets up its DHM context from the server's public
* DHM key material.
*
* \param ctx The DHM context to use. This must be initialized.
* \param ctx The DHM context.
* \param p On input, *p must be the start of the input buffer.
* On output, *p is updated to point to the end of the data
* that has been read. On success, this is the first byte
@ -145,44 +125,38 @@ void mbedtls_dhm_init( mbedtls_dhm_context *ctx );
* failures.
* \param end The end of the input buffer.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_DHM_XXX error code on failure.
* \return \c 0 on success, or an \c MBEDTLS_ERR_DHM_XXX error code
* on failure.
*/
int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
unsigned char **p,
const unsigned char *end );
unsigned char **p,
const unsigned char *end );
/**
* \brief This function generates a DHM key pair and exports its
* public part together with the DHM parameters in the format
* used in a TLS ServerKeyExchange handshake message.
* \brief This function sets up and writes the ServerKeyExchange
* parameters.
*
* \note This function assumes that the DHM parameters \c ctx->P
* and \c ctx->G have already been properly set. For that, use
* \param ctx The DHM context.
* \param x_size The private value size in Bytes.
* \param olen The number of characters written.
* \param output The destination buffer.
* \param f_rng The RNG function.
* \param p_rng The RNG parameter.
*
* \note The destination buffer must be large enough to hold
* the reduced binary presentation of the modulus, the generator
* and the public key, each wrapped with a 2-byte length field.
* It is the responsibility of the caller to ensure that enough
* space is available. Refer to \c mbedtls_mpi_size to computing
* the byte-size of an MPI.
*
* \note This function assumes that \c ctx->P and \c ctx->G
* have already been properly set. For that, use
* mbedtls_dhm_set_group() below in conjunction with
* mbedtls_mpi_read_binary() and mbedtls_mpi_read_string().
*
* \note In a TLS handshake, this is the how the server generates
* and exports its DHM key material.
*
* \param ctx The DHM context to use. This must be initialized
* and have the DHM parameters set. It may or may not
* already have imported the peer's public key.
* \param x_size The private key size in Bytes.
* \param olen The address at which to store the number of Bytes
* written on success. This must not be \c NULL.
* \param output The destination buffer. This must be a writable buffer of
* sufficient size to hold the reduced binary presentation of
* the modulus, the generator and the public key, each wrapped
* with a 2-byte length field. It is the responsibility of the
* caller to ensure that enough space is available. Refer to
* mbedtls_mpi_size() to computing the byte-size of an MPI.
* \param f_rng The RNG function. Must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context parameter.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_DHM_XXX error code on failure.
* \return \c 0 on success, or an \c MBEDTLS_ERR_DHM_XXX error code
* on failure.
*/
int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
unsigned char *output, size_t *olen,
@ -190,66 +164,54 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
void *p_rng );
/**
* \brief This function sets the prime modulus and generator.
* \brief Set prime modulus and generator
*
* \note This function can be used to set \c ctx->P, \c ctx->G
* in preparation for mbedtls_dhm_make_params().
* \param ctx The DHM context.
* \param P The MPI holding DHM prime modulus.
* \param G The MPI holding DHM generator.
*
* \param ctx The DHM context to configure. This must be initialized.
* \param P The MPI holding the DHM prime modulus. This must be
* an initialized MPI.
* \param G The MPI holding the DHM generator. This must be an
* initialized MPI.
* \note This function can be used to set P, G
* in preparation for \c mbedtls_dhm_make_params.
*
* \return \c 0 if successful.
* \return An \c MBEDTLS_ERR_DHM_XXX error code on failure.
* \return \c 0 if successful, or an \c MBEDTLS_ERR_DHM_XXX error code
* on failure.
*/
int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
const mbedtls_mpi *P,
const mbedtls_mpi *G );
/**
* \brief This function imports the raw public value of the peer.
* \brief This function imports the public value G^Y of the peer.
*
* \note In a TLS handshake, this is the how the server imports
* the Client's public DHM key.
* \param ctx The DHM context.
* \param input The input buffer.
* \param ilen The size of the input buffer.
*
* \param ctx The DHM context to use. This must be initialized and have
* its DHM parameters set, e.g. via mbedtls_dhm_set_group().
* It may or may not already have generated its own private key.
* \param input The input buffer containing the \c G^Y value of the peer.
* This must be a readable buffer of size \p ilen Bytes.
* \param ilen The size of the input buffer \p input in Bytes.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_DHM_XXX error code on failure.
* \return \c 0 on success, or an \c MBEDTLS_ERR_DHM_XXX error code
* on failure.
*/
int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
const unsigned char *input, size_t ilen );
/**
* \brief This function creates a DHM key pair and exports
* the raw public key in big-endian format.
* \brief This function creates its own private value \c X and
* exports \c G^X.
*
* \note The destination buffer is always fully written
* so as to contain a big-endian representation of G^X mod P.
* If it is larger than \c ctx->len, it is padded accordingly
* with zero-bytes at the beginning.
* \param ctx The DHM context.
* \param x_size The private value size in Bytes.
* \param output The destination buffer.
* \param olen The length of the destination buffer. Must be at least
equal to ctx->len (the size of \c P).
* \param f_rng The RNG function.
* \param p_rng The RNG parameter.
*
* \param ctx The DHM context to use. This must be initialized and
* have the DHM parameters set. It may or may not already
* have imported the peer's public key.
* \param x_size The private key size in Bytes.
* \param output The destination buffer. This must be a writable buffer of
* size \p olen Bytes.
* \param olen The length of the destination buffer. This must be at least
* equal to `ctx->len` (the size of \c P).
* \param f_rng The RNG function. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL
* if \p f_rng doesn't need a context argument.
* \note The destination buffer will always be fully written
* so as to contain a big-endian presentation of G^X mod P.
* If it is larger than ctx->len, it will accordingly be
* padded with zero-bytes in the beginning.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_DHM_XXX error code on failure.
* \return \c 0 on success, or an \c MBEDTLS_ERR_DHM_XXX error code
* on failure.
*/
int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
unsigned char *output, size_t olen,
@ -257,30 +219,25 @@ int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
void *p_rng );
/**
* \brief This function derives and exports the shared secret
* \c (G^Y)^X mod \c P.
* \brief This function derives and exports the shared secret
* \c (G^Y)^X mod \c P.
*
* \note If \p f_rng is not \c NULL, it is used to blind the input as
* a countermeasure against timing attacks. Blinding is used
* only if our private key \c X is re-used, and not used
* otherwise. We recommend always passing a non-NULL
* \p f_rng argument.
*
* \param ctx The DHM context to use. This must be initialized
* and have its own private key generated and the peer's
* public key imported.
* \param output The buffer to write the generated shared key to. This
* must be a writable buffer of size \p output_size Bytes.
* \param output_size The size of the destination buffer. This must be at
* least the size of \c ctx->len (the size of \c P).
* \param ctx The DHM context.
* \param output The destination buffer.
* \param output_size The size of the destination buffer. Must be at least
* the size of ctx->len.
* \param olen On exit, holds the actual number of Bytes written.
* \param f_rng The RNG function, for blinding purposes. This may
* b \c NULL if blinding isn't needed.
* \param p_rng The RNG context. This may be \c NULL if \p f_rng
* doesn't need a context argument.
* \param f_rng The RNG function, for blinding purposes.
* \param p_rng The RNG parameter.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_DHM_XXX error code on failure.
* \return \c 0 on success, or an \c MBEDTLS_ERR_DHM_XXX error code
* on failure.
*
* \note If non-NULL, \p f_rng is used to blind the input as
* a countermeasure against timing attacks. Blinding is used
* only if our secret value \p X is re-used and omitted
* otherwise. Therefore, we recommend always passing a
* non-NULL \p f_rng argument.
*/
int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
unsigned char *output, size_t output_size, size_t *olen,
@ -288,12 +245,9 @@ int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
void *p_rng );
/**
* \brief This function frees and clears the components
* of a DHM context.
* \brief This function frees and clears the components of a DHM key.
*
* \param ctx The DHM context to free and clear. This may be \c NULL,
* in which case this function is a no-op. If it is not \c NULL,
* it must point to an initialized DHM context.
* \param ctx The DHM context to free and clear.
*/
void mbedtls_dhm_free( mbedtls_dhm_context *ctx );
@ -302,19 +256,16 @@ void mbedtls_dhm_free( mbedtls_dhm_context *ctx );
/**
* \brief This function parses DHM parameters in PEM or DER format.
*
* \param dhm The DHM context to import the DHM parameters into.
* This must be initialized.
* \param dhmin The input buffer. This must be a readable buffer of
* length \p dhminlen Bytes.
* \param dhminlen The size of the input buffer \p dhmin, including the
* terminating \c NULL Byte for PEM data.
* \param dhm The DHM context to initialize.
* \param dhmin The input buffer.
* \param dhminlen The size of the buffer, including the terminating null
* Byte for PEM data.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX error
* code on failure.
* \return \c 0 on success, or a specific DHM or PEM error code
* on failure.
*/
int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
size_t dhminlen );
size_t dhminlen );
#if defined(MBEDTLS_FS_IO)
/** \ingroup x509_module */
@ -322,29 +273,34 @@ int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
* \brief This function loads and parses DHM parameters from a file.
*
* \param dhm The DHM context to load the parameters to.
* This must be initialized.
* \param path The filename to read the DHM parameters from.
* This must not be \c NULL.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX
* error code on failure.
* \return \c 0 on success, or a specific DHM or PEM error code
* on failure.
*/
int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path );
#endif /* MBEDTLS_FS_IO */
#endif /* MBEDTLS_ASN1_PARSE_C */
#if defined(MBEDTLS_SELF_TEST)
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_DHM_ALT */
#include "dhm_alt.h"
#endif /* MBEDTLS_DHM_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief The DMH checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
* \return \c 0 on success, or \c 1 on failure.
*/
int mbedtls_dhm_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
@ -392,6 +348,15 @@ int mbedtls_dhm_self_test( int verbose );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
MBEDTLS_DEPRECATED typedef char const * mbedtls_deprecated_constant_t;
#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) \
( (mbedtls_deprecated_constant_t) ( VAL ) )
#else
#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) VAL
#endif /* ! MBEDTLS_DEPRECATED_WARNING */
/**
* \warning The origin of the primes in RFC 5114 is not documented and
* their use therefore constitutes a security risk!

View File

@ -0,0 +1,268 @@
/*
* Elliptic curve Diffie-Hellman
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* References:
*
* SEC1 http://www.secg.org/index.php?action=secg,docs_secg
* RFC 4492
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_ECDH_C)
#include "ecdh.h"
#include <string.h>
#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
/*
* Generate public key: simple wrapper around mbedtls_ecp_gen_keypair
*/
int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
return mbedtls_ecp_gen_keypair( grp, d, Q, f_rng, p_rng );
}
#endif /* MBEDTLS_ECDH_GEN_PUBLIC_ALT */
#if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
/*
* Compute shared secret (SEC1 3.3.1)
*/
int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret;
mbedtls_ecp_point P;
mbedtls_ecp_point_init( &P );
/*
* Make sure Q is a valid pubkey before using it
*/
MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, &P, d, Q, f_rng, p_rng ) );
if( mbedtls_ecp_is_zero( &P ) )
{
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
goto cleanup;
}
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( z, &P.X ) );
cleanup:
mbedtls_ecp_point_free( &P );
return( ret );
}
#endif /* MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
/*
* Initialize context
*/
void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_ecdh_context ) );
}
/*
* Free context
*/
void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_ecp_group_free( &ctx->grp );
mbedtls_ecp_point_free( &ctx->Q );
mbedtls_ecp_point_free( &ctx->Qp );
mbedtls_ecp_point_free( &ctx->Vi );
mbedtls_ecp_point_free( &ctx->Vf );
mbedtls_mpi_free( &ctx->d );
mbedtls_mpi_free( &ctx->z );
mbedtls_mpi_free( &ctx->_d );
}
/*
* Setup and write the ServerKeyExhange parameters (RFC 4492)
* struct {
* ECParameters curve_params;
* ECPoint public;
* } ServerECDHParams;
*/
int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret;
size_t grp_len, pt_len;
if( ctx == NULL || ctx->grp.pbits == 0 )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) )
!= 0 )
return( ret );
if( ( ret = mbedtls_ecp_tls_write_group( &ctx->grp, &grp_len, buf, blen ) )
!= 0 )
return( ret );
buf += grp_len;
blen -= grp_len;
if( ( ret = mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
&pt_len, buf, blen ) ) != 0 )
return( ret );
*olen = grp_len + pt_len;
return( 0 );
}
/*
* Read the ServerKeyExhange parameters (RFC 4492)
* struct {
* ECParameters curve_params;
* ECPoint public;
* } ServerECDHParams;
*/
int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
const unsigned char **buf, const unsigned char *end )
{
int ret;
if( ( ret = mbedtls_ecp_tls_read_group( &ctx->grp, buf, end - *buf ) ) != 0 )
return( ret );
if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf, end - *buf ) )
!= 0 )
return( ret );
return( 0 );
}
/*
* Get parameters from a keypair
*/
int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key,
mbedtls_ecdh_side side )
{
int ret;
if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 )
return( ret );
/* If it's not our key, just import the public part as Qp */
if( side == MBEDTLS_ECDH_THEIRS )
return( mbedtls_ecp_copy( &ctx->Qp, &key->Q ) );
/* Our key: import public (as Q) and private parts */
if( side != MBEDTLS_ECDH_OURS )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 ||
( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 )
return( ret );
return( 0 );
}
/*
* Setup and export the client public value
*/
int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret;
if( ctx == NULL || ctx->grp.pbits == 0 )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) )
!= 0 )
return( ret );
return mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
olen, buf, blen );
}
/*
* Parse and import the client's public value
*/
int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
const unsigned char *buf, size_t blen )
{
int ret;
const unsigned char *p = buf;
if( ctx == NULL )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p, blen ) ) != 0 )
return( ret );
if( (size_t)( p - buf ) != blen )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
return( 0 );
}
/*
* Derive and export the shared secret
*/
int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret;
if( ctx == NULL )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = mbedtls_ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, &ctx->d,
f_rng, p_rng ) ) != 0 )
{
return( ret );
}
if( mbedtls_mpi_size( &ctx->z ) > blen )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
*olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 );
return mbedtls_mpi_write_binary( &ctx->z, buf, *olen );
}
#endif /* MBEDTLS_ECDH_C */

View File

@ -1,12 +1,11 @@
/**
* \file ecdh.h
*
* \brief This file contains ECDH definitions and functions.
* \brief The Elliptic Curve Diffie-Hellman (ECDH) protocol APIs.
*
* The Elliptic Curve Diffie-Hellman (ECDH) protocol is an anonymous
* key agreement protocol allowing two parties to establish a shared
* secret over an insecure channel. Each party must have an
* elliptic-curve publicprivate key pair.
* ECDH is an anonymous key agreement protocol allowing two parties to
* establish a shared secret over an insecure channel. Each party must have an
* elliptic-curve publicprivate key pair.
*
* For more information, see <em>NIST SP 800-56A Rev. 2: Recommendation for
* Pair-Wise Key Establishment Schemes Using Discrete Logarithm
@ -42,74 +41,26 @@
#include "ecp.h"
/*
* Use a backward compatible ECDH context.
*
* This flag is always enabled for now and future versions might add a
* configuration option that conditionally undefines this flag.
* The configuration option in question may have a different name.
*
* Features undefining this flag, must have a warning in their description in
* config.h stating that the feature breaks backward compatibility.
*/
#define MBEDTLS_ECDH_LEGACY_CONTEXT
#ifdef __cplusplus
extern "C" {
#endif
/**
* Defines the source of the imported EC key.
* Defines the source of the imported EC key:
* <ul><li>Our key.</li>
* <li>The key of the peer.</li></ul>
*/
typedef enum
{
MBEDTLS_ECDH_OURS, /**< Our key. */
MBEDTLS_ECDH_THEIRS, /**< The key of the peer. */
MBEDTLS_ECDH_OURS,
MBEDTLS_ECDH_THEIRS,
} mbedtls_ecdh_side;
#if !defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
/**
* Defines the ECDH implementation used.
*
* Later versions of the library may add new variants, therefore users should
* not make any assumptions about them.
*/
typedef enum
{
MBEDTLS_ECDH_VARIANT_NONE = 0, /*!< Implementation not defined. */
MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0,/*!< The default Mbed TLS implementation */
} mbedtls_ecdh_variant;
/**
* The context used by the default ECDH implementation.
*
* Later versions might change the structure of this context, therefore users
* should not make any assumptions about the structure of
* mbedtls_ecdh_context_mbed.
*/
typedef struct mbedtls_ecdh_context_mbed
{
mbedtls_ecp_group grp; /*!< The elliptic curve used. */
mbedtls_mpi d; /*!< The private key. */
mbedtls_ecp_point Q; /*!< The public key. */
mbedtls_ecp_point Qp; /*!< The value of the public key of the peer. */
mbedtls_mpi z; /*!< The shared secret. */
#if defined(MBEDTLS_ECP_RESTARTABLE)
mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */
#endif
} mbedtls_ecdh_context_mbed;
#endif
/**
*
* \warning Performing multiple operations concurrently on the same
* ECDSA context is not supported; objects of this type
* should not be shared between multiple threads.
* \brief The ECDH context structure.
*/
typedef struct mbedtls_ecdh_context
typedef struct
{
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
mbedtls_ecp_group grp; /*!< The elliptic curve used. */
mbedtls_mpi d; /*!< The private key. */
mbedtls_ecp_point Q; /*!< The public key. */
@ -119,29 +70,6 @@ typedef struct mbedtls_ecdh_context
mbedtls_ecp_point Vi; /*!< The blinding value. */
mbedtls_ecp_point Vf; /*!< The unblinding value. */
mbedtls_mpi _d; /*!< The previous \p d. */
#if defined(MBEDTLS_ECP_RESTARTABLE)
int restart_enabled; /*!< The flag for restartable mode. */
mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */
#endif /* MBEDTLS_ECP_RESTARTABLE */
#else
uint8_t point_format; /*!< The format of point export in TLS messages
as defined in RFC 4492. */
mbedtls_ecp_group_id grp_id;/*!< The elliptic curve used. */
mbedtls_ecdh_variant var; /*!< The ECDH implementation/structure used. */
union
{
mbedtls_ecdh_context_mbed mbed_ecdh;
} ctx; /*!< Implementation-specific context. The
context in use is specified by the \c var
field. */
#if defined(MBEDTLS_ECP_RESTARTABLE)
uint8_t restart_enabled; /*!< The flag for restartable mode. Functions of
an alternative implementation not supporting
restartable mode must return
MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED error
if this flag is set. */
#endif /* MBEDTLS_ECP_RESTARTABLE */
#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */
}
mbedtls_ecdh_context;
@ -153,22 +81,16 @@ mbedtls_ecdh_context;
* implemented during the ECDH key exchange. The second core
* computation is performed by mbedtls_ecdh_compute_shared().
*
* \see ecp.h
*
* \param grp The ECP group to use. This must be initialized and have
* domain parameters loaded, for example through
* mbedtls_ecp_load() or mbedtls_ecp_tls_read_group().
* \param grp The ECP group.
* \param d The destination MPI (private key).
* This must be initialized.
* \param Q The destination point (public key).
* This must be initialized.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL in case \p f_rng doesn't need a context argument.
* \param f_rng The RNG function.
* \param p_rng The RNG parameter.
*
* \return \c 0 on success.
* \return Another \c MBEDTLS_ERR_ECP_XXX or
* \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX or
* \c MBEDTLS_MPI_XXX error code on failure.
*
* \see ecp.h
*/
int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
@ -181,32 +103,21 @@ int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp
* implemented during the ECDH key exchange. The first core
* computation is performed by mbedtls_ecdh_gen_public().
*
* \param grp The ECP group.
* \param z The destination MPI (shared secret).
* \param Q The public key from another party.
* \param d Our secret exponent (private key).
* \param f_rng The RNG function.
* \param p_rng The RNG parameter.
*
* \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX or
* \c MBEDTLS_MPI_XXX error code on failure.
*
* \see ecp.h
*
* \note If \p f_rng is not NULL, it is used to implement
* countermeasures against side-channel attacks.
* For more information, see mbedtls_ecp_mul().
*
* \param grp The ECP group to use. This must be initialized and have
* domain parameters loaded, for example through
* mbedtls_ecp_load() or mbedtls_ecp_tls_read_group().
* \param z The destination MPI (shared secret).
* This must be initialized.
* \param Q The public key from another party.
* This must be initialized.
* \param d Our secret exponent (private key).
* This must be initialized.
* \param f_rng The RNG function. This may be \c NULL if randomization
* of intermediate results during the ECP computations is
* not needed (discouraged). See the documentation of
* mbedtls_ecp_mul() for more.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng is \c NULL or doesn't need a
* context argument.
*
* \return \c 0 on success.
* \return Another \c MBEDTLS_ERR_ECP_XXX or
* \c MBEDTLS_MPI_XXX error code on failure.
* countermeasures against potential elaborate timing
* attacks. For more information, see mbedtls_ecp_mul().
*/
int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
@ -216,62 +127,39 @@ int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
/**
* \brief This function initializes an ECDH context.
*
* \param ctx The ECDH context to initialize. This must not be \c NULL.
* \param ctx The ECDH context to initialize.
*/
void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx );
/**
* \brief This function sets up the ECDH context with the information
* given.
*
* This function should be called after mbedtls_ecdh_init() but
* before mbedtls_ecdh_make_params(). There is no need to call
* this function before mbedtls_ecdh_read_params().
*
* This is the first function used by a TLS server for ECDHE
* ciphersuites.
*
* \param ctx The ECDH context to set up. This must be initialized.
* \param grp_id The group id of the group to set up the context for.
*
* \return \c 0 on success.
*/
int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx,
mbedtls_ecp_group_id grp_id );
/**
* \brief This function frees a context.
*
* \param ctx The context to free. This may be \c NULL, in which
* case this function does nothing. If it is not \c NULL,
* it must point to an initialized ECDH context.
* \param ctx The context to free.
*/
void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx );
/**
* \brief This function generates an EC key pair and exports its
* in the format used in a TLS ServerKeyExchange handshake
* message.
* \brief This function generates a public key and a TLS
* ServerKeyExchange payload.
*
* This is the second function used by a TLS server for ECDHE
* ciphersuites. (It is called after mbedtls_ecdh_setup().)
* This is the first function used by a TLS server for ECDHE
* ciphersuites.
*
* \param ctx The ECDH context.
* \param olen The number of characters written.
* \param buf The destination buffer.
* \param blen The length of the destination buffer.
* \param f_rng The RNG function.
* \param p_rng The RNG parameter.
*
* \note This function assumes that the ECP group (grp) of the
* \p ctx context has already been properly set,
* for example, using mbedtls_ecp_group_load().
*
* \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
* on failure.
*
* \see ecp.h
*
* \param ctx The ECDH context to use. This must be initialized
* and bound to a group, for example via mbedtls_ecdh_setup().
* \param olen The address at which to store the number of Bytes written.
* \param buf The destination buffer. This must be a writable buffer of
* length \p blen Bytes.
* \param blen The length of the destination buffer \p buf in Bytes.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL in case \p f_rng doesn't need a context argument.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
@ -279,32 +167,23 @@ int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
void *p_rng );
/**
* \brief This function parses the ECDHE parameters in a
* TLS ServerKeyExchange handshake message.
* \brief This function parses and processes a TLS ServerKeyExhange
* payload.
*
* \note In a TLS handshake, this is the how the client
* sets up its ECDHE context from the server's public
* ECDHE key material.
* This is the first function used by a TLS client for ECDHE
* ciphersuites.
*
* \param ctx The ECDH context.
* \param buf The pointer to the start of the input buffer.
* \param end The address for one Byte past the end of the buffer.
*
* \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
* on failure.
*
* \see ecp.h
*
* \param ctx The ECDHE context to use. This must be initialized.
* \param buf On input, \c *buf must be the start of the input buffer.
* On output, \c *buf is updated to point to the end of the
* data that has been read. On success, this is the first byte
* past the end of the ServerKeyExchange parameters.
* On error, this is the point at which an error has been
* detected, which is usually not useful except to debug
* failures.
* \param end The end of the input buffer.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*
*/
int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
const unsigned char **buf,
const unsigned char *end );
const unsigned char **buf, const unsigned char *end );
/**
* \brief This function sets up an ECDH context from an EC key.
@ -313,47 +192,38 @@ int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
* ServerKeyEchange for static ECDH, and imports ECDH
* parameters from the EC key information of a certificate.
*
* \param ctx The ECDH context to set up.
* \param key The EC key to use.
* \param side Defines the source of the key:
* <ul><li>1: Our key.</li>
<li>0: The key of the peer.</li></ul>
*
* \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
* on failure.
*
* \see ecp.h
*
* \param ctx The ECDH context to set up. This must be initialized.
* \param key The EC key to use. This must be initialized.
* \param side Defines the source of the key. Possible values are:
* - #MBEDTLS_ECDH_OURS: The key is ours.
* - #MBEDTLS_ECDH_THEIRS: The key is that of the peer.
*
* \return \c 0 on success.
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
*
*/
int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx,
const mbedtls_ecp_keypair *key,
mbedtls_ecdh_side side );
int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key,
mbedtls_ecdh_side side );
/**
* \brief This function generates a public key and exports it
* as a TLS ClientKeyExchange payload.
* \brief This function generates a public key and a TLS
* ClientKeyExchange payload.
*
* This is the second function used by a TLS client for ECDH(E)
* ciphersuites.
*
* \param ctx The ECDH context.
* \param olen The number of Bytes written.
* \param buf The destination buffer.
* \param blen The size of the destination buffer.
* \param f_rng The RNG function.
* \param p_rng The RNG parameter.
*
* \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
* on failure.
*
* \see ecp.h
*
* \param ctx The ECDH context to use. This must be initialized
* and bound to a group, the latter usually by
* mbedtls_ecdh_read_params().
* \param olen The address at which to store the number of Bytes written.
* This must not be \c NULL.
* \param buf The destination buffer. This must be a writable buffer
* of length \p blen Bytes.
* \param blen The size of the destination buffer \p buf in Bytes.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL in case \p f_rng doesn't need a context argument.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
@ -361,26 +231,23 @@ int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
void *p_rng );
/**
* \brief This function parses and processes the ECDHE payload of a
* TLS ClientKeyExchange message.
* \brief This function parses and processes a TLS ClientKeyExchange
* payload.
*
* This is the third function used by a TLS server for ECDH(E)
* ciphersuites. (It is called after mbedtls_ecdh_setup() and
* mbedtls_ecdh_make_params().)
* This is the second function used by a TLS server for ECDH(E)
* ciphersuites.
*
* \param ctx The ECDH context.
* \param buf The start of the input buffer.
* \param blen The length of the input buffer.
*
* \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
* on failure.
*
* \see ecp.h
*
* \param ctx The ECDH context to use. This must be initialized
* and bound to a group, for example via mbedtls_ecdh_setup().
* \param buf The pointer to the ClientKeyExchange payload. This must
* be a readable buffer of length \p blen Bytes.
* \param blen The length of the input buffer \p buf in Bytes.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
const unsigned char *buf, size_t blen );
const unsigned char *buf, size_t blen );
/**
* \brief This function derives and exports the shared secret.
@ -388,51 +255,27 @@ int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
* This is the last function used by both TLS client
* and servers.
*
* \note If \p f_rng is not NULL, it is used to implement
* countermeasures against side-channel attacks.
* For more information, see mbedtls_ecp_mul().
* \param ctx The ECDH context.
* \param olen The number of Bytes written.
* \param buf The destination buffer.
* \param blen The length of the destination buffer.
* \param f_rng The RNG function.
* \param p_rng The RNG parameter.
*
* \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
* on failure.
*
* \see ecp.h
* \param ctx The ECDH context to use. This must be initialized
* and have its own private key generated and the peer's
* public key imported.
* \param olen The address at which to store the total number of
* Bytes written on success. This must not be \c NULL.
* \param buf The buffer to write the generated shared key to. This
* must be a writable buffer of size \p blen Bytes.
* \param blen The length of the destination buffer \p buf in Bytes.
* \param f_rng The RNG function, for blinding purposes. This may
* b \c NULL if blinding isn't needed.
* \param p_rng The RNG context. This may be \c NULL if \p f_rng
* doesn't need a context argument.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
* \note If \p f_rng is not NULL, it is used to implement
* countermeasures against potential elaborate timing
* attacks. For more information, see mbedtls_ecp_mul().
*/
int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
#if defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief This function enables restartable EC computations for this
* context. (Default: disabled.)
*
* \see \c mbedtls_ecp_set_max_ops()
*
* \note It is not possible to safely disable restartable
* computations once enabled, except by free-ing the context,
* which cancels possible in-progress operations.
*
* \param ctx The ECDH context to use. This must be initialized.
*/
void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx );
#endif /* MBEDTLS_ECP_RESTARTABLE */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,466 @@
/*
* Elliptic curve DSA
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* References:
*
* SEC1 http://www.secg.org/index.php?action=secg,docs_secg
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_ECDSA_C)
#include "ecdsa.h"
#include "asn1write.h"
#include <string.h>
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
#include "hmac_drbg.h"
#endif
/*
* Derive a suitable integer for group grp from a buffer of length len
* SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3
*/
static int derive_mpi( const mbedtls_ecp_group *grp, mbedtls_mpi *x,
const unsigned char *buf, size_t blen )
{
int ret;
size_t n_size = ( grp->nbits + 7 ) / 8;
size_t use_size = blen > n_size ? n_size : blen;
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( x, buf, use_size ) );
if( use_size * 8 > grp->nbits )
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( x, use_size * 8 - grp->nbits ) );
/* While at it, reduce modulo N */
if( mbedtls_mpi_cmp_mpi( x, &grp->N ) >= 0 )
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( x, x, &grp->N ) );
cleanup:
return( ret );
}
#if !defined(MBEDTLS_ECDSA_SIGN_ALT)
/*
* Compute ECDSA signature of a hashed message (SEC1 4.1.3)
* Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message)
*/
int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
int ret, key_tries, sign_tries, blind_tries;
mbedtls_ecp_point R;
mbedtls_mpi k, e, t;
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
if( grp->N.p == NULL )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
/* Make sure d is in range 1..n-1 */
if( mbedtls_mpi_cmp_int( d, 1 ) < 0 || mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 )
return( MBEDTLS_ERR_ECP_INVALID_KEY );
mbedtls_ecp_point_init( &R );
mbedtls_mpi_init( &k ); mbedtls_mpi_init( &e ); mbedtls_mpi_init( &t );
sign_tries = 0;
do
{
/*
* Steps 1-3: generate a suitable ephemeral keypair
* and set r = xR mod n
*/
key_tries = 0;
do
{
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair( grp, &k, &R, f_rng, p_rng ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( r, &R.X, &grp->N ) );
if( key_tries++ > 10 )
{
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
goto cleanup;
}
}
while( mbedtls_mpi_cmp_int( r, 0 ) == 0 );
/*
* Step 5: derive MPI from hashed message
*/
MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) );
/*
* Generate a random value to blind inv_mod in next step,
* avoiding a potential timing leak.
*/
blind_tries = 0;
do
{
size_t n_size = ( grp->nbits + 7 ) / 8;
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &t, n_size, f_rng, p_rng ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &t, 8 * n_size - grp->nbits ) );
/* See mbedtls_ecp_gen_keypair() */
if( ++blind_tries > 30 )
return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
}
while( mbedtls_mpi_cmp_int( &t, 1 ) < 0 ||
mbedtls_mpi_cmp_mpi( &t, &grp->N ) >= 0 );
/*
* Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n
*/
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, r, d ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e, &e, s ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e, &e, &t ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &k, &k, &t ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, &k, &grp->N ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) );
if( sign_tries++ > 10 )
{
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
goto cleanup;
}
}
while( mbedtls_mpi_cmp_int( s, 0 ) == 0 );
cleanup:
mbedtls_ecp_point_free( &R );
mbedtls_mpi_free( &k ); mbedtls_mpi_free( &e ); mbedtls_mpi_free( &t );
return( ret );
}
#endif /* MBEDTLS_ECDSA_SIGN_ALT */
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
/*
* Deterministic signature wrapper
*/
int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg )
{
int ret;
mbedtls_hmac_drbg_context rng_ctx;
unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES];
size_t grp_len = ( grp->nbits + 7 ) / 8;
const mbedtls_md_info_t *md_info;
mbedtls_mpi h;
if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
mbedtls_mpi_init( &h );
mbedtls_hmac_drbg_init( &rng_ctx );
/* Use private key and message hash (reduced) to initialize HMAC_DRBG */
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) );
MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) );
mbedtls_hmac_drbg_seed_buf( &rng_ctx, md_info, data, 2 * grp_len );
ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen,
mbedtls_hmac_drbg_random, &rng_ctx );
cleanup:
mbedtls_hmac_drbg_free( &rng_ctx );
mbedtls_mpi_free( &h );
return( ret );
}
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
#if !defined(MBEDTLS_ECDSA_VERIFY_ALT)
/*
* Verify ECDSA signature of hashed message (SEC1 4.1.4)
* Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message)
*/
int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
const unsigned char *buf, size_t blen,
const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s)
{
int ret;
mbedtls_mpi e, s_inv, u1, u2;
mbedtls_ecp_point R;
mbedtls_ecp_point_init( &R );
mbedtls_mpi_init( &e ); mbedtls_mpi_init( &s_inv ); mbedtls_mpi_init( &u1 ); mbedtls_mpi_init( &u2 );
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
if( grp->N.p == NULL )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
/*
* Step 1: make sure r and s are in range 1..n-1
*/
if( mbedtls_mpi_cmp_int( r, 1 ) < 0 || mbedtls_mpi_cmp_mpi( r, &grp->N ) >= 0 ||
mbedtls_mpi_cmp_int( s, 1 ) < 0 || mbedtls_mpi_cmp_mpi( s, &grp->N ) >= 0 )
{
ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
goto cleanup;
}
/*
* Additional precaution: make sure Q is valid
*/
MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) );
/*
* Step 3: derive MPI from hashed message
*/
MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) );
/*
* Step 4: u1 = e / s mod n, u2 = r / s mod n
*/
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &s_inv, s, &grp->N ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u1, &e, &s_inv ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u1, &u1, &grp->N ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u2, r, &s_inv ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u2, &u2, &grp->N ) );
/*
* Step 5: R = u1 G + u2 Q
*
* Since we're not using any secret data, no need to pass a RNG to
* mbedtls_ecp_mul() for countermesures.
*/
MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, &R, &u1, &grp->G, &u2, Q ) );
if( mbedtls_ecp_is_zero( &R ) )
{
ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
goto cleanup;
}
/*
* Step 6: convert xR to an integer (no-op)
* Step 7: reduce xR mod n (gives v)
*/
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &R.X, &R.X, &grp->N ) );
/*
* Step 8: check if v (that is, R.X) is equal to r
*/
if( mbedtls_mpi_cmp_mpi( &R.X, r ) != 0 )
{
ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
goto cleanup;
}
cleanup:
mbedtls_ecp_point_free( &R );
mbedtls_mpi_free( &e ); mbedtls_mpi_free( &s_inv ); mbedtls_mpi_free( &u1 ); mbedtls_mpi_free( &u2 );
return( ret );
}
#endif /* MBEDTLS_ECDSA_VERIFY_ALT */
/*
* Convert a signature (given by context) to ASN.1
*/
static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
unsigned char *sig, size_t *slen )
{
int ret;
unsigned char buf[MBEDTLS_ECDSA_MAX_LEN];
unsigned char *p = buf + sizeof( buf );
size_t len = 0;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, s ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, r ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, buf, len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, buf,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
memcpy( sig, p, len );
*slen = len;
return( 0 );
}
/*
* Compute and write signature
*/
int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_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 )
{
int ret;
mbedtls_mpi r, s;
mbedtls_mpi_init( &r );
mbedtls_mpi_init( &s );
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
(void) f_rng;
(void) p_rng;
MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ctx->grp, &r, &s, &ctx->d,
hash, hlen, md_alg ) );
#else
(void) md_alg;
MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx->grp, &r, &s, &ctx->d,
hash, hlen, f_rng, p_rng ) );
#endif
MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, slen ) );
cleanup:
mbedtls_mpi_free( &r );
mbedtls_mpi_free( &s );
return( ret );
}
#if ! defined(MBEDTLS_DEPRECATED_REMOVED) && \
defined(MBEDTLS_ECDSA_DETERMINISTIC)
int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen,
unsigned char *sig, size_t *slen,
mbedtls_md_type_t md_alg )
{
return( mbedtls_ecdsa_write_signature( ctx, md_alg, hash, hlen, sig, slen,
NULL, NULL ) );
}
#endif
/*
* Read and check signature
*/
int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen,
const unsigned char *sig, size_t slen )
{
int ret;
unsigned char *p = (unsigned char *) sig;
const unsigned char *end = sig + slen;
size_t len;
mbedtls_mpi r, s;
mbedtls_mpi_init( &r );
mbedtls_mpi_init( &s );
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
goto cleanup;
}
if( p + len != end )
{
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA +
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
goto cleanup;
}
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &r ) ) != 0 ||
( ret = mbedtls_asn1_get_mpi( &p, end, &s ) ) != 0 )
{
ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
goto cleanup;
}
if( ( ret = mbedtls_ecdsa_verify( &ctx->grp, hash, hlen,
&ctx->Q, &r, &s ) ) != 0 )
goto cleanup;
/* At this point we know that the buffer starts with a valid signature.
* Return 0 if the buffer just contains the signature, and a specific
* error code if the valid signature is followed by more data. */
if( p != end )
ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH;
cleanup:
mbedtls_mpi_free( &r );
mbedtls_mpi_free( &s );
return( ret );
}
#if !defined(MBEDTLS_ECDSA_GENKEY_ALT)
/*
* Generate key pair
*/
int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
int ret = 0;
ret = mbedtls_ecp_group_load( &ctx->grp, gid );
if( ret != 0 )
return( ret );
return( mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d,
&ctx->Q, f_rng, p_rng ) );
}
#endif /* MBEDTLS_ECDSA_GENKEY_ALT */
/*
* Set context from an mbedtls_ecp_keypair
*/
int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key )
{
int ret;
if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 ||
( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 ||
( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 )
{
mbedtls_ecdsa_free( ctx );
}
return( ret );
}
/*
* Initialize context
*/
void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx )
{
mbedtls_ecp_keypair_init( ctx );
}
/*
* Free context
*/
void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx )
{
mbedtls_ecp_keypair_free( ctx );
}
#endif /* MBEDTLS_ECDSA_C */

View File

@ -1,10 +1,9 @@
/**
* \file ecdsa.h
*
* \brief This file contains ECDSA definitions and functions.
* \brief The Elliptic Curve Digital Signature Algorithm (ECDSA).
*
* The Elliptic Curve Digital Signature Algorithm (ECDSA) is defined in
* <em>Standards for Efficient Cryptography Group (SECG):
* 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>.
@ -61,71 +60,29 @@
/** The maximal size of an ECDSA signature in Bytes. */
#define MBEDTLS_ECDSA_MAX_LEN ( 3 + 2 * ( 3 + MBEDTLS_ECP_MAX_BYTES ) )
/**
* \brief The ECDSA context structure.
*/
typedef mbedtls_ecp_keypair mbedtls_ecdsa_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief The ECDSA context structure.
*
* \warning Performing multiple operations concurrently on the same
* ECDSA context is not supported; objects of this type
* should not be shared between multiple threads.
*/
typedef mbedtls_ecp_keypair mbedtls_ecdsa_context;
#if defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief Internal restart context for ecdsa_verify()
*
* \note Opaque struct, defined in ecdsa.c
*/
typedef struct mbedtls_ecdsa_restart_ver mbedtls_ecdsa_restart_ver_ctx;
/**
* \brief Internal restart context for ecdsa_sign()
*
* \note Opaque struct, defined in ecdsa.c
*/
typedef struct mbedtls_ecdsa_restart_sig mbedtls_ecdsa_restart_sig_ctx;
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
/**
* \brief Internal restart context for ecdsa_sign_det()
*
* \note Opaque struct, defined in ecdsa.c
*/
typedef struct mbedtls_ecdsa_restart_det mbedtls_ecdsa_restart_det_ctx;
#endif
/**
* \brief General context for resuming ECDSA operations
*/
typedef struct
{
mbedtls_ecp_restart_ctx ecp; /*!< base context for ECP restart and
shared administrative info */
mbedtls_ecdsa_restart_ver_ctx *ver; /*!< ecdsa_verify() sub-context */
mbedtls_ecdsa_restart_sig_ctx *sig; /*!< ecdsa_sign() sub-context */
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
mbedtls_ecdsa_restart_det_ctx *det; /*!< ecdsa_sign_det() sub-context */
#endif
} mbedtls_ecdsa_restart_ctx;
#else /* MBEDTLS_ECP_RESTARTABLE */
/* Now we can declare functions that take a pointer to that */
typedef void mbedtls_ecdsa_restart_ctx;
#endif /* MBEDTLS_ECP_RESTARTABLE */
/**
* \brief This function computes the ECDSA signature of a
* previously-hashed message.
*
* \note The deterministic version implemented in
* mbedtls_ecdsa_sign_det() is usually preferred.
* \note The deterministic version is usually preferred.
*
* \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 parameter.
*
* \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated
@ -133,28 +90,10 @@ typedef void mbedtls_ecdsa_restart_ctx;
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.3, step 5.
*
* \see ecp.h
*
* \param grp The context for the elliptic curve to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
* \param r The MPI context in which to store the first part
* the signature. This must be initialized.
* \param s The MPI context in which to store the second part
* the signature. This must be initialized.
* \param d The private signing key. This must be initialized.
* \param buf The content to be signed. This is usually the hash of
* the original data to be signed. This must be a readable
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param f_rng The RNG function. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context parameter.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX
* \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX
* or \c MBEDTLS_MPI_XXX error code on failure.
*
* \see ecp.h
*/
int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
@ -164,139 +103,62 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
/**
* \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>.
*
* \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.
*
* \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.
*
* \warning Since the output of the internal RNG is always the same for
* the same key and message, this limits the efficiency of
* blinding and leaks information through side channels. For
* secure behavior use mbedtls_ecdsa_sign_det_ext() instead.
*
* (Optimally the blinding is a random value that is different
* on every execution. In this case the blinding is still
* random from the attackers perspective, but is the same on
* each execution. This means that this blinding does not
* prevent attackers from recovering secrets by combining
* several measurement traces, but may prevent some attacks
* that exploit relationships between secret data.)
* \return \c 0 on success,
* or an \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
* error code on failure.
*
* \see ecp.h
*
* \param grp The context for the elliptic curve to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
* \param r The MPI context in which to store the first part
* the signature. This must be initialized.
* \param s The MPI context in which to store the second part
* the signature. This must be initialized.
* \param d The private signing key. This must be initialized
* and setup, for example through mbedtls_ecp_gen_privkey().
* \param buf The hashed content to be signed. This must be a readable
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param md_alg The hash algorithm used to hash the original data.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
* error code on failure.
*/
int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r,
mbedtls_mpi *s, const mbedtls_mpi *d,
const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg );
/**
* \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 context for the elliptic curve to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
* \param r The MPI context in which to store the first part
* the signature. This must be initialized.
* \param s The MPI context in which to store the second part
* the signature. This must be initialized.
* \param d The private signing key. This must be initialized
* and setup, for example through mbedtls_ecp_gen_privkey().
* \param buf The hashed content to be signed. This must be a readable
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param md_alg The hash algorithm used to hash the original data.
* \param f_rng_blind The RNG function used for blinding. This must not be
* \c NULL.
* \param p_rng_blind The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context parameter.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
* error code on failure.
*/
int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r,
mbedtls_mpi *s, const mbedtls_mpi *d,
const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg,
int (*f_rng_blind)(void *, unsigned char *,
size_t),
void *p_rng_blind );
int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg );
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
/**
* \brief This function verifies the ECDSA signature of a
* previously-hashed message.
*
* \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.
*
* \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 to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
* \param buf The hashed content that was signed. This must be a readable
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param Q The public key to use for verification. This must be
* initialized and setup.
* \param r The first integer of the signature.
* This must be initialized.
* \param s The second integer of the signature.
* This must be initialized.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the signature
* is invalid.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
* \return \c 0 on success,
* #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid,
* or an \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
* error code on failure for any other reason.
*
* \see ecp.h
*/
int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
const unsigned char *buf, size_t blen,
const mbedtls_ecp_point *Q, const mbedtls_mpi *r,
const mbedtls_mpi *s);
const unsigned char *buf, size_t blen,
const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s);
/**
* \brief This function computes the ECDSA signature and writes it
@ -313,92 +175,38 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
* of the Digital Signature Algorithm (DSA) and Elliptic
* Curve Digital Signature Algorithm (ECDSA)</em>.
*
* \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 parameter.
*
* \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
* #MBEDTLS_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 to use. This must be initialized
* and have a group and private key bound to it, for example
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
* \param md_alg The message digest that was used to hash the message.
* \param hash The message hash to be signed. This must be a readable
* buffer of length \p blen Bytes.
* \param hlen The length of the hash \p hash in Bytes.
* \param sig The buffer to which to write the signature. This must be a
* writable buffer of length 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
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
* \param slen The address at which to store the actual length of
* the signature written. Must not be \c NULL.
* \param f_rng The RNG function. This must not be \c NULL if
* #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
* it is unused and may be set to \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng is \c NULL or doesn't use a context.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
* \return \c 0 on success,
* or an \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
* \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*
* \see ecp.h
*/
int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx,
mbedtls_md_type_t md_alg,
int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_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 );
/**
* \brief This function computes the ECDSA signature and writes it
* to a buffer, in a restartable way.
*
* \see \c mbedtls_ecdsa_write_signature()
*
* \note This function is like \c mbedtls_ecdsa_write_signature()
* but it can return early and restart according to the limit
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
*
* \param ctx The ECDSA context to use. This must be initialized
* and have a group and private key bound to it, for example
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
* \param md_alg The message digest that was used to hash the message.
* \param hash The message hash to be signed. This must be a readable
* buffer of length \p blen Bytes.
* \param hlen The length of the hash \p hash in Bytes.
* \param sig The buffer to which to write the signature. This must be a
* writable buffer of length 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
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
* \param slen The address at which to store the actual length of
* the signature written. Must not be \c NULL.
* \param f_rng The RNG function. This must not be \c NULL if
* #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
* it is unused and may be set to \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng is \c NULL or doesn't use a context.
* \param rs_ctx The restart context to use. This may be \c NULL to disable
* restarting. If it is not \c NULL, it must point to an
* initialized restart context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return Another \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
* \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
mbedtls_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,
mbedtls_ecdsa_restart_ctx *rs_ctx );
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
@ -407,17 +215,31 @@ int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
#define MBEDTLS_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>.
* \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>.
* 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.
*
* \deprecated Superseded by mbedtls_ecdsa_write_signature() in 2.0.0
*
* \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.
*
* \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
* #MBEDTLS_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
@ -425,29 +247,11 @@ int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.3, step 5.
*
* \see ecp.h
*
* \deprecated Superseded by mbedtls_ecdsa_write_signature() in
* Mbed TLS version 2.0 and later.
*
* \param ctx The ECDSA context to use. This must be initialized
* and have a group and private key bound to it, for example
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
* \param hash The message hash to be signed. This must be a readable
* buffer of length \p blen Bytes.
* \param hlen The length of the hash \p hash in Bytes.
* \param sig The buffer to which to write the signature. This must be a
* writable buffer of length 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
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
* \param slen The address at which to store the actual length of
* the signature written. Must not be \c NULL.
* \param md_alg The message digest that was used to hash the message.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
* \return \c 0 on success,
* or an \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
* \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*
* \see ecp.h
*/
int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen,
@ -460,143 +264,75 @@ int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
/**
* \brief This function reads and verifies an ECDSA signature.
*
* \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.
*
* \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 to use. This must be initialized
* and have a group and public key bound to it.
* \param hash The message hash that was signed. This must be a readable
* buffer of length \p size Bytes.
* \param hlen The size of the hash \p hash.
* \param sig The signature to read and verify. This must be a readable
* buffer of length \p slen Bytes.
* \param slen The size of \p sig in Bytes.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
* \return #MBEDTLS_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 MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
* \return \c 0 on success,
* #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid,
* #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid
* signature in sig but its length is less than \p siglen,
* or an \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
* error code on failure for any other reason.
*
* \see ecp.h
*/
int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen,
const unsigned char *sig, size_t slen );
/**
* \brief This function reads and verifies an ECDSA signature,
* in a restartable way.
*
* \see \c mbedtls_ecdsa_read_signature()
*
* \note This function is like \c mbedtls_ecdsa_read_signature()
* but it can return early and restart according to the limit
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
*
* \param ctx The ECDSA context to use. This must be initialized
* and have a group and public key bound to it.
* \param hash The message hash that was signed. This must be a readable
* buffer of length \p size Bytes.
* \param hlen The size of the hash \p hash.
* \param sig The signature to read and verify. This must be a readable
* buffer of length \p slen Bytes.
* \param slen The size of \p sig in Bytes.
* \param rs_ctx The restart context to use. This may be \c NULL to disable
* restarting. If it is not \c NULL, it must point to an
* initialized restart context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
* \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid
* signature in \p sig, but its length is less than \p siglen.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return Another \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
* error code on failure for any other reason.
*/
int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen,
const unsigned char *sig, size_t slen,
mbedtls_ecdsa_restart_ctx *rs_ctx );
/**
* \brief This function generates an ECDSA keypair on the given curve.
*
* \see ecp.h
*
* \param ctx The ECDSA context to store the keypair in.
* This must be initialized.
* \param gid The elliptic curve to use. One of the various
* \c MBEDTLS_ECP_DP_XXX macros depending on configuration.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context argument.
* \param f_rng The RNG function.
* \param p_rng The RNG parameter.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX code on failure.
* \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX code on
* failure.
*
* \see ecp.h
*/
int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
/**
* \brief This function sets up an ECDSA context from an EC key pair.
* \brief This function sets an ECDSA context from an EC key pair.
*
* \param ctx The ECDSA context to set.
* \param key The EC key to use.
*
* \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX code on
* failure.
*
* \see ecp.h
*
* \param ctx The ECDSA context to setup. This must be initialized.
* \param key The EC key to use. This must be initialized and hold
* a private-public key pair or a public key. In the former
* case, the ECDSA context may be used for signature creation
* and verification after this call. In the latter case, it
* may be used for signature verification.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX code on failure.
*/
int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx,
const mbedtls_ecp_keypair *key );
int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key );
/**
* \brief This function initializes an ECDSA context.
*
* \param ctx The ECDSA context to initialize.
* This must not be \c NULL.
*/
void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx );
/**
* \brief This function frees an ECDSA context.
*
* \param ctx The ECDSA context to free. This may be \c NULL,
* in which case this function does nothing. If it
* is not \c NULL, it must be initialized.
* \param ctx The ECDSA context to free.
*/
void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx );
#if defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief Initialize a restart context.
*
* \param ctx The restart context to initialize.
* This must not be \c NULL.
*/
void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx );
/**
* \brief Free the components of a restart context.
*
* \param ctx The restart context to free. This may be \c NULL,
* in which case this function does nothing. If it
* is not \c NULL, it must be initialized.
*/
void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx );
#endif /* MBEDTLS_ECP_RESTARTABLE */
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -49,6 +49,8 @@
#include "ecp.h"
#include "md.h"
#if !defined(MBEDTLS_ECJPAKE_ALT)
#ifdef __cplusplus
extern "C" {
#endif
@ -61,7 +63,6 @@ typedef enum {
MBEDTLS_ECJPAKE_SERVER, /**< Server */
} mbedtls_ecjpake_role;
#if !defined(MBEDTLS_ECJPAKE_ALT)
/**
* EC J-PAKE context structure.
*
@ -73,9 +74,9 @@ typedef enum {
* convetion from the Thread v1.0 spec. Correspondance is indicated in the
* description as a pair C: client name, S: server name
*/
typedef struct mbedtls_ecjpake_context
typedef struct
{
mbedtls_md_handle_t md_info; /**< Hash to use */
const mbedtls_md_info_t *md_info; /**< Hash to use */
mbedtls_ecp_group grp; /**< Elliptic curve */
mbedtls_ecjpake_role role; /**< Are we client or server? */
int point_format; /**< Format for point export */
@ -92,38 +93,29 @@ typedef struct mbedtls_ecjpake_context
mbedtls_mpi s; /**< Pre-shared secret (passphrase) */
} mbedtls_ecjpake_context;
#else /* MBEDTLS_ECJPAKE_ALT */
#include "ecjpake_alt.h"
#endif /* MBEDTLS_ECJPAKE_ALT */
/**
* \brief Initialize an ECJPAKE context.
* \brief Initialize a context
* (just makes it ready for setup() or free()).
*
* \param ctx The ECJPAKE context to initialize.
* This must not be \c NULL.
* \param ctx context to initialize
*/
void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx );
/**
* \brief Set up an ECJPAKE context for use.
* \brief Set up a context for use
*
* \note Currently the only values for hash/curve allowed by the
* standard are #MBEDTLS_MD_SHA256/#MBEDTLS_ECP_DP_SECP256R1.
* standard are MBEDTLS_MD_SHA256/MBEDTLS_ECP_DP_SECP256R1.
*
* \param ctx The ECJPAKE context to set up. This must be initialized.
* \param role The role of the caller. This must be either
* #MBEDTLS_ECJPAKE_CLIENT or #MBEDTLS_ECJPAKE_SERVER.
* \param hash The identifier of the hash function to use,
* for example #MBEDTLS_MD_SHA256.
* \param curve The identifier of the elliptic curve to use,
* for example #MBEDTLS_ECP_DP_SECP256R1.
* \param secret The pre-shared secret (passphrase). This must be
* a readable buffer of length \p len Bytes. It need
* only be valid for the duration of this call.
* \param len The length of the pre-shared secret \p secret.
* \param ctx context to set up
* \param role Our role: client or server
* \param hash hash function to use (MBEDTLS_MD_XXX)
* \param curve elliptic curve identifier (MBEDTLS_ECP_DP_XXX)
* \param secret pre-shared secret (passphrase)
* \param len length of the shared secret
*
* \return \c 0 if successful.
* \return A negative error code on failure.
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
mbedtls_ecjpake_role role,
@ -133,34 +125,29 @@ int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
size_t len );
/**
* \brief Check if an ECJPAKE context is ready for use.
* \brief Check if a context is ready for use
*
* \param ctx The ECJPAKE context to check. This must be
* initialized.
* \param ctx Context to check
*
* \return \c 0 if the context is ready for use.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise.
* \return 0 if the context is ready for use,
* MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise
*/
int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx );
/**
* \brief Generate and write the first round message
* (TLS: contents of the Client/ServerHello extension,
* excluding extension type and length bytes).
* excluding extension type and length bytes)
*
* \param ctx The ECJPAKE context to use. This must be
* initialized and set up.
* \param buf The buffer to write the contents to. This must be a
* writable buffer of length \p len Bytes.
* \param len The length of \p buf in Bytes.
* \param olen The address at which to store the total number
* of Bytes written to \p buf. This must not be \c NULL.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG parameter to be passed to \p f_rng. This
* may be \c NULL if \p f_rng doesn't use a context.
* \param ctx Context to use
* \param buf Buffer to write the contents to
* \param len Buffer size
* \param olen Will be updated with the number of bytes written
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return \c 0 if successful.
* \return A negative error code on failure.
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
@ -170,16 +157,14 @@ int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
/**
* \brief Read and process the first round message
* (TLS: contents of the Client/ServerHello extension,
* excluding extension type and length bytes).
* excluding extension type and length bytes)
*
* \param ctx The ECJPAKE context to use. This must be initialized
* and set up.
* \param buf The buffer holding the first round message. This must
* be a readable buffer of length \p len Bytes.
* \param len The length in Bytes of \p buf.
* \param ctx Context to use
* \param buf Pointer to extension contents
* \param len Extension length
*
* \return \c 0 if successful.
* \return A negative error code on failure.
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
const unsigned char *buf,
@ -187,21 +172,17 @@ int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
/**
* \brief Generate and write the second round message
* (TLS: contents of the Client/ServerKeyExchange).
* (TLS: contents of the Client/ServerKeyExchange)
*
* \param ctx The ECJPAKE context to use. This must be initialized,
* set up, and already have performed round one.
* \param buf The buffer to write the round two contents to.
* This must be a writable buffer of length \p len Bytes.
* \param len The size of \p buf in Bytes.
* \param olen The address at which to store the total number of Bytes
* written to \p buf. This must not be \c NULL.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG parameter to be passed to \p f_rng. This
* may be \c NULL if \p f_rng doesn't use a context.
* \param ctx Context to use
* \param buf Buffer to write the contents to
* \param len Buffer size
* \param olen Will be updated with the number of bytes written
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return \c 0 if successful.
* \return A negative error code on failure.
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
@ -210,16 +191,14 @@ int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
/**
* \brief Read and process the second round message
* (TLS: contents of the Client/ServerKeyExchange).
* (TLS: contents of the Client/ServerKeyExchange)
*
* \param ctx The ECJPAKE context to use. This must be initialized
* and set up and already have performed round one.
* \param buf The buffer holding the second round message. This must
* be a readable buffer of length \p len Bytes.
* \param len The length in Bytes of \p buf.
* \param ctx Context to use
* \param buf Pointer to the message
* \param len Message length
*
* \return \c 0 if successful.
* \return A negative error code on failure.
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
const unsigned char *buf,
@ -227,21 +206,17 @@ int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
/**
* \brief Derive the shared secret
* (TLS: Pre-Master Secret).
* (TLS: Pre-Master Secret)
*
* \param ctx The ECJPAKE context to use. This must be initialized,
* set up and have performed both round one and two.
* \param buf The buffer to write the derived secret to. This must
* be a writable buffer of length \p len Bytes.
* \param len The length of \p buf in Bytes.
* \param olen The address at which to store the total number of Bytes
* written to \p buf. This must not be \c NULL.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG parameter to be passed to \p f_rng. This
* may be \c NULL if \p f_rng doesn't use a context.
* \param ctx Context to use
* \param buf Buffer to write the contents to
* \param len Buffer size
* \param olen Will be updated with the number of bytes written
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return \c 0 if successful.
* \return A negative error code on failure.
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
@ -249,17 +224,26 @@ int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
void *p_rng );
/**
* \brief This clears an ECJPAKE context and frees any
* embedded data structure.
* \brief Free a context's content
*
* \param ctx The ECJPAKE context to free. This may be \c NULL,
* in which case this function does nothing. If it is not
* \c NULL, it must point to an initialized ECJPAKE context.
* \param ctx context to free
*/
void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx );
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_ECJPAKE_ALT */
#include "ecjpake_alt.h"
#endif /* MBEDTLS_ECJPAKE_ALT */
#if defined(MBEDTLS_SELF_TEST)
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Checkup routine
*
@ -267,11 +251,10 @@ void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx );
*/
int mbedtls_ecjpake_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_SELF_TEST */
#endif /* ecjpake.h */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -35,7 +35,6 @@
#include "entropy.h"
#include "entropy_poll.h"
#include "platform_util.h"
#include <string.h>
@ -43,7 +42,9 @@
#include <stdio.h>
#endif
#if defined(MBEDTLS_ENTROPY_NV_SEED)
#include "platform.h"
#endif
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
@ -58,6 +59,11 @@
#include "havege.h"
#endif
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
#define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */
void mbedtls_entropy_init( mbedtls_entropy_context *ctx )
@ -134,7 +140,7 @@ void mbedtls_entropy_free( mbedtls_entropy_context *ctx )
ctx->initial_entropy_run = 0;
#endif
ctx->source_count = 0;
mbedtls_platform_zeroize( ctx->source, sizeof( ctx->source ) );
mbedtls_zeroize( ctx->source, sizeof( ctx->source ) );
ctx->accumulator_started = 0;
}
@ -142,11 +148,7 @@ int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
mbedtls_entropy_f_source_ptr f_source, void *p_source,
size_t threshold, int strong )
{
int idx, ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
volatile mbedtls_entropy_f_source_ptr f_source_dup = f_source;
volatile void *p_source_dup = p_source;
volatile size_t threshold_dup = threshold;
volatile int strong_dup = strong;
int idx, ret = 0;
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
@ -166,7 +168,6 @@ int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
ctx->source[idx].strong = strong;
ctx->source_count++;
ret = 0;
exit:
#if defined(MBEDTLS_THREADING_C)
@ -174,11 +175,6 @@ exit:
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif
if( f_source_dup != f_source || p_source_dup != p_source ||
threshold_dup != threshold || strong_dup != strong )
{
ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
}
return( ret );
}
@ -192,9 +188,8 @@ static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id
unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE];
size_t use_len = len;
const unsigned char *p = data;
int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
volatile const unsigned char *data_dup = data;
volatile size_t len_dup = len;
int ret = 0;
if( use_len > MBEDTLS_ENTROPY_BLOCK_SIZE )
{
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
@ -237,19 +232,15 @@ static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id
#endif
cleanup:
mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
mbedtls_zeroize( tmp, sizeof( tmp ) );
if( len_dup != len || data_dup != data )
{
ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
}
return( ret );
}
int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
const unsigned char *data, size_t len )
{
int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
int ret;
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
@ -271,9 +262,7 @@ int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
*/
static int entropy_gather_internal( mbedtls_entropy_context *ctx )
{
int i;
volatile int ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE;
volatile int have_one_strong_fi = MBEDTLS_ENTROPY_SOURCE_WEAK;
int ret, i, have_one_strong = 0;
unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER];
size_t olen;
@ -285,16 +274,8 @@ static int entropy_gather_internal( mbedtls_entropy_context *ctx )
*/
for( i = 0; i < ctx->source_count; i++ )
{
volatile int strong_fi = ctx->source[i].strong;
if( strong_fi == MBEDTLS_ENTROPY_SOURCE_STRONG )
{
mbedtls_platform_random_delay();
if( strong_fi == MBEDTLS_ENTROPY_SOURCE_STRONG )
have_one_strong_fi = MBEDTLS_ENTROPY_SOURCE_STRONG;
else
return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
}
if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG )
have_one_strong = 1;
olen = 0;
if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source,
@ -315,24 +296,13 @@ static int entropy_gather_internal( mbedtls_entropy_context *ctx )
}
}
if( have_one_strong == 0 )
ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE;
cleanup:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
mbedtls_zeroize( buf, sizeof( buf ) );
if( have_one_strong_fi == MBEDTLS_ENTROPY_SOURCE_STRONG )
{
mbedtls_platform_random_delay();
if( have_one_strong_fi == MBEDTLS_ENTROPY_SOURCE_STRONG )
{
return( ret );
}
else
{
return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
}
}
return( MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE );
return( ret );
}
/*
@ -340,7 +310,7 @@ cleanup:
*/
int mbedtls_entropy_gather( mbedtls_entropy_context *ctx )
{
int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
int ret;
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
@ -359,13 +329,9 @@ int mbedtls_entropy_gather( mbedtls_entropy_context *ctx )
int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
{
int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
int count = 0, i, done;
int ret, count = 0, i, done;
mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data;
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
volatile void *data_dup = data;
volatile unsigned char *output_dup = output;
volatile size_t len_dup = len;
if( len > MBEDTLS_ENTROPY_BLOCK_SIZE )
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
@ -462,22 +428,18 @@ int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
for( i = 0; i < ctx->source_count; i++ )
ctx->source[i].size = 0;
if( output == mbedtls_platform_memcpy( output, buf, len ) )
{
ret = 0;
}
memcpy( output, buf, len );
ret = 0;
exit:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
mbedtls_zeroize( buf, sizeof( buf ) );
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif
if( data_dup != data || len_dup != len || output_dup != output )
{
ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
}
return( ret );
}
@ -495,7 +457,7 @@ int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx )
return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
/* Manually update the remaining stream with a separator value to diverge */
mbedtls_platform_memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
ret = mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
return( ret );
@ -524,7 +486,7 @@ int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *p
ret = 0;
exit:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
mbedtls_zeroize( buf, sizeof( buf ) );
fclose( f );
return( ret );
@ -554,7 +516,7 @@ int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *
fclose( f );
mbedtls_platform_zeroize( buf, sizeof( buf ) );
mbedtls_zeroize( buf, sizeof( buf ) );
if( ret != 0 )
return( ret );
@ -573,7 +535,7 @@ static int entropy_dummy_source( void *data, unsigned char *output,
{
((void) data);
mbedtls_platform_memset( output, 0x2a, len );
memset( output, 0x2a, len );
*olen = len;
return( 0 );
@ -644,8 +606,8 @@ int mbedtls_entropy_source_self_test( int verbose )
if( verbose != 0 )
mbedtls_printf( " ENTROPY_BIAS test: " );
mbedtls_platform_memset( buf0, 0x00, sizeof( buf0 ) );
mbedtls_platform_memset( buf1, 0x00, sizeof( buf1 ) );
memset( buf0, 0x00, sizeof( buf0 ) );
memset( buf1, 0x00, sizeof( buf1 ) );
if( ( ret = mbedtls_entropy_source_self_test_gather( buf0, sizeof( buf0 ) ) ) != 0 )
goto cleanup;

View File

@ -83,8 +83,8 @@
#define MBEDTLS_ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */
#define MBEDTLS_ENTROPY_SOURCE_MANUAL MBEDTLS_ENTROPY_MAX_SOURCES
#define MBEDTLS_ENTROPY_SOURCE_STRONG 0x7F /**< Entropy source is strong */
#define MBEDTLS_ENTROPY_SOURCE_WEAK 0x0 /**< Entropy source is weak */
#define MBEDTLS_ENTROPY_SOURCE_STRONG 1 /**< Entropy source is strong */
#define MBEDTLS_ENTROPY_SOURCE_WEAK 0 /**< Entropy source is weak */
#ifdef __cplusplus
extern "C" {
@ -107,7 +107,7 @@ typedef int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output, s
/**
* \brief Entropy source state
*/
typedef struct mbedtls_entropy_source_state
typedef struct
{
mbedtls_entropy_f_source_ptr f_source; /**< The entropy source callback */
void * p_source; /**< The callback data pointer */
@ -120,7 +120,7 @@ mbedtls_entropy_source_state;
/**
* \brief Entropy context structure
*/
typedef struct mbedtls_entropy_context
typedef struct
{
int accumulator_started;
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
@ -166,7 +166,7 @@ void mbedtls_entropy_free( mbedtls_entropy_context *ctx );
* \param threshold Minimum required from source before entropy is released
* ( with mbedtls_entropy_func() ) (in bytes)
* \param strong MBEDTLS_ENTROPY_SOURCE_STRONG or
* MBEDTLS_ENTROPY_SOURCE_WEAK.
* MBEDTSL_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.

View File

@ -0,0 +1,229 @@
/*
* 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 TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_ENTROPY_C)
#include "entropy.h"
#include "entropy_poll.h"
#if defined(MBEDTLS_TIMING_C)
#include <string.h>
#include "timing.h"
#endif
#if defined(MBEDTLS_HAVEGE_C)
#include "havege.h"
#endif
#if defined(MBEDTLS_ENTROPY_NV_SEED)
#include "platform.h"
#endif
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
!defined(__APPLE__) && !defined(_WIN32)
#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h"
#endif
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
#if !defined(_WIN32_WINNT)
#define _WIN32_WINNT 0x0400
#endif
#include <windows.h>
#include <wincrypt.h>
int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len,
size_t *olen )
{
HCRYPTPROV provider;
((void) data);
*olen = 0;
if( CryptAcquireContext( &provider, NULL, NULL,
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE )
{
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
}
if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE )
{
CryptReleaseContext( provider, 0 );
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
}
CryptReleaseContext( provider, 0 );
*olen = len;
return( 0 );
}
#else /* _WIN32 && !EFIX64 && !EFI32 */
/*
* Test for Linux getrandom() support.
* Since there is no wrapper in the libc yet, use the generic syscall wrapper
* available in GNU libc and compatible libc's (eg uClibc).
*/
#if defined(__linux__) && defined(__GLIBC__)
#include <unistd.h>
#include <sys/syscall.h>
#if defined(SYS_getrandom)
#define HAVE_GETRANDOM
#include <errno.h>
static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
{
/* MemSan cannot understand that the syscall writes to the buffer */
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
memset( buf, 0, buflen );
#endif
#endif
return( syscall( SYS_getrandom, buf, buflen, flags ) );
}
#endif /* SYS_getrandom */
#endif /* __linux__ */
#include <stdio.h>
int mbedtls_platform_entropy_poll( void *data,
unsigned char *output, size_t len, size_t *olen )
{
FILE *file;
size_t read_len;
int ret;
((void) data);
#if defined(HAVE_GETRANDOM)
ret = getrandom_wrapper( output, len, 0 );
if( ret >= 0 )
{
*olen = ret;
return( 0 );
}
else if( errno != ENOSYS )
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
/* Fall through if the system call isn't known. */
#else
((void) ret);
#endif /* HAVE_GETRANDOM */
*olen = 0;
file = fopen( "/dev/urandom", "rb" );
if( file == NULL )
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
read_len = fread( output, 1, len, file );
if( read_len != len )
{
fclose( file );
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
}
fclose( file );
*olen = len;
return( 0 );
}
#endif /* _WIN32 && !EFIX64 && !EFI32 */
#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
#if defined(MBEDTLS_TEST_NULL_ENTROPY)
int mbedtls_null_entropy_poll( void *data,
unsigned char *output, size_t len, size_t *olen )
{
((void) data);
((void) output);
*olen = 0;
if( len < sizeof(unsigned char) )
return( 0 );
*olen = sizeof(unsigned char);
return( 0 );
}
#endif
#if defined(MBEDTLS_TIMING_C)
int mbedtls_hardclock_poll( void *data,
unsigned char *output, size_t len, size_t *olen )
{
unsigned long timer = mbedtls_timing_hardclock();
((void) data);
*olen = 0;
if( len < sizeof(unsigned long) )
return( 0 );
memcpy( output, &timer, sizeof(unsigned long) );
*olen = sizeof(unsigned long);
return( 0 );
}
#endif /* MBEDTLS_TIMING_C */
#if defined(MBEDTLS_HAVEGE_C)
int mbedtls_havege_poll( void *data,
unsigned char *output, size_t len, size_t *olen )
{
mbedtls_havege_state *hs = (mbedtls_havege_state *) data;
*olen = 0;
if( mbedtls_havege_random( hs, output, len ) != 0 )
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
*olen = len;
return( 0 );
}
#endif /* MBEDTLS_HAVEGE_C */
#if defined(MBEDTLS_ENTROPY_NV_SEED)
int mbedtls_nv_seed_poll( void *data,
unsigned char *output, size_t len, size_t *olen )
{
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
((void) data);
memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
if( mbedtls_nv_seed_read( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 )
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
if( len < use_len )
use_len = len;
memcpy( output, buf, use_len );
*olen = use_len;
return( 0 );
}
#endif /* MBEDTLS_ENTROPY_NV_SEED */
#endif /* MBEDTLS_ENTROPY_C */

View File

@ -0,0 +1,822 @@
/*
* Error message information
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
#include "error.h"
#include <string.h>
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "platform.h"
#else
#define mbedtls_snprintf snprintf
#define mbedtls_time_t time_t
#endif
#if defined(MBEDTLS_ERROR_C)
#include <stdio.h>
#if defined(MBEDTLS_AES_C)
#include "aes.h"
#endif
#if defined(MBEDTLS_ARC4_C)
#include "arc4.h"
#endif
#if defined(MBEDTLS_BASE64_C)
#include "base64.h"
#endif
#if defined(MBEDTLS_BIGNUM_C)
#include "bignum.h"
#endif
#if defined(MBEDTLS_BLOWFISH_C)
#include "blowfish.h"
#endif
#if defined(MBEDTLS_CAMELLIA_C)
#include "camellia.h"
#endif
#if defined(MBEDTLS_CCM_C)
#include "ccm.h"
#endif
#if defined(MBEDTLS_CIPHER_C)
#include "cipher.h"
#endif
#if defined(MBEDTLS_CMAC_C)
#include "cmac.h"
#endif
#if defined(MBEDTLS_CTR_DRBG_C)
#include "ctr_drbg.h"
#endif
#if defined(MBEDTLS_DES_C)
#include "des.h"
#endif
#if defined(MBEDTLS_DHM_C)
#include "dhm.h"
#endif
#if defined(MBEDTLS_ECP_C)
#include "ecp.h"
#endif
#if defined(MBEDTLS_ENTROPY_C)
#include "entropy.h"
#endif
#if defined(MBEDTLS_GCM_C)
#include "gcm.h"
#endif
#if defined(MBEDTLS_HMAC_DRBG_C)
#include "hmac_drbg.h"
#endif
#if defined(MBEDTLS_MD_C)
#include "md.h"
#endif
#if defined(MBEDTLS_MD2_C)
#include "md2.h"
#endif
#if defined(MBEDTLS_MD4_C)
#include "md4.h"
#endif
#if defined(MBEDTLS_MD5_C)
#include "md5.h"
#endif
#if defined(MBEDTLS_NET_C)
#include "net_sockets.h"
#endif
#if defined(MBEDTLS_OID_C)
#include "oid.h"
#endif
#if defined(MBEDTLS_PADLOCK_C)
#include "padlock.h"
#endif
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
#include "pem.h"
#endif
#if defined(MBEDTLS_PK_C)
#include "pk.h"
#endif
#if defined(MBEDTLS_PKCS12_C)
#include "pkcs12.h"
#endif
#if defined(MBEDTLS_PKCS5_C)
#include "pkcs5.h"
#endif
#if defined(MBEDTLS_RIPEMD160_C)
#include "ripemd160.h"
#endif
#if defined(MBEDTLS_RSA_C)
#include "rsa.h"
#endif
#if defined(MBEDTLS_SHA1_C)
#include "sha1.h"
#endif
#if defined(MBEDTLS_SHA256_C)
#include "sha256.h"
#endif
#if defined(MBEDTLS_SHA512_C)
#include "sha512.h"
#endif
#if defined(MBEDTLS_SSL_TLS_C)
#include "ssl.h"
#endif
#if defined(MBEDTLS_THREADING_C)
#include "threading.h"
#endif
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
#include "x509.h"
#endif
#if defined(MBEDTLS_XTEA_C)
#include "xtea.h"
#endif
void mbedtls_strerror( int ret, char *buf, size_t buflen )
{
size_t len;
int use_ret;
if( buflen == 0 )
return;
memset( buf, 0x00, buflen );
if( ret < 0 )
ret = -ret;
if( ret & 0xFF80 )
{
use_ret = ret & 0xFF80;
// High level error codes
//
// BEGIN generated code
#if defined(MBEDTLS_CIPHER_C)
if( use_ret == -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "CIPHER - The selected feature is not available" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "CIPHER - Bad input parameters" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "CIPHER - Failed to allocate memory" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_PADDING) )
mbedtls_snprintf( buf, buflen, "CIPHER - Input data contains invalid padding and is rejected" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED) )
mbedtls_snprintf( buf, buflen, "CIPHER - Decryption of block requires a full block" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) )
mbedtls_snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT) )
mbedtls_snprintf( buf, buflen, "CIPHER - The context is invalid. For example, because it was freed" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "CIPHER - Cipher hardware accelerator failed" );
#endif /* MBEDTLS_CIPHER_C */
#if defined(MBEDTLS_DHM_C)
if( use_ret == -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "DHM - Bad input parameters" );
if( use_ret == -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - Reading of the DHM parameters failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - Making of the DHM parameters failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - Reading of the public values failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - Making of the public value failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - Calculation of the DHM secret failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_INVALID_FORMAT) )
mbedtls_snprintf( buf, buflen, "DHM - The ASN.1 data is not formatted correctly" );
if( use_ret == -(MBEDTLS_ERR_DHM_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - Allocation of memory failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "DHM - Read or write of file failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - DHM hardware accelerator failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_SET_GROUP_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - Setting the modulus and generator failed" );
#endif /* MBEDTLS_DHM_C */
#if defined(MBEDTLS_ECP_C)
if( use_ret == -(MBEDTLS_ERR_ECP_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "ECP - Bad input parameters to function" );
if( use_ret == -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL) )
mbedtls_snprintf( buf, buflen, "ECP - The buffer is too small to write to" );
if( use_ret == -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "ECP - Requested curve not available" );
if( use_ret == -(MBEDTLS_ERR_ECP_VERIFY_FAILED) )
mbedtls_snprintf( buf, buflen, "ECP - The signature is not valid" );
if( use_ret == -(MBEDTLS_ERR_ECP_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "ECP - Memory allocation failed" );
if( use_ret == -(MBEDTLS_ERR_ECP_RANDOM_FAILED) )
mbedtls_snprintf( buf, buflen, "ECP - Generation of random value, such as (ephemeral) key, failed" );
if( use_ret == -(MBEDTLS_ERR_ECP_INVALID_KEY) )
mbedtls_snprintf( buf, buflen, "ECP - Invalid private or public key" );
if( use_ret == -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) )
mbedtls_snprintf( buf, buflen, "ECP - The buffer contains a valid signature followed by more data" );
if( use_ret == -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "ECP - ECP hardware accelerator failed" );
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_MD_C)
if( use_ret == -(MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "MD - The selected feature is not available" );
if( use_ret == -(MBEDTLS_ERR_MD_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "MD - Bad input parameters to function" );
if( use_ret == -(MBEDTLS_ERR_MD_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "MD - Failed to allocate memory" );
if( use_ret == -(MBEDTLS_ERR_MD_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "MD - Opening or reading of file failed" );
if( use_ret == -(MBEDTLS_ERR_MD_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "MD - MD hardware accelerator failed" );
#endif /* MBEDTLS_MD_C */
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
if( use_ret == -(MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) )
mbedtls_snprintf( buf, buflen, "PEM - No PEM header or footer found" );
if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_DATA) )
mbedtls_snprintf( buf, buflen, "PEM - PEM string is not as expected" );
if( use_ret == -(MBEDTLS_ERR_PEM_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "PEM - Failed to allocate memory" );
if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_ENC_IV) )
mbedtls_snprintf( buf, buflen, "PEM - RSA IV is not in hex-format" );
if( use_ret == -(MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG) )
mbedtls_snprintf( buf, buflen, "PEM - Unsupported key encryption algorithm" );
if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) )
mbedtls_snprintf( buf, buflen, "PEM - Private key password can't be empty" );
if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) )
mbedtls_snprintf( buf, buflen, "PEM - Given private key password does not allow for correct decryption" );
if( use_ret == -(MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "PEM - Unavailable feature, e.g. hashing/encryption combination" );
if( use_ret == -(MBEDTLS_ERR_PEM_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "PEM - Bad input parameters to function" );
#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */
#if defined(MBEDTLS_PK_C)
if( use_ret == -(MBEDTLS_ERR_PK_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "PK - Memory allocation failed" );
if( use_ret == -(MBEDTLS_ERR_PK_TYPE_MISMATCH) )
mbedtls_snprintf( buf, buflen, "PK - Type mismatch, eg attempt to encrypt with an ECDSA key" );
if( use_ret == -(MBEDTLS_ERR_PK_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "PK - Bad input parameters to function" );
if( use_ret == -(MBEDTLS_ERR_PK_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "PK - Read/write of file failed" );
if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_VERSION) )
mbedtls_snprintf( buf, buflen, "PK - Unsupported key version" );
if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT) )
mbedtls_snprintf( buf, buflen, "PK - Invalid key tag or value" );
if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_PK_ALG) )
mbedtls_snprintf( buf, buflen, "PK - Key algorithm is unsupported (only RSA and EC are supported)" );
if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_REQUIRED) )
mbedtls_snprintf( buf, buflen, "PK - Private key password can't be empty" );
if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_MISMATCH) )
mbedtls_snprintf( buf, buflen, "PK - Given private key password does not allow for correct decryption" );
if( use_ret == -(MBEDTLS_ERR_PK_INVALID_PUBKEY) )
mbedtls_snprintf( buf, buflen, "PK - The pubkey tag or value is invalid (only RSA and EC are supported)" );
if( use_ret == -(MBEDTLS_ERR_PK_INVALID_ALG) )
mbedtls_snprintf( buf, buflen, "PK - The algorithm tag or value is invalid" );
if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE) )
mbedtls_snprintf( buf, buflen, "PK - Elliptic curve is unsupported (only NIST curves are supported)" );
if( use_ret == -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" );
if( use_ret == -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH) )
mbedtls_snprintf( buf, buflen, "PK - The buffer contains a valid signature followed by more data" );
if( use_ret == -(MBEDTLS_ERR_PK_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "PK - PK hardware accelerator failed" );
#endif /* MBEDTLS_PK_C */
#if defined(MBEDTLS_PKCS12_C)
if( use_ret == -(MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "PKCS12 - Bad input parameters to function" );
if( use_ret == -(MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "PKCS12 - Feature not available, e.g. unsupported encryption scheme" );
if( use_ret == -(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT) )
mbedtls_snprintf( buf, buflen, "PKCS12 - PBE ASN.1 data not as expected" );
if( use_ret == -(MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH) )
mbedtls_snprintf( buf, buflen, "PKCS12 - Given private key password does not allow for correct decryption" );
#endif /* MBEDTLS_PKCS12_C */
#if defined(MBEDTLS_PKCS5_C)
if( use_ret == -(MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "PKCS5 - Bad input parameters to function" );
if( use_ret == -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT) )
mbedtls_snprintf( buf, buflen, "PKCS5 - Unexpected ASN.1 data" );
if( use_ret == -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "PKCS5 - Requested encryption or digest alg not available" );
if( use_ret == -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH) )
mbedtls_snprintf( buf, buflen, "PKCS5 - Given private key password does not allow for correct decryption" );
#endif /* MBEDTLS_PKCS5_C */
#if defined(MBEDTLS_RSA_C)
if( use_ret == -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "RSA - Bad input parameters to function" );
if( use_ret == -(MBEDTLS_ERR_RSA_INVALID_PADDING) )
mbedtls_snprintf( buf, buflen, "RSA - Input data contains invalid padding and is rejected" );
if( use_ret == -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - Something failed during generation of a key" );
if( use_ret == -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - Key failed to pass the validity check of the library" );
if( use_ret == -(MBEDTLS_ERR_RSA_PUBLIC_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - The public key operation failed" );
if( use_ret == -(MBEDTLS_ERR_RSA_PRIVATE_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - The private key operation failed" );
if( use_ret == -(MBEDTLS_ERR_RSA_VERIFY_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - The PKCS#1 verification failed" );
if( use_ret == -(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE) )
mbedtls_snprintf( buf, buflen, "RSA - The output buffer for decryption is not large enough" );
if( use_ret == -(MBEDTLS_ERR_RSA_RNG_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - The random generator failed to generate non-zeros" );
if( use_ret == -(MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION) )
mbedtls_snprintf( buf, buflen, "RSA - The implementation does not offer the requested operation, for example, because of security violations or lack of functionality" );
if( use_ret == -(MBEDTLS_ERR_RSA_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - RSA hardware accelerator failed" );
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_SSL_TLS_C)
if( use_ret == -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "SSL - The requested feature is not available" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "SSL - Bad input parameters to function" );
if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_MAC) )
mbedtls_snprintf( buf, buflen, "SSL - Verification of the message MAC failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_RECORD) )
mbedtls_snprintf( buf, buflen, "SSL - An invalid SSL record was received" );
if( use_ret == -(MBEDTLS_ERR_SSL_CONN_EOF) )
mbedtls_snprintf( buf, buflen, "SSL - The connection indicated an EOF" );
if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER) )
mbedtls_snprintf( buf, buflen, "SSL - An unknown cipher was received" );
if( use_ret == -(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN) )
mbedtls_snprintf( buf, buflen, "SSL - The server has no ciphersuites in common with the client" );
if( use_ret == -(MBEDTLS_ERR_SSL_NO_RNG) )
mbedtls_snprintf( buf, buflen, "SSL - No RNG was provided to the SSL module" );
if( use_ret == -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE) )
mbedtls_snprintf( buf, buflen, "SSL - No client certification received from the client, but required by the authentication mode" );
if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE) )
mbedtls_snprintf( buf, buflen, "SSL - Our own certificate(s) is/are too large to send in an SSL message" );
if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED) )
mbedtls_snprintf( buf, buflen, "SSL - The own certificate is not set, but needed by the server" );
if( use_ret == -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED) )
mbedtls_snprintf( buf, buflen, "SSL - The own private key or pre-shared key is not set, but needed" );
if( use_ret == -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED) )
mbedtls_snprintf( buf, buflen, "SSL - No CA Chain is set, but required to operate" );
if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) )
mbedtls_snprintf( buf, buflen, "SSL - An unexpected message was received from our peer" );
if( use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE) )
{
mbedtls_snprintf( buf, buflen, "SSL - A fatal alert message was received from our peer" );
return;
}
if( use_ret == -(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED) )
mbedtls_snprintf( buf, buflen, "SSL - Verification of our peer failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) )
mbedtls_snprintf( buf, buflen, "SSL - The peer notified us that the connection is going to be closed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientHello handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHello handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the Certificate handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateRequest handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerKeyExchange handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHelloDone handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateVerify handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ChangeCipherSpec handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_FINISHED) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the Finished handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "SSL - Memory allocation failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function returned with error" );
if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH) )
mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function skipped / left alone data" );
if( use_ret == -(MBEDTLS_ERR_SSL_COMPRESSION_FAILED) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the compression / decompression failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION) )
mbedtls_snprintf( buf, buflen, "SSL - Handshake protocol not within min/max boundaries" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the NewSessionTicket handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) )
mbedtls_snprintf( buf, buflen, "SSL - Session ticket has expired" );
if( use_ret == -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH) )
mbedtls_snprintf( buf, buflen, "SSL - Public key type mismatch (eg, asked for RSA key exchange and presented EC key)" );
if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) )
mbedtls_snprintf( buf, buflen, "SSL - Unknown identity received (eg, PSK identity)" );
if( use_ret == -(MBEDTLS_ERR_SSL_INTERNAL_ERROR) )
mbedtls_snprintf( buf, buflen, "SSL - Internal error (eg, unexpected failure in lower-level module)" );
if( use_ret == -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING) )
mbedtls_snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" );
if( use_ret == -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO) )
mbedtls_snprintf( buf, buflen, "SSL - Unexpected message at ServerHello in renegotiation" );
if( use_ret == -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) )
mbedtls_snprintf( buf, buflen, "SSL - DTLS client must retry for hello verification" );
if( use_ret == -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) )
mbedtls_snprintf( buf, buflen, "SSL - A buffer is too small to receive or write a message" );
if( use_ret == -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE) )
mbedtls_snprintf( buf, buflen, "SSL - None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages)" );
if( use_ret == -(MBEDTLS_ERR_SSL_WANT_READ) )
mbedtls_snprintf( buf, buflen, "SSL - Connection requires a read call" );
if( use_ret == -(MBEDTLS_ERR_SSL_WANT_WRITE) )
mbedtls_snprintf( buf, buflen, "SSL - Connection requires a write call" );
if( use_ret == -(MBEDTLS_ERR_SSL_TIMEOUT) )
mbedtls_snprintf( buf, buflen, "SSL - The operation timed out" );
if( use_ret == -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT) )
mbedtls_snprintf( buf, buflen, "SSL - The client initiated a reconnect from the same port" );
if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) )
mbedtls_snprintf( buf, buflen, "SSL - Record header looks valid but is not expected" );
if( use_ret == -(MBEDTLS_ERR_SSL_NON_FATAL) )
mbedtls_snprintf( buf, buflen, "SSL - The alert message received indicates a non-fatal error" );
if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH) )
mbedtls_snprintf( buf, buflen, "SSL - Couldn't set the hash for verifying CertificateVerify" );
#endif /* MBEDTLS_SSL_TLS_C */
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
if( use_ret == -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "X509 - Unavailable feature, e.g. RSA hashing/encryption combination" );
if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_OID) )
mbedtls_snprintf( buf, buflen, "X509 - Requested OID is unknown" );
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_FORMAT) )
mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected" );
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_VERSION) )
mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR version element is invalid" );
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SERIAL) )
mbedtls_snprintf( buf, buflen, "X509 - The serial tag or value is invalid" );
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_ALG) )
mbedtls_snprintf( buf, buflen, "X509 - The algorithm tag or value is invalid" );
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_NAME) )
mbedtls_snprintf( buf, buflen, "X509 - The name tag or value is invalid" );
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_DATE) )
mbedtls_snprintf( buf, buflen, "X509 - The date tag or value is invalid" );
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SIGNATURE) )
mbedtls_snprintf( buf, buflen, "X509 - The signature tag or value invalid" );
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_EXTENSIONS) )
mbedtls_snprintf( buf, buflen, "X509 - The extension tag or value is invalid" );
if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_VERSION) )
mbedtls_snprintf( buf, buflen, "X509 - CRT/CRL/CSR has an unsupported version number" );
if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG) )
mbedtls_snprintf( buf, buflen, "X509 - Signature algorithm (oid) is unsupported" );
if( use_ret == -(MBEDTLS_ERR_X509_SIG_MISMATCH) )
mbedtls_snprintf( buf, buflen, "X509 - Signature algorithms do not match. (see \\c ::mbedtls_x509_crt sig_oid)" );
if( use_ret == -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) )
mbedtls_snprintf( buf, buflen, "X509 - Certificate verification failed, e.g. CRL, CA or signature check failed" );
if( use_ret == -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT) )
mbedtls_snprintf( buf, buflen, "X509 - Format not recognized as DER or PEM" );
if( use_ret == -(MBEDTLS_ERR_X509_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "X509 - Input invalid" );
if( use_ret == -(MBEDTLS_ERR_X509_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "X509 - Allocation of memory failed" );
if( use_ret == -(MBEDTLS_ERR_X509_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "X509 - Read/write of file failed" );
if( use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL) )
mbedtls_snprintf( buf, buflen, "X509 - Destination buffer is too small" );
if( use_ret == -(MBEDTLS_ERR_X509_FATAL_ERROR) )
mbedtls_snprintf( buf, buflen, "X509 - A fatal error occured, eg the chain is too long or the vrfy callback failed" );
#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
// END generated code
if( strlen( buf ) == 0 )
mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
}
use_ret = ret & ~0xFF80;
if( use_ret == 0 )
return;
// If high level code is present, make a concatenation between both
// error strings.
//
len = strlen( buf );
if( len > 0 )
{
if( buflen - len < 5 )
return;
mbedtls_snprintf( buf + len, buflen - len, " : " );
buf += len + 3;
buflen -= len + 3;
}
// Low level error codes
//
// BEGIN generated code
#if defined(MBEDTLS_AES_C)
if( use_ret == -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH) )
mbedtls_snprintf( buf, buflen, "AES - Invalid key length" );
if( use_ret == -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "AES - Invalid data input length" );
if( use_ret == -(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "AES - Feature not available. For example, an unsupported AES key size" );
if( use_ret == -(MBEDTLS_ERR_AES_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "AES - AES hardware accelerator failed" );
#endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_ARC4_C)
if( use_ret == -(MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "ARC4 - ARC4 hardware accelerator failed" );
#endif /* MBEDTLS_ARC4_C */
#if defined(MBEDTLS_ASN1_PARSE_C)
if( use_ret == -(MBEDTLS_ERR_ASN1_OUT_OF_DATA) )
mbedtls_snprintf( buf, buflen, "ASN1 - Out of data when parsing an ASN1 data structure" );
if( use_ret == -(MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) )
mbedtls_snprintf( buf, buflen, "ASN1 - ASN1 tag was of an unexpected value" );
if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_LENGTH) )
mbedtls_snprintf( buf, buflen, "ASN1 - Error when trying to determine the length or invalid length" );
if( use_ret == -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH) )
mbedtls_snprintf( buf, buflen, "ASN1 - Actual length differs from expected length" );
if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_DATA) )
mbedtls_snprintf( buf, buflen, "ASN1 - Data is invalid. (not used)" );
if( use_ret == -(MBEDTLS_ERR_ASN1_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "ASN1 - Memory allocation failed" );
if( use_ret == -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) )
mbedtls_snprintf( buf, buflen, "ASN1 - Buffer too small when writing ASN.1 data structure" );
#endif /* MBEDTLS_ASN1_PARSE_C */
#if defined(MBEDTLS_BASE64_C)
if( use_ret == -(MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) )
mbedtls_snprintf( buf, buflen, "BASE64 - Output buffer too small" );
if( use_ret == -(MBEDTLS_ERR_BASE64_INVALID_CHARACTER) )
mbedtls_snprintf( buf, buflen, "BASE64 - Invalid character in input" );
#endif /* MBEDTLS_BASE64_C */
#if defined(MBEDTLS_BIGNUM_C)
if( use_ret == -(MBEDTLS_ERR_MPI_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "BIGNUM - An error occurred while reading from or writing to a file" );
if( use_ret == -(MBEDTLS_ERR_MPI_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "BIGNUM - Bad input parameters to function" );
if( use_ret == -(MBEDTLS_ERR_MPI_INVALID_CHARACTER) )
mbedtls_snprintf( buf, buflen, "BIGNUM - There is an invalid character in the digit string" );
if( use_ret == -(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL) )
mbedtls_snprintf( buf, buflen, "BIGNUM - The buffer is too small to write to" );
if( use_ret == -(MBEDTLS_ERR_MPI_NEGATIVE_VALUE) )
mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are negative or result in illegal output" );
if( use_ret == -(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO) )
mbedtls_snprintf( buf, buflen, "BIGNUM - The input argument for division is zero, which is not allowed" );
if( use_ret == -(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) )
mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are not acceptable" );
if( use_ret == -(MBEDTLS_ERR_MPI_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "BIGNUM - Memory allocation failed" );
#endif /* MBEDTLS_BIGNUM_C */
#if defined(MBEDTLS_BLOWFISH_C)
if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH) )
mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid key length" );
if( use_ret == -(MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "BLOWFISH - Blowfish hardware accelerator failed" );
if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid data input length" );
#endif /* MBEDTLS_BLOWFISH_C */
#if defined(MBEDTLS_CAMELLIA_C)
if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH) )
mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid key length" );
if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid data input length" );
if( use_ret == -(MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "CAMELLIA - Camellia hardware accelerator failed" );
#endif /* MBEDTLS_CAMELLIA_C */
#if defined(MBEDTLS_CCM_C)
if( use_ret == -(MBEDTLS_ERR_CCM_BAD_INPUT) )
mbedtls_snprintf( buf, buflen, "CCM - Bad input parameters to the function" );
if( use_ret == -(MBEDTLS_ERR_CCM_AUTH_FAILED) )
mbedtls_snprintf( buf, buflen, "CCM - Authenticated decryption failed" );
if( use_ret == -(MBEDTLS_ERR_CCM_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "CCM - CCM hardware accelerator failed" );
#endif /* MBEDTLS_CCM_C */
#if defined(MBEDTLS_CMAC_C)
if( use_ret == -(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "CMAC - CMAC hardware accelerator failed" );
#endif /* MBEDTLS_CMAC_C */
#if defined(MBEDTLS_CTR_DRBG_C)
if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) )
mbedtls_snprintf( buf, buflen, "CTR_DRBG - The entropy source failed" );
if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG) )
mbedtls_snprintf( buf, buflen, "CTR_DRBG - The requested random buffer length is too big" );
if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG) )
mbedtls_snprintf( buf, buflen, "CTR_DRBG - The input (entropy + additional data) is too large" );
if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "CTR_DRBG - Read or write error in file" );
#endif /* MBEDTLS_CTR_DRBG_C */
#if defined(MBEDTLS_DES_C)
if( use_ret == -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "DES - The data input has an invalid length" );
if( use_ret == -(MBEDTLS_ERR_DES_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "DES - DES hardware accelerator failed" );
#endif /* MBEDTLS_DES_C */
#if defined(MBEDTLS_ENTROPY_C)
if( use_ret == -(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED) )
mbedtls_snprintf( buf, buflen, "ENTROPY - Critical entropy source failure" );
if( use_ret == -(MBEDTLS_ERR_ENTROPY_MAX_SOURCES) )
mbedtls_snprintf( buf, buflen, "ENTROPY - No more sources can be added" );
if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED) )
mbedtls_snprintf( buf, buflen, "ENTROPY - No sources have been added to poll" );
if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE) )
mbedtls_snprintf( buf, buflen, "ENTROPY - No strong sources have been added to poll" );
if( use_ret == -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "ENTROPY - Read/write error in file" );
#endif /* MBEDTLS_ENTROPY_C */
#if defined(MBEDTLS_GCM_C)
if( use_ret == -(MBEDTLS_ERR_GCM_AUTH_FAILED) )
mbedtls_snprintf( buf, buflen, "GCM - Authenticated decryption failed" );
if( use_ret == -(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "GCM - GCM hardware accelerator failed" );
if( use_ret == -(MBEDTLS_ERR_GCM_BAD_INPUT) )
mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" );
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_HMAC_DRBG_C)
if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG) )
mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Too many random requested in single call" );
if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG) )
mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Input too large (Entropy + additional)" );
if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Read/write error in file" );
if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED) )
mbedtls_snprintf( buf, buflen, "HMAC_DRBG - The entropy source failed" );
#endif /* MBEDTLS_HMAC_DRBG_C */
#if defined(MBEDTLS_MD2_C)
if( use_ret == -(MBEDTLS_ERR_MD2_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "MD2 - MD2 hardware accelerator failed" );
#endif /* MBEDTLS_MD2_C */
#if defined(MBEDTLS_MD4_C)
if( use_ret == -(MBEDTLS_ERR_MD4_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "MD4 - MD4 hardware accelerator failed" );
#endif /* MBEDTLS_MD4_C */
#if defined(MBEDTLS_MD5_C)
if( use_ret == -(MBEDTLS_ERR_MD5_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "MD5 - MD5 hardware accelerator failed" );
#endif /* MBEDTLS_MD5_C */
#if defined(MBEDTLS_NET_C)
if( use_ret == -(MBEDTLS_ERR_NET_SOCKET_FAILED) )
mbedtls_snprintf( buf, buflen, "NET - Failed to open a socket" );
if( use_ret == -(MBEDTLS_ERR_NET_CONNECT_FAILED) )
mbedtls_snprintf( buf, buflen, "NET - The connection to the given server / port failed" );
if( use_ret == -(MBEDTLS_ERR_NET_BIND_FAILED) )
mbedtls_snprintf( buf, buflen, "NET - Binding of the socket failed" );
if( use_ret == -(MBEDTLS_ERR_NET_LISTEN_FAILED) )
mbedtls_snprintf( buf, buflen, "NET - Could not listen on the socket" );
if( use_ret == -(MBEDTLS_ERR_NET_ACCEPT_FAILED) )
mbedtls_snprintf( buf, buflen, "NET - Could not accept the incoming connection" );
if( use_ret == -(MBEDTLS_ERR_NET_RECV_FAILED) )
mbedtls_snprintf( buf, buflen, "NET - Reading information from the socket failed" );
if( use_ret == -(MBEDTLS_ERR_NET_SEND_FAILED) )
mbedtls_snprintf( buf, buflen, "NET - Sending information through the socket failed" );
if( use_ret == -(MBEDTLS_ERR_NET_CONN_RESET) )
mbedtls_snprintf( buf, buflen, "NET - Connection was reset by peer" );
if( use_ret == -(MBEDTLS_ERR_NET_UNKNOWN_HOST) )
mbedtls_snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" );
if( use_ret == -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL) )
mbedtls_snprintf( buf, buflen, "NET - Buffer is too small to hold the data" );
if( use_ret == -(MBEDTLS_ERR_NET_INVALID_CONTEXT) )
mbedtls_snprintf( buf, buflen, "NET - The context is invalid, eg because it was free()ed" );
#endif /* MBEDTLS_NET_C */
#if defined(MBEDTLS_OID_C)
if( use_ret == -(MBEDTLS_ERR_OID_NOT_FOUND) )
mbedtls_snprintf( buf, buflen, "OID - OID is not found" );
if( use_ret == -(MBEDTLS_ERR_OID_BUF_TOO_SMALL) )
mbedtls_snprintf( buf, buflen, "OID - output buffer is too small" );
#endif /* MBEDTLS_OID_C */
#if defined(MBEDTLS_PADLOCK_C)
if( use_ret == -(MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED) )
mbedtls_snprintf( buf, buflen, "PADLOCK - Input data should be aligned" );
#endif /* MBEDTLS_PADLOCK_C */
#if defined(MBEDTLS_RIPEMD160_C)
if( use_ret == -(MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "RIPEMD160 - RIPEMD160 hardware accelerator failed" );
#endif /* MBEDTLS_RIPEMD160_C */
#if defined(MBEDTLS_SHA1_C)
if( use_ret == -(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "SHA1 - SHA-1 hardware accelerator failed" );
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA256_C)
if( use_ret == -(MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "SHA256 - SHA-256 hardware accelerator failed" );
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
if( use_ret == -(MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "SHA512 - SHA-512 hardware accelerator failed" );
#endif /* MBEDTLS_SHA512_C */
#if defined(MBEDTLS_THREADING_C)
if( use_ret == -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "THREADING - The selected feature is not available" );
if( use_ret == -(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "THREADING - Bad input parameters to function" );
if( use_ret == -(MBEDTLS_ERR_THREADING_MUTEX_ERROR) )
mbedtls_snprintf( buf, buflen, "THREADING - Locking / unlocking / free failed with error code" );
#endif /* MBEDTLS_THREADING_C */
#if defined(MBEDTLS_XTEA_C)
if( use_ret == -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "XTEA - The data input has an invalid length" );
if( use_ret == -(MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "XTEA - XTEA hardware accelerator failed" );
#endif /* MBEDTLS_XTEA_C */
// END generated code
if( strlen( buf ) != 0 )
return;
mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
}
#else /* MBEDTLS_ERROR_C */
#if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
/*
* Provide an non-function in case MBEDTLS_ERROR_C is not defined
*/
void mbedtls_strerror( int ret, char *buf, size_t buflen )
{
((void) ret);
if( buflen > 0 )
buf[0] = '\0';
}
#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */
#endif /* MBEDTLS_ERROR_C */

View File

@ -4,7 +4,7 @@
* \brief Error to string translation
*/
/*
* Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
* 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
@ -59,7 +59,7 @@
* GCM 3 0x0012-0x0014 0x0013-0x0013
* BLOWFISH 3 0x0016-0x0018 0x0017-0x0017
* THREADING 3 0x001A-0x001E
* AES 5 0x0020-0x0022 0x0021-0x0025
* AES 4 0x0020-0x0022 0x0023-0x0025
* CAMELLIA 3 0x0024-0x0026 0x0027-0x0027
* XTEA 2 0x0028-0x0028 0x0029-0x0029
* BASE64 2 0x002A-0x002C
@ -68,8 +68,7 @@
* DES 2 0x0032-0x0032 0x0033-0x0033
* CTR_DBRG 4 0x0034-0x003A
* ENTROPY 3 0x003C-0x0040 0x003D-0x003F
* NET 13 0x0042-0x0052 0x0043-0x0049
* ARIA 4 0x0058-0x005E
* NET 11 0x0042-0x0052 0x0043-0x0045
* ASN1 7 0x0060-0x006C
* CMAC 1 0x007A-0x007A
* PBKDF2 1 0x007C-0x007C
@ -80,13 +79,9 @@
* MD4 1 0x002D-0x002D
* MD5 1 0x002F-0x002F
* RIPEMD160 1 0x0031-0x0031
* SHA1 1 0x0035-0x0035 0x0073-0x0073
* SHA256 1 0x0037-0x0037 0x0074-0x0074
* SHA512 1 0x0039-0x0039 0x0075-0x0075
* CHACHA20 3 0x0051-0x0055
* POLY1305 3 0x0057-0x005B
* CHACHAPOLY 2 0x0054-0x0056
* PLATFORM 4 0x0070-0x0072 0x0071-0x0071 0x0076-0x0076
* 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
@ -97,13 +92,11 @@
* DHM 3 11
* PK 3 15 (Started from top)
* RSA 4 11
* ECP 4 10 (Started from top)
* ECP 4 9 (Started from top)
* MD 5 5
* HKDF 5 1 (Started from top)
* SSL 5 1 (Started from 0x5F00)
* CIPHER 6 8 (Started from 0x6080)
* SSL 6 24 (Started from top, plus 0x6000)
* SSL 7 32
* CIPHER 6 8
* SSL 6 17 (Started from top)
* SSL 7 31
*
* Module dependent error code (5 bits 0x.00.-0x.F8.)
*/

View File

@ -0,0 +1,958 @@
/*
* NIST SP800-38D compliant GCM implementation
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
*
* See also:
* [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
*
* We use the algorithm described as Shoup's method with 4-bit tables in
* [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_GCM_C)
#include "gcm.h"
#include <string.h>
#if defined(MBEDTLS_AESNI_C)
#include "aesni.h"
#endif
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
#include "aes.h"
#if defined(MBEDTLS_PLATFORM_C)
#include "platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
#if !defined(MBEDTLS_GCM_ALT)
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(n,b,i) \
{ \
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
| ( (uint32_t) (b)[(i) + 3] ); \
}
#endif
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
}
#endif
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/*
* Initialize a context
*/
void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
}
/*
* Precompute small multiples of H, that is set
* HH[i] || HL[i] = H times i,
* where i is seen as a field element as in [MGV], ie high-order bits
* correspond to low powers of P. The result is stored in the same way, that
* is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
* corresponds to P^127.
*/
static int gcm_gen_table( mbedtls_gcm_context *ctx )
{
int ret, i, j;
uint64_t hi, lo;
uint64_t vl, vh;
unsigned char h[16];
size_t olen = 0;
memset( h, 0, 16 );
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
return( ret );
/* pack h as two 64-bits ints, big-endian */
GET_UINT32_BE( hi, h, 0 );
GET_UINT32_BE( lo, h, 4 );
vh = (uint64_t) hi << 32 | lo;
GET_UINT32_BE( hi, h, 8 );
GET_UINT32_BE( lo, h, 12 );
vl = (uint64_t) hi << 32 | lo;
/* 8 = 1000 corresponds to 1 in GF(2^128) */
ctx->HL[8] = vl;
ctx->HH[8] = vh;
#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
/* With CLMUL support, we need only h, not the rest of the table */
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
return( 0 );
#endif
/* 0 corresponds to 0 in GF(2^128) */
ctx->HH[0] = 0;
ctx->HL[0] = 0;
for( i = 4; i > 0; i >>= 1 )
{
uint32_t T = ( vl & 1 ) * 0xe1000000U;
vl = ( vh << 63 ) | ( vl >> 1 );
vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
ctx->HL[i] = vl;
ctx->HH[i] = vh;
}
for( i = 2; i <= 8; i *= 2 )
{
uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
vh = *HiH;
vl = *HiL;
for( j = 1; j < i; j++ )
{
HiH[j] = vh ^ ctx->HH[j];
HiL[j] = vl ^ ctx->HL[j];
}
}
return( 0 );
}
int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
mbedtls_cipher_id_t cipher,
const unsigned char *key,
unsigned int keybits )
{
int ret;
const mbedtls_cipher_info_t *cipher_info;
cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
if( cipher_info == NULL )
return( MBEDTLS_ERR_GCM_BAD_INPUT );
if( cipher_info->block_size != 16 )
return( MBEDTLS_ERR_GCM_BAD_INPUT );
mbedtls_cipher_free( &ctx->cipher_ctx );
if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
return( ret );
if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
MBEDTLS_ENCRYPT ) ) != 0 )
{
return( ret );
}
if( ( ret = gcm_gen_table( ctx ) ) != 0 )
return( ret );
return( 0 );
}
/*
* Shoup's method for multiplication use this table with
* last4[x] = x times P^128
* where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
*/
static const uint64_t last4[16] =
{
0x0000, 0x1c20, 0x3840, 0x2460,
0x7080, 0x6ca0, 0x48c0, 0x54e0,
0xe100, 0xfd20, 0xd940, 0xc560,
0x9180, 0x8da0, 0xa9c0, 0xb5e0
};
/*
* Sets output to x times H using the precomputed tables.
* x and output are seen as elements of GF(2^128) as in [MGV].
*/
static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
unsigned char output[16] )
{
int i = 0;
unsigned char lo, hi, rem;
uint64_t zh, zl;
#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
unsigned char h[16];
PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
PUT_UINT32_BE( ctx->HH[8], h, 4 );
PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
PUT_UINT32_BE( ctx->HL[8], h, 12 );
mbedtls_aesni_gcm_mult( output, x, h );
return;
}
#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
lo = x[15] & 0xf;
zh = ctx->HH[lo];
zl = ctx->HL[lo];
for( i = 15; i >= 0; i-- )
{
lo = x[i] & 0xf;
hi = x[i] >> 4;
if( i != 15 )
{
rem = (unsigned char) zl & 0xf;
zl = ( zh << 60 ) | ( zl >> 4 );
zh = ( zh >> 4 );
zh ^= (uint64_t) last4[rem] << 48;
zh ^= ctx->HH[lo];
zl ^= ctx->HL[lo];
}
rem = (unsigned char) zl & 0xf;
zl = ( zh << 60 ) | ( zl >> 4 );
zh = ( zh >> 4 );
zh ^= (uint64_t) last4[rem] << 48;
zh ^= ctx->HH[hi];
zl ^= ctx->HL[hi];
}
PUT_UINT32_BE( zh >> 32, output, 0 );
PUT_UINT32_BE( zh, output, 4 );
PUT_UINT32_BE( zl >> 32, output, 8 );
PUT_UINT32_BE( zl, output, 12 );
}
int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
int mode,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len )
{
int ret;
unsigned char work_buf[16];
size_t i;
const unsigned char *p;
size_t use_len, olen = 0;
/* IV and AD are limited to 2^64 bits, so 2^61 bytes */
/* IV is not allowed to be zero length */
if( iv_len == 0 ||
( (uint64_t) iv_len ) >> 61 != 0 ||
( (uint64_t) add_len ) >> 61 != 0 )
{
return( MBEDTLS_ERR_GCM_BAD_INPUT );
}
memset( ctx->y, 0x00, sizeof(ctx->y) );
memset( ctx->buf, 0x00, sizeof(ctx->buf) );
ctx->mode = mode;
ctx->len = 0;
ctx->add_len = 0;
if( iv_len == 12 )
{
memcpy( ctx->y, iv, iv_len );
ctx->y[15] = 1;
}
else
{
memset( work_buf, 0x00, 16 );
PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
p = iv;
while( iv_len > 0 )
{
use_len = ( iv_len < 16 ) ? iv_len : 16;
for( i = 0; i < use_len; i++ )
ctx->y[i] ^= p[i];
gcm_mult( ctx, ctx->y, ctx->y );
iv_len -= use_len;
p += use_len;
}
for( i = 0; i < 16; i++ )
ctx->y[i] ^= work_buf[i];
gcm_mult( ctx, ctx->y, ctx->y );
}
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
&olen ) ) != 0 )
{
return( ret );
}
ctx->add_len = add_len;
p = add;
while( add_len > 0 )
{
use_len = ( add_len < 16 ) ? add_len : 16;
for( i = 0; i < use_len; i++ )
ctx->buf[i] ^= p[i];
gcm_mult( ctx, ctx->buf, ctx->buf );
add_len -= use_len;
p += use_len;
}
return( 0 );
}
int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
size_t length,
const unsigned char *input,
unsigned char *output )
{
int ret;
unsigned char ectr[16];
size_t i;
const unsigned char *p;
unsigned char *out_p = output;
size_t use_len, olen = 0;
if( output > input && (size_t) ( output - input ) < length )
return( MBEDTLS_ERR_GCM_BAD_INPUT );
/* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
* Also check for possible overflow */
if( ctx->len + length < ctx->len ||
(uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
{
return( MBEDTLS_ERR_GCM_BAD_INPUT );
}
ctx->len += length;
p = input;
while( length > 0 )
{
use_len = ( length < 16 ) ? length : 16;
for( i = 16; i > 12; i-- )
if( ++ctx->y[i - 1] != 0 )
break;
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
&olen ) ) != 0 )
{
return( ret );
}
for( i = 0; i < use_len; i++ )
{
if( ctx->mode == MBEDTLS_GCM_DECRYPT )
ctx->buf[i] ^= p[i];
out_p[i] = ectr[i] ^ p[i];
if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
ctx->buf[i] ^= out_p[i];
}
gcm_mult( ctx, ctx->buf, ctx->buf );
length -= use_len;
p += use_len;
out_p += use_len;
}
return( 0 );
}
int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
unsigned char *tag,
size_t tag_len )
{
unsigned char work_buf[16];
size_t i;
uint64_t orig_len = ctx->len * 8;
uint64_t orig_add_len = ctx->add_len * 8;
if( tag_len > 16 || tag_len < 4 )
return( MBEDTLS_ERR_GCM_BAD_INPUT );
memcpy( tag, ctx->base_ectr, tag_len );
if( orig_len || orig_add_len )
{
memset( work_buf, 0x00, 16 );
PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
for( i = 0; i < 16; i++ )
ctx->buf[i] ^= work_buf[i];
gcm_mult( ctx, ctx->buf, ctx->buf );
for( i = 0; i < tag_len; i++ )
tag[i] ^= ctx->buf[i];
}
return( 0 );
}
int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
int mode,
size_t length,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len,
const unsigned char *input,
unsigned char *output,
size_t tag_len,
unsigned char *tag )
{
int ret;
if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
return( ret );
if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
return( ret );
if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
return( ret );
return( 0 );
}
int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
size_t length,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len,
const unsigned char *tag,
size_t tag_len,
const unsigned char *input,
unsigned char *output )
{
int ret;
unsigned char check_tag[16];
size_t i;
int diff;
if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
iv, iv_len, add, add_len,
input, output, tag_len, check_tag ) ) != 0 )
{
return( ret );
}
/* Check tag in "constant-time" */
for( diff = 0, i = 0; i < tag_len; i++ )
diff |= tag[i] ^ check_tag[i];
if( diff != 0 )
{
mbedtls_zeroize( output, length );
return( MBEDTLS_ERR_GCM_AUTH_FAILED );
}
return( 0 );
}
void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
{
mbedtls_cipher_free( &ctx->cipher_ctx );
mbedtls_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
}
#endif /* !MBEDTLS_GCM_ALT */
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
/*
* AES-GCM test vectors from:
*
* http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
*/
#define MAX_TESTS 6
static const int key_index[MAX_TESTS] =
{ 0, 0, 1, 1, 1, 1 };
static const unsigned char key[MAX_TESTS][32] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
};
static const size_t iv_len[MAX_TESTS] =
{ 12, 12, 12, 12, 8, 60 };
static const int iv_index[MAX_TESTS] =
{ 0, 0, 1, 1, 1, 2 };
static const unsigned char iv[MAX_TESTS][64] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 },
{ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
0xde, 0xca, 0xf8, 0x88 },
{ 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
0xa6, 0x37, 0xb3, 0x9b },
};
static const size_t add_len[MAX_TESTS] =
{ 0, 0, 0, 20, 20, 20 };
static const int add_index[MAX_TESTS] =
{ 0, 0, 0, 1, 1, 1 };
static const unsigned char additional[MAX_TESTS][64] =
{
{ 0x00 },
{ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
0xab, 0xad, 0xda, 0xd2 },
};
static const size_t pt_len[MAX_TESTS] =
{ 0, 16, 64, 60, 60, 60 };
static const int pt_index[MAX_TESTS] =
{ 0, 0, 1, 1, 1, 1 };
static const unsigned char pt[MAX_TESTS][64] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
};
static const unsigned char ct[MAX_TESTS * 3][64] =
{
{ 0x00 },
{ 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
{ 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
{ 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
0x3d, 0x58, 0xe0, 0x91 },
{ 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
0xc2, 0x3f, 0x45, 0x98 },
{ 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
0x4c, 0x34, 0xae, 0xe5 },
{ 0x00 },
{ 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
{ 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
{ 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
0xcc, 0xda, 0x27, 0x10 },
{ 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
0xa0, 0xf0, 0x62, 0xf7 },
{ 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
0xe9, 0xb7, 0x37, 0x3b },
{ 0x00 },
{ 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
{ 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
{ 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
0xbc, 0xc9, 0xf6, 0x62 },
{ 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
0xf4, 0x7c, 0x9b, 0x1f },
{ 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
0x44, 0xae, 0x7e, 0x3f },
};
static const unsigned char tag[MAX_TESTS * 3][16] =
{
{ 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
{ 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
{ 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
{ 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
{ 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
{ 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
{ 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
{ 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
{ 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
{ 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
{ 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
{ 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
{ 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
{ 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
{ 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
{ 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
{ 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
{ 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
};
int mbedtls_gcm_self_test( int verbose )
{
mbedtls_gcm_context ctx;
unsigned char buf[64];
unsigned char tag_buf[16];
int i, j, ret;
mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
for( j = 0; j < 3; j++ )
{
int key_len = 128 + 64 * j;
for( i = 0; i < MAX_TESTS; i++ )
{
mbedtls_gcm_init( &ctx );
if( verbose != 0 )
mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
key_len, i, "enc" );
ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
key_len );
/*
* AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
* MBEDTLS_AES_ALT is defined.
*/
if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && key_len == 192 )
{
mbedtls_printf( "skipped\n" );
break;
}
else if( ret != 0 )
{
goto exit;
}
ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
pt_len[i],
iv[iv_index[i]], iv_len[i],
additional[add_index[i]], add_len[i],
pt[pt_index[i]], buf, 16, tag_buf );
if( ret != 0 )
goto exit;
if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
{
ret = 1;
goto exit;
}
mbedtls_gcm_free( &ctx );
if( verbose != 0 )
mbedtls_printf( "passed\n" );
mbedtls_gcm_init( &ctx );
if( verbose != 0 )
mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
key_len, i, "dec" );
ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
key_len );
if( ret != 0 )
goto exit;
ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
pt_len[i],
iv[iv_index[i]], iv_len[i],
additional[add_index[i]], add_len[i],
ct[j * 6 + i], buf, 16, tag_buf );
if( ret != 0 )
goto exit;
if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
{
ret = 1;
goto exit;
}
mbedtls_gcm_free( &ctx );
if( verbose != 0 )
mbedtls_printf( "passed\n" );
mbedtls_gcm_init( &ctx );
if( verbose != 0 )
mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
key_len, i, "enc" );
ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
key_len );
if( ret != 0 )
goto exit;
ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
iv[iv_index[i]], iv_len[i],
additional[add_index[i]], add_len[i] );
if( ret != 0 )
goto exit;
if( pt_len[i] > 32 )
{
size_t rest_len = pt_len[i] - 32;
ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf );
if( ret != 0 )
goto exit;
ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
buf + 32 );
if( ret != 0 )
goto exit;
}
else
{
ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
if( ret != 0 )
goto exit;
}
ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
if( ret != 0 )
goto exit;
if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
{
ret = 1;
goto exit;
}
mbedtls_gcm_free( &ctx );
if( verbose != 0 )
mbedtls_printf( "passed\n" );
mbedtls_gcm_init( &ctx );
if( verbose != 0 )
mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
key_len, i, "dec" );
ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
key_len );
if( ret != 0 )
goto exit;
ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
iv[iv_index[i]], iv_len[i],
additional[add_index[i]], add_len[i] );
if( ret != 0 )
goto exit;
if( pt_len[i] > 32 )
{
size_t rest_len = pt_len[i] - 32;
ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf );
if( ret != 0 )
goto exit;
ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
buf + 32 );
if( ret != 0 )
goto exit;
}
else
{
ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i],
buf );
if( ret != 0 )
goto exit;
}
ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
if( ret != 0 )
goto exit;
if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
{
ret = 1;
goto exit;
}
mbedtls_gcm_free( &ctx );
if( verbose != 0 )
mbedtls_printf( "passed\n" );
}
}
if( verbose != 0 )
mbedtls_printf( "\n" );
ret = 0;
exit:
if( ret != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
mbedtls_gcm_free( &ctx );
}
return( ret );
}
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
#endif /* MBEDTLS_GCM_C */

View File

@ -1,11 +1,9 @@
/**
* \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>
* \brief Galois/Counter Mode (GCM) for 128-bit block ciphers, as 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>.
@ -47,23 +45,19 @@
#define MBEDTLS_GCM_DECRYPT 0
#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */
/* MBEDTLS_ERR_GCM_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_GCM_HW_ACCEL_FAILED -0x0013 /**< GCM hardware accelerator failed. */
#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */
#if !defined(MBEDTLS_GCM_ALT)
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_GCM_ALT)
/**
* \brief The GCM context structure.
*/
typedef struct mbedtls_gcm_context
{
typedef struct {
mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */
uint64_t HL[16]; /*!< Precalculated HTable low. */
uint64_t HH[16]; /*!< Precalculated HTable high. */
@ -78,10 +72,6 @@ typedef struct mbedtls_gcm_context
}
mbedtls_gcm_context;
#else /* !MBEDTLS_GCM_ALT */
#include "gcm_alt.h"
#endif /* !MBEDTLS_GCM_ALT */
/**
* \brief This function initializes the specified GCM context,
* to make references valid, and prepares the context
@ -91,7 +81,7 @@ mbedtls_gcm_context;
* cipher, nor set the key. For this purpose, use
* mbedtls_gcm_setkey().
*
* \param ctx The GCM context to initialize. This must not be \c NULL.
* \param ctx The GCM context to initialize.
*/
void mbedtls_gcm_init( mbedtls_gcm_context *ctx );
@ -99,17 +89,15 @@ void mbedtls_gcm_init( mbedtls_gcm_context *ctx );
* \brief This function associates a GCM context with a
* cipher algorithm and a key.
*
* \param ctx The GCM context. This must be initialized.
* \param ctx The GCM context to initialize.
* \param cipher The 128-bit block cipher to use.
* \param key The encryption key. This must be a readable buffer of at
* least \p keybits bits.
* \param 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.
* \return \c 0 on success, or a cipher specific error code.
*/
int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
mbedtls_cipher_id_t cipher,
@ -119,18 +107,17 @@ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
/**
* \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.
* \note For encryption, the output buffer can be the same as the input buffer.
* For decryption, the output buffer cannot be the same as input buffer.
* If the buffers overlap, the output buffer must trail at least 8 Bytes
* behind the input buffer.
*
* \warning When this function performs a decryption, it outputs the
* authentication tag and does not verify that the data is
* authentic. You should use this function to perform encryption
* only. For decryption, use mbedtls_gcm_auth_decrypt() instead.
*
* \param ctx The GCM context to use for encryption or decryption. This
* must be initialized.
* \param ctx The GCM context to use for encryption or decryption.
* \param mode The operation to perform:
* - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption.
* The ciphertext is written to \p output and the
@ -144,28 +131,22 @@ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
* calling this function in decryption mode.
* \param length The length of the input data, which is equal to the length
* of the output data.
* \param iv The initialization vector. This must be a readable buffer of
* at least \p iv_len Bytes.
* \param iv The initialization vector.
* \param iv_len The length of the IV.
* \param add The buffer holding the additional data. This must be of at
* least that size in Bytes.
* \param add The buffer holding the additional data.
* \param add_len The length of the additional data.
* \param input The buffer holding the input data. If \p length is greater
* than zero, this must be a readable buffer of at least that
* size in Bytes.
* \param output The buffer for holding the output data. If \p length is greater
* than zero, this must be a writable buffer of at least that
* size in Bytes.
* \param input The buffer holding the input data. Its size is \b length.
* \param output The buffer for holding the output data. It must have room
* for \b length bytes.
* \param tag_len The length of the tag to generate.
* \param tag The buffer for holding the tag. This must be a readable
* buffer of at least \p tag_len Bytes.
* \param tag The buffer for holding the tag.
*
* \return \c 0 if the encryption or decryption was performed
* successfully. Note that in #MBEDTLS_GCM_DECRYPT mode,
* this does not indicate that the data is authentic.
* \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are
* not valid or a cipher-specific error code if the encryption
* or decryption failed.
* \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths are not valid.
* \return #MBEDTLS_ERR_GCM_HW_ACCEL_FAILED or a cipher-specific
* error code if the encryption or decryption failed.
*/
int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
int mode,
@ -183,34 +164,28 @@ int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
* \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.
* \note For decryption, the output buffer cannot be the same as input buffer.
* If the buffers overlap, the output buffer must trail at least 8 Bytes
* behind the input buffer.
*
* \param ctx The GCM context. This must be initialized.
* \param ctx The GCM context.
* \param length The length of the ciphertext to decrypt, which is also
* the length of the decrypted plaintext.
* \param iv The initialization vector. This must be a readable buffer
* of at least \p iv_len Bytes.
* \param iv The initialization vector.
* \param iv_len The length of the IV.
* \param add The buffer holding the additional data. This must be of at
* least that size in Bytes.
* \param add The buffer holding the additional data.
* \param add_len The length of the additional data.
* \param tag The buffer holding the tag to verify. This must be a
* readable buffer of at least \p tag_len Bytes.
* \param tag The buffer holding the tag to verify.
* \param tag_len The length of the tag to verify.
* \param input The buffer holding the ciphertext. If \p length is greater
* than zero, this must be a readable buffer of at least that
* size.
* \param output The buffer for holding the decrypted plaintext. If \p length
* is greater than zero, this must be a writable buffer of at
* least that size.
* \param input The buffer holding the ciphertext. Its size is \b length.
* \param output The buffer for holding the decrypted plaintext. It must
* have room for \b length bytes.
*
* \return \c 0 if successful and authenticated.
* \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match.
* \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are
* not valid or a cipher-specific error code if the decryption
* failed.
* \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths are not valid.
* \return #MBEDTLS_ERR_GCM_HW_ACCEL_FAILED or a cipher-specific
* error code if the decryption failed.
*/
int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
size_t length,
@ -227,18 +202,15 @@ int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
* \brief This function starts a GCM encryption or decryption
* operation.
*
* \param ctx The GCM context. This must be initialized.
* \param ctx The GCM context.
* \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or
* #MBEDTLS_GCM_DECRYPT.
* \param iv The initialization vector. This must be a readable buffer of
* at least \p iv_len Bytes.
* \param iv The initialization vector.
* \param iv_len The length of the IV.
* \param add The buffer holding the additional data, or \c NULL
* if \p add_len is \c 0.
* \param add_len The length of the additional data. If \c 0,
* \p add may be \c NULL.
* \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.
* \return \c 0 on success.
*/
int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
int mode,
@ -255,22 +227,16 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
* Bytes. Only the last call before calling
* mbedtls_gcm_finish() can be less than 16 Bytes.
*
* \note For decryption, the output buffer cannot be the same as
* input buffer. If the buffers overlap, the output buffer
* must trail at least 8 Bytes behind the input buffer.
* \note For decryption, the output buffer cannot be the same as input buffer.
* If the buffers overlap, the output buffer must trail at least 8 Bytes
* behind the input buffer.
*
* \param ctx The GCM context. This must be initialized.
* \param length The length of the input data. This must be a multiple of
* 16 except in the last call before mbedtls_gcm_finish().
* \param input The buffer holding the input data. If \p length is greater
* than zero, this must be a readable buffer of at least that
* size in Bytes.
* \param output The buffer for holding the output data. If \p length is
* greater than zero, this must be a writable buffer of at
* least that size in Bytes.
* \param ctx The GCM context.
* \param length The length of the input data. This must be a multiple of 16 except in the last call before mbedtls_gcm_finish().
* \param input The buffer holding the input data.
* \param output The buffer for holding the output data.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
* \return \c 0 on success, or #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
*/
int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
size_t length,
@ -284,14 +250,11 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
* It wraps up the GCM stream, and generates the
* tag. The tag can have a maximum length of 16 Bytes.
*
* \param ctx The GCM context. This must be initialized.
* \param tag The buffer for holding the tag. This must be a readable
* buffer of at least \p tag_len Bytes.
* \param tag_len The length of the tag to generate. This must be at least
* four.
* \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 #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
* \return \c 0 on success, or #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
*/
int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
unsigned char *tag,
@ -301,23 +264,29 @@ int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
* \brief This function clears a GCM context and the underlying
* cipher sub-context.
*
* \param ctx The GCM context to clear. If this is \c NULL, the call has
* no effect. Otherwise, this must be initialized.
* \param ctx The GCM context to clear.
*/
void mbedtls_gcm_free( mbedtls_gcm_context *ctx );
#if defined(MBEDTLS_SELF_TEST)
#ifdef __cplusplus
}
#endif
#else /* !MBEDTLS_GCM_ALT */
#include "gcm_alt.h"
#endif /* !MBEDTLS_GCM_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief The GCM checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
* \return \c 0 on success, or \c 1 on failure.
*/
int mbedtls_gcm_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,245 @@
/**
* \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The HAVEGE RNG was designed by Andre Seznec in 2002.
*
* http://www.irisa.fr/caps/projects/hipsor/publi.php
*
* Contact: seznec(at)irisa_dot_fr - orocheco(at)irisa_dot_fr
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_HAVEGE_C)
#include "havege.h"
#include "timing.h"
#include <string.h>
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/* ------------------------------------------------------------------------
* On average, one iteration accesses two 8-word blocks in the havege WALK
* table, and generates 16 words in the RES array.
*
* The data read in the WALK table is updated and permuted after each use.
* The result of the hardware clock counter read is used for this update.
*
* 25 conditional tests are present. The conditional tests are grouped in
* two nested groups of 12 conditional tests and 1 test that controls the
* permutation; on average, there should be 6 tests executed and 3 of them
* should be mispredicted.
* ------------------------------------------------------------------------
*/
#define SWAP(X,Y) { int *T = X; X = Y; Y = T; }
#define TST1_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
#define TST2_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
#define TST1_LEAVE U1++; }
#define TST2_LEAVE U2++; }
#define ONE_ITERATION \
\
PTEST = PT1 >> 20; \
\
TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
\
TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
\
PTX = (PT1 >> 18) & 7; \
PT1 &= 0x1FFF; \
PT2 &= 0x1FFF; \
CLK = (int) mbedtls_timing_hardclock(); \
\
i = 0; \
A = &WALK[PT1 ]; RES[i++] ^= *A; \
B = &WALK[PT2 ]; RES[i++] ^= *B; \
C = &WALK[PT1 ^ 1]; RES[i++] ^= *C; \
D = &WALK[PT2 ^ 4]; RES[i++] ^= *D; \
\
IN = (*A >> (1)) ^ (*A << (31)) ^ CLK; \
*A = (*B >> (2)) ^ (*B << (30)) ^ CLK; \
*B = IN ^ U1; \
*C = (*C >> (3)) ^ (*C << (29)) ^ CLK; \
*D = (*D >> (4)) ^ (*D << (28)) ^ CLK; \
\
A = &WALK[PT1 ^ 2]; RES[i++] ^= *A; \
B = &WALK[PT2 ^ 2]; RES[i++] ^= *B; \
C = &WALK[PT1 ^ 3]; RES[i++] ^= *C; \
D = &WALK[PT2 ^ 6]; RES[i++] ^= *D; \
\
if( PTEST & 1 ) SWAP( A, C ); \
\
IN = (*A >> (5)) ^ (*A << (27)) ^ CLK; \
*A = (*B >> (6)) ^ (*B << (26)) ^ CLK; \
*B = IN; CLK = (int) mbedtls_timing_hardclock(); \
*C = (*C >> (7)) ^ (*C << (25)) ^ CLK; \
*D = (*D >> (8)) ^ (*D << (24)) ^ CLK; \
\
A = &WALK[PT1 ^ 4]; \
B = &WALK[PT2 ^ 1]; \
\
PTEST = PT2 >> 1; \
\
PT2 = (RES[(i - 8) ^ PTY] ^ WALK[PT2 ^ PTY ^ 7]); \
PT2 = ((PT2 & 0x1FFF) & (~8)) ^ ((PT1 ^ 8) & 0x8); \
PTY = (PT2 >> 10) & 7; \
\
TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
\
TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
\
C = &WALK[PT1 ^ 5]; \
D = &WALK[PT2 ^ 5]; \
\
RES[i++] ^= *A; \
RES[i++] ^= *B; \
RES[i++] ^= *C; \
RES[i++] ^= *D; \
\
IN = (*A >> ( 9)) ^ (*A << (23)) ^ CLK; \
*A = (*B >> (10)) ^ (*B << (22)) ^ CLK; \
*B = IN ^ U2; \
*C = (*C >> (11)) ^ (*C << (21)) ^ CLK; \
*D = (*D >> (12)) ^ (*D << (20)) ^ CLK; \
\
A = &WALK[PT1 ^ 6]; RES[i++] ^= *A; \
B = &WALK[PT2 ^ 3]; RES[i++] ^= *B; \
C = &WALK[PT1 ^ 7]; RES[i++] ^= *C; \
D = &WALK[PT2 ^ 7]; RES[i++] ^= *D; \
\
IN = (*A >> (13)) ^ (*A << (19)) ^ CLK; \
*A = (*B >> (14)) ^ (*B << (18)) ^ CLK; \
*B = IN; \
*C = (*C >> (15)) ^ (*C << (17)) ^ CLK; \
*D = (*D >> (16)) ^ (*D << (16)) ^ CLK; \
\
PT1 = ( RES[( i - 8 ) ^ PTX] ^ \
WALK[PT1 ^ PTX ^ 7] ) & (~1); \
PT1 ^= (PT2 ^ 0x10) & 0x10; \
\
for( n++, i = 0; i < 16; i++ ) \
hs->pool[n % MBEDTLS_HAVEGE_COLLECT_SIZE] ^= RES[i];
/*
* Entropy gathering function
*/
static void havege_fill( mbedtls_havege_state *hs )
{
int i, n = 0;
int U1, U2, *A, *B, *C, *D;
int PT1, PT2, *WALK, RES[16];
int PTX, PTY, CLK, PTEST, IN;
WALK = hs->WALK;
PT1 = hs->PT1;
PT2 = hs->PT2;
PTX = U1 = 0;
PTY = U2 = 0;
(void)PTX;
memset( RES, 0, sizeof( RES ) );
while( n < MBEDTLS_HAVEGE_COLLECT_SIZE * 4 )
{
ONE_ITERATION
ONE_ITERATION
ONE_ITERATION
ONE_ITERATION
}
hs->PT1 = PT1;
hs->PT2 = PT2;
hs->offset[0] = 0;
hs->offset[1] = MBEDTLS_HAVEGE_COLLECT_SIZE / 2;
}
/*
* HAVEGE initialization
*/
void mbedtls_havege_init( mbedtls_havege_state *hs )
{
memset( hs, 0, sizeof( mbedtls_havege_state ) );
havege_fill( hs );
}
void mbedtls_havege_free( mbedtls_havege_state *hs )
{
if( hs == NULL )
return;
mbedtls_zeroize( hs, sizeof( mbedtls_havege_state ) );
}
/*
* HAVEGE rand function
*/
int mbedtls_havege_random( void *p_rng, unsigned char *buf, size_t len )
{
int val;
size_t use_len;
mbedtls_havege_state *hs = (mbedtls_havege_state *) p_rng;
unsigned char *p = buf;
while( len > 0 )
{
use_len = len;
if( use_len > sizeof(int) )
use_len = sizeof(int);
if( hs->offset[1] >= MBEDTLS_HAVEGE_COLLECT_SIZE )
havege_fill( hs );
val = hs->pool[hs->offset[0]++];
val ^= hs->pool[hs->offset[1]++];
memcpy( p, &val, use_len );
len -= use_len;
p += use_len;
}
return( 0 );
}
#endif /* MBEDTLS_HAVEGE_C */

View File

@ -41,7 +41,7 @@ extern "C" {
/**
* \brief HAVEGE state structure
*/
typedef struct mbedtls_havege_state
typedef struct
{
int PT1, PT2, offset[2];
int pool[MBEDTLS_HAVEGE_COLLECT_SIZE];

View File

@ -1,141 +0,0 @@
/**
* \file hkdf.h
*
* \brief This file contains the HKDF interface.
*
* The HMAC-based Extract-and-Expand Key Derivation Function (HKDF) is
* specified by RFC 5869.
*/
/*
* Copyright (C) 2016-2019, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_HKDF_H
#define MBEDTLS_HKDF_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "md.h"
/**
* \name HKDF Error codes
* \{
*/
#define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA -0x5F80 /**< Bad input parameters to function. */
/* \} name */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief This is the HMAC-based Extract-and-Expand Key Derivation Function
* (HKDF).
*
* \param md A hash function; md.size denotes the length of the hash
* function output in bytes.
* \param salt An optional salt value (a non-secret random value);
* if the salt is not provided, a string of all zeros of
* md.size length is used as the salt.
* \param salt_len The length in bytes of the optional \p salt.
* \param ikm The input keying material.
* \param ikm_len The length in bytes of \p ikm.
* \param info An optional context and application specific information
* string. This can be a zero-length string.
* \param info_len The length of \p info in bytes.
* \param okm The output keying material of \p okm_len bytes.
* \param okm_len The length of the output keying material in bytes. This
* must be less than or equal to 255 * md.size bytes.
*
* \return 0 on success.
* \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
* \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
* MD layer.
*/
int mbedtls_hkdf( mbedtls_md_handle_t md, const unsigned char *salt,
size_t salt_len, const unsigned char *ikm, size_t ikm_len,
const unsigned char *info, size_t info_len,
unsigned char *okm, size_t okm_len );
/**
* \brief Take the input keying material \p ikm and extract from it a
* fixed-length pseudorandom key \p prk.
*
* \warning This function should only be used if the security of it has been
* studied and established in that particular context (eg. TLS 1.3
* key schedule). For standard HKDF security guarantees use
* \c mbedtls_hkdf instead.
*
* \param md A hash function; md.size denotes the length of the
* hash function output in bytes.
* \param salt An optional salt value (a non-secret random value);
* if the salt is not provided, a string of all zeros
* of md.size length is used as the salt.
* \param salt_len The length in bytes of the optional \p salt.
* \param ikm The input keying material.
* \param ikm_len The length in bytes of \p ikm.
* \param[out] prk A pseudorandom key of at least md.size bytes.
*
* \return 0 on success.
* \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
* \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
* MD layer.
*/
int mbedtls_hkdf_extract( mbedtls_md_handle_t md,
const unsigned char *salt, size_t salt_len,
const unsigned char *ikm, size_t ikm_len,
unsigned char *prk );
/**
* \brief Expand the supplied \p prk into several additional pseudorandom
* keys, which is the output of the HKDF.
*
* \warning This function should only be used if the security of it has been
* studied and established in that particular context (eg. TLS 1.3
* key schedule). For standard HKDF security guarantees use
* \c mbedtls_hkdf instead.
*
* \param md A hash function; md.size denotes the length of the hash
* function output in bytes.
* \param prk A pseudorandom key of at least md.size bytes. \p prk is
* usually the output from the HKDF extract step.
* \param prk_len The length in bytes of \p prk.
* \param info An optional context and application specific information
* string. This can be a zero-length string.
* \param info_len The length of \p info in bytes.
* \param okm The output keying material of \p okm_len bytes.
* \param okm_len The length of the output keying material in bytes. This
* must be less than or equal to 255 * md.size bytes.
*
* \return 0 on success.
* \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
* \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
* MD layer.
*/
int mbedtls_hkdf_expand( mbedtls_md_handle_t md, const unsigned char *prk,
size_t prk_len, const unsigned char *info,
size_t info_len, unsigned char *okm, size_t okm_len );
#ifdef __cplusplus
}
#endif
#endif /* hkdf.h */

View File

@ -0,0 +1,581 @@
/*
* HMAC_DRBG implementation (NIST SP 800-90)
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The NIST SP 800-90A DRBGs are described in the following publication.
* http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
* References below are based on rev. 1 (January 2012).
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_HMAC_DRBG_C)
#include "hmac_drbg.h"
#include <string.h>
#if defined(MBEDTLS_FS_IO)
#include <stdio.h>
#endif
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_PLATFORM_C */
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/*
* HMAC_DRBG context initialization
*/
void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &ctx->mutex );
#endif
}
/*
* HMAC_DRBG update, using optional additional data (10.1.2.2)
*/
int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
const unsigned char *additional,
size_t add_len )
{
size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
unsigned char sep[1];
unsigned char K[MBEDTLS_MD_MAX_SIZE];
int ret;
for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
{
/* Step 1 or 4 */
if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
ctx->V, md_len ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
sep, 1 ) ) != 0 )
goto exit;
if( rounds == 2 )
{
if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
additional, add_len ) ) != 0 )
goto exit;
}
if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
goto exit;
/* Step 2 or 5 */
if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
ctx->V, md_len ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
goto exit;
}
exit:
mbedtls_zeroize( K, sizeof( K ) );
return( ret );
}
void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
const unsigned char *additional,
size_t add_len )
{
(void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
}
/*
* Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
*/
int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
const mbedtls_md_info_t * md_info,
const unsigned char *data, size_t data_len )
{
int ret;
if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
return( ret );
/*
* Set initial working state.
* Use the V memory location, which is currently all 0, to initialize the
* MD context with an all-zero key. Then set V to its initial value.
*/
if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
mbedtls_md_get_size( md_info ) ) ) != 0 )
return( ret );
memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
return( ret );
return( 0 );
}
/*
* HMAC_DRBG reseeding: 10.1.2.4 (arabic) + 9.2 (Roman)
*/
int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
const unsigned char *additional, size_t len )
{
unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
size_t seedlen;
int ret;
/* III. Check input length */
if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
ctx->entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
{
return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
}
memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
/* IV. Gather entropy_len bytes of entropy for the seed */
if( ( ret = ctx->f_entropy( ctx->p_entropy,
seed, ctx->entropy_len ) ) != 0 )
return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
seedlen = ctx->entropy_len;
/* 1. Concatenate entropy and additional data if any */
if( additional != NULL && len != 0 )
{
memcpy( seed + seedlen, additional, len );
seedlen += len;
}
/* 2. Update state */
if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
goto exit;
/* 3. Reset reseed_counter */
ctx->reseed_counter = 1;
exit:
/* 4. Done */
mbedtls_zeroize( seed, seedlen );
return( ret );
}
/*
* HMAC_DRBG initialisation (10.1.2.3 + 9.1)
*/
int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
const mbedtls_md_info_t * md_info,
int (*f_entropy)(void *, unsigned char *, size_t),
void *p_entropy,
const unsigned char *custom,
size_t len )
{
int ret;
size_t entropy_len, md_size;
if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
return( ret );
md_size = mbedtls_md_get_size( md_info );
/*
* Set initial working state.
* Use the V memory location, which is currently all 0, to initialize the
* MD context with an all-zero key. Then set V to its initial value.
*/
if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
return( ret );
memset( ctx->V, 0x01, md_size );
ctx->f_entropy = f_entropy;
ctx->p_entropy = p_entropy;
ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
/*
* See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
* each hash function, then according to SP800-90A rev1 10.1 table 2,
* min_entropy_len (in bits) is security_strength.
*
* (This also matches the sizes used in the NIST test vectors.)
*/
entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
32; /* better (256+) -> 256 bits */
/*
* For initialisation, use more entropy to emulate a nonce
* (Again, matches test vectors.)
*/
ctx->entropy_len = entropy_len * 3 / 2;
if( ( ret = mbedtls_hmac_drbg_reseed( ctx, custom, len ) ) != 0 )
return( ret );
ctx->entropy_len = entropy_len;
return( 0 );
}
/*
* Set prediction resistance
*/
void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
int resistance )
{
ctx->prediction_resistance = resistance;
}
/*
* Set entropy length grabbed for reseeds
*/
void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
{
ctx->entropy_len = len;
}
/*
* Set reseed interval
*/
void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
{
ctx->reseed_interval = interval;
}
/*
* HMAC_DRBG random function with optional additional data:
* 10.1.2.5 (arabic) + 9.3 (Roman)
*/
int mbedtls_hmac_drbg_random_with_add( void *p_rng,
unsigned char *output, size_t out_len,
const unsigned char *additional, size_t add_len )
{
int ret;
mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
size_t left = out_len;
unsigned char *out = output;
/* II. Check request length */
if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
/* III. Check input length */
if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
/* 1. (aka VII and IX) Check reseed counter and PR */
if( ctx->f_entropy != NULL && /* For no-reseeding instances */
( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
ctx->reseed_counter > ctx->reseed_interval ) )
{
if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
return( ret );
add_len = 0; /* VII.4 */
}
/* 2. Use additional data if any */
if( additional != NULL && add_len != 0 )
{
if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
additional, add_len ) ) != 0 )
goto exit;
}
/* 3, 4, 5. Generate bytes */
while( left != 0 )
{
size_t use_len = left > md_len ? md_len : left;
if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
ctx->V, md_len ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
goto exit;
memcpy( out, ctx->V, use_len );
out += use_len;
left -= use_len;
}
/* 6. Update */
if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
additional, add_len ) ) != 0 )
goto exit;
/* 7. Update reseed counter */
ctx->reseed_counter++;
exit:
/* 8. Done */
return( ret );
}
/*
* HMAC_DRBG random function
*/
int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
{
int ret;
mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
return( ret );
#endif
ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif
return( ret );
}
/*
* Free an HMAC_DRBG context
*/
void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
{
if( ctx == NULL )
return;
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_free( &ctx->mutex );
#endif
mbedtls_md_free( &ctx->md_ctx );
mbedtls_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
}
#if defined(MBEDTLS_FS_IO)
int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
{
int ret;
FILE *f;
unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
if( ( f = fopen( path, "wb" ) ) == NULL )
return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
goto exit;
if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
{
ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
goto exit;
}
ret = 0;
exit:
fclose( f );
mbedtls_zeroize( buf, sizeof( buf ) );
return( ret );
}
int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
{
int ret = 0;
FILE *f;
size_t n;
unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
if( ( f = fopen( path, "rb" ) ) == NULL )
return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
fseek( f, 0, SEEK_END );
n = (size_t) ftell( f );
fseek( f, 0, SEEK_SET );
if( n > MBEDTLS_HMAC_DRBG_MAX_INPUT )
{
fclose( f );
return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
}
if( fread( buf, 1, n, f ) != n )
ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
else
ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
fclose( f );
mbedtls_zeroize( buf, sizeof( buf ) );
if( ret != 0 )
return( ret );
return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
}
#endif /* MBEDTLS_FS_IO */
#if defined(MBEDTLS_SELF_TEST)
#if !defined(MBEDTLS_SHA1_C)
/* Dummy checkup routine */
int mbedtls_hmac_drbg_self_test( int verbose )
{
(void) verbose;
return( 0 );
}
#else
#define OUTPUT_LEN 80
/* From a NIST PR=true test vector */
static const unsigned char entropy_pr[] = {
0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
static const unsigned char result_pr[OUTPUT_LEN] = {
0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
/* From a NIST PR=false test vector */
static const unsigned char entropy_nopr[] = {
0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
0xe9, 0x9d, 0xfe, 0xdf };
static const unsigned char result_nopr[OUTPUT_LEN] = {
0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
/* "Entropy" from buffer */
static size_t test_offset;
static int hmac_drbg_self_test_entropy( void *data,
unsigned char *buf, size_t len )
{
const unsigned char *p = data;
memcpy( buf, p + test_offset, len );
test_offset += len;
return( 0 );
}
#define CHK( c ) if( (c) != 0 ) \
{ \
if( verbose != 0 ) \
mbedtls_printf( "failed\n" ); \
return( 1 ); \
}
/*
* Checkup routine for HMAC_DRBG with SHA-1
*/
int mbedtls_hmac_drbg_self_test( int verbose )
{
mbedtls_hmac_drbg_context ctx;
unsigned char buf[OUTPUT_LEN];
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
mbedtls_hmac_drbg_init( &ctx );
/*
* PR = True
*/
if( verbose != 0 )
mbedtls_printf( " HMAC_DRBG (PR = True) : " );
test_offset = 0;
CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
hmac_drbg_self_test_entropy, (void *) entropy_pr,
NULL, 0 ) );
mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
mbedtls_hmac_drbg_free( &ctx );
mbedtls_hmac_drbg_free( &ctx );
if( verbose != 0 )
mbedtls_printf( "passed\n" );
/*
* PR = False
*/
if( verbose != 0 )
mbedtls_printf( " HMAC_DRBG (PR = False) : " );
mbedtls_hmac_drbg_init( &ctx );
test_offset = 0;
CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
hmac_drbg_self_test_entropy, (void *) entropy_nopr,
NULL, 0 ) );
CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
mbedtls_hmac_drbg_free( &ctx );
mbedtls_hmac_drbg_free( &ctx );
if( verbose != 0 )
mbedtls_printf( "passed\n" );
if( verbose != 0 )
mbedtls_printf( "\n" );
return( 0 );
}
#endif /* MBEDTLS_SHA1_C */
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_HMAC_DRBG_C */

View File

@ -1,14 +1,10 @@
/**
* \file hmac_drbg.h
*
* \brief The HMAC_DRBG pseudorandom generator.
*
* This module implements the HMAC_DRBG pseudorandom generator described
* in <em>NIST SP 800-90A: Recommendation for Random Number Generation Using
* Deterministic Random Bit Generators</em>.
* \brief HMAC_DRBG (NIST SP 800-90A)
*/
/*
* Copyright (C) 2006-2019, ARM Limited, All Rights Reserved
* 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
@ -74,11 +70,8 @@
/* \} name SECTION: Module settings */
#define MBEDTLS_HMAC_DRBG_PR_OFF 0x55555555 /**< No prediction resistance */
#define MBEDTLS_HMAC_DRBG_PR_ON 0x2AAAAAAA /**< Prediction resistance enabled */
#define MBEDTLS_HMAC_DRBG_RESEED 0x78547854 /**< Default environment, reseeding enabled */
#define MBEDTLS_HMAC_DRBG_NO_RESEED 0x07AB87F0 /**< Reseeding disabled, no f_entropy required */
#define MBEDTLS_HMAC_DRBG_PR_OFF 0 /**< No prediction resistance */
#define MBEDTLS_HMAC_DRBG_PR_ON 1 /**< Prediction resistance enabled */
#ifdef __cplusplus
extern "C" {
@ -87,14 +80,14 @@ extern "C" {
/**
* HMAC_DRBG context.
*/
typedef struct mbedtls_hmac_drbg_context
typedef struct
{
/* Working state: the key K is not stored explicitly,
/* Working state: the key K is not stored explicitely,
* but is implied by the HMAC context */
mbedtls_md_context_t md_ctx; /*!< HMAC context (inc. K) */
unsigned char V[MBEDTLS_MD_MAX_SIZE]; /*!< V in the spec */
int reseed_counter; /*!< reseed counter */
int reseed_flag; /*!< disables reseeding if set to MBEDTLS_HMAC_DRBG_NO_RESEED */
/* Administrative state */
size_t entropy_len; /*!< entropy bytes grabbed on each (re)seed */
int prediction_resistance; /*!< enable prediction resistance (Automatic
@ -111,75 +104,41 @@ typedef struct mbedtls_hmac_drbg_context
} mbedtls_hmac_drbg_context;
/**
* \brief HMAC_DRBG context initialization.
* \brief HMAC_DRBG context initialization
* Makes the context ready for mbedtls_hmac_drbg_seed(),
* mbedtls_hmac_drbg_seed_buf() or
* mbedtls_hmac_drbg_free().
*
* This function makes the context ready for mbedtls_hmac_drbg_seed(),
* mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free().
*
* \param ctx HMAC_DRBG context to be initialized.
* \param ctx HMAC_DRBG context to be initialized
*/
void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx );
/**
* \brief HMAC_DRBG initial seeding.
* \brief HMAC_DRBG initial seeding
* Seed and setup entropy source for future reseeds.
*
* Set the initial seed and set up the 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
*
* A typical choice for the \p f_entropy and \p p_entropy parameters is
* to use the entropy module:
* - \p f_entropy is mbedtls_entropy_func();
* - \p p_entropy is an instance of ::mbedtls_entropy_context initialized
* with mbedtls_entropy_init() (which registers the platform's default
* entropy sources).
*
* You can provide a personalization string in addition to the
* entropy source, to make this instantiation as unique as possible.
*
* \note By default, the security strength as defined by NIST is:
* - 128 bits if \p md_info is SHA-1;
* - 192 bits if \p md_info is SHA-224;
* - 256 bits if \p md_info is SHA-256, SHA-384 or SHA-512.
* \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.
* The security strength can be reduced if a smaller
* entropy length is set with
* mbedtls_hmac_drbg_set_entropy_len().
*
* \note The default entropy length is the security strength
* (converted from bits to bytes). You can override
* it by calling mbedtls_hmac_drbg_set_entropy_len().
*
* \note During the initial seeding, this function calls
* the entropy source to obtain a nonce
* whose length is half the entropy length.
*
* \param ctx HMAC_DRBG context to be seeded.
* \param md_info MD algorithm to use for HMAC_DRBG.
* \param f_entropy The entropy callback, taking as arguments the
* \p p_entropy context, the buffer to fill, and the
* length of the buffer.
* \p f_entropy is always called with a length that is
* less than or equal to the entropy length.
* \param p_entropy The entropy context to pass to \p f_entropy.
* \param custom The personalization string.
* This can be \c NULL, in which case the personalization
* string is empty regardless of the value of \p len.
* \param len The length of the personalization string.
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT
* and also at most
* #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len * 3 / 2
* where \p entropy_len is the entropy length
* described above.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is
* invalid.
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough
* memory to allocate context data.
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
* if the call to \p f_entropy failed.
* \return 0 if successful, or
* MBEDTLS_ERR_MD_BAD_INPUT_DATA, or
* MBEDTLS_ERR_MD_ALLOC_FAILED, or
* MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED.
*/
int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
mbedtls_md_handle_t md_info,
const mbedtls_md_info_t * md_info,
int (*f_entropy)(void *, unsigned char *, size_t),
void *p_entropy,
const unsigned char *custom,
@ -187,150 +146,115 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
/**
* \brief Initilisation of simpified HMAC_DRBG (never reseeds).
* (For use with deterministic ECDSA.)
*
* This function is meant for use in algorithms that need a pseudorandom
* input such as 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
*
* \param ctx HMAC_DRBG context to be initialised.
* \param md_info MD algorithm to use for HMAC_DRBG.
* \param data Concatenation of the initial entropy string and
* the additional data.
* \param data_len Length of \p data in bytes.
*
* \return \c 0 if successful. or
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is
* invalid.
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough
* memory to allocate context data.
* \return 0 if successful, or
* MBEDTLS_ERR_MD_BAD_INPUT_DATA, or
* MBEDTLS_ERR_MD_ALLOC_FAILED.
*/
int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
mbedtls_md_handle_t md_info,
const mbedtls_md_info_t * md_info,
const unsigned char *data, size_t data_len );
/**
* \brief This function turns prediction resistance on or off.
* The default value is off.
* \brief Enable / disable prediction resistance (Default: Off)
*
* \note If enabled, entropy is gathered at the beginning of
* every call to mbedtls_hmac_drbg_random_with_add()
* or mbedtls_hmac_drbg_random().
* Only use this if your entropy source has sufficient
* throughput.
* 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 The HMAC_DRBG context.
* \param resistance #MBEDTLS_HMAC_DRBG_PR_ON or #MBEDTLS_HMAC_DRBG_PR_OFF.
* \param ctx HMAC_DRBG context
* \param resistance MBEDTLS_HMAC_DRBG_PR_ON or MBEDTLS_HMAC_DRBG_PR_OFF
*/
void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
int resistance );
/**
* \brief This function turns reseeding on or off.
* Default value is on.
* \brief Set the amount of entropy grabbed on each reseed
* (Default: given by the security strength, which
* depends on the hash used, see \c mbedtls_hmac_drbg_init() )
*
* \note If set to MBEDTLS_HMAC_DRBG_NO_RESEED, this function
* disables reseeding, providing a no_reseed environment.
* f_entropy can then be null.
*
* \param ctx The HMAC_DRBG context.
* \param reseed_flag #MBEDTLS_HMAC_DRBG_NO_RESEED or #MBEDTLS_HMAC_DRBG_RESEED
* \param ctx HMAC_DRBG context
* \param len Amount of entropy to grab, in bytes
*/
void mbedtls_hmac_drbg_set_reseeding( mbedtls_hmac_drbg_context *ctx,
int reseed_flag );
void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx,
size_t len );
/**
* \brief This function sets the amount of entropy grabbed on each
* seed or reseed.
* \brief Set the reseed interval
* (Default: MBEDTLS_HMAC_DRBG_RESEED_INTERVAL)
*
* See the documentation of mbedtls_hmac_drbg_seed() for the default value.
*
* \param ctx The HMAC_DRBG context.
* \param len The amount of entropy to grab, in bytes.
*
* \return \c 0 if \p len is valid, MBEDTLS_HMAC_DRBG_MAX_INPUT otherwise.
*/
int mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx,
size_t len );
/**
* \brief Set the reseed interval.
*
* The reseed interval is the number of calls to mbedtls_hmac_drbg_random()
* or mbedtls_hmac_drbg_random_with_add() after which the entropy function
* is called again.
*
* The default value is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL.
*
* \param ctx The HMAC_DRBG context.
* \param interval The reseed interval.
* \param ctx HMAC_DRBG context
* \param interval Reseed interval
*/
void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx,
int interval );
/**
* \brief This function updates the state of the HMAC_DRBG context.
* \brief HMAC_DRBG update state
*
* \param ctx The HMAC_DRBG context.
* \param additional The data to update the state with.
* If this is \c NULL, there is no additional data.
* \param add_len Length of \p additional in bytes.
* Unused if \p additional is \c NULL.
* \param ctx HMAC_DRBG context
* \param additional Additional data to update state with, or NULL
* \param add_len Length of additional data, or 0
*
* \return \c 0 on success, or an error from the underlying
* hash calculation or
* MBEDTLS_ERR_PLATFORM_FAULT_DETECTED.
* hash calculation.
*
* \note Additional data is optional, pass NULL and 0 as second
* third argument if no additional data is being used.
*/
int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
const unsigned char *additional, size_t add_len );
/**
* \brief This function reseeds the HMAC_DRBG context, that is
* extracts data from the entropy source.
* \brief HMAC_DRBG update state
*
* \param ctx The HMAC_DRBG context.
* \param additional Additional data to add to the state.
* If this is \c NULL, there is no additional data
* and \p len should be \c 0.
* \param len The length of the additional data.
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT
* and also at most
* #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len
* where \p entropy_len is the entropy length
* (see mbedtls_hmac_drbg_set_entropy_len()).
* \warning This function cannot report errors. You should use
* mbedtls_hmac_drbg_update_ret() instead.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
* if a call to the entropy function failed.
* \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 mbedtls_hmac_drbg_update( mbedtls_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
* MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
*/
int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
const unsigned char *additional, size_t len );
/**
* \brief This function updates an HMAC_DRBG instance with additional
* data and uses it to generate random data.
* \brief HMAC_DRBG generate random with additional update input
*
* This function automatically reseeds if the reseed counter is exceeded
* or prediction resistance is enabled.
* Note: Automatically reseeds if reseed_counter is reached or PR is enabled.
*
* \param p_rng The HMAC_DRBG context. This must be a pointer to a
* #mbedtls_hmac_drbg_context structure.
* \param output The buffer to fill.
* \param output_len The length of the buffer in bytes.
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
* \param additional Additional data to update with.
* If this is \c NULL, there is no additional data
* and \p add_len should be \c 0.
* \param add_len The length of the additional data.
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT.
* \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 \c 0 if successful.
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
* if a call to the entropy source failed.
* \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if
* \p output_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
* \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if
* \p add_len > #MBEDTLS_HMAC_DRBG_MAX_INPUT.
* \return #MBEDTLS_ERR_PLATFORM_FAULT_DETECTED if
* a logical fault is detected.
* \return 0 if successful, or
* MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or
* MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG, or
* MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG.
*/
int mbedtls_hmac_drbg_random_with_add( void *p_rng,
unsigned char *output, size_t output_len,
@ -338,85 +262,49 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
size_t add_len );
/**
* \brief This function uses HMAC_DRBG to generate random data.
* \brief HMAC_DRBG generate random
*
* This function automatically reseeds if the reseed counter is exceeded
* or prediction resistance is enabled.
* Note: Automatically reseeds if reseed_counter is reached or PR is enabled.
*
* \param p_rng The HMAC_DRBG context. This must be a pointer to a
* #mbedtls_hmac_drbg_context structure.
* \param output The buffer to fill.
* \param out_len The length of the buffer in bytes.
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
* \param p_rng HMAC_DRBG context
* \param output Buffer to fill
* \param out_len Length of the buffer
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
* if a call to the entropy source failed.
* \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if
* \p out_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
* \return #MBEDTLS_ERR_PLATFORM_FAULT_DETECTED if
* a logical fault is detected.
* \return 0 if successful, or
* MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or
* MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG
*/
int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len );
/**
* \brief Free an HMAC_DRBG context
*
* \param ctx The HMAC_DRBG context to free.
* \param ctx HMAC_DRBG context to free.
*/
void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx );
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief This function updates the state of the HMAC_DRBG context.
*
* \deprecated Superseded by mbedtls_hmac_drbg_update_ret()
* in 2.16.0.
*
* \param ctx The HMAC_DRBG context.
* \param additional The data to update the state with.
* If this is \c NULL, there is no additional data.
* \param add_len Length of \p additional in bytes.
* Unused if \p additional is \c NULL.
*/
MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update(
mbedtls_hmac_drbg_context *ctx,
const unsigned char *additional, size_t add_len );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_FS_IO)
/**
* \brief This function writes a seed file.
* \brief Write a seed file
*
* \param ctx The HMAC_DRBG context.
* \param path The name of the file.
* \param ctx HMAC_DRBG context
* \param path Name of the file
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error.
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on reseed
* failure.
* \return 0 if successful, 1 on file error, or
* MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
*/
int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path );
/**
* \brief This function reads and updates a seed file. The seed
* is added to this instance.
* \brief Read and update a seed file. Seed is added to this
* instance
*
* \param ctx The HMAC_DRBG context.
* \param path The name of the file.
* \param ctx HMAC_DRBG context
* \param path Name of the file
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error.
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on
* reseed failure.
* \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if the existing
* seed file is too large.
* \return 0 if successful, 1 on file error,
* MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED or
* MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG
*/
int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path );
#endif /* MBEDTLS_FS_IO */
@ -424,10 +312,9 @@ int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const ch
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief The HMAC_DRBG Checkup routine.
* \brief Checkup routine
*
* \return \c 0 if successful.
* \return \c 1 if the test failed.
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_hmac_drbg_self_test( int verbose );
#endif

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEoQIBAAKCAQBrQixost2wJXnBQBB9lV0gg4KLrM+ilC/VF7oKXVuth66ReeYH
qDzkjvi2+sexoRyPm0Tz7lB2YGSzD+hF8IKKM4BlqPacExlZt+yQLpzDUJA5+etu
gb/9yuYOig4UujIDElIeu101vCNlMSEN6iKIaNgknNmO2Wrkr3vsDUy/RzOxcwly
jN4lm3vvkZz9PmO466+S6rx/RUYPs1gx+Uos4TT3wSxbkH8u61Hq4VMhCaFZwRgQ
Qoa3M0yrnyguJa2iqqZIRk1A7VULrH0975+9IXgcBImTdT5sXgLgkoSzzC0C5HX/
dryiSElWNukLUfxnC2dMoyrb5qI6CWYz3/NPAgMBAAECggEAEL9XYc2z8cIYPcV8
Da/Zx67hHmAQV6ldwp8ezGmBXBoYdtyav01UnLd6PE/yCFlItV+gJ5ppc+JfNtpg
ATOpnlymSrlUMFCHH8wpIuY0UgbtTjAow6t8x+r7ev+xbSkZkAM3UVceGbrTqARA
zgRl+fis7yKSkcx+9VA1QElfV2pZ3fp1LzLmY36M+kzZaou5us+qoJOb6JIZ+jHY
sqhIErWKKbltAFLnmBQaLkeig7PyzHtO2Hoqt7yz2SOEkji2S/Qfk8jPxglQtXtw
tf56UcvsnzI/78lKo80dK1fHtrqDNfjLtAbw2RttsJ8HH6hxIccBJQjKVhp+UsuE
LBH8OQKBgQCwVx3nTj3AKwaU1xc+Y/E5TCcerMX1pZeIhmL4NH/q+QtuxBN85lw+
hE0mQjw2L55jteYWX8/0L9/lVceevp4TtaGQ3vfASB6+VBUMVIvSefrmFsvwzgC2
QTAvQvv+rJUuJF7rvhvExWK2qfA3pb4rYuPT/KP46edtD0tlgiMJiwKBgQCbthZP
tOF6O2cI2PBbdjlR/Q57BykK5G+PJbNFLyiZMT4y5QKM3Y2EA0+ip9LzFLtCCEV/
B8HFinep71ANLqc8JSnRV5XCqZNax//B7mN3/0XubjiX63m5jNOw1JOrkO2lnwDI
TVjx6FkBxcz3U9N9gO+9PXxfFCytl5IS0SfNzQKBgB+ySQm+opLcKP6v+tmYFU/7
RDzbSWnyLd64aSm8JhISWd+7FtWogoQqO8PYvAHxZUL++zCiYDrAMDqExLDgCoH4
b+YebeH+FKiZbH8e41Md4d9h0Z6jKLWZ2hNksu8ADoCQwQ8WyN8Bq9CxkyAthpU9
3T3Jd5/SS2rrCN5iGfIpAoGALEQUja5HV19hyDMcCXRPkU5WeoUrlswgJtq53xYr
/XjxTLisA+3MGFZ0ojIBl1cycPA3CYjj/kuB/05oPIchxchu3fN/QKrCmFE5FSG3
J1rrv3+YGSA5J5WwbJnSLTjzRl0wdMEAYy0BeK6JuVocSpaIEQ1UuRbcKLFpNm49
WZUCgYAJTRgepWC9id5guhKjccnUTpcOgaiV7RbNS9Ba2/4LPhRCaxsmy43L8IwV
NFinvdsjheeD/uk684dva7LE7BefpMtMHkIIZVIyKX8yO0KtooAkbwOWUsDhuIE1
H5cyam3QiPJPIUe1+3qI+YafSJEqL3qo5nVJrPAU48wpYW04Ag==
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBITANBgkqhkiG9w0BAQEFAAOCAQ4AMIIBCQKCAQBrQixost2wJXnBQBB9lV0g
g4KLrM+ilC/VF7oKXVuth66ReeYHqDzkjvi2+sexoRyPm0Tz7lB2YGSzD+hF8IKK
M4BlqPacExlZt+yQLpzDUJA5+etugb/9yuYOig4UujIDElIeu101vCNlMSEN6iKI
aNgknNmO2Wrkr3vsDUy/RzOxcwlyjN4lm3vvkZz9PmO466+S6rx/RUYPs1gx+Uos
4TT3wSxbkH8u61Hq4VMhCaFZwRgQQoa3M0yrnyguJa2iqqZIRk1A7VULrH0975+9
IXgcBImTdT5sXgLgkoSzzC0C5HX/dryiSElWNukLUfxnC2dMoyrb5qI6CWYz3/NP
AgMBAAE=
-----END PUBLIC KEY-----

View File

@ -32,8 +32,7 @@
#if defined(MBEDTLS_MD_C)
#include "md.h"
#include "platform.h"
#include "platform_util.h"
#include "md_internal.h"
#if defined(MBEDTLS_PLATFORM_C)
#include "platform.h"
@ -49,176 +48,10 @@
#include <stdio.h>
#endif
#if !defined(MBEDTLS_MD_SINGLE_HASH)
/*
*
* Definitions of MD information structures for various digests.
*
*/
/*
* MD-2
*/
#if defined(MBEDTLS_MD2_C)
static const mbedtls_md_info_t mbedtls_md2_info = {
MBEDTLS_MD_MD2,
"MD2",
16,
16,
mbedtls_md2_starts_wrap,
mbedtls_md2_update_wrap,
mbedtls_md2_finish_wrap,
mbedtls_md2_ret,
mbedtls_md2_ctx_alloc,
mbedtls_md2_ctx_free,
mbedtls_md2_clone_wrap,
mbedtls_md2_process_wrap,
};
#endif /* MBEDTLS_MD2_C */
/*
* MD-4
*/
#if defined(MBEDTLS_MD4_C)
static const mbedtls_md_info_t mbedtls_md4_info = {
MBEDTLS_MD_MD4,
"MD4",
16,
64,
mbedtls_md4_starts_wrap,
mbedtls_md4_update_wrap,
mbedtls_md4_finish_wrap,
mbedtls_md4_ret,
mbedtls_md4_ctx_alloc,
mbedtls_md4_ctx_free,
mbedtls_md4_clone_wrap,
mbedtls_md4_process_wrap,
};
#endif /* MBEDTLS_MD4_C */
/*
* MD-5
*/
#if defined(MBEDTLS_MD5_C)
static const mbedtls_md_info_t mbedtls_md5_info = {
MBEDTLS_MD_MD5,
"MD5",
16,
64,
mbedtls_md5_starts_wrap,
mbedtls_md5_update_wrap,
mbedtls_md5_finish_wrap,
mbedtls_md5_ret,
mbedtls_md5_ctx_alloc,
mbedtls_md5_ctx_free,
mbedtls_md5_clone_wrap,
mbedtls_md5_process_wrap,
};
#endif /* MBEDTLS_MD5_C */
/*
* RIPEMD-160
*/
#if defined(MBEDTLS_RIPEMD160_C)
static const mbedtls_md_info_t mbedtls_ripemd160_info = {
MBEDTLS_MD_RIPEMD160,
"RIPEMD160",
20,
64,
mbedtls_ripemd160_starts_wrap,
mbedtls_ripemd160_update_wrap,
mbedtls_ripemd160_finish_wrap,
mbedtls_ripemd160_ret,
mbedtls_ripemd160_ctx_alloc,
mbedtls_ripemd160_ctx_free,
mbedtls_ripemd160_clone_wrap,
mbedtls_ripemd160_process_wrap,
};
#endif /* MBEDTLS_RIPEMD160_C */
/*
* SHA-1
*/
#if defined(MBEDTLS_SHA1_C)
static const mbedtls_md_info_t mbedtls_sha1_info = {
MBEDTLS_MD_SHA1,
"SHA1",
20,
64,
mbedtls_sha1_starts_wrap,
mbedtls_sha1_update_wrap,
mbedtls_sha1_finish_wrap,
mbedtls_sha1_ret,
mbedtls_sha1_ctx_alloc,
mbedtls_sha1_ctx_free,
mbedtls_sha1_clone_wrap,
mbedtls_sha1_process_wrap,
};
#endif /* MBEDTLS_SHA1_C */
/*
* SHA-224 and SHA-256
*/
#if defined(MBEDTLS_SHA256_C)
#if !defined(MBEDTLS_SHA256_NO_SHA224)
static const mbedtls_md_info_t mbedtls_sha224_info = {
MBEDTLS_MD_SHA224,
"SHA224",
28,
64,
mbedtls_sha224_starts_wrap,
mbedtls_sha224_update_wrap,
mbedtls_sha224_finish_wrap,
mbedtls_sha224_wrap,
mbedtls_sha224_ctx_alloc,
mbedtls_sha224_ctx_free,
mbedtls_sha224_clone_wrap,
mbedtls_sha224_process_wrap,
};
#endif /* !MBEDTLS_SHA256_NO_SHA224 */
static const mbedtls_md_info_t mbedtls_sha256_info =
MBEDTLS_MD_INFO( MBEDTLS_MD_INFO_SHA256 );
#endif /* MBEDTLS_SHA256_C */
/*
* SHA-384 and SHA-512
*/
#if defined(MBEDTLS_SHA512_C)
static const mbedtls_md_info_t mbedtls_sha384_info = {
MBEDTLS_MD_SHA384,
"SHA384",
48,
128,
mbedtls_sha384_starts_wrap,
mbedtls_sha384_update_wrap,
mbedtls_sha384_finish_wrap,
mbedtls_sha384_wrap,
mbedtls_sha384_ctx_alloc,
mbedtls_sha384_ctx_free,
mbedtls_sha384_clone_wrap,
mbedtls_sha384_process_wrap,
};
static const mbedtls_md_info_t mbedtls_sha512_info = {
MBEDTLS_MD_SHA512,
"SHA512",
64,
128,
mbedtls_sha512_starts_wrap,
mbedtls_sha384_update_wrap,
mbedtls_sha384_finish_wrap,
mbedtls_sha512_wrap,
mbedtls_sha384_ctx_alloc,
mbedtls_sha384_ctx_free,
mbedtls_sha384_clone_wrap,
mbedtls_sha384_process_wrap,
};
#endif /* MBEDTLS_SHA512_C */
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/*
* Reminder: update profiles in x509_crt.c when adding a new hash!
@ -232,10 +65,8 @@ static const int supported_digests[] = {
#if defined(MBEDTLS_SHA256_C)
MBEDTLS_MD_SHA256,
#if !defined(MBEDTLS_SHA256_NO_SHA224)
MBEDTLS_MD_SHA224,
#endif
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA1_C)
MBEDTLS_MD_SHA1,
@ -265,7 +96,7 @@ const int *mbedtls_md_list( void )
return( supported_digests );
}
mbedtls_md_handle_t mbedtls_md_info_from_string( const char *md_name )
const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name )
{
if( NULL == md_name )
return( NULL );
@ -292,13 +123,11 @@ mbedtls_md_handle_t mbedtls_md_info_from_string( const char *md_name )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
#endif
#if defined(MBEDTLS_SHA256_C)
#if !defined(MBEDTLS_SHA256_NO_SHA224)
if( !strcmp( "SHA224", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 );
#endif
if( !strcmp( "SHA256", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
#endif /* MBEDTLS_SHA256_C */
#endif
#if defined(MBEDTLS_SHA512_C)
if( !strcmp( "SHA384", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 );
@ -308,7 +137,7 @@ mbedtls_md_handle_t mbedtls_md_info_from_string( const char *md_name )
return( NULL );
}
mbedtls_md_handle_t mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
{
switch( md_type )
{
@ -333,13 +162,11 @@ mbedtls_md_handle_t mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
return( &mbedtls_sha1_info );
#endif
#if defined(MBEDTLS_SHA256_C)
#if !defined(MBEDTLS_SHA256_NO_SHA224)
case MBEDTLS_MD_SHA224:
return( &mbedtls_sha224_info );
#endif
case MBEDTLS_MD_SHA256:
return( &mbedtls_sha256_info );
#endif /* MBEDTLS_SHA256_C */
#endif
#if defined(MBEDTLS_SHA512_C)
case MBEDTLS_MD_SHA384:
return( &mbedtls_sha384_info );
@ -351,127 +178,108 @@ mbedtls_md_handle_t mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
}
}
#else /* MBEDTLS_MD_SINGLE_HASH */
const int *mbedtls_md_list( void )
{
static int single_hash[2] =
{ MBEDTLS_MD_INFO_TYPE( MBEDTLS_MD_SINGLE_HASH ),
MBEDTLS_MD_INVALID_HANDLE };
return( single_hash );
}
mbedtls_md_handle_t mbedtls_md_info_from_string( const char *md_name )
{
static const char * const hash_name =
MBEDTLS_MD_INFO_NAME( MBEDTLS_MD_SINGLE_HASH );
if( md_name != NULL && strcmp( hash_name, md_name ) == 0 )
return( MBEDTLS_MD_UNIQUE_VALID_HANDLE );
return( MBEDTLS_MD_INVALID_HANDLE );
}
mbedtls_md_handle_t mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
{
static const mbedtls_md_type_t hash_type =
MBEDTLS_MD_INFO_TYPE( MBEDTLS_MD_SINGLE_HASH );
if( hash_type == md_type )
return( MBEDTLS_MD_UNIQUE_VALID_HANDLE );
return( MBEDTLS_MD_INVALID_HANDLE );
}
#endif /* MBEDTLS_MD_SINGLE_HASH */
void mbedtls_md_init( mbedtls_md_context_t *ctx )
{
memset( ctx, 0, sizeof( mbedtls_md_context_t ) );
#if defined(MBEDTLS_MD_SINGLE_HASH)
mbedtls_md_info_init( mbedtls_md_get_handle( ctx ),
ctx->md_ctx );
#endif
}
void mbedtls_md_free( mbedtls_md_context_t *ctx )
{
if( ctx == NULL || mbedtls_md_get_handle( ctx ) == MBEDTLS_MD_INVALID_HANDLE )
if( ctx == NULL || ctx->md_info == NULL )
return;
#if !defined(MBEDTLS_MD_SINGLE_HASH)
if( ctx->md_ctx != NULL )
{
mbedtls_md_info_ctx_free( mbedtls_md_get_handle( ctx ), ctx->md_ctx );
}
ctx->md_info->ctx_free_func( ctx->md_ctx );
if( ctx->hmac_ctx != NULL )
{
mbedtls_platform_zeroize( ctx->hmac_ctx,
2 * mbedtls_md_info_block_size( mbedtls_md_get_handle( ctx ) ) );
mbedtls_zeroize( ctx->hmac_ctx, 2 * ctx->md_info->block_size );
mbedtls_free( ctx->hmac_ctx );
}
#endif /* MBEDTLS_MD_SINGLE_HASH */
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
mbedtls_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
}
int mbedtls_md_clone( mbedtls_md_context_t *dst,
const mbedtls_md_context_t *src )
{
if( dst == NULL || mbedtls_md_get_handle( dst ) == MBEDTLS_MD_INVALID_HANDLE ||
src == NULL || mbedtls_md_get_handle( src ) == MBEDTLS_MD_INVALID_HANDLE ||
mbedtls_md_get_handle( dst ) != mbedtls_md_get_handle( src ) )
if( dst == NULL || dst->md_info == NULL ||
src == NULL || src->md_info == NULL ||
dst->md_info != src->md_info )
{
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
}
mbedtls_md_info_clone( mbedtls_md_get_handle( dst ),
dst->md_ctx, src->md_ctx );
dst->md_info->clone_func( dst->md_ctx, src->md_ctx );
return( 0 );
}
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, mbedtls_md_handle_t md_info )
int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info )
{
return mbedtls_md_setup( ctx, md_info, 1 );
}
#endif
#if !defined(MBEDTLS_MD_SINGLE_HASH)
int mbedtls_md_setup( mbedtls_md_context_t *ctx, mbedtls_md_handle_t md_info, int hmac )
int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
{
return( mbedtls_md_setup_internal( ctx, md_info, hmac ) );
if( md_info == NULL || ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
return( MBEDTLS_ERR_MD_ALLOC_FAILED );
if( hmac != 0 )
{
ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size );
if( ctx->hmac_ctx == NULL )
{
md_info->ctx_free_func( ctx->md_ctx );
return( MBEDTLS_ERR_MD_ALLOC_FAILED );
}
}
ctx->md_info = md_info;
return( 0 );
}
int mbedtls_md_starts( mbedtls_md_context_t *ctx )
{
return( mbedtls_md_starts_internal( ctx ) );
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
return( ctx->md_info->starts_func( ctx->md_ctx ) );
}
int mbedtls_md_update( mbedtls_md_context_t *ctx,
const unsigned char *input,
size_t ilen )
int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
{
return( mbedtls_md_update_internal( ctx, input, ilen ) );
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
}
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
{
return( mbedtls_md_finish_internal( ctx, output ) );
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
}
int mbedtls_md( mbedtls_md_handle_t md_info, const unsigned char *input, size_t ilen,
int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
unsigned char *output )
{
return( mbedtls_md_internal( md_info, input, ilen, output ) );
if( md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
return( md_info->digest_func( input, ilen, output ) );
}
#endif /* !MBEDTLS_MD_SINGLE_HASH */
#if defined(MBEDTLS_FS_IO)
int mbedtls_md_file( mbedtls_md_handle_t md_info, const char *path, unsigned char *output )
int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output )
{
int ret;
FILE *f;
@ -479,7 +287,7 @@ int mbedtls_md_file( mbedtls_md_handle_t md_info, const char *path, unsigned cha
mbedtls_md_context_t ctx;
unsigned char buf[1024];
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
if( md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
if( ( f = fopen( path, "rb" ) ) == NULL )
@ -490,30 +298,20 @@ int mbedtls_md_file( mbedtls_md_handle_t md_info, const char *path, unsigned cha
if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
goto cleanup;
ret = mbedtls_md_info_starts( md_info, ctx.md_ctx );
if( ret != 0 )
if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 )
goto cleanup;
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
{
ret = mbedtls_md_info_update( md_info, ctx.md_ctx,
buf, n );
if( ret != 0 )
if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 )
goto cleanup;
}
if( ferror( f ) != 0 )
{
ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
}
else
{
ret = mbedtls_md_info_finish( md_info, ctx.md_ctx,
output );
}
ret = md_info->finish_func( ctx.md_ctx, output );
cleanup:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
mbedtls_zeroize( buf, sizeof( buf ) );
fclose( f );
mbedtls_md_free( &ctx );
@ -526,46 +324,29 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
int ret;
unsigned char sum[MBEDTLS_MD_MAX_SIZE];
unsigned char *ipad, *opad;
size_t i = 0;
size_t i;
mbedtls_md_handle_t md_info;
if( ctx == NULL )
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
#if !defined(MBEDTLS_MD_SINGLE_HASH)
if( ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
#endif /* !MBEDTLS_MD_SINGLE_HASH */
md_info = mbedtls_md_get_handle( ctx );
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
if( keylen > (size_t) mbedtls_md_info_block_size( md_info ) )
if( keylen > (size_t) ctx->md_info->block_size )
{
if( ( ret = mbedtls_md_info_starts( md_info, ctx->md_ctx ) ) != 0 )
if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
goto cleanup;
if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 )
goto cleanup;
if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 )
goto cleanup;
if( ( ret = mbedtls_md_info_update( md_info, ctx->md_ctx,
key, keylen ) ) != 0 )
{
goto cleanup;
}
if( ( ret = mbedtls_md_info_finish( md_info, ctx->md_ctx, sum ) ) != 0 )
goto cleanup;
keylen = mbedtls_md_info_size( md_info );
keylen = ctx->md_info->size;
key = sum;
}
ipad = (unsigned char *) ctx->hmac_ctx;
opad = (unsigned char *) ctx->hmac_ctx +
mbedtls_md_info_block_size( md_info );
opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
mbedtls_platform_memset( ipad, 0x36, mbedtls_md_info_block_size( md_info ) );
mbedtls_platform_memset( opad, 0x5C, mbedtls_md_info_block_size( md_info ) );
memset( ipad, 0x36, ctx->md_info->block_size );
memset( opad, 0x5C, ctx->md_info->block_size );
for( i = 0; i < keylen; i++ )
{
@ -573,52 +354,24 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
opad[i] = (unsigned char)( opad[i] ^ key[i] );
}
if( ( ret = mbedtls_md_info_starts( md_info, ctx->md_ctx ) ) != 0 )
if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
goto cleanup;
i++; // Use i as flow control
if( ( ret = mbedtls_md_info_update( md_info, ctx->md_ctx, ipad,
mbedtls_md_info_block_size( md_info ) ) ) != 0 )
{
if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad,
ctx->md_info->block_size ) ) != 0 )
goto cleanup;
}
i++; // Use i as flow control now
cleanup:
mbedtls_platform_zeroize( sum, sizeof( sum ) );
mbedtls_zeroize( sum, sizeof( sum ) );
if ( ret != 0 )
return ret;
/* Check possible fault injection */
if ( ( i - 2 ) == keylen )
return ret; // success, return 0 from ret
return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
return( ret );
}
int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx,
const unsigned char *input, size_t ilen )
int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
{
mbedtls_md_handle_t md_info;
if( ctx == NULL )
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
#if !defined(MBEDTLS_MD_SINGLE_HASH)
if( ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
#endif /* !MBEDTLS_MD_SINGLE_HASH */
md_info = mbedtls_md_get_handle( ctx );
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
return( mbedtls_md_info_update( md_info,
ctx->md_ctx, input,
ilen ) );
return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
}
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
@ -627,45 +380,22 @@ int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
unsigned char *opad;
mbedtls_md_handle_t md_info;
if( ctx == NULL )
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
#if !defined(MBEDTLS_MD_SINGLE_HASH)
if( ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
#endif /* !MBEDTLS_MD_SINGLE_HASH */
opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
md_info = mbedtls_md_get_handle( ctx );
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
opad = (unsigned char *) ctx->hmac_ctx +
mbedtls_md_info_block_size( md_info );
if( ( ret = mbedtls_md_info_finish( md_info, ctx->md_ctx, tmp ) ) != 0 )
if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 )
return( ret );
if( ( ret = mbedtls_md_info_starts( md_info, ctx->md_ctx ) ) != 0 )
if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
return( ret );
if( ( ret = mbedtls_md_info_update( md_info, ctx->md_ctx, opad,
mbedtls_md_info_block_size( md_info ) ) ) != 0 )
{
if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad,
ctx->md_info->block_size ) ) != 0 )
return( ret );
}
if( ( ret = mbedtls_md_info_update( md_info, ctx->md_ctx, tmp,
mbedtls_md_info_size( md_info ) ) ) != 0 )
{
if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp,
ctx->md_info->size ) ) != 0 )
return( ret );
}
if( ( ret = mbedtls_md_info_finish( md_info, ctx->md_ctx, output ) ) != 0 )
return( ret );
return( ret );
return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
}
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
@ -673,33 +403,18 @@ int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
int ret;
unsigned char *ipad;
mbedtls_md_handle_t md_info;
if( ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
#if !defined(MBEDTLS_MD_SINGLE_HASH)
if( ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
#endif /* !MBEDTLS_MD_SINGLE_HASH */
md_info = mbedtls_md_get_handle( ctx );
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
ipad = (unsigned char *) ctx->hmac_ctx;
ret = mbedtls_md_info_starts( md_info, ctx->md_ctx );
if( ret != 0 )
if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
return( ret );
ret = mbedtls_md_info_update( md_info,
ctx->md_ctx, ipad,
mbedtls_md_info_block_size( md_info ) );
return( ret );
return( ctx->md_info->update_func( ctx->md_ctx, ipad,
ctx->md_info->block_size ) );
}
int mbedtls_md_hmac( mbedtls_md_handle_t md_info,
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output )
@ -707,7 +422,7 @@ int mbedtls_md_hmac( mbedtls_md_handle_t md_info,
mbedtls_md_context_t ctx;
int ret;
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
if( md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
mbedtls_md_init( &ctx );
@ -728,35 +443,36 @@ cleanup:
return( ret );
}
#if !defined(MBEDTLS_MD_SINGLE_HASH)
int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
{
return( mbedtls_md_process_internal( ctx, data ) );
}
#endif /* !MBEDTLS_MD_SINGLE_HASH */
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
unsigned char mbedtls_md_get_size( mbedtls_md_handle_t md_info )
return( ctx->md_info->process_func( ctx->md_ctx, data ) );
}
unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )
{
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
if( md_info == NULL )
return( 0 );
return mbedtls_md_info_size( md_info );
return md_info->size;
}
mbedtls_md_type_t mbedtls_md_get_type( mbedtls_md_handle_t md_info )
mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info )
{
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
if( md_info == NULL )
return( MBEDTLS_MD_NONE );
return mbedtls_md_info_type( md_info );
return md_info->type;
}
const char *mbedtls_md_get_name( mbedtls_md_handle_t md_info )
const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info )
{
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
if( md_info == NULL )
return( NULL );
return mbedtls_md_info_name( md_info );
return md_info->name;
}
#endif /* MBEDTLS_MD_C */

View File

@ -1,7 +1,7 @@
/**
* \file md.h
*
* \brief This file contains the generic message-digest wrapper.
* \brief The generic message-digest wrapper.
*
* \author Adriaan de Jong <dejong@fox-it.com>
*/
@ -35,17 +35,10 @@
#include MBEDTLS_CONFIG_FILE
#endif
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 /**< The selected feature is not available. */
#define MBEDTLS_ERR_MD_BAD_INPUT_DATA -0x5100 /**< Bad input parameters to function. */
#define MBEDTLS_ERR_MD_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */
#define MBEDTLS_ERR_MD_FILE_IO_ERROR -0x5200 /**< Opening or reading of file failed. */
/* MBEDTLS_ERR_MD_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_MD_HW_ACCEL_FAILED -0x5280 /**< MD hardware accelerator failed. */
#ifdef __cplusplus
@ -53,7 +46,7 @@ extern "C" {
#endif
/**
* \brief Supported message digests.
* \brief Enumeration of 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
@ -61,16 +54,16 @@ extern "C" {
*
*/
typedef enum {
MBEDTLS_MD_NONE=0, /**< None. */
MBEDTLS_MD_MD2, /**< The MD2 message digest. */
MBEDTLS_MD_MD4, /**< The MD4 message digest. */
MBEDTLS_MD_MD5, /**< The MD5 message digest. */
MBEDTLS_MD_SHA1, /**< The SHA-1 message digest. */
MBEDTLS_MD_SHA224, /**< The SHA-224 message digest. */
MBEDTLS_MD_SHA256, /**< The SHA-256 message digest. */
MBEDTLS_MD_SHA384, /**< The SHA-384 message digest. */
MBEDTLS_MD_SHA512, /**< The SHA-512 message digest. */
MBEDTLS_MD_RIPEMD160, /**< The RIPEMD-160 message digest. */
MBEDTLS_MD_NONE=0,
MBEDTLS_MD_MD2,
MBEDTLS_MD_MD4,
MBEDTLS_MD_MD5,
MBEDTLS_MD_SHA1,
MBEDTLS_MD_SHA224,
MBEDTLS_MD_SHA256,
MBEDTLS_MD_SHA384,
MBEDTLS_MD_SHA512,
MBEDTLS_MD_RIPEMD160,
} mbedtls_md_type_t;
#if defined(MBEDTLS_SHA512_C)
@ -79,78 +72,25 @@ typedef enum {
#define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 or less */
#endif
#if defined(MBEDTLS_SHA512_C)
#define MBEDTLS_MD_MAX_BLOCK_SIZE 128
#else
#define MBEDTLS_MD_MAX_BLOCK_SIZE 64
#endif
#if !defined(MBEDTLS_MD_SINGLE_HASH)
#define MBEDTLS_MD_INLINABLE_API
/**
* Opaque struct defined in md.c.
* Opaque struct defined in md_internal.h.
*/
typedef struct mbedtls_md_info_t mbedtls_md_info_t;
typedef struct mbedtls_md_info_t const * mbedtls_md_handle_t;
#define MBEDTLS_MD_INVALID_HANDLE ( (mbedtls_md_handle_t) NULL )
#else /* !MBEDTLS_MD_SINGLE_HASH */
#define MBEDTLS_MD_INLINABLE_API MBEDTLS_ALWAYS_INLINE static inline
typedef int mbedtls_md_handle_t;
#define MBEDTLS_MD_INVALID_HANDLE ( (mbedtls_md_handle_t) 0 )
#define MBEDTLS_MD_UNIQUE_VALID_HANDLE ( (mbedtls_md_handle_t) 1 )
#endif /* !MBEDTLS_MD_SINGLE_HASH */
#include "md_internal.h"
/**
* The generic message-digest context.
*/
typedef struct mbedtls_md_context_t
{
#if !defined(MBEDTLS_MD_SINGLE_HASH)
typedef struct {
/** Information about the associated message digest. */
mbedtls_md_handle_t md_info;
#endif
const mbedtls_md_info_t *md_info;
#if !defined(MBEDTLS_MD_SINGLE_HASH)
/** The digest-specific context. */
void *md_ctx;
/** The HMAC part of the context. */
void *hmac_ctx;
#else
unsigned char md_ctx[ sizeof( MBEDTLS_MD_INFO_CTX_TYPE(
MBEDTLS_MD_SINGLE_HASH ) ) ];
unsigned char hmac_ctx[ 2 * MBEDTLS_MD_INFO_BLOCKSIZE(
MBEDTLS_MD_SINGLE_HASH ) ];
#endif /* MBEDTLS_MD_SINGLE_HASH */
} mbedtls_md_context_t;
#if !defined(MBEDTLS_MD_SINGLE_HASH)
static inline mbedtls_md_handle_t mbedtls_md_get_handle(
struct mbedtls_md_context_t const *ctx )
{
return( ctx->md_info );
}
#else /* !MBEDTLS_MD_SINGLE_HASH */
static inline mbedtls_md_handle_t mbedtls_md_get_handle(
struct mbedtls_md_context_t const *ctx )
{
((void) ctx);
return( MBEDTLS_MD_UNIQUE_VALID_HANDLE );
}
#endif /* !MBEDTLS_MD_SINGLE_HASH */
/**
* \brief This function returns the list of digests supported by the
* generic digest module.
@ -168,10 +108,10 @@ const int *mbedtls_md_list( void );
*
* \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.
* \return The message-digest information associated with \p md_name,
* or NULL if not found.
*/
mbedtls_md_handle_t mbedtls_md_info_from_string( const char *md_name );
const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name );
/**
* \brief This function returns the message-digest information
@ -179,10 +119,10 @@ mbedtls_md_handle_t mbedtls_md_info_from_string( const char *md_name );
*
* \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.
* \return The message-digest information associated with \p md_type,
* or NULL if not found.
*/
mbedtls_md_handle_t mbedtls_md_info_from_type( mbedtls_md_type_t md_type );
const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type );
/**
* \brief This function initializes a message-digest context without
@ -228,12 +168,11 @@ void mbedtls_md_free( mbedtls_md_context_t *ctx );
* \param md_info The information structure of the message-digest algorithm
* to use.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
* \returns \c 0 on success,
* #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure,
* #MBEDTLS_ERR_MD_ALLOC_FAILED memory allocation failure.
*/
int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, mbedtls_md_handle_t md_info ) MBEDTLS_DEPRECATED;
int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) MBEDTLS_DEPRECATED;
#undef MBEDTLS_DEPRECATED
#endif /* MBEDTLS_DEPRECATED_REMOVED */
@ -248,17 +187,14 @@ int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, mbedtls_md_handle_t md_info
* \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.
* \param hmac <ul><li>0: HMAC is not used. Saves some memory.</li>
* <li>non-zero: HMAC is used with this context.</li></ul>
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
* \returns \c 0 on success,
* #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure, or
* #MBEDTLS_ERR_MD_ALLOC_FAILED on memory allocation failure.
*/
MBEDTLS_MD_INLINABLE_API int mbedtls_md_setup( mbedtls_md_context_t *ctx,
mbedtls_md_handle_t md_info,
int hmac );
int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac );
/**
* \brief This function clones the state of an message-digest
@ -276,8 +212,8 @@ MBEDTLS_MD_INLINABLE_API int mbedtls_md_setup( mbedtls_md_context_t *ctx,
* \param dst The destination context.
* \param src The context to be cloned.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure.
* \return \c 0 on success,
* #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure.
*/
int mbedtls_md_clone( mbedtls_md_context_t *dst,
const mbedtls_md_context_t *src );
@ -291,7 +227,7 @@ int mbedtls_md_clone( mbedtls_md_context_t *dst,
*
* \return The size of the message-digest output in Bytes.
*/
unsigned char mbedtls_md_get_size( mbedtls_md_handle_t md_info );
unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info );
/**
* \brief This function extracts the message-digest type from the
@ -302,7 +238,7 @@ unsigned char mbedtls_md_get_size( mbedtls_md_handle_t md_info );
*
* \return The type of the message digest.
*/
mbedtls_md_type_t mbedtls_md_get_type( mbedtls_md_handle_t md_info );
mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info );
/**
* \brief This function extracts the message-digest name from the
@ -313,7 +249,7 @@ mbedtls_md_type_t mbedtls_md_get_type( mbedtls_md_handle_t md_info );
*
* \return The name of the message digest.
*/
const char *mbedtls_md_get_name( mbedtls_md_handle_t md_info );
const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info );
/**
* \brief This function starts a message-digest computation.
@ -324,11 +260,10 @@ const char *mbedtls_md_get_name( mbedtls_md_handle_t md_info );
*
* \param ctx The generic message-digest context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
* \returns \c 0 on success, #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
* parameter verification fails.
*/
MBEDTLS_MD_INLINABLE_API int mbedtls_md_starts( mbedtls_md_context_t *ctx );
int mbedtls_md_starts( mbedtls_md_context_t *ctx );
/**
* \brief This function feeds an input buffer into an ongoing
@ -342,13 +277,10 @@ MBEDTLS_MD_INLINABLE_API int mbedtls_md_starts( mbedtls_md_context_t *ctx );
* \param input The buffer holding the input data.
* \param ilen The length of the input data.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
* \returns \c 0 on success, #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
* parameter verification fails.
*/
MBEDTLS_MD_INLINABLE_API int mbedtls_md_update( mbedtls_md_context_t *ctx,
const unsigned char *input,
size_t ilen );
int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen );
/**
* \brief This function finishes the digest operation,
@ -364,12 +296,10 @@ MBEDTLS_MD_INLINABLE_API int mbedtls_md_update( mbedtls_md_context_t *ctx,
* \param ctx The generic message-digest context.
* \param output The buffer for the generic message-digest checksum result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
* parameter verification fails.
*/
MBEDTLS_MD_INLINABLE_API int mbedtls_md_finish( mbedtls_md_context_t *ctx,
unsigned char *output );
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output );
/**
* \brief This function calculates the message-digest of a buffer,
@ -385,15 +315,11 @@ MBEDTLS_MD_INLINABLE_API int mbedtls_md_finish( mbedtls_md_context_t *ctx,
* \param ilen The length of the input data.
* \param output The generic message-digest checksum result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
* parameter verification fails.
*/
MBEDTLS_MD_INLINABLE_API int mbedtls_md(
mbedtls_md_handle_t md_info,
const unsigned char *input,
size_t ilen,
unsigned char *output );
int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
unsigned char *output );
#if defined(MBEDTLS_FS_IO)
/**
@ -408,12 +334,11 @@ MBEDTLS_MD_INLINABLE_API int mbedtls_md(
* \param path The input file name.
* \param output The generic message-digest checksum result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_FILE_IO_ERROR on an I/O error accessing
* the file pointed by \p path.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL.
* \return \c 0 on success,
* #MBEDTLS_ERR_MD_FILE_IO_ERROR if file input failed, or
* #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL.
*/
int mbedtls_md_file( mbedtls_md_handle_t md_info, const char *path,
int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path,
unsigned char *output );
#endif /* MBEDTLS_FS_IO */
@ -431,9 +356,8 @@ int mbedtls_md_file( mbedtls_md_handle_t md_info, const char *path,
* \param key The HMAC secret key.
* \param keylen The length of the HMAC key in Bytes.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
* parameter verification fails.
*/
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
size_t keylen );
@ -453,9 +377,8 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
* \param input The buffer holding the input data.
* \param ilen The length of the input data.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
* parameter verification fails.
*/
int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input,
size_t ilen );
@ -474,9 +397,8 @@ int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *inpu
* context.
* \param output The generic HMAC checksum result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
* parameter verification fails.
*/
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output);
@ -491,9 +413,8 @@ int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output);
* \param ctx The message digest context containing an embedded HMAC
* context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
* parameter verification fails.
*/
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx );
@ -515,171 +436,15 @@ int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx );
* \param ilen The length of the input data.
* \param output The generic HMAC result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
* parameter verification fails.
*/
int mbedtls_md_hmac( mbedtls_md_handle_t md_info, const unsigned char *key, size_t keylen,
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output );
/* Internal use */
MBEDTLS_MD_INLINABLE_API int mbedtls_md_process( mbedtls_md_context_t *ctx,
const unsigned char *data );
/*
* Internal wrapper functions for those MD API functions which should be
* inlined in some but not all configurations. The actual MD API will be
* implemented either here or in md.c, and forward to the wrappers.
*/
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_setup_internal(
mbedtls_md_context_t *ctx, mbedtls_md_handle_t md_info, int hmac )
{
if( md_info == MBEDTLS_MD_INVALID_HANDLE || ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
#if !defined(MBEDTLS_MD_SINGLE_HASH)
ctx->md_ctx = mbedtls_md_info_ctx_alloc( md_info );
if( ctx->md_ctx == NULL )
return( MBEDTLS_ERR_MD_ALLOC_FAILED );
if( hmac != 0 )
{
ctx->hmac_ctx = mbedtls_calloc( 2,
mbedtls_md_info_block_size( md_info ) );
if( ctx->hmac_ctx == NULL )
{
mbedtls_md_info_ctx_free( md_info, ctx->md_ctx);
return( MBEDTLS_ERR_MD_ALLOC_FAILED );
}
}
ctx->md_info = md_info;
#else
((void) hmac);
#endif /* MBEDTLS_MD_SINGLE_HASH */
return( 0 );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_starts_internal(
mbedtls_md_context_t *ctx )
{
mbedtls_md_handle_t md_info;
if( ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
md_info = mbedtls_md_get_handle( ctx );
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
return( mbedtls_md_info_starts( md_info, ctx->md_ctx ) );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_update_internal(
mbedtls_md_context_t *ctx,
const unsigned char *input,
size_t ilen )
{
mbedtls_md_handle_t md_info;
if( ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
md_info = mbedtls_md_get_handle( ctx );
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
return( mbedtls_md_info_update( md_info, ctx->md_ctx,
input, ilen ) );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_finish_internal(
mbedtls_md_context_t *ctx, unsigned char *output )
{
mbedtls_md_handle_t md_info;
if( ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
md_info = mbedtls_md_get_handle( ctx );
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
return( mbedtls_md_info_finish( md_info, ctx->md_ctx,
output ) );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_internal(
mbedtls_md_handle_t md_info,
const unsigned char *input,
size_t ilen,
unsigned char *output )
{
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
return( mbedtls_md_info_digest( md_info, input,
ilen, output) );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_process_internal(
mbedtls_md_context_t *ctx, const unsigned char *data )
{
mbedtls_md_handle_t md_info;
if( ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
md_info = mbedtls_md_get_handle( ctx );
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
return( mbedtls_md_info_process( md_info, ctx->md_ctx, data ) );
}
#if defined(MBEDTLS_MD_SINGLE_HASH)
MBEDTLS_MD_INLINABLE_API int mbedtls_md_setup(
mbedtls_md_context_t *ctx, mbedtls_md_handle_t md_info, int hmac )
{
return( mbedtls_md_setup_internal( ctx, md_info, hmac ) );
}
MBEDTLS_MD_INLINABLE_API int mbedtls_md_starts(
mbedtls_md_context_t *ctx )
{
return( mbedtls_md_starts_internal( ctx ) );
}
MBEDTLS_MD_INLINABLE_API int mbedtls_md_update(
mbedtls_md_context_t *ctx,
const unsigned char *input,
size_t ilen )
{
return( mbedtls_md_update_internal( ctx, input, ilen ) );
}
MBEDTLS_MD_INLINABLE_API int mbedtls_md_finish(
mbedtls_md_context_t *ctx, unsigned char *output )
{
return( mbedtls_md_finish_internal( ctx, output ) );
}
MBEDTLS_MD_INLINABLE_API int mbedtls_md(
mbedtls_md_handle_t md_info,
const unsigned char *input,
size_t ilen,
unsigned char *output )
{
return( mbedtls_md_internal( md_info, input, ilen, output ) );
}
MBEDTLS_MD_INLINABLE_API int mbedtls_md_process(
mbedtls_md_context_t *ctx, const unsigned char *data )
{
return( mbedtls_md_process_internal( ctx, data ) );
}
#endif /* MBEDTLS_MD_SINGLE_HASH */
int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data );
#ifdef __cplusplus
}

View File

@ -0,0 +1,367 @@
/*
* RFC 1115/1319 compliant MD2 implementation
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The MD2 algorithm was designed by Ron Rivest in 1989.
*
* http://www.ietf.org/rfc/rfc1115.txt
* http://www.ietf.org/rfc/rfc1319.txt
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_MD2_C)
#include "md2.h"
#include <string.h>
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#if !defined(MBEDTLS_MD2_ALT)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
static const unsigned char PI_SUBST[256] =
{
0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36,
0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3,
0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C,
0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E,
0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E,
0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2,
0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E,
0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3,
0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56,
0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D,
0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65,
0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0,
0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C,
0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E,
0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81,
0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88,
0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE,
0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58,
0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99,
0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
};
void mbedtls_md2_init( mbedtls_md2_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_md2_context ) );
}
void mbedtls_md2_free( mbedtls_md2_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_zeroize( ctx, sizeof( mbedtls_md2_context ) );
}
void mbedtls_md2_clone( mbedtls_md2_context *dst,
const mbedtls_md2_context *src )
{
*dst = *src;
}
/*
* MD2 context setup
*/
int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx )
{
memset( ctx->cksum, 0, 16 );
memset( ctx->state, 0, 46 );
memset( ctx->buffer, 0, 16 );
ctx->left = 0;
return( 0 );
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md2_starts( mbedtls_md2_context *ctx )
{
mbedtls_md2_starts_ret( ctx );
}
#endif
#if !defined(MBEDTLS_MD2_PROCESS_ALT)
int mbedtls_internal_md2_process( mbedtls_md2_context *ctx )
{
int i, j;
unsigned char t = 0;
for( i = 0; i < 16; i++ )
{
ctx->state[i + 16] = ctx->buffer[i];
ctx->state[i + 32] =
(unsigned char)( ctx->buffer[i] ^ ctx->state[i]);
}
for( i = 0; i < 18; i++ )
{
for( j = 0; j < 48; j++ )
{
ctx->state[j] = (unsigned char)
( ctx->state[j] ^ PI_SUBST[t] );
t = ctx->state[j];
}
t = (unsigned char)( t + i );
}
t = ctx->cksum[15];
for( i = 0; i < 16; i++ )
{
ctx->cksum[i] = (unsigned char)
( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] );
t = ctx->cksum[i];
}
return( 0 );
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md2_process( mbedtls_md2_context *ctx )
{
mbedtls_internal_md2_process( ctx );
}
#endif
#endif /* !MBEDTLS_MD2_PROCESS_ALT */
/*
* MD2 process buffer
*/
int mbedtls_md2_update_ret( mbedtls_md2_context *ctx,
const unsigned char *input,
size_t ilen )
{
int ret;
size_t fill;
while( ilen > 0 )
{
if( ilen > 16 - ctx->left )
fill = 16 - ctx->left;
else
fill = ilen;
memcpy( ctx->buffer + ctx->left, input, fill );
ctx->left += fill;
input += fill;
ilen -= fill;
if( ctx->left == 16 )
{
ctx->left = 0;
if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
return( ret );
}
}
return( 0 );
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md2_update( mbedtls_md2_context *ctx,
const unsigned char *input,
size_t ilen )
{
mbedtls_md2_update_ret( ctx, input, ilen );
}
#endif
/*
* MD2 final digest
*/
int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx,
unsigned char output[16] )
{
int ret;
size_t i;
unsigned char x;
x = (unsigned char)( 16 - ctx->left );
for( i = ctx->left; i < 16; i++ )
ctx->buffer[i] = x;
if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
return( ret );
memcpy( ctx->buffer, ctx->cksum, 16 );
if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
return( ret );
memcpy( output, ctx->state, 16 );
return( 0 );
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md2_finish( mbedtls_md2_context *ctx,
unsigned char output[16] )
{
mbedtls_md2_finish_ret( ctx, output );
}
#endif
#endif /* !MBEDTLS_MD2_ALT */
/*
* output = MD2( input buffer )
*/
int mbedtls_md2_ret( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{
int ret;
mbedtls_md2_context ctx;
mbedtls_md2_init( &ctx );
if( ( ret = mbedtls_md2_starts_ret( &ctx ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md2_update_ret( &ctx, input, ilen ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md2_finish_ret( &ctx, output ) ) != 0 )
goto exit;
exit:
mbedtls_md2_free( &ctx );
return( ret );
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md2( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{
mbedtls_md2_ret( input, ilen, output );
}
#endif
#if defined(MBEDTLS_SELF_TEST)
/*
* RFC 1319 test vectors
*/
static const unsigned char md2_test_str[7][81] =
{
{ "" },
{ "a" },
{ "abc" },
{ "message digest" },
{ "abcdefghijklmnopqrstuvwxyz" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
{ "12345678901234567890123456789012345678901234567890123456789012"
"345678901234567890" }
};
static const size_t md2_test_strlen[7] =
{
0, 1, 3, 14, 26, 62, 80
};
static const unsigned char md2_test_sum[7][16] =
{
{ 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D,
0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 },
{ 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72,
0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 },
{ 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B,
0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB },
{ 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B,
0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 },
{ 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB,
0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B },
{ 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39,
0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD },
{ 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D,
0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 }
};
/*
* Checkup routine
*/
int mbedtls_md2_self_test( int verbose )
{
int i, ret = 0;
unsigned char md2sum[16];
for( i = 0; i < 7; i++ )
{
if( verbose != 0 )
mbedtls_printf( " MD2 test #%d: ", i + 1 );
ret = mbedtls_md2_ret( md2_test_str[i], md2_test_strlen[i], md2sum );
if( ret != 0 )
goto fail;
if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 )
{
ret = 1;
goto fail;
}
if( verbose != 0 )
mbedtls_printf( "passed\n" );
}
if( verbose != 0 )
mbedtls_printf( "\n" );
return( 0 );
fail:
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( ret );
}
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_MD2_C */

View File

@ -37,17 +37,16 @@
#include <stddef.h>
/* MBEDTLS_ERR_MD2_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_MD2_HW_ACCEL_FAILED -0x002B /**< MD2 hardware accelerator failed */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_MD2_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MD2 context structure
*
@ -56,7 +55,7 @@ extern "C" {
* stronger message digests instead.
*
*/
typedef struct mbedtls_md2_context
typedef struct
{
unsigned char cksum[16]; /*!< checksum of the data block */
unsigned char state[48]; /*!< intermediate digest state */
@ -65,10 +64,6 @@ typedef struct mbedtls_md2_context
}
mbedtls_md2_context;
#else /* MBEDTLS_MD2_ALT */
#include "md2_alt.h"
#endif /* MBEDTLS_MD2_ALT */
/**
* \brief Initialize MD2 context
*
@ -240,6 +235,18 @@ MBEDTLS_DEPRECATED void mbedtls_md2_process( mbedtls_md2_context *ctx );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_MD2_ALT */
#include "md2_alt.h"
#endif /* MBEDTLS_MD2_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Output = MD2( input buffer )
*
@ -283,8 +290,6 @@ MBEDTLS_DEPRECATED void mbedtls_md2( const unsigned char *input,
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
@ -297,8 +302,6 @@ MBEDTLS_DEPRECATED void mbedtls_md2( const unsigned char *input,
*/
int mbedtls_md2_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,472 @@
/*
* RFC 1186/1320 compliant MD4 implementation
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The MD4 algorithm was designed by Ron Rivest in 1990.
*
* http://www.ietf.org/rfc/rfc1186.txt
* http://www.ietf.org/rfc/rfc1320.txt
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_MD4_C)
#include "md4.h"
#include <string.h>
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#if !defined(MBEDTLS_MD4_ALT)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/*
* 32-bit integer manipulation macros (little endian)
*/
#ifndef GET_UINT32_LE
#define GET_UINT32_LE(n,b,i) \
{ \
(n) = ( (uint32_t) (b)[(i) ] ) \
| ( (uint32_t) (b)[(i) + 1] << 8 ) \
| ( (uint32_t) (b)[(i) + 2] << 16 ) \
| ( (uint32_t) (b)[(i) + 3] << 24 ); \
}
#endif
#ifndef PUT_UINT32_LE
#define PUT_UINT32_LE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
(b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
(b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
(b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
}
#endif
void mbedtls_md4_init( mbedtls_md4_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_md4_context ) );
}
void mbedtls_md4_free( mbedtls_md4_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_zeroize( ctx, sizeof( mbedtls_md4_context ) );
}
void mbedtls_md4_clone( mbedtls_md4_context *dst,
const mbedtls_md4_context *src )
{
*dst = *src;
}
/*
* MD4 context setup
*/
int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476;
return( 0 );
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md4_starts( mbedtls_md4_context *ctx )
{
mbedtls_md4_starts_ret( ctx );
}
#endif
#if !defined(MBEDTLS_MD4_PROCESS_ALT)
int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
const unsigned char data[64] )
{
uint32_t X[16], A, B, C, D;
GET_UINT32_LE( X[ 0], data, 0 );
GET_UINT32_LE( X[ 1], data, 4 );
GET_UINT32_LE( X[ 2], data, 8 );
GET_UINT32_LE( X[ 3], data, 12 );
GET_UINT32_LE( X[ 4], data, 16 );
GET_UINT32_LE( X[ 5], data, 20 );
GET_UINT32_LE( X[ 6], data, 24 );
GET_UINT32_LE( X[ 7], data, 28 );
GET_UINT32_LE( X[ 8], data, 32 );
GET_UINT32_LE( X[ 9], data, 36 );
GET_UINT32_LE( X[10], data, 40 );
GET_UINT32_LE( X[11], data, 44 );
GET_UINT32_LE( X[12], data, 48 );
GET_UINT32_LE( X[13], data, 52 );
GET_UINT32_LE( X[14], data, 56 );
GET_UINT32_LE( X[15], data, 60 );
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
#define F(x, y, z) ((x & y) | ((~x) & z))
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
P( A, B, C, D, X[ 0], 3 );
P( D, A, B, C, X[ 1], 7 );
P( C, D, A, B, X[ 2], 11 );
P( B, C, D, A, X[ 3], 19 );
P( A, B, C, D, X[ 4], 3 );
P( D, A, B, C, X[ 5], 7 );
P( C, D, A, B, X[ 6], 11 );
P( B, C, D, A, X[ 7], 19 );
P( A, B, C, D, X[ 8], 3 );
P( D, A, B, C, X[ 9], 7 );
P( C, D, A, B, X[10], 11 );
P( B, C, D, A, X[11], 19 );
P( A, B, C, D, X[12], 3 );
P( D, A, B, C, X[13], 7 );
P( C, D, A, B, X[14], 11 );
P( B, C, D, A, X[15], 19 );
#undef P
#undef F
#define F(x,y,z) ((x & y) | (x & z) | (y & z))
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
P( A, B, C, D, X[ 0], 3 );
P( D, A, B, C, X[ 4], 5 );
P( C, D, A, B, X[ 8], 9 );
P( B, C, D, A, X[12], 13 );
P( A, B, C, D, X[ 1], 3 );
P( D, A, B, C, X[ 5], 5 );
P( C, D, A, B, X[ 9], 9 );
P( B, C, D, A, X[13], 13 );
P( A, B, C, D, X[ 2], 3 );
P( D, A, B, C, X[ 6], 5 );
P( C, D, A, B, X[10], 9 );
P( B, C, D, A, X[14], 13 );
P( A, B, C, D, X[ 3], 3 );
P( D, A, B, C, X[ 7], 5 );
P( C, D, A, B, X[11], 9 );
P( B, C, D, A, X[15], 13 );
#undef P
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
P( A, B, C, D, X[ 0], 3 );
P( D, A, B, C, X[ 8], 9 );
P( C, D, A, B, X[ 4], 11 );
P( B, C, D, A, X[12], 15 );
P( A, B, C, D, X[ 2], 3 );
P( D, A, B, C, X[10], 9 );
P( C, D, A, B, X[ 6], 11 );
P( B, C, D, A, X[14], 15 );
P( A, B, C, D, X[ 1], 3 );
P( D, A, B, C, X[ 9], 9 );
P( C, D, A, B, X[ 5], 11 );
P( B, C, D, A, X[13], 15 );
P( A, B, C, D, X[ 3], 3 );
P( D, A, B, C, X[11], 9 );
P( C, D, A, B, X[ 7], 11 );
P( B, C, D, A, X[15], 15 );
#undef F
#undef P
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
return( 0 );
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md4_process( mbedtls_md4_context *ctx,
const unsigned char data[64] )
{
mbedtls_internal_md4_process( ctx, data );
}
#endif
#endif /* !MBEDTLS_MD4_PROCESS_ALT */
/*
* MD4 process buffer
*/
int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
const unsigned char *input,
size_t ilen )
{
int ret;
size_t fill;
uint32_t left;
if( ilen == 0 )
return( 0 );
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += (uint32_t) ilen;
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < (uint32_t) ilen )
ctx->total[1]++;
if( left && ilen >= fill )
{
memcpy( (void *) (ctx->buffer + left),
(void *) input, fill );
if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
input += fill;
ilen -= fill;
left = 0;
}
while( ilen >= 64 )
{
if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
return( ret );
input += 64;
ilen -= 64;
}
if( ilen > 0 )
{
memcpy( (void *) (ctx->buffer + left),
(void *) input, ilen );
}
return( 0 );
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md4_update( mbedtls_md4_context *ctx,
const unsigned char *input,
size_t ilen )
{
mbedtls_md4_update_ret( ctx, input, ilen );
}
#endif
static const unsigned char md4_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* MD4 final digest
*/
int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
unsigned char output[16] )
{
int ret;
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT32_LE( low, msglen, 0 );
PUT_UINT32_LE( high, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
if( ret != 0 )
return( ret );
if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
return( ret );
PUT_UINT32_LE( ctx->state[0], output, 0 );
PUT_UINT32_LE( ctx->state[1], output, 4 );
PUT_UINT32_LE( ctx->state[2], output, 8 );
PUT_UINT32_LE( ctx->state[3], output, 12 );
return( 0 );
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md4_finish( mbedtls_md4_context *ctx,
unsigned char output[16] )
{
mbedtls_md4_finish_ret( ctx, output );
}
#endif
#endif /* !MBEDTLS_MD4_ALT */
/*
* output = MD4( input buffer )
*/
int mbedtls_md4_ret( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{
int ret;
mbedtls_md4_context ctx;
mbedtls_md4_init( &ctx );
if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
goto exit;
exit:
mbedtls_md4_free( &ctx );
return( ret );
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md4( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{
mbedtls_md4_ret( input, ilen, output );
}
#endif
#if defined(MBEDTLS_SELF_TEST)
/*
* RFC 1320 test vectors
*/
static const unsigned char md4_test_str[7][81] =
{
{ "" },
{ "a" },
{ "abc" },
{ "message digest" },
{ "abcdefghijklmnopqrstuvwxyz" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
{ "12345678901234567890123456789012345678901234567890123456789012"
"345678901234567890" }
};
static const size_t md4_test_strlen[7] =
{
0, 1, 3, 14, 26, 62, 80
};
static const unsigned char md4_test_sum[7][16] =
{
{ 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
{ 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
{ 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
{ 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
{ 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
{ 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
{ 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
};
/*
* Checkup routine
*/
int mbedtls_md4_self_test( int verbose )
{
int i, ret = 0;
unsigned char md4sum[16];
for( i = 0; i < 7; i++ )
{
if( verbose != 0 )
mbedtls_printf( " MD4 test #%d: ", i + 1 );
ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
if( ret != 0 )
goto fail;
if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
{
ret = 1;
goto fail;
}
if( verbose != 0 )
mbedtls_printf( "passed\n" );
}
if( verbose != 0 )
mbedtls_printf( "\n" );
return( 0 );
fail:
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( ret );
}
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_MD4_C */

View File

@ -38,17 +38,16 @@
#include <stddef.h>
#include <stdint.h>
/* MBEDTLS_ERR_MD4_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_MD4_HW_ACCEL_FAILED -0x002D /**< MD4 hardware accelerator failed */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_MD4_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MD4 context structure
*
@ -57,7 +56,7 @@ extern "C" {
* stronger message digests instead.
*
*/
typedef struct mbedtls_md4_context
typedef struct
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[4]; /*!< intermediate digest state */
@ -65,10 +64,6 @@ typedef struct mbedtls_md4_context
}
mbedtls_md4_context;
#else /* MBEDTLS_MD4_ALT */
#include "md4_alt.h"
#endif /* MBEDTLS_MD4_ALT */
/**
* \brief Initialize MD4 context
*
@ -243,6 +238,18 @@ MBEDTLS_DEPRECATED void mbedtls_md4_process( mbedtls_md4_context *ctx,
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_MD4_ALT */
#include "md4_alt.h"
#endif /* MBEDTLS_MD4_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Output = MD4( input buffer )
*
@ -288,8 +295,6 @@ MBEDTLS_DEPRECATED void mbedtls_md4( const unsigned char *input,
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
@ -302,8 +307,6 @@ MBEDTLS_DEPRECATED void mbedtls_md4( const unsigned char *input,
*/
int mbedtls_md4_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif

View File

@ -33,7 +33,6 @@
#if defined(MBEDTLS_MD5_C)
#include "md5.h"
#include "platform_util.h"
#include <string.h>
@ -48,6 +47,11 @@
#if !defined(MBEDTLS_MD5_ALT)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/*
* 32-bit integer manipulation macros (little endian)
*/
@ -73,7 +77,7 @@
void mbedtls_md5_init( mbedtls_md5_context *ctx )
{
mbedtls_platform_memset( ctx, 0, sizeof( mbedtls_md5_context ) );
memset( ctx, 0, sizeof( mbedtls_md5_context ) );
}
void mbedtls_md5_free( mbedtls_md5_context *ctx )
@ -81,7 +85,7 @@ void mbedtls_md5_free( mbedtls_md5_context *ctx )
if( ctx == NULL )
return;
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md5_context ) );
mbedtls_zeroize( ctx, sizeof( mbedtls_md5_context ) );
}
void mbedtls_md5_clone( mbedtls_md5_context *dst,
@ -136,22 +140,19 @@ int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
GET_UINT32_LE( X[14], data, 56 );
GET_UINT32_LE( X[15], data, 60 );
#define S(x,n) \
( ( (x) << (n) ) | ( ( (x) & 0xFFFFFFFF) >> ( 32 - (n) ) ) )
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define P(a,b,c,d,k,s,t) \
do \
{ \
(a) += F((b),(c),(d)) + X[(k)] + (t); \
(a) = S((a),(s)) + (b); \
} while( 0 )
#define P(a,b,c,d,k,s,t) \
{ \
a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
}
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
#define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
#define F(x,y,z) (z ^ (x & (y ^ z)))
P( A, B, C, D, 0, 7, 0xD76AA478 );
P( D, A, B, C, 1, 12, 0xE8C7B756 );
@ -172,7 +173,7 @@ int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
#undef F
#define F(x,y,z) ((y) ^ ((z) & ((x) ^ (y))))
#define F(x,y,z) (y ^ (z & (x ^ y)))
P( A, B, C, D, 1, 5, 0xF61E2562 );
P( D, A, B, C, 6, 9, 0xC040B340 );
@ -193,7 +194,7 @@ int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
#undef F
#define F(x,y,z) ((x) ^ (y) ^ (z))
#define F(x,y,z) (x ^ y ^ z)
P( A, B, C, D, 5, 4, 0xFFFA3942 );
P( D, A, B, C, 8, 11, 0x8771F681 );
@ -214,7 +215,7 @@ int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
#undef F
#define F(x,y,z) ((y) ^ ((x) | ~(z)))
#define F(x,y,z) (y ^ (x | ~z))
P( A, B, C, D, 0, 6, 0xF4292244 );
P( D, A, B, C, 7, 10, 0x432AFF97 );
@ -277,7 +278,7 @@ int mbedtls_md5_update_ret( mbedtls_md5_context *ctx,
if( left && ilen >= fill )
{
mbedtls_platform_memcpy( (void *) (ctx->buffer + left), input, fill );
memcpy( (void *) (ctx->buffer + left), input, fill );
if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
@ -297,7 +298,7 @@ int mbedtls_md5_update_ret( mbedtls_md5_context *ctx,
if( ilen > 0 )
{
mbedtls_platform_memcpy( (void *) (ctx->buffer + left), input, ilen );
memcpy( (void *) (ctx->buffer + left), input, ilen );
}
return( 0 );
@ -332,17 +333,17 @@ int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
if( used <= 56 )
{
/* Enough room for padding + length in current block */
mbedtls_platform_memset( ctx->buffer + used, 0, 56 - used );
memset( ctx->buffer + used, 0, 56 - used );
}
else
{
/* We'll need an extra block */
mbedtls_platform_memset( ctx->buffer + used, 0, 64 - used );
memset( ctx->buffer + used, 0, 64 - used );
if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
mbedtls_platform_memset( ctx->buffer, 0, 56 );
memset( ctx->buffer, 0, 56 );
}
/*

View File

@ -37,17 +37,16 @@
#include <stddef.h>
#include <stdint.h>
/* MBEDTLS_ERR_MD5_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_MD5_HW_ACCEL_FAILED -0x002F /**< MD5 hardware accelerator failed */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_MD5_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MD5 context structure
*
@ -56,7 +55,7 @@ extern "C" {
* stronger message digests instead.
*
*/
typedef struct mbedtls_md5_context
typedef struct
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[4]; /*!< intermediate digest state */
@ -64,10 +63,6 @@ typedef struct mbedtls_md5_context
}
mbedtls_md5_context;
#else /* MBEDTLS_MD5_ALT */
#include "md5_alt.h"
#endif /* MBEDTLS_MD5_ALT */
/**
* \brief Initialize MD5 context
*
@ -243,6 +238,18 @@ MBEDTLS_DEPRECATED void mbedtls_md5_process( mbedtls_md5_context *ctx,
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_MD5_ALT */
#include "md5_alt.h"
#endif /* MBEDTLS_MD5_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Output = MD5( input buffer )
*
@ -288,8 +295,6 @@ MBEDTLS_DEPRECATED void mbedtls_md5( const unsigned char *input,
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
@ -302,8 +307,6 @@ MBEDTLS_DEPRECATED void mbedtls_md5( const unsigned char *input,
*/
int mbedtls_md5_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif

View File

@ -1,12 +1,14 @@
/**
/**
* \file md_internal.h
*
* \brief This file contains the generic message-digest wrapper.
* \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-2018, Arm Limited (or its affiliates), All Rights Reserved
* 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
@ -21,157 +23,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of Mbed TLS (https://tls.mbed.org)
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_MD_WRAP_H
#define MBEDTLS_MD_WRAP_H
#ifndef MBEDTLS_MD_INTERNAL_H
#define MBEDTLS_MD_INTERNAL_H
#if defined(MBEDTLS_MD2_C)
#include "md2.h"
#endif
#if defined(MBEDTLS_MD4_C)
#include "md4.h"
#endif
#if defined(MBEDTLS_MD5_C)
#include "md5.h"
#endif
#if defined(MBEDTLS_RIPEMD160_C)
#include "ripemd160.h"
#endif
#if defined(MBEDTLS_SHA1_C)
#include "sha1.h"
#endif
#if defined(MBEDTLS_SHA256_C)
#include "sha256.h"
#endif
#if defined(MBEDTLS_SHA512_C)
#include "sha512.h"
#endif
#include "platform_util.h"
#if defined(MBEDTLS_PLATFORM_C)
#include "platform.h"
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
#include MBEDTLS_CONFIG_FILE
#endif
#include "md.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MBEDTLS_MD_WRAPPER MBEDTLS_ALWAYS_INLINE static inline
/*
* Message-digest information macro definition
*/
/* Dummy definition to keep check-names.sh happy - don't uncomment */
//#define MBEDTLS_MD_INFO_SHA256
/* SHA-256 */
static inline void mbedtls_md_sha256_init_free_dummy( void* ctx )
{
/* Zero-initialization can be skipped. */
((void) ctx);
}
#define MBEDTLS_MD_INFO_SHA256_TYPE MBEDTLS_MD_SHA256
#define MBEDTLS_MD_INFO_SHA256_CTX_TYPE mbedtls_sha256_context
#if defined(MBEDTLS_MD_SINGLE_HASH) && !defined(MBEDTLS_SHA256_ALT)
/* mbedtls_md_sha256_init() only zeroizes, which is redundant
* because mbedtls_md_context is zeroized in mbedtls_md_init(),
* and the mbedtls_sha256_context is embedded in mbedtls_md_context_t. */
#define MBEDTLS_MD_INFO_SHA256_INIT_FUNC mbedtls_md_sha256_init_free_dummy
#else
#define MBEDTLS_MD_INFO_SHA256_INIT_FUNC mbedtls_sha256_init
#endif /* MBEDTLS_MD_SINGLE_HASH && !MBEDTLS_SHA256_ALT */
#define MBEDTLS_MD_INFO_SHA256_NAME "SHA256"
#define MBEDTLS_MD_INFO_SHA256_SIZE 32
#define MBEDTLS_MD_INFO_SHA256_BLOCKSIZE 64
#define MBEDTLS_MD_INFO_SHA256_STARTS_FUNC mbedtls_sha256_starts_wrap
#define MBEDTLS_MD_INFO_SHA256_UPDATE_FUNC mbedtls_sha224_update_wrap
#define MBEDTLS_MD_INFO_SHA256_FINISH_FUNC mbedtls_sha224_finish_wrap
#define MBEDTLS_MD_INFO_SHA256_DIGEST_FUNC mbedtls_sha256_wrap
#define MBEDTLS_MD_INFO_SHA256_ALLOC_FUNC mbedtls_sha224_ctx_alloc
#if defined(MBEDTLS_MD_SINGLE_HASH) && !defined(MBEDTLS_SHA256_ALT)
/* mbedtls_md_sha256_free() only zeroizes, which is redundant
* because mbedtls_md_context is zeroized in mbedtls_md_init(),
* and the mbedtls_sha256_context is embedded in mbedtls_md_context_t. */
#define MBEDTLS_MD_INFO_SHA256_FREE_FUNC mbedtls_md_sha256_init_free_dummy
#else
#define MBEDTLS_MD_INFO_SHA256_FREE_FUNC mbedtls_sha224_ctx_free
#endif /* MBEDTLS_MD_SINGLE_HASH && !MBEDTLS_SHA256_ALT */
#define MBEDTLS_MD_INFO_SHA256_CLONE_FUNC mbedtls_sha224_clone_wrap
#define MBEDTLS_MD_INFO_SHA256_PROCESS_FUNC mbedtls_sha224_process_wrap
/*
* Helper macros to extract fields from ciphersuites.
*/
#define MBEDTLS_MD_INFO_CTX_TYPE_T( MD ) MD ## _CTX_TYPE
#define MBEDTLS_MD_INFO_INIT_FUNC_T( MD ) MD ## _INIT_FUNC
#define MBEDTLS_MD_INFO_TYPE_T( MD ) MD ## _TYPE
#define MBEDTLS_MD_INFO_NAME_T( MD ) MD ## _NAME
#define MBEDTLS_MD_INFO_SIZE_T( MD ) MD ## _SIZE
#define MBEDTLS_MD_INFO_BLOCKSIZE_T( MD ) MD ## _BLOCKSIZE
#define MBEDTLS_MD_INFO_STARTS_FUNC_T( MD ) MD ## _STARTS_FUNC
#define MBEDTLS_MD_INFO_UPDATE_FUNC_T( MD ) MD ## _UPDATE_FUNC
#define MBEDTLS_MD_INFO_FINISH_FUNC_T( MD ) MD ## _FINISH_FUNC
#define MBEDTLS_MD_INFO_DIGEST_FUNC_T( MD ) MD ## _DIGEST_FUNC
#define MBEDTLS_MD_INFO_ALLOC_FUNC_T( MD ) MD ## _ALLOC_FUNC
#define MBEDTLS_MD_INFO_FREE_FUNC_T( MD ) MD ## _FREE_FUNC
#define MBEDTLS_MD_INFO_CLONE_FUNC_T( MD ) MD ## _CLONE_FUNC
#define MBEDTLS_MD_INFO_PROCESS_FUNC_T( MD ) MD ## _PROCESS_FUNC
/* Wrapper around MBEDTLS_MD_INFO_{FIELD}_T() which makes sure that
* the argument is macro-expanded before concatenated with the
* field name. This allows to call these macros as
* MBEDTLS_MD_INFO_{FIELD}( MBEDTLS_MD_SINGLE_HASH ).
* where MBEDTLS_MD_SINGLE_HASH expands to MBEDTLS_MD_INFO_{DIGEST}. */
#define MBEDTLS_MD_INFO_CTX_TYPE( MD ) MBEDTLS_MD_INFO_CTX_TYPE_T( MD )
#define MBEDTLS_MD_INFO_INIT_FUNC( MD ) MBEDTLS_MD_INFO_INIT_FUNC_T( MD )
#define MBEDTLS_MD_INFO_TYPE( MD ) MBEDTLS_MD_INFO_TYPE_T( MD )
#define MBEDTLS_MD_INFO_NAME( MD ) MBEDTLS_MD_INFO_NAME_T( MD )
#define MBEDTLS_MD_INFO_SIZE( MD ) MBEDTLS_MD_INFO_SIZE_T( MD )
#define MBEDTLS_MD_INFO_BLOCKSIZE( MD ) MBEDTLS_MD_INFO_BLOCKSIZE_T( MD )
#define MBEDTLS_MD_INFO_STARTS_FUNC( MD ) MBEDTLS_MD_INFO_STARTS_FUNC_T( MD )
#define MBEDTLS_MD_INFO_UPDATE_FUNC( MD ) MBEDTLS_MD_INFO_UPDATE_FUNC_T( MD )
#define MBEDTLS_MD_INFO_FINISH_FUNC( MD ) MBEDTLS_MD_INFO_FINISH_FUNC_T( MD )
#define MBEDTLS_MD_INFO_DIGEST_FUNC( MD ) MBEDTLS_MD_INFO_DIGEST_FUNC_T( MD )
#define MBEDTLS_MD_INFO_ALLOC_FUNC( MD ) MBEDTLS_MD_INFO_ALLOC_FUNC_T( MD )
#define MBEDTLS_MD_INFO_FREE_FUNC( MD ) MBEDTLS_MD_INFO_FREE_FUNC_T( MD )
#define MBEDTLS_MD_INFO_CLONE_FUNC( MD ) MBEDTLS_MD_INFO_CLONE_FUNC_T( MD )
#define MBEDTLS_MD_INFO_PROCESS_FUNC( MD ) MBEDTLS_MD_INFO_PROCESS_FUNC_T( MD )
/**
* Message digest information.
* Allows message digest functions to be called in a generic way.
*/
typedef int mbedtls_md_starts_func_t( void *ctx );
typedef int mbedtls_md_update_func_t( void *ctx,
const unsigned char *input,
size_t ilen );
typedef int mbedtls_md_finish_func_t( void *ctx, unsigned char *output );
typedef int mbedtls_md_digest_func_t( const unsigned char *input,
size_t ilen,
unsigned char *output );
typedef void* mbedtls_md_ctx_alloc_func_t( void );
typedef void mbedtls_md_ctx_free_func_t( void *ctx );
typedef void mbedtls_md_clone_func_t( void *st, const void *src );
typedef int mbedtls_md_process_func_t( void *ctx,
const unsigned char *input );
#if !defined(MBEDTLS_MD_SINGLE_HASH)
struct mbedtls_md_info_t
{
/** Digest identifier */
@ -187,672 +59,57 @@ struct mbedtls_md_info_t
int block_size;
/** Digest initialisation function */
mbedtls_md_starts_func_t *starts_func;
int (*starts_func)( void *ctx );
/** Digest update function */
mbedtls_md_update_func_t *update_func;
int (*update_func)( void *ctx, const unsigned char *input, size_t ilen );
/** Digest finalisation function */
mbedtls_md_finish_func_t *finish_func;
int (*finish_func)( void *ctx, unsigned char *output );
/** Generic digest function */
mbedtls_md_digest_func_t *digest_func;
int (*digest_func)( const unsigned char *input, size_t ilen,
unsigned char *output );
/** Allocate a new context */
mbedtls_md_ctx_alloc_func_t *ctx_alloc_func;
void * (*ctx_alloc_func)( void );
/** Free the given context */
mbedtls_md_ctx_free_func_t *ctx_free_func;
void (*ctx_free_func)( void *ctx );
/** Clone state from a context */
mbedtls_md_clone_func_t *clone_func;
void (*clone_func)( void *dst, const void *src );
/** Internal use only */
mbedtls_md_process_func_t *process_func;
int (*process_func)( void *ctx, const unsigned char *input );
};
/**
* \brief This macro builds an instance of ::mbedtls_md_info_t
* from an \c MBEDTLS_MD_INFO_XXX identifier.
*/
#define MBEDTLS_MD_INFO( MD ) \
{ MBEDTLS_MD_INFO_TYPE( MD ), \
MBEDTLS_MD_INFO_NAME( MD ), \
MBEDTLS_MD_INFO_SIZE( MD ), \
MBEDTLS_MD_INFO_BLOCKSIZE( MD ), \
MBEDTLS_MD_INFO_STARTS_FUNC( MD ), \
MBEDTLS_MD_INFO_UPDATE_FUNC( MD ), \
MBEDTLS_MD_INFO_FINISH_FUNC( MD ), \
MBEDTLS_MD_INFO_DIGEST_FUNC( MD ), \
MBEDTLS_MD_INFO_ALLOC_FUNC( MD ), \
MBEDTLS_MD_INFO_FREE_FUNC( MD ), \
MBEDTLS_MD_INFO_CLONE_FUNC( MD ), \
MBEDTLS_MD_INFO_PROCESS_FUNC( MD ) }
#endif /* !MBEDTLS_MD_SINGLE_HASH */
/*
*
* Definitions of MD information structures for various digests.
*
*/
/*
* MD-2
*/
#if defined(MBEDTLS_MD2_C)
MBEDTLS_MD_WRAPPER int mbedtls_md2_starts_wrap( void *ctx )
{
return( mbedtls_md2_starts_ret( (mbedtls_md2_context *) ctx ) );
}
MBEDTLS_MD_WRAPPER int mbedtls_md2_update_wrap( void *ctx, const unsigned char *input,
size_t ilen )
{
return( mbedtls_md2_update_ret( (mbedtls_md2_context *) ctx, input, ilen ) );
}
MBEDTLS_MD_WRAPPER int mbedtls_md2_finish_wrap( void *ctx, unsigned char *output )
{
return( mbedtls_md2_finish_ret( (mbedtls_md2_context *) ctx, output ) );
}
MBEDTLS_MD_WRAPPER void* mbedtls_md2_ctx_alloc( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md2_context ) );
if( ctx != NULL )
mbedtls_md2_init( (mbedtls_md2_context *) ctx );
return( ctx );
}
MBEDTLS_MD_WRAPPER void mbedtls_md2_ctx_free( void *ctx )
{
mbedtls_md2_free( (mbedtls_md2_context *) ctx );
mbedtls_free( ctx );
}
MBEDTLS_MD_WRAPPER void mbedtls_md2_clone_wrap( void *dst, const void *src )
{
mbedtls_md2_clone( (mbedtls_md2_context *) dst,
(const mbedtls_md2_context *) src );
}
MBEDTLS_MD_WRAPPER int mbedtls_md2_process_wrap( void *ctx, const unsigned char *data )
{
((void) data);
return( mbedtls_internal_md2_process( (mbedtls_md2_context *) ctx ) );
}
#endif /* MBEDTLS_MD2_C */
/*
* MD-4
*/
extern const mbedtls_md_info_t mbedtls_md2_info;
#endif
#if defined(MBEDTLS_MD4_C)
MBEDTLS_MD_WRAPPER int mbedtls_md4_starts_wrap( void *ctx )
{
return( mbedtls_md4_starts_ret( (mbedtls_md4_context *) ctx ) );
}
MBEDTLS_MD_WRAPPER int mbedtls_md4_update_wrap( void *ctx, const unsigned char *input,
size_t ilen )
{
return( mbedtls_md4_update_ret( (mbedtls_md4_context *) ctx, input, ilen ) );
}
MBEDTLS_MD_WRAPPER int mbedtls_md4_finish_wrap( void *ctx, unsigned char *output )
{
return( mbedtls_md4_finish_ret( (mbedtls_md4_context *) ctx, output ) );
}
MBEDTLS_MD_WRAPPER void* mbedtls_md4_ctx_alloc( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md4_context ) );
if( ctx != NULL )
mbedtls_md4_init( (mbedtls_md4_context *) ctx );
return( ctx );
}
MBEDTLS_MD_WRAPPER void mbedtls_md4_ctx_free( void *ctx )
{
mbedtls_md4_free( (mbedtls_md4_context *) ctx );
mbedtls_free( ctx );
}
MBEDTLS_MD_WRAPPER void mbedtls_md4_clone_wrap( void *dst, const void *src )
{
mbedtls_md4_clone( (mbedtls_md4_context *) dst,
(const mbedtls_md4_context *) src );
}
MBEDTLS_MD_WRAPPER int mbedtls_md4_process_wrap( void *ctx, const unsigned char *data )
{
return( mbedtls_internal_md4_process( (mbedtls_md4_context *) ctx, data ) );
}
#endif /* MBEDTLS_MD4_C */
/*
* MD-5
*/
extern const mbedtls_md_info_t mbedtls_md4_info;
#endif
#if defined(MBEDTLS_MD5_C)
MBEDTLS_MD_WRAPPER int mbedtls_md5_starts_wrap( void *ctx )
{
return( mbedtls_md5_starts_ret( (mbedtls_md5_context *) ctx ) );
}
MBEDTLS_MD_WRAPPER int mbedtls_md5_update_wrap( void *ctx, const unsigned char *input,
size_t ilen )
{
return( mbedtls_md5_update_ret( (mbedtls_md5_context *) ctx, input, ilen ) );
}
MBEDTLS_MD_WRAPPER int mbedtls_md5_finish_wrap( void *ctx, unsigned char *output )
{
return( mbedtls_md5_finish_ret( (mbedtls_md5_context *) ctx, output ) );
}
MBEDTLS_MD_WRAPPER void* mbedtls_md5_ctx_alloc( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md5_context ) );
if( ctx != NULL )
mbedtls_md5_init( (mbedtls_md5_context *) ctx );
return( ctx );
}
MBEDTLS_MD_WRAPPER void mbedtls_md5_ctx_free( void *ctx )
{
mbedtls_md5_free( (mbedtls_md5_context *) ctx );
mbedtls_free( ctx );
}
MBEDTLS_MD_WRAPPER void mbedtls_md5_clone_wrap( void *dst, const void *src )
{
mbedtls_md5_clone( (mbedtls_md5_context *) dst,
(const mbedtls_md5_context *) src );
}
MBEDTLS_MD_WRAPPER int mbedtls_md5_process_wrap( void *ctx, const unsigned char *data )
{
return( mbedtls_internal_md5_process( (mbedtls_md5_context *) ctx, data ) );
}
#endif /* MBEDTLS_MD5_C */
/*
* RIPEMD-160
*/
extern const mbedtls_md_info_t mbedtls_md5_info;
#endif
#if defined(MBEDTLS_RIPEMD160_C)
MBEDTLS_MD_WRAPPER int mbedtls_ripemd160_starts_wrap( void *ctx )
{
return( mbedtls_ripemd160_starts_ret( (mbedtls_ripemd160_context *) ctx ) );
}
MBEDTLS_MD_WRAPPER int mbedtls_ripemd160_update_wrap( void *ctx, const unsigned char *input,
size_t ilen )
{
return( mbedtls_ripemd160_update_ret( (mbedtls_ripemd160_context *) ctx,
input, ilen ) );
}
MBEDTLS_MD_WRAPPER int mbedtls_ripemd160_finish_wrap( void *ctx, unsigned char *output )
{
return( mbedtls_ripemd160_finish_ret( (mbedtls_ripemd160_context *) ctx,
output ) );
}
MBEDTLS_MD_WRAPPER void* mbedtls_ripemd160_ctx_alloc( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ripemd160_context ) );
if( ctx != NULL )
mbedtls_ripemd160_init( (mbedtls_ripemd160_context *) ctx );
return( ctx );
}
MBEDTLS_MD_WRAPPER void mbedtls_ripemd160_ctx_free( void *ctx )
{
mbedtls_ripemd160_free( (mbedtls_ripemd160_context *) ctx );
mbedtls_free( ctx );
}
MBEDTLS_MD_WRAPPER void mbedtls_ripemd160_clone_wrap( void *dst, const void *src )
{
mbedtls_ripemd160_clone( (mbedtls_ripemd160_context *) dst,
(const mbedtls_ripemd160_context *) src );
}
MBEDTLS_MD_WRAPPER int mbedtls_ripemd160_process_wrap( void *ctx, const unsigned char *data )
{
return( mbedtls_internal_ripemd160_process(
(mbedtls_ripemd160_context *) ctx, data ) );
}
#endif /* MBEDTLS_RIPEMD160_C */
/*
* SHA-1
*/
extern const mbedtls_md_info_t mbedtls_ripemd160_info;
#endif
#if defined(MBEDTLS_SHA1_C)
MBEDTLS_MD_WRAPPER int mbedtls_sha1_starts_wrap( void *ctx )
{
return( mbedtls_sha1_starts_ret( (mbedtls_sha1_context *) ctx ) );
}
MBEDTLS_MD_WRAPPER int mbedtls_sha1_update_wrap( void *ctx, const unsigned char *input,
size_t ilen )
{
return( mbedtls_sha1_update_ret( (mbedtls_sha1_context *) ctx,
input, ilen ) );
}
MBEDTLS_MD_WRAPPER int mbedtls_sha1_finish_wrap( void *ctx, unsigned char *output )
{
return( mbedtls_sha1_finish_ret( (mbedtls_sha1_context *) ctx, output ) );
}
MBEDTLS_MD_WRAPPER void* mbedtls_sha1_ctx_alloc( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha1_context ) );
if( ctx != NULL )
mbedtls_sha1_init( (mbedtls_sha1_context *) ctx );
return( ctx );
}
MBEDTLS_MD_WRAPPER void mbedtls_sha1_clone_wrap( void *dst, const void *src )
{
mbedtls_sha1_clone( (mbedtls_sha1_context *) dst,
(const mbedtls_sha1_context *) src );
}
MBEDTLS_MD_WRAPPER void mbedtls_sha1_ctx_free( void *ctx )
{
mbedtls_sha1_free( (mbedtls_sha1_context *) ctx );
mbedtls_free( ctx );
}
MBEDTLS_MD_WRAPPER int mbedtls_sha1_process_wrap( void *ctx, const unsigned char *data )
{
return( mbedtls_internal_sha1_process( (mbedtls_sha1_context *) ctx,
data ) );
}
#endif /* MBEDTLS_SHA1_C */
/*
* SHA-224 and SHA-256
*/
extern const mbedtls_md_info_t mbedtls_sha1_info;
#endif
#if defined(MBEDTLS_SHA256_C)
#if !defined(MBEDTLS_SHA256_NO_SHA224)
MBEDTLS_MD_WRAPPER int mbedtls_sha224_starts_wrap( void *ctx )
{
return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 1 ) );
}
#endif /* !MBEDTLS_SHA256_NO_SHA224 */
MBEDTLS_MD_WRAPPER int mbedtls_sha224_update_wrap( void *ctx, const unsigned char *input,
size_t ilen )
{
return( mbedtls_sha256_update_ret( (mbedtls_sha256_context *) ctx,
input, ilen ) );
}
MBEDTLS_MD_WRAPPER int mbedtls_sha224_finish_wrap( void *ctx, unsigned char *output )
{
return( mbedtls_sha256_finish_ret( (mbedtls_sha256_context *) ctx,
output ) );
}
#if !defined(MBEDTLS_SHA256_NO_SHA224)
MBEDTLS_MD_WRAPPER int mbedtls_sha224_wrap( const unsigned char *input, size_t ilen,
unsigned char *output )
{
return( mbedtls_sha256_ret( input, ilen, output, 1 ) );
}
#endif /* !MBEDTLS_SHA256_NO_SHA224 */
MBEDTLS_MD_WRAPPER void* mbedtls_sha224_ctx_alloc( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha256_context ) );
if( ctx != NULL )
mbedtls_sha256_init( (mbedtls_sha256_context *) ctx );
return( ctx );
}
MBEDTLS_MD_WRAPPER void mbedtls_sha224_ctx_free( void *ctx )
{
mbedtls_sha256_free( (mbedtls_sha256_context *) ctx );
mbedtls_free( ctx );
}
MBEDTLS_MD_WRAPPER void mbedtls_sha224_clone_wrap( void *dst, const void *src )
{
mbedtls_sha256_clone( (mbedtls_sha256_context *) dst,
(const mbedtls_sha256_context *) src );
}
MBEDTLS_MD_WRAPPER int mbedtls_sha224_process_wrap( void *ctx, const unsigned char *data )
{
return( mbedtls_internal_sha256_process( (mbedtls_sha256_context *) ctx,
data ) );
}
MBEDTLS_MD_WRAPPER int mbedtls_sha256_starts_wrap( void *ctx )
{
return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 0 ) );
}
MBEDTLS_MD_WRAPPER int mbedtls_sha256_wrap( const unsigned char *input, size_t ilen,
unsigned char *output )
{
return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
}
#endif /* MBEDTLS_SHA256_C */
/*
* SHA-384 and SHA-512
*/
extern const mbedtls_md_info_t mbedtls_sha224_info;
extern const mbedtls_md_info_t mbedtls_sha256_info;
#endif
#if defined(MBEDTLS_SHA512_C)
MBEDTLS_MD_WRAPPER int mbedtls_sha384_starts_wrap( void *ctx )
{
return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 1 ) );
}
MBEDTLS_MD_WRAPPER int mbedtls_sha384_update_wrap( void *ctx, const unsigned char *input,
size_t ilen )
{
return( mbedtls_sha512_update_ret( (mbedtls_sha512_context *) ctx,
input, ilen ) );
}
MBEDTLS_MD_WRAPPER int mbedtls_sha384_finish_wrap( void *ctx, unsigned char *output )
{
return( mbedtls_sha512_finish_ret( (mbedtls_sha512_context *) ctx,
output ) );
}
MBEDTLS_MD_WRAPPER int mbedtls_sha384_wrap( const unsigned char *input, size_t ilen,
unsigned char *output )
{
return( mbedtls_sha512_ret( input, ilen, output, 1 ) );
}
MBEDTLS_MD_WRAPPER void* mbedtls_sha384_ctx_alloc( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha512_context ) );
if( ctx != NULL )
mbedtls_sha512_init( (mbedtls_sha512_context *) ctx );
return( ctx );
}
MBEDTLS_MD_WRAPPER void mbedtls_sha384_ctx_free( void *ctx )
{
mbedtls_sha512_free( (mbedtls_sha512_context *) ctx );
mbedtls_free( ctx );
}
MBEDTLS_MD_WRAPPER void mbedtls_sha384_clone_wrap( void *dst, const void *src )
{
mbedtls_sha512_clone( (mbedtls_sha512_context *) dst,
(const mbedtls_sha512_context *) src );
}
MBEDTLS_MD_WRAPPER int mbedtls_sha384_process_wrap( void *ctx, const unsigned char *data )
{
return( mbedtls_internal_sha512_process( (mbedtls_sha512_context *) ctx,
data ) );
}
MBEDTLS_MD_WRAPPER int mbedtls_sha512_starts_wrap( void *ctx )
{
return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 0 ) );
}
MBEDTLS_MD_WRAPPER int mbedtls_sha512_wrap( const unsigned char *input, size_t ilen,
unsigned char *output )
{
return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
}
#endif /* MBEDTLS_SHA512_C */
/*
* Getter functions for MD info structure.
*/
#if !defined(MBEDTLS_MD_SINGLE_HASH)
MBEDTLS_ALWAYS_INLINE static inline mbedtls_md_type_t mbedtls_md_info_type(
mbedtls_md_handle_t info )
{
return( info->type );
}
MBEDTLS_ALWAYS_INLINE static inline const char * mbedtls_md_info_name(
mbedtls_md_handle_t info )
{
return( info->name );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_size(
mbedtls_md_handle_t info )
{
return( info->size );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_block_size(
mbedtls_md_handle_t info )
{
return( info->block_size );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_starts(
mbedtls_md_handle_t info,
void *ctx )
{
return( info->starts_func( ctx ) );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_update(
mbedtls_md_handle_t info,
void *ctx,
const unsigned char *input,
size_t ilen )
{
return( info->update_func( ctx, input, ilen ) );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_finish(
mbedtls_md_handle_t info,
void *ctx,
unsigned char *output )
{
return( info->finish_func( ctx, output ) );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_digest(
mbedtls_md_handle_t info,
const unsigned char *input,
size_t ilen,
unsigned char *output )
{
return( info->digest_func( input, ilen, output ) );
}
MBEDTLS_ALWAYS_INLINE static inline void* mbedtls_md_info_ctx_alloc(
mbedtls_md_handle_t info )
{
return( info->ctx_alloc_func() );
}
MBEDTLS_ALWAYS_INLINE static inline void mbedtls_md_info_ctx_free(
mbedtls_md_handle_t info,
void *ctx )
{
info->ctx_free_func( ctx );
}
MBEDTLS_ALWAYS_INLINE static inline void mbedtls_md_info_clone(
mbedtls_md_handle_t info,
void *dst,
const void *src )
{
info->clone_func( dst, src );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_process(
mbedtls_md_handle_t info,
void *ctx,
const unsigned char *input )
{
return( info->process_func( ctx, input ) );
}
#else /* !MBEDTLS_MD_SINGLE_HASH */
MBEDTLS_ALWAYS_INLINE static inline mbedtls_md_type_t mbedtls_md_info_type(
mbedtls_md_handle_t info )
{
((void) info);
return( MBEDTLS_MD_INFO_TYPE( MBEDTLS_MD_SINGLE_HASH ) );
}
MBEDTLS_ALWAYS_INLINE static inline const char * mbedtls_md_info_name(
mbedtls_md_handle_t info )
{
((void) info);
return( MBEDTLS_MD_INFO_NAME( MBEDTLS_MD_SINGLE_HASH ) );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_size(
mbedtls_md_handle_t info )
{
((void) info);
return( MBEDTLS_MD_INFO_SIZE( MBEDTLS_MD_SINGLE_HASH ) );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_block_size(
mbedtls_md_handle_t info )
{
((void) info);
return( MBEDTLS_MD_INFO_BLOCKSIZE( MBEDTLS_MD_SINGLE_HASH ) );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_starts(
mbedtls_md_handle_t info,
void *ctx )
{
((void) info);
return( MBEDTLS_MD_INFO_STARTS_FUNC( MBEDTLS_MD_SINGLE_HASH )( ctx ) );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_update(
mbedtls_md_handle_t info,
void *ctx,
const unsigned char *input,
size_t ilen )
{
((void) info);
return( MBEDTLS_MD_INFO_UPDATE_FUNC( MBEDTLS_MD_SINGLE_HASH )
( ctx, input, ilen ) );
}
MBEDTLS_ALWAYS_INLINE static inline void mbedtls_md_info_init(
mbedtls_md_handle_t info,
void *ctx )
{
((void) info);
MBEDTLS_MD_INFO_INIT_FUNC( MBEDTLS_MD_SINGLE_HASH )( ctx );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_finish(
mbedtls_md_handle_t info,
void *ctx,
unsigned char *output )
{
((void) info);
return( MBEDTLS_MD_INFO_FINISH_FUNC( MBEDTLS_MD_SINGLE_HASH )
( ctx, output ) );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_digest(
mbedtls_md_handle_t info,
const unsigned char *input,
size_t ilen,
unsigned char *output )
{
((void) info);
return( MBEDTLS_MD_INFO_DIGEST_FUNC( MBEDTLS_MD_SINGLE_HASH )
( input, ilen, output ) );
}
MBEDTLS_ALWAYS_INLINE static inline void* mbedtls_md_info_ctx_alloc(
mbedtls_md_handle_t info )
{
((void) info);
return( MBEDTLS_MD_INFO_ALLOC_FUNC( MBEDTLS_MD_SINGLE_HASH )() );
}
MBEDTLS_ALWAYS_INLINE static inline void mbedtls_md_info_ctx_free(
mbedtls_md_handle_t info,
void *ctx )
{
((void) info);
MBEDTLS_MD_INFO_FREE_FUNC( MBEDTLS_MD_SINGLE_HASH )( ctx );
}
MBEDTLS_ALWAYS_INLINE static inline void mbedtls_md_info_clone(
mbedtls_md_handle_t info,
void *dst,
const void *src )
{
((void) info);
MBEDTLS_MD_INFO_CLONE_FUNC( MBEDTLS_MD_SINGLE_HASH )( dst, src );
}
MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_process(
mbedtls_md_handle_t info,
void *ctx,
const unsigned char *input )
{
((void) info);
return( MBEDTLS_MD_INFO_PROCESS_FUNC( MBEDTLS_MD_SINGLE_HASH )
( ctx, input ) );
}
#endif /* MBEDTLS_MD_SINGLE_HASH */
extern const mbedtls_md_info_t mbedtls_sha384_info;
extern const mbedtls_md_info_t mbedtls_sha512_info;
#endif
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_MD_INTERNAL_H */
#endif /* MBEDTLS_MD_WRAP_H */

View File

@ -0,0 +1,586 @@
/**
* \file md_wrap.c
*
* \brief Generic message digest wrapper for mbed TLS
*
* \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 TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_MD_C)
#include "md_internal.h"
#if defined(MBEDTLS_MD2_C)
#include "md2.h"
#endif
#if defined(MBEDTLS_MD4_C)
#include "md4.h"
#endif
#if defined(MBEDTLS_MD5_C)
#include "md5.h"
#endif
#if defined(MBEDTLS_RIPEMD160_C)
#include "ripemd160.h"
#endif
#if defined(MBEDTLS_SHA1_C)
#include "sha1.h"
#endif
#if defined(MBEDTLS_SHA256_C)
#include "sha256.h"
#endif
#if defined(MBEDTLS_SHA512_C)
#include "sha512.h"
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "platform.h"
#else
#include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
#if defined(MBEDTLS_MD2_C)
static int md2_starts_wrap( void *ctx )
{
return( mbedtls_md2_starts_ret( (mbedtls_md2_context *) ctx ) );
}
static int md2_update_wrap( void *ctx, const unsigned char *input,
size_t ilen )
{
return( mbedtls_md2_update_ret( (mbedtls_md2_context *) ctx, input, ilen ) );
}
static int md2_finish_wrap( void *ctx, unsigned char *output )
{
return( mbedtls_md2_finish_ret( (mbedtls_md2_context *) ctx, output ) );
}
static void *md2_ctx_alloc( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md2_context ) );
if( ctx != NULL )
mbedtls_md2_init( (mbedtls_md2_context *) ctx );
return( ctx );
}
static void md2_ctx_free( void *ctx )
{
mbedtls_md2_free( (mbedtls_md2_context *) ctx );
mbedtls_free( ctx );
}
static void md2_clone_wrap( void *dst, const void *src )
{
mbedtls_md2_clone( (mbedtls_md2_context *) dst,
(const mbedtls_md2_context *) src );
}
static int md2_process_wrap( void *ctx, const unsigned char *data )
{
((void) data);
return( mbedtls_internal_md2_process( (mbedtls_md2_context *) ctx ) );
}
const mbedtls_md_info_t mbedtls_md2_info = {
MBEDTLS_MD_MD2,
"MD2",
16,
16,
md2_starts_wrap,
md2_update_wrap,
md2_finish_wrap,
mbedtls_md2_ret,
md2_ctx_alloc,
md2_ctx_free,
md2_clone_wrap,
md2_process_wrap,
};
#endif /* MBEDTLS_MD2_C */
#if defined(MBEDTLS_MD4_C)
static int md4_starts_wrap( void *ctx )
{
return( mbedtls_md4_starts_ret( (mbedtls_md4_context *) ctx ) );
}
static int md4_update_wrap( void *ctx, const unsigned char *input,
size_t ilen )
{
return( mbedtls_md4_update_ret( (mbedtls_md4_context *) ctx, input, ilen ) );
}
static int md4_finish_wrap( void *ctx, unsigned char *output )
{
return( mbedtls_md4_finish_ret( (mbedtls_md4_context *) ctx, output ) );
}
static void *md4_ctx_alloc( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md4_context ) );
if( ctx != NULL )
mbedtls_md4_init( (mbedtls_md4_context *) ctx );
return( ctx );
}
static void md4_ctx_free( void *ctx )
{
mbedtls_md4_free( (mbedtls_md4_context *) ctx );
mbedtls_free( ctx );
}
static void md4_clone_wrap( void *dst, const void *src )
{
mbedtls_md4_clone( (mbedtls_md4_context *) dst,
(const mbedtls_md4_context *) src );
}
static int md4_process_wrap( void *ctx, const unsigned char *data )
{
return( mbedtls_internal_md4_process( (mbedtls_md4_context *) ctx, data ) );
}
const mbedtls_md_info_t mbedtls_md4_info = {
MBEDTLS_MD_MD4,
"MD4",
16,
64,
md4_starts_wrap,
md4_update_wrap,
md4_finish_wrap,
mbedtls_md4_ret,
md4_ctx_alloc,
md4_ctx_free,
md4_clone_wrap,
md4_process_wrap,
};
#endif /* MBEDTLS_MD4_C */
#if defined(MBEDTLS_MD5_C)
static int md5_starts_wrap( void *ctx )
{
return( mbedtls_md5_starts_ret( (mbedtls_md5_context *) ctx ) );
}
static int md5_update_wrap( void *ctx, const unsigned char *input,
size_t ilen )
{
return( mbedtls_md5_update_ret( (mbedtls_md5_context *) ctx, input, ilen ) );
}
static int md5_finish_wrap( void *ctx, unsigned char *output )
{
return( mbedtls_md5_finish_ret( (mbedtls_md5_context *) ctx, output ) );
}
static void *md5_ctx_alloc( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md5_context ) );
if( ctx != NULL )
mbedtls_md5_init( (mbedtls_md5_context *) ctx );
return( ctx );
}
static void md5_ctx_free( void *ctx )
{
mbedtls_md5_free( (mbedtls_md5_context *) ctx );
mbedtls_free( ctx );
}
static void md5_clone_wrap( void *dst, const void *src )
{
mbedtls_md5_clone( (mbedtls_md5_context *) dst,
(const mbedtls_md5_context *) src );
}
static int md5_process_wrap( void *ctx, const unsigned char *data )
{
return( mbedtls_internal_md5_process( (mbedtls_md5_context *) ctx, data ) );
}
const mbedtls_md_info_t mbedtls_md5_info = {
MBEDTLS_MD_MD5,
"MD5",
16,
64,
md5_starts_wrap,
md5_update_wrap,
md5_finish_wrap,
mbedtls_md5_ret,
md5_ctx_alloc,
md5_ctx_free,
md5_clone_wrap,
md5_process_wrap,
};
#endif /* MBEDTLS_MD5_C */
#if defined(MBEDTLS_RIPEMD160_C)
static int ripemd160_starts_wrap( void *ctx )
{
return( mbedtls_ripemd160_starts_ret( (mbedtls_ripemd160_context *) ctx ) );
}
static int ripemd160_update_wrap( void *ctx, const unsigned char *input,
size_t ilen )
{
return( mbedtls_ripemd160_update_ret( (mbedtls_ripemd160_context *) ctx,
input, ilen ) );
}
static int ripemd160_finish_wrap( void *ctx, unsigned char *output )
{
return( mbedtls_ripemd160_finish_ret( (mbedtls_ripemd160_context *) ctx,
output ) );
}
static void *ripemd160_ctx_alloc( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ripemd160_context ) );
if( ctx != NULL )
mbedtls_ripemd160_init( (mbedtls_ripemd160_context *) ctx );
return( ctx );
}
static void ripemd160_ctx_free( void *ctx )
{
mbedtls_ripemd160_free( (mbedtls_ripemd160_context *) ctx );
mbedtls_free( ctx );
}
static void ripemd160_clone_wrap( void *dst, const void *src )
{
mbedtls_ripemd160_clone( (mbedtls_ripemd160_context *) dst,
(const mbedtls_ripemd160_context *) src );
}
static int ripemd160_process_wrap( void *ctx, const unsigned char *data )
{
return( mbedtls_internal_ripemd160_process(
(mbedtls_ripemd160_context *) ctx, data ) );
}
const mbedtls_md_info_t mbedtls_ripemd160_info = {
MBEDTLS_MD_RIPEMD160,
"RIPEMD160",
20,
64,
ripemd160_starts_wrap,
ripemd160_update_wrap,
ripemd160_finish_wrap,
mbedtls_ripemd160_ret,
ripemd160_ctx_alloc,
ripemd160_ctx_free,
ripemd160_clone_wrap,
ripemd160_process_wrap,
};
#endif /* MBEDTLS_RIPEMD160_C */
#if defined(MBEDTLS_SHA1_C)
static int sha1_starts_wrap( void *ctx )
{
return( mbedtls_sha1_starts_ret( (mbedtls_sha1_context *) ctx ) );
}
static int sha1_update_wrap( void *ctx, const unsigned char *input,
size_t ilen )
{
return( mbedtls_sha1_update_ret( (mbedtls_sha1_context *) ctx,
input, ilen ) );
}
static int sha1_finish_wrap( void *ctx, unsigned char *output )
{
return( mbedtls_sha1_finish_ret( (mbedtls_sha1_context *) ctx, output ) );
}
static void *sha1_ctx_alloc( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha1_context ) );
if( ctx != NULL )
mbedtls_sha1_init( (mbedtls_sha1_context *) ctx );
return( ctx );
}
static void sha1_clone_wrap( void *dst, const void *src )
{
mbedtls_sha1_clone( (mbedtls_sha1_context *) dst,
(const mbedtls_sha1_context *) src );
}
static void sha1_ctx_free( void *ctx )
{
mbedtls_sha1_free( (mbedtls_sha1_context *) ctx );
mbedtls_free( ctx );
}
static int sha1_process_wrap( void *ctx, const unsigned char *data )
{
return( mbedtls_internal_sha1_process( (mbedtls_sha1_context *) ctx,
data ) );
}
const mbedtls_md_info_t mbedtls_sha1_info = {
MBEDTLS_MD_SHA1,
"SHA1",
20,
64,
sha1_starts_wrap,
sha1_update_wrap,
sha1_finish_wrap,
mbedtls_sha1_ret,
sha1_ctx_alloc,
sha1_ctx_free,
sha1_clone_wrap,
sha1_process_wrap,
};
#endif /* MBEDTLS_SHA1_C */
/*
* Wrappers for generic message digests
*/
#if defined(MBEDTLS_SHA256_C)
static int sha224_starts_wrap( void *ctx )
{
return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 1 ) );
}
static int sha224_update_wrap( void *ctx, const unsigned char *input,
size_t ilen )
{
return( mbedtls_sha256_update_ret( (mbedtls_sha256_context *) ctx,
input, ilen ) );
}
static int sha224_finish_wrap( void *ctx, unsigned char *output )
{
return( mbedtls_sha256_finish_ret( (mbedtls_sha256_context *) ctx,
output ) );
}
static int sha224_wrap( const unsigned char *input, size_t ilen,
unsigned char *output )
{
return( mbedtls_sha256_ret( input, ilen, output, 1 ) );
}
static void *sha224_ctx_alloc( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha256_context ) );
if( ctx != NULL )
mbedtls_sha256_init( (mbedtls_sha256_context *) ctx );
return( ctx );
}
static void sha224_ctx_free( void *ctx )
{
mbedtls_sha256_free( (mbedtls_sha256_context *) ctx );
mbedtls_free( ctx );
}
static void sha224_clone_wrap( void *dst, const void *src )
{
mbedtls_sha256_clone( (mbedtls_sha256_context *) dst,
(const mbedtls_sha256_context *) src );
}
static int sha224_process_wrap( void *ctx, const unsigned char *data )
{
return( mbedtls_internal_sha256_process( (mbedtls_sha256_context *) ctx,
data ) );
}
const mbedtls_md_info_t mbedtls_sha224_info = {
MBEDTLS_MD_SHA224,
"SHA224",
28,
64,
sha224_starts_wrap,
sha224_update_wrap,
sha224_finish_wrap,
sha224_wrap,
sha224_ctx_alloc,
sha224_ctx_free,
sha224_clone_wrap,
sha224_process_wrap,
};
static int sha256_starts_wrap( void *ctx )
{
return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 0 ) );
}
static int sha256_wrap( const unsigned char *input, size_t ilen,
unsigned char *output )
{
return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
}
const mbedtls_md_info_t mbedtls_sha256_info = {
MBEDTLS_MD_SHA256,
"SHA256",
32,
64,
sha256_starts_wrap,
sha224_update_wrap,
sha224_finish_wrap,
sha256_wrap,
sha224_ctx_alloc,
sha224_ctx_free,
sha224_clone_wrap,
sha224_process_wrap,
};
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
static int sha384_starts_wrap( void *ctx )
{
return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 1 ) );
}
static int sha384_update_wrap( void *ctx, const unsigned char *input,
size_t ilen )
{
return( mbedtls_sha512_update_ret( (mbedtls_sha512_context *) ctx,
input, ilen ) );
}
static int sha384_finish_wrap( void *ctx, unsigned char *output )
{
return( mbedtls_sha512_finish_ret( (mbedtls_sha512_context *) ctx,
output ) );
}
static int sha384_wrap( const unsigned char *input, size_t ilen,
unsigned char *output )
{
return( mbedtls_sha512_ret( input, ilen, output, 1 ) );
}
static void *sha384_ctx_alloc( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha512_context ) );
if( ctx != NULL )
mbedtls_sha512_init( (mbedtls_sha512_context *) ctx );
return( ctx );
}
static void sha384_ctx_free( void *ctx )
{
mbedtls_sha512_free( (mbedtls_sha512_context *) ctx );
mbedtls_free( ctx );
}
static void sha384_clone_wrap( void *dst, const void *src )
{
mbedtls_sha512_clone( (mbedtls_sha512_context *) dst,
(const mbedtls_sha512_context *) src );
}
static int sha384_process_wrap( void *ctx, const unsigned char *data )
{
return( mbedtls_internal_sha512_process( (mbedtls_sha512_context *) ctx,
data ) );
}
const mbedtls_md_info_t mbedtls_sha384_info = {
MBEDTLS_MD_SHA384,
"SHA384",
48,
128,
sha384_starts_wrap,
sha384_update_wrap,
sha384_finish_wrap,
sha384_wrap,
sha384_ctx_alloc,
sha384_ctx_free,
sha384_clone_wrap,
sha384_process_wrap,
};
static int sha512_starts_wrap( void *ctx )
{
return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 0 ) );
}
static int sha512_wrap( const unsigned char *input, size_t ilen,
unsigned char *output )
{
return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
}
const mbedtls_md_info_t mbedtls_sha512_info = {
MBEDTLS_MD_SHA512,
"SHA512",
64,
128,
sha512_starts_wrap,
sha384_update_wrap,
sha384_finish_wrap,
sha512_wrap,
sha384_ctx_alloc,
sha384_ctx_free,
sha384_clone_wrap,
sha384_process_wrap,
};
#endif /* MBEDTLS_SHA512_C */
#endif /* MBEDTLS_MD_C */

View File

@ -0,0 +1,754 @@
/*
* Buffer-based memory allocator
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
#include "memory_buffer_alloc.h"
/* No need for the header guard as MBEDTLS_MEMORY_BUFFER_ALLOC_C
is dependent upon MBEDTLS_PLATFORM_C */
#include "platform.h"
#include <string.h>
#if defined(MBEDTLS_MEMORY_BACKTRACE)
#include <execinfo.h>
#endif
#if defined(MBEDTLS_THREADING_C)
#include "threading.h"
#endif
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
#define MAGIC1 0xFF00AA55
#define MAGIC2 0xEE119966
#define MAX_BT 20
typedef struct _memory_header memory_header;
struct _memory_header
{
size_t magic1;
size_t size;
size_t alloc;
memory_header *prev;
memory_header *next;
memory_header *prev_free;
memory_header *next_free;
#if defined(MBEDTLS_MEMORY_BACKTRACE)
char **trace;
size_t trace_count;
#endif
size_t magic2;
};
typedef struct
{
unsigned char *buf;
size_t len;
memory_header *first;
memory_header *first_free;
int verify;
#if defined(MBEDTLS_MEMORY_DEBUG)
size_t alloc_count;
size_t free_count;
size_t total_used;
size_t maximum_used;
size_t header_count;
size_t maximum_header_count;
#endif
#if defined(MBEDTLS_THREADING_C)
mbedtls_threading_mutex_t mutex;
#endif
}
buffer_alloc_ctx;
static buffer_alloc_ctx heap;
#if defined(MBEDTLS_MEMORY_DEBUG)
static void debug_header( memory_header *hdr )
{
#if defined(MBEDTLS_MEMORY_BACKTRACE)
size_t i;
#endif
mbedtls_fprintf( stderr, "HDR: PTR(%10zu), PREV(%10zu), NEXT(%10zu), "
"ALLOC(%zu), SIZE(%10zu)\n",
(size_t) hdr, (size_t) hdr->prev, (size_t) hdr->next,
hdr->alloc, hdr->size );
mbedtls_fprintf( stderr, " FPREV(%10zu), FNEXT(%10zu)\n",
(size_t) hdr->prev_free, (size_t) hdr->next_free );
#if defined(MBEDTLS_MEMORY_BACKTRACE)
mbedtls_fprintf( stderr, "TRACE: \n" );
for( i = 0; i < hdr->trace_count; i++ )
mbedtls_fprintf( stderr, "%s\n", hdr->trace[i] );
mbedtls_fprintf( stderr, "\n" );
#endif
}
static void debug_chain()
{
memory_header *cur = heap.first;
mbedtls_fprintf( stderr, "\nBlock list\n" );
while( cur != NULL )
{
debug_header( cur );
cur = cur->next;
}
mbedtls_fprintf( stderr, "Free list\n" );
cur = heap.first_free;
while( cur != NULL )
{
debug_header( cur );
cur = cur->next_free;
}
}
#endif /* MBEDTLS_MEMORY_DEBUG */
static int verify_header( memory_header *hdr )
{
if( hdr->magic1 != MAGIC1 )
{
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_fprintf( stderr, "FATAL: MAGIC1 mismatch\n" );
#endif
return( 1 );
}
if( hdr->magic2 != MAGIC2 )
{
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_fprintf( stderr, "FATAL: MAGIC2 mismatch\n" );
#endif
return( 1 );
}
if( hdr->alloc > 1 )
{
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_fprintf( stderr, "FATAL: alloc has illegal value\n" );
#endif
return( 1 );
}
if( hdr->prev != NULL && hdr->prev == hdr->next )
{
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_fprintf( stderr, "FATAL: prev == next\n" );
#endif
return( 1 );
}
if( hdr->prev_free != NULL && hdr->prev_free == hdr->next_free )
{
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_fprintf( stderr, "FATAL: prev_free == next_free\n" );
#endif
return( 1 );
}
return( 0 );
}
static int verify_chain()
{
memory_header *prv = heap.first, *cur;
if( prv == NULL || verify_header( prv ) != 0 )
{
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_fprintf( stderr, "FATAL: verification of first header "
"failed\n" );
#endif
return( 1 );
}
if( heap.first->prev != NULL )
{
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_fprintf( stderr, "FATAL: verification failed: "
"first->prev != NULL\n" );
#endif
return( 1 );
}
cur = heap.first->next;
while( cur != NULL )
{
if( verify_header( cur ) != 0 )
{
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_fprintf( stderr, "FATAL: verification of header "
"failed\n" );
#endif
return( 1 );
}
if( cur->prev != prv )
{
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_fprintf( stderr, "FATAL: verification failed: "
"cur->prev != prv\n" );
#endif
return( 1 );
}
prv = cur;
cur = cur->next;
}
return( 0 );
}
static void *buffer_alloc_calloc( size_t n, size_t size )
{
memory_header *new, *cur = heap.first_free;
unsigned char *p;
void *ret;
size_t original_len, len;
#if defined(MBEDTLS_MEMORY_BACKTRACE)
void *trace_buffer[MAX_BT];
size_t trace_cnt;
#endif
if( heap.buf == NULL || heap.first == NULL )
return( NULL );
original_len = len = n * size;
if( n == 0 || size == 0 || len / n != size )
return( NULL );
else if( len > (size_t)-MBEDTLS_MEMORY_ALIGN_MULTIPLE )
return( NULL );
if( len % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
{
len -= len % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
len += MBEDTLS_MEMORY_ALIGN_MULTIPLE;
}
// Find block that fits
//
while( cur != NULL )
{
if( cur->size >= len )
break;
cur = cur->next_free;
}
if( cur == NULL )
return( NULL );
if( cur->alloc != 0 )
{
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_fprintf( stderr, "FATAL: block in free_list but allocated "
"data\n" );
#endif
mbedtls_exit( 1 );
}
#if defined(MBEDTLS_MEMORY_DEBUG)
heap.alloc_count++;
#endif
// Found location, split block if > memory_header + 4 room left
//
if( cur->size - len < sizeof(memory_header) +
MBEDTLS_MEMORY_ALIGN_MULTIPLE )
{
cur->alloc = 1;
// Remove from free_list
//
if( cur->prev_free != NULL )
cur->prev_free->next_free = cur->next_free;
else
heap.first_free = cur->next_free;
if( cur->next_free != NULL )
cur->next_free->prev_free = cur->prev_free;
cur->prev_free = NULL;
cur->next_free = NULL;
#if defined(MBEDTLS_MEMORY_DEBUG)
heap.total_used += cur->size;
if( heap.total_used > heap.maximum_used )
heap.maximum_used = heap.total_used;
#endif
#if defined(MBEDTLS_MEMORY_BACKTRACE)
trace_cnt = backtrace( trace_buffer, MAX_BT );
cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
cur->trace_count = trace_cnt;
#endif
if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 )
mbedtls_exit( 1 );
ret = (unsigned char *) cur + sizeof( memory_header );
memset( ret, 0, original_len );
return( ret );
}
p = ( (unsigned char *) cur ) + sizeof(memory_header) + len;
new = (memory_header *) p;
new->size = cur->size - len - sizeof(memory_header);
new->alloc = 0;
new->prev = cur;
new->next = cur->next;
#if defined(MBEDTLS_MEMORY_BACKTRACE)
new->trace = NULL;
new->trace_count = 0;
#endif
new->magic1 = MAGIC1;
new->magic2 = MAGIC2;
if( new->next != NULL )
new->next->prev = new;
// Replace cur with new in free_list
//
new->prev_free = cur->prev_free;
new->next_free = cur->next_free;
if( new->prev_free != NULL )
new->prev_free->next_free = new;
else
heap.first_free = new;
if( new->next_free != NULL )
new->next_free->prev_free = new;
cur->alloc = 1;
cur->size = len;
cur->next = new;
cur->prev_free = NULL;
cur->next_free = NULL;
#if defined(MBEDTLS_MEMORY_DEBUG)
heap.header_count++;
if( heap.header_count > heap.maximum_header_count )
heap.maximum_header_count = heap.header_count;
heap.total_used += cur->size;
if( heap.total_used > heap.maximum_used )
heap.maximum_used = heap.total_used;
#endif
#if defined(MBEDTLS_MEMORY_BACKTRACE)
trace_cnt = backtrace( trace_buffer, MAX_BT );
cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
cur->trace_count = trace_cnt;
#endif
if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 )
mbedtls_exit( 1 );
ret = (unsigned char *) cur + sizeof( memory_header );
memset( ret, 0, original_len );
return( ret );
}
static void buffer_alloc_free( void *ptr )
{
memory_header *hdr, *old = NULL;
unsigned char *p = (unsigned char *) ptr;
if( ptr == NULL || heap.buf == NULL || heap.first == NULL )
return;
if( p < heap.buf || p >= heap.buf + heap.len )
{
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_fprintf( stderr, "FATAL: mbedtls_free() outside of managed "
"space\n" );
#endif
mbedtls_exit( 1 );
}
p -= sizeof(memory_header);
hdr = (memory_header *) p;
if( verify_header( hdr ) != 0 )
mbedtls_exit( 1 );
if( hdr->alloc != 1 )
{
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_fprintf( stderr, "FATAL: mbedtls_free() on unallocated "
"data\n" );
#endif
mbedtls_exit( 1 );
}
hdr->alloc = 0;
#if defined(MBEDTLS_MEMORY_DEBUG)
heap.free_count++;
heap.total_used -= hdr->size;
#endif
#if defined(MBEDTLS_MEMORY_BACKTRACE)
free( hdr->trace );
hdr->trace = NULL;
hdr->trace_count = 0;
#endif
// Regroup with block before
//
if( hdr->prev != NULL && hdr->prev->alloc == 0 )
{
#if defined(MBEDTLS_MEMORY_DEBUG)
heap.header_count--;
#endif
hdr->prev->size += sizeof(memory_header) + hdr->size;
hdr->prev->next = hdr->next;
old = hdr;
hdr = hdr->prev;
if( hdr->next != NULL )
hdr->next->prev = hdr;
memset( old, 0, sizeof(memory_header) );
}
// Regroup with block after
//
if( hdr->next != NULL && hdr->next->alloc == 0 )
{
#if defined(MBEDTLS_MEMORY_DEBUG)
heap.header_count--;
#endif
hdr->size += sizeof(memory_header) + hdr->next->size;
old = hdr->next;
hdr->next = hdr->next->next;
if( hdr->prev_free != NULL || hdr->next_free != NULL )
{
if( hdr->prev_free != NULL )
hdr->prev_free->next_free = hdr->next_free;
else
heap.first_free = hdr->next_free;
if( hdr->next_free != NULL )
hdr->next_free->prev_free = hdr->prev_free;
}
hdr->prev_free = old->prev_free;
hdr->next_free = old->next_free;
if( hdr->prev_free != NULL )
hdr->prev_free->next_free = hdr;
else
heap.first_free = hdr;
if( hdr->next_free != NULL )
hdr->next_free->prev_free = hdr;
if( hdr->next != NULL )
hdr->next->prev = hdr;
memset( old, 0, sizeof(memory_header) );
}
// Prepend to free_list if we have not merged
// (Does not have to stay in same order as prev / next list)
//
if( old == NULL )
{
hdr->next_free = heap.first_free;
if( heap.first_free != NULL )
heap.first_free->prev_free = hdr;
heap.first_free = hdr;
}
if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_FREE ) && verify_chain() != 0 )
mbedtls_exit( 1 );
}
void mbedtls_memory_buffer_set_verify( int verify )
{
heap.verify = verify;
}
int mbedtls_memory_buffer_alloc_verify()
{
return verify_chain();
}
#if defined(MBEDTLS_MEMORY_DEBUG)
void mbedtls_memory_buffer_alloc_status()
{
mbedtls_fprintf( stderr,
"Current use: %zu blocks / %zu bytes, max: %zu blocks / "
"%zu bytes (total %zu bytes), alloc / free: %zu / %zu\n",
heap.header_count, heap.total_used,
heap.maximum_header_count, heap.maximum_used,
heap.maximum_header_count * sizeof( memory_header )
+ heap.maximum_used,
heap.alloc_count, heap.free_count );
if( heap.first->next == NULL )
{
mbedtls_fprintf( stderr, "All memory de-allocated in stack buffer\n" );
}
else
{
mbedtls_fprintf( stderr, "Memory currently allocated:\n" );
debug_chain();
}
}
void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks )
{
*max_used = heap.maximum_used;
*max_blocks = heap.maximum_header_count;
}
void mbedtls_memory_buffer_alloc_max_reset( void )
{
heap.maximum_used = 0;
heap.maximum_header_count = 0;
}
void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks )
{
*cur_used = heap.total_used;
*cur_blocks = heap.header_count;
}
#endif /* MBEDTLS_MEMORY_DEBUG */
#if defined(MBEDTLS_THREADING_C)
static void *buffer_alloc_calloc_mutexed( size_t n, size_t size )
{
void *buf;
if( mbedtls_mutex_lock( &heap.mutex ) != 0 )
return( NULL );
buf = buffer_alloc_calloc( n, size );
if( mbedtls_mutex_unlock( &heap.mutex ) )
return( NULL );
return( buf );
}
static void buffer_alloc_free_mutexed( void *ptr )
{
/* We have to good option here, but corrupting the heap seems
* worse than loosing memory. */
if( mbedtls_mutex_lock( &heap.mutex ) )
return;
buffer_alloc_free( ptr );
(void) mbedtls_mutex_unlock( &heap.mutex );
}
#endif /* MBEDTLS_THREADING_C */
void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len )
{
memset( &heap, 0, sizeof( buffer_alloc_ctx ) );
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &heap.mutex );
mbedtls_platform_set_calloc_free( buffer_alloc_calloc_mutexed,
buffer_alloc_free_mutexed );
#else
mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free );
#endif
if( len < sizeof( memory_header ) + MBEDTLS_MEMORY_ALIGN_MULTIPLE )
return;
else if( (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
{
/* Adjust len first since buf is used in the computation */
len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE
- (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE
- (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
}
memset( buf, 0, len );
heap.buf = buf;
heap.len = len;
heap.first = (memory_header *)buf;
heap.first->size = len - sizeof( memory_header );
heap.first->magic1 = MAGIC1;
heap.first->magic2 = MAGIC2;
heap.first_free = heap.first;
}
void mbedtls_memory_buffer_alloc_free()
{
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_free( &heap.mutex );
#endif
mbedtls_zeroize( &heap, sizeof(buffer_alloc_ctx) );
}
#if defined(MBEDTLS_SELF_TEST)
static int check_pointer( void *p )
{
if( p == NULL )
return( -1 );
if( (size_t) p % MBEDTLS_MEMORY_ALIGN_MULTIPLE != 0 )
return( -1 );
return( 0 );
}
static int check_all_free( )
{
if(
#if defined(MBEDTLS_MEMORY_DEBUG)
heap.total_used != 0 ||
#endif
heap.first != heap.first_free ||
(void *) heap.first != (void *) heap.buf )
{
return( -1 );
}
return( 0 );
}
#define TEST_ASSERT( condition ) \
if( ! (condition) ) \
{ \
if( verbose != 0 ) \
mbedtls_printf( "failed\n" ); \
\
ret = 1; \
goto cleanup; \
}
int mbedtls_memory_buffer_alloc_self_test( int verbose )
{
unsigned char buf[1024];
unsigned char *p, *q, *r, *end;
int ret = 0;
if( verbose != 0 )
mbedtls_printf( " MBA test #1 (basic alloc-free cycle): " );
mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
p = mbedtls_calloc( 1, 1 );
q = mbedtls_calloc( 1, 128 );
r = mbedtls_calloc( 1, 16 );
TEST_ASSERT( check_pointer( p ) == 0 &&
check_pointer( q ) == 0 &&
check_pointer( r ) == 0 );
mbedtls_free( r );
mbedtls_free( q );
mbedtls_free( p );
TEST_ASSERT( check_all_free( ) == 0 );
/* Memorize end to compare with the next test */
end = heap.buf + heap.len;
mbedtls_memory_buffer_alloc_free( );
if( verbose != 0 )
mbedtls_printf( "passed\n" );
if( verbose != 0 )
mbedtls_printf( " MBA test #2 (buf not aligned): " );
mbedtls_memory_buffer_alloc_init( buf + 1, sizeof( buf ) - 1 );
TEST_ASSERT( heap.buf + heap.len == end );
p = mbedtls_calloc( 1, 1 );
q = mbedtls_calloc( 1, 128 );
r = mbedtls_calloc( 1, 16 );
TEST_ASSERT( check_pointer( p ) == 0 &&
check_pointer( q ) == 0 &&
check_pointer( r ) == 0 );
mbedtls_free( r );
mbedtls_free( q );
mbedtls_free( p );
TEST_ASSERT( check_all_free( ) == 0 );
mbedtls_memory_buffer_alloc_free( );
if( verbose != 0 )
mbedtls_printf( "passed\n" );
if( verbose != 0 )
mbedtls_printf( " MBA test #3 (full): " );
mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
p = mbedtls_calloc( 1, sizeof( buf ) - sizeof( memory_header ) );
TEST_ASSERT( check_pointer( p ) == 0 );
TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL );
mbedtls_free( p );
p = mbedtls_calloc( 1, sizeof( buf ) - 2 * sizeof( memory_header ) - 16 );
q = mbedtls_calloc( 1, 16 );
TEST_ASSERT( check_pointer( p ) == 0 && check_pointer( q ) == 0 );
TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL );
mbedtls_free( q );
TEST_ASSERT( mbedtls_calloc( 1, 17 ) == NULL );
mbedtls_free( p );
TEST_ASSERT( check_all_free( ) == 0 );
mbedtls_memory_buffer_alloc_free( );
if( verbose != 0 )
mbedtls_printf( "passed\n" );
cleanup:
mbedtls_memory_buffer_alloc_free( );
return( ret );
}
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */

View File

@ -0,0 +1 @@
aes.c aesni.c arc4.c asn1parse.c asn1write.c base64.c bignum.c blowfish.c camellia.c ccm.c certs.c cipher.c cipher_wrap.c cmac.c ctr_drbg.c debug.c des.c dhm.c ecdh.c ecdsa.c ecjpake.c ecp.c ecp_curves.c entropy.c entropy_poll.c error.c gcm.c havege.c hmac_drbg.c md2.c md4.c md5.c md.c md_wrap.c memory_buffer_alloc.c net_sockets.c oid.c padlock.c pem.c pk.c pkcs11.c pkcs12.c pkcs5.c pkparse.c pk_wrap.c pkwrite.c platform.c ripemd160.c rsa.c rsa_internal.c sha1.c sha256.c sha512.c ssl_cache.c ssl_ciphersuites.c ssl_cli.c ssl_cookie.c ssl_srv.c ssl_ticket.c ssl_tls.c threading.c timing.c version.c version_features.c x509.c x509_create.c x509_crl.c x509_crt.c x509_csr.c x509write_crt.c x509write_csr.c xtea.c

View File

@ -3,7 +3,7 @@
*
* \brief Deprecated header file that includes net_sockets.h
*
* \deprecated Superseded by net_sockets.h
* \deprecated Superseded by mbedtls/net_sockets.h
*/
/*
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
@ -32,6 +32,6 @@
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#include "net_sockets.h"
#if defined(MBEDTLS_DEPRECATED_WARNING)
#warning "Deprecated header file: Superseded by net_sockets.h"
#warning "Deprecated header file: Superseded by mbedtls/net_sockets.h"
#endif /* MBEDTLS_DEPRECATED_WARNING */
#endif /* !MBEDTLS_DEPRECATED_REMOVED */

View File

@ -0,0 +1,592 @@
/*
* TCP/IP or UDP/IP networking 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 TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_NET_C)
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
!defined(__APPLE__) && !defined(_WIN32)
#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h"
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "platform.h"
#else
#include <stdlib.h>
#endif
#include "net_sockets.h"
#include <string.h>
#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
!defined(EFI32)
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501)
#undef _WIN32_WINNT
/* Enables getaddrinfo() & Co */
#define _WIN32_WINNT 0x0501
#endif
#include <ws2tcpip.h>
#include <winsock2.h>
#include <windows.h>
#if defined(_MSC_VER)
#if defined(_WIN32_WCE)
#pragma comment( lib, "ws2.lib" )
#else
#pragma comment( lib, "ws2_32.lib" )
#endif
#endif /* _MSC_VER */
#define read(fd,buf,len) recv( fd, (char*)( buf ), (int)( len ), 0 )
#define write(fd,buf,len) send( fd, (char*)( buf ), (int)( len ), 0 )
#define close(fd) closesocket(fd)
static int wsa_init_done = 0;
#else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <netdb.h>
#include <errno.h>
#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
/* Some MS functions want int and MSVC warns if we pass size_t,
* but the standard functions use socklen_t, so cast only for MSVC */
#if defined(_MSC_VER)
#define MSVC_INT_CAST (int)
#else
#define MSVC_INT_CAST
#endif
#include <stdio.h>
#include <time.h>
#include <stdint.h>
/*
* Prepare for using the sockets interface
*/
static int net_prepare( void )
{
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
!defined(EFI32)
WSADATA wsaData;
if( wsa_init_done == 0 )
{
if( WSAStartup( MAKEWORD(2,0), &wsaData ) != 0 )
return( MBEDTLS_ERR_NET_SOCKET_FAILED );
wsa_init_done = 1;
}
#else
#if !defined(EFIX64) && !defined(EFI32)
signal( SIGPIPE, SIG_IGN );
#endif
#endif
return( 0 );
}
/*
* Initialize a context
*/
void mbedtls_net_init( mbedtls_net_context *ctx )
{
ctx->fd = -1;
}
/*
* Initiate a TCP connection with host:port and the given protocol
*/
int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host,
const char *port, int proto )
{
int ret;
struct addrinfo hints, *addr_list, *cur;
if( ( ret = net_prepare() ) != 0 )
return( ret );
/* Do name resolution with both IPv6 and IPv4 */
memset( &hints, 0, sizeof( hints ) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
if( getaddrinfo( host, port, &hints, &addr_list ) != 0 )
return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
/* Try the sockaddrs until a connection succeeds */
ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
for( cur = addr_list; cur != NULL; cur = cur->ai_next )
{
ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
cur->ai_protocol );
if( ctx->fd < 0 )
{
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
continue;
}
if( connect( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) == 0 )
{
ret = 0;
break;
}
close( ctx->fd );
ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
}
freeaddrinfo( addr_list );
return( ret );
}
/*
* Create a listening socket on bind_ip:port
*/
int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto )
{
int n, ret;
struct addrinfo hints, *addr_list, *cur;
if( ( ret = net_prepare() ) != 0 )
return( ret );
/* Bind to IPv6 and/or IPv4, but only in the desired protocol */
memset( &hints, 0, sizeof( hints ) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
if( bind_ip == NULL )
hints.ai_flags = AI_PASSIVE;
if( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 )
return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
/* Try the sockaddrs until a binding succeeds */
ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
for( cur = addr_list; cur != NULL; cur = cur->ai_next )
{
ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
cur->ai_protocol );
if( ctx->fd < 0 )
{
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
continue;
}
n = 1;
if( setsockopt( ctx->fd, SOL_SOCKET, SO_REUSEADDR,
(const char *) &n, sizeof( n ) ) != 0 )
{
close( ctx->fd );
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
continue;
}
if( bind( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) != 0 )
{
close( ctx->fd );
ret = MBEDTLS_ERR_NET_BIND_FAILED;
continue;
}
/* Listen only makes sense for TCP */
if( proto == MBEDTLS_NET_PROTO_TCP )
{
if( listen( ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG ) != 0 )
{
close( ctx->fd );
ret = MBEDTLS_ERR_NET_LISTEN_FAILED;
continue;
}
}
/* Bind was successful */
ret = 0;
break;
}
freeaddrinfo( addr_list );
return( ret );
}
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
!defined(EFI32)
/*
* Check if the requested operation would be blocking on a non-blocking socket
* and thus 'failed' with a negative return value.
*/
static int net_would_block( const mbedtls_net_context *ctx )
{
((void) ctx);
return( WSAGetLastError() == WSAEWOULDBLOCK );
}
#else
/*
* Check if the requested operation would be blocking on a non-blocking socket
* and thus 'failed' with a negative return value.
*
* Note: on a blocking socket this function always returns 0!
*/
static int net_would_block( const mbedtls_net_context *ctx )
{
int err = errno;
/*
* Never return 'WOULD BLOCK' on a non-blocking socket
*/
if( ( fcntl( ctx->fd, F_GETFL ) & O_NONBLOCK ) != O_NONBLOCK )
{
errno = err;
return( 0 );
}
switch( errno = err )
{
#if defined EAGAIN
case EAGAIN:
#endif
#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
#endif
return( 1 );
}
return( 0 );
}
#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
/*
* Accept a connection from a remote client
*/
int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
mbedtls_net_context *client_ctx,
void *client_ip, size_t buf_size, size_t *ip_len )
{
int ret;
int type;
struct sockaddr_storage client_addr;
#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \
defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t)
socklen_t n = (socklen_t) sizeof( client_addr );
socklen_t type_len = (socklen_t) sizeof( type );
#else
int n = (int) sizeof( client_addr );
int type_len = (int) sizeof( type );
#endif
/* Is this a TCP or UDP socket? */
if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE,
(void *) &type, &type_len ) != 0 ||
( type != SOCK_STREAM && type != SOCK_DGRAM ) )
{
return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
}
if( type == SOCK_STREAM )
{
/* TCP: actual accept() */
ret = client_ctx->fd = (int) accept( bind_ctx->fd,
(struct sockaddr *) &client_addr, &n );
}
else
{
/* UDP: wait for a message, but keep it in the queue */
char buf[1] = { 0 };
ret = (int) recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK,
(struct sockaddr *) &client_addr, &n );
#if defined(_WIN32)
if( ret == SOCKET_ERROR &&
WSAGetLastError() == WSAEMSGSIZE )
{
/* We know buf is too small, thanks, just peeking here */
ret = 0;
}
#endif
}
if( ret < 0 )
{
if( net_would_block( bind_ctx ) != 0 )
return( MBEDTLS_ERR_SSL_WANT_READ );
return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
}
/* UDP: hijack the listening socket to communicate with the client,
* then bind a new socket to accept new connections */
if( type != SOCK_STREAM )
{
struct sockaddr_storage local_addr;
int one = 1;
if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 )
return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
client_ctx->fd = bind_ctx->fd;
bind_ctx->fd = -1; /* In case we exit early */
n = sizeof( struct sockaddr_storage );
if( getsockname( client_ctx->fd,
(struct sockaddr *) &local_addr, &n ) != 0 ||
( bind_ctx->fd = (int) socket( local_addr.ss_family,
SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ||
setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
(const char *) &one, sizeof( one ) ) != 0 )
{
return( MBEDTLS_ERR_NET_SOCKET_FAILED );
}
if( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 )
{
return( MBEDTLS_ERR_NET_BIND_FAILED );
}
}
if( client_ip != NULL )
{
if( client_addr.ss_family == AF_INET )
{
struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
*ip_len = sizeof( addr4->sin_addr.s_addr );
if( buf_size < *ip_len )
return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len );
}
else
{
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr;
*ip_len = sizeof( addr6->sin6_addr.s6_addr );
if( buf_size < *ip_len )
return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
memcpy( client_ip, &addr6->sin6_addr.s6_addr, *ip_len);
}
}
return( 0 );
}
/*
* Set the socket blocking or non-blocking
*/
int mbedtls_net_set_block( mbedtls_net_context *ctx )
{
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
!defined(EFI32)
u_long n = 0;
return( ioctlsocket( ctx->fd, FIONBIO, &n ) );
#else
return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) & ~O_NONBLOCK ) );
#endif
}
int mbedtls_net_set_nonblock( mbedtls_net_context *ctx )
{
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
!defined(EFI32)
u_long n = 1;
return( ioctlsocket( ctx->fd, FIONBIO, &n ) );
#else
return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) | O_NONBLOCK ) );
#endif
}
/*
* Portable usleep helper
*/
void mbedtls_net_usleep( unsigned long usec )
{
#if defined(_WIN32)
Sleep( ( usec + 999 ) / 1000 );
#else
struct timeval tv;
tv.tv_sec = usec / 1000000;
#if defined(__unix__) || defined(__unix) || \
( defined(__APPLE__) && defined(__MACH__) )
tv.tv_usec = (suseconds_t) usec % 1000000;
#else
tv.tv_usec = usec % 1000000;
#endif
select( 0, NULL, NULL, NULL, &tv );
#endif
}
/*
* Read at most 'len' characters
*/
int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
{
int ret;
int fd = ((mbedtls_net_context *) ctx)->fd;
if( fd < 0 )
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
ret = (int) read( fd, buf, len );
if( ret < 0 )
{
if( net_would_block( ctx ) != 0 )
return( MBEDTLS_ERR_SSL_WANT_READ );
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
!defined(EFI32)
if( WSAGetLastError() == WSAECONNRESET )
return( MBEDTLS_ERR_NET_CONN_RESET );
#else
if( errno == EPIPE || errno == ECONNRESET )
return( MBEDTLS_ERR_NET_CONN_RESET );
if( errno == EINTR )
return( MBEDTLS_ERR_SSL_WANT_READ );
#endif
return( MBEDTLS_ERR_NET_RECV_FAILED );
}
return( ret );
}
/*
* Read at most 'len' characters, blocking for at most 'timeout' ms
*/
int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
uint32_t timeout )
{
int ret;
struct timeval tv;
fd_set read_fds;
int fd = ((mbedtls_net_context *) ctx)->fd;
if( fd < 0 )
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
FD_ZERO( &read_fds );
FD_SET( fd, &read_fds );
tv.tv_sec = timeout / 1000;
tv.tv_usec = ( timeout % 1000 ) * 1000;
ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv );
/* Zero fds ready means we timed out */
if( ret == 0 )
return( MBEDTLS_ERR_SSL_TIMEOUT );
if( ret < 0 )
{
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
!defined(EFI32)
if( WSAGetLastError() == WSAEINTR )
return( MBEDTLS_ERR_SSL_WANT_READ );
#else
if( errno == EINTR )
return( MBEDTLS_ERR_SSL_WANT_READ );
#endif
return( MBEDTLS_ERR_NET_RECV_FAILED );
}
/* This call will not block */
return( mbedtls_net_recv( ctx, buf, len ) );
}
/*
* Write at most 'len' characters
*/
int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
{
int ret;
int fd = ((mbedtls_net_context *) ctx)->fd;
if( fd < 0 )
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
ret = (int) write( fd, buf, len );
if( ret < 0 )
{
if( net_would_block( ctx ) != 0 )
return( MBEDTLS_ERR_SSL_WANT_WRITE );
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
!defined(EFI32)
if( WSAGetLastError() == WSAECONNRESET )
return( MBEDTLS_ERR_NET_CONN_RESET );
#else
if( errno == EPIPE || errno == ECONNRESET )
return( MBEDTLS_ERR_NET_CONN_RESET );
if( errno == EINTR )
return( MBEDTLS_ERR_SSL_WANT_WRITE );
#endif
return( MBEDTLS_ERR_NET_SEND_FAILED );
}
return( ret );
}
/*
* Gracefully close the connection
*/
void mbedtls_net_free( mbedtls_net_context *ctx )
{
if( ctx->fd == -1 )
return;
shutdown( ctx->fd, 2 );
close( ctx->fd );
ctx->fd = -1;
}
#endif /* MBEDTLS_NET_C */

View File

@ -1,23 +1,7 @@
/**
* \file net_sockets.h
*
* \brief Network sockets abstraction layer to integrate Mbed TLS into a
* BSD-style sockets API.
*
* The network sockets module provides an example integration of the
* Mbed TLS library into a BSD sockets implementation. The module is
* intended to be an example of how Mbed TLS can be integrated into a
* networking stack, as well as to be Mbed TLS's network integration
* for its supported platforms.
*
* The module is intended only to be used with the Mbed TLS library and
* is not intended to be used by third party application software
* directly.
*
* The supported platforms are as follows:
* * Microsoft Windows and Windows CE
* * POSIX/Unix platforms including Linux, OS X
*
* \brief Network communication functions
*/
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
@ -62,17 +46,12 @@
#define MBEDTLS_ERR_NET_UNKNOWN_HOST -0x0052 /**< Failed to get an IP address for the given hostname. */
#define MBEDTLS_ERR_NET_BUFFER_TOO_SMALL -0x0043 /**< Buffer is too small to hold the data. */
#define MBEDTLS_ERR_NET_INVALID_CONTEXT -0x0045 /**< The context is invalid, eg because it was free()ed. */
#define MBEDTLS_ERR_NET_POLL_FAILED -0x0047 /**< Polling the net context failed. */
#define MBEDTLS_ERR_NET_BAD_INPUT_DATA -0x0049 /**< Input invalid. */
#define MBEDTLS_NET_LISTEN_BACKLOG 10 /**< The backlog that listen() should use. */
#define MBEDTLS_NET_PROTO_TCP 0 /**< The TCP transport protocol */
#define MBEDTLS_NET_PROTO_UDP 1 /**< The UDP transport protocol */
#define MBEDTLS_NET_POLL_READ 1 /**< Used in \c mbedtls_net_poll to check for pending data */
#define MBEDTLS_NET_POLL_WRITE 2 /**< Used in \c mbedtls_net_poll to check if write possible */
#ifdef __cplusplus
extern "C" {
#endif
@ -84,7 +63,7 @@ extern "C" {
* (eg two file descriptors for combined IPv4 + IPv6 support, or additional
* structures for hand-made UDP demultiplexing).
*/
typedef struct mbedtls_net_context
typedef struct
{
int fd; /**< The underlying file descriptor */
}
@ -154,29 +133,6 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
mbedtls_net_context *client_ctx,
void *client_ip, size_t buf_size, size_t *ip_len );
/**
* \brief Check and wait for the context to be ready for read/write
*
* \param ctx Socket to check
* \param rw Bitflag composed of MBEDTLS_NET_POLL_READ and
* MBEDTLS_NET_POLL_WRITE specifying the events
* to wait for:
* - If MBEDTLS_NET_POLL_READ is set, the function
* will return as soon as the net context is available
* for reading.
* - If MBEDTLS_NET_POLL_WRITE is set, the function
* will return as soon as the net context is available
* for writing.
* \param timeout Maximal amount of time to wait before returning,
* in milliseconds. If \c timeout is zero, the
* function returns immediately. If \c timeout is
* -1u, the function blocks potentially indefinitely.
*
* \return Bitmask composed of MBEDTLS_NET_POLL_READ/WRITE
* on success or timeout, or a negative return code otherwise.
*/
int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout );
/**
* \brief Set the socket blocking
*

View File

@ -1,185 +0,0 @@
/**
* \file nist_kw.h
*
* \brief This file provides an API for key wrapping (KW) and key wrapping with
* padding (KWP) as defined in NIST SP 800-38F.
* https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf
*
* Key wrapping specifies a deterministic authenticated-encryption mode
* of operation, according to <em>NIST SP 800-38F: Recommendation for
* Block Cipher Modes of Operation: Methods for Key Wrapping</em>. Its
* purpose is to protect cryptographic keys.
*
* Its equivalent is RFC 3394 for KW, and RFC 5649 for KWP.
* https://tools.ietf.org/html/rfc3394
* https://tools.ietf.org/html/rfc5649
*
*/
/*
* Copyright (C) 2018, Arm Limited (or its affiliates), All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_NIST_KW_H
#define MBEDTLS_NIST_KW_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "cipher.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum
{
MBEDTLS_KW_MODE_KW = 0,
MBEDTLS_KW_MODE_KWP = 1
} mbedtls_nist_kw_mode_t;
#if !defined(MBEDTLS_NIST_KW_ALT)
// Regular implementation
//
/**
* \brief The key wrapping context-type definition. The key wrapping context is passed
* to the APIs called.
*
* \note The definition of this type may change in future library versions.
* Don't make any assumptions on this context!
*/
typedef struct {
mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */
} mbedtls_nist_kw_context;
#else /* MBEDTLS_NIST_key wrapping_ALT */
#include "nist_kw_alt.h"
#endif /* MBEDTLS_NIST_KW_ALT */
/**
* \brief This function initializes the specified key wrapping context
* to make references valid and prepare the context
* for mbedtls_nist_kw_setkey() or mbedtls_nist_kw_free().
*
* \param ctx The key wrapping context to initialize.
*
*/
void mbedtls_nist_kw_init( mbedtls_nist_kw_context *ctx );
/**
* \brief This function initializes the key wrapping context set in the
* \p ctx parameter and sets the encryption key.
*
* \param ctx The key wrapping context.
* \param cipher The 128-bit block cipher to use. Only AES is supported.
* \param key The Key Encryption Key (KEK).
* \param keybits The KEK size in bits. This must be acceptable by the cipher.
* \param is_wrap Specify whether the operation within the context is wrapping or unwrapping
*
* \return \c 0 on success.
* \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for any invalid input.
* \return \c MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE for 128-bit block ciphers
* which are not supported.
* \return cipher-specific error code on failure of the underlying cipher.
*/
int mbedtls_nist_kw_setkey( mbedtls_nist_kw_context *ctx,
mbedtls_cipher_id_t cipher,
const unsigned char *key,
unsigned int keybits,
const int is_wrap );
/**
* \brief This function releases and clears the specified key wrapping context
* and underlying cipher sub-context.
*
* \param ctx The key wrapping context to clear.
*/
void mbedtls_nist_kw_free( mbedtls_nist_kw_context *ctx );
/**
* \brief This function encrypts a buffer using key wrapping.
*
* \param ctx The key wrapping context to use for encryption.
* \param mode The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP)
* \param input The buffer holding the input data.
* \param in_len The length of the input data in Bytes.
* The input uses units of 8 Bytes called semiblocks.
* <ul><li>For KW mode: a multiple of 8 bytes between 16 and 2^57-8 inclusive. </li>
* <li>For KWP mode: any length between 1 and 2^32-1 inclusive.</li></ul>
* \param[out] output The buffer holding the output data.
* <ul><li>For KW mode: Must be at least 8 bytes larger than \p in_len.</li>
* <li>For KWP mode: Must be at least 8 bytes larger rounded up to a multiple of
* 8 bytes for KWP (15 bytes at most).</li></ul>
* \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure.
* \param[in] out_size The capacity of the output buffer.
*
* \return \c 0 on success.
* \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length.
* \return \c MBEDTLS_ERR_PLATFORM_ALLOC_FAILED in case of a memory allocation failure.
* \return cipher-specific error code on failure of the underlying cipher.
*/
int mbedtls_nist_kw_wrap( mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode,
const unsigned char *input, size_t in_len,
unsigned char *output, size_t* out_len, size_t out_size );
/**
* \brief This function decrypts a buffer using key wrapping.
*
* \param ctx The key wrapping context to use for decryption.
* \param mode The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP)
* \param input The buffer holding the input data.
* \param in_len The length of the input data in Bytes.
* The input uses units of 8 Bytes called semiblocks.
* The input must be a multiple of semiblocks.
* <ul><li>For KW mode: a multiple of 8 bytes between 24 and 2^57 inclusive. </li>
* <li>For KWP mode: a multiple of 8 bytes between 16 and 2^32 inclusive.</li></ul>
* \param[out] output The buffer holding the output data.
* The output buffer's minimal length is 8 bytes shorter than \p in_len.
* \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure.
* For KWP mode, the length could be up to 15 bytes shorter than \p in_len,
* depending on how much padding was added to the data.
* \param[in] out_size The capacity of the output buffer.
*
* \return \c 0 on success.
* \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length.
* \return \c MBEDTLS_ERR_CIPHER_AUTH_FAILED for verification failure of the ciphertext.
* \return cipher-specific error code on failure of the underlying cipher.
*/
int mbedtls_nist_kw_unwrap( mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode,
const unsigned char *input, size_t in_len,
unsigned char *output, size_t* out_len, size_t out_size);
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
/**
* \brief The key wrapping checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
*/
int mbedtls_nist_kw_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_NIST_KW_H */

View File

@ -50,41 +50,27 @@
*/
#define ADD_LEN(s) s, MBEDTLS_OID_SIZE(s)
/*
* Macro to generate mbedtls_oid_descriptor_t
*/
#if !defined(MBEDTLS_X509_REMOVE_INFO)
#define OID_DESCRIPTOR(s, name, description) { ADD_LEN(s), name, description }
#define NULL_OID_DESCRIPTOR { NULL, 0, NULL, NULL }
#else
#define OID_DESCRIPTOR(s, name, description) { ADD_LEN(s) }
#define NULL_OID_DESCRIPTOR { NULL, 0 }
#endif
/*
* Macro to generate an internal function for oid_XXX_from_asn1() (used by
* the other functions)
*/
#define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST ) \
static const TYPE_T * oid_ ## NAME ## _from_asn1( \
const mbedtls_asn1_buf *oid ) \
{ \
const TYPE_T *p = (LIST); \
const mbedtls_oid_descriptor_t *cur = \
(const mbedtls_oid_descriptor_t *) p; \
if( p == NULL || oid == NULL ) return( NULL ); \
while( cur->asn1 != NULL ) { \
if( cur->asn1_len == oid->len && \
mbedtls_platform_memequal( cur->asn1, oid->p, oid->len ) == 0 ) { \
return( p ); \
} \
p++; \
cur = (const mbedtls_oid_descriptor_t *) p; \
} \
return( NULL ); \
}
#define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST ) \
static const TYPE_T * oid_ ## NAME ## _from_asn1( const mbedtls_asn1_buf *oid ) \
{ \
const TYPE_T *p = LIST; \
const mbedtls_oid_descriptor_t *cur = (const mbedtls_oid_descriptor_t *) p; \
if( p == NULL || oid == NULL ) return( NULL ); \
while( cur->asn1 != NULL ) { \
if( cur->asn1_len == oid->len && \
memcmp( cur->asn1, oid->p, oid->len ) == 0 ) { \
return( p ); \
} \
p++; \
cur = (const mbedtls_oid_descriptor_t *) p; \
} \
return( NULL ); \
}
#if !defined(MBEDTLS_X509_REMOVE_INFO)
/*
* Macro to generate a function for retrieving a single attribute from the
* descriptor of an mbedtls_oid_descriptor_t wrapper.
@ -97,7 +83,6 @@ int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 )
*ATTR1 = data->descriptor.ATTR1; \
return( 0 ); \
}
#endif /* !MBEDTLS_X509_REMOVE_INFO */
/*
* Macro to generate a function for retrieving a single attribute from an
@ -118,13 +103,12 @@ int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 )
*/
#define FN_OID_GET_ATTR2(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1, \
ATTR2_TYPE, ATTR2) \
int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, \
ATTR2_TYPE * ATTR2 ) \
int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, ATTR2_TYPE * ATTR2 ) \
{ \
const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \
if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \
*(ATTR1) = data->ATTR1; \
*(ATTR2) = data->ATTR2; \
if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \
*ATTR1 = data->ATTR1; \
*ATTR2 = data->ATTR2; \
return( 0 ); \
}
@ -135,16 +119,16 @@ int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, \
#define FN_OID_GET_OID_BY_ATTR1(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1) \
int FN_NAME( ATTR1_TYPE ATTR1, const char **oid, size_t *olen ) \
{ \
const TYPE_T *cur = (LIST); \
const TYPE_T *cur = LIST; \
while( cur->descriptor.asn1 != NULL ) { \
if( cur->ATTR1 == (ATTR1) ) { \
if( cur->ATTR1 == ATTR1 ) { \
*oid = cur->descriptor.asn1; \
*olen = cur->descriptor.asn1_len; \
return( 0 ); \
} \
cur++; \
} \
return( MBEDTLS_ERR_OID_NOT_FOUND ); \
return( MBEDTLS_ERR_OID_NOT_FOUND ); \
}
/*
@ -156,9 +140,9 @@ int FN_NAME( ATTR1_TYPE ATTR1, const char **oid, size_t *olen ) \
int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \
size_t *olen ) \
{ \
const TYPE_T *cur = (LIST); \
const TYPE_T *cur = LIST; \
while( cur->descriptor.asn1 != NULL ) { \
if( cur->ATTR1 == (ATTR1) && cur->ATTR2 == (ATTR2) ) { \
if( cur->ATTR1 == ATTR1 && cur->ATTR2 == ATTR2 ) { \
*oid = cur->descriptor.asn1; \
*olen = cur->descriptor.asn1_len; \
return( 0 ); \
@ -180,83 +164,83 @@ typedef struct {
static const oid_x520_attr_t oid_x520_attr_type[] =
{
{
OID_DESCRIPTOR( MBEDTLS_OID_AT_CN, "id-at-commonName", "Common Name" ),
{ ADD_LEN( MBEDTLS_OID_AT_CN ), "id-at-commonName", "Common Name" },
"CN",
},
{
OID_DESCRIPTOR( MBEDTLS_OID_AT_COUNTRY, "id-at-countryName", "Country" ),
{ ADD_LEN( MBEDTLS_OID_AT_COUNTRY ), "id-at-countryName", "Country" },
"C",
},
{
OID_DESCRIPTOR( MBEDTLS_OID_AT_LOCALITY, "id-at-locality", "Locality" ),
{ ADD_LEN( MBEDTLS_OID_AT_LOCALITY ), "id-at-locality", "Locality" },
"L",
},
{
OID_DESCRIPTOR( MBEDTLS_OID_AT_STATE, "id-at-state", "State" ),
{ ADD_LEN( MBEDTLS_OID_AT_STATE ), "id-at-state", "State" },
"ST",
},
{
OID_DESCRIPTOR( MBEDTLS_OID_AT_ORGANIZATION,"id-at-organizationName", "Organization" ),
{ ADD_LEN( MBEDTLS_OID_AT_ORGANIZATION ),"id-at-organizationName", "Organization" },
"O",
},
{
OID_DESCRIPTOR( MBEDTLS_OID_AT_ORG_UNIT, "id-at-organizationalUnitName", "Org Unit" ),
{ ADD_LEN( MBEDTLS_OID_AT_ORG_UNIT ), "id-at-organizationalUnitName", "Org Unit" },
"OU",
},
{
OID_DESCRIPTOR( MBEDTLS_OID_PKCS9_EMAIL, "emailAddress", "E-mail address" ),
{ ADD_LEN( MBEDTLS_OID_PKCS9_EMAIL ), "emailAddress", "E-mail address" },
"emailAddress",
},
{
OID_DESCRIPTOR( MBEDTLS_OID_AT_SERIAL_NUMBER,"id-at-serialNumber", "Serial number" ),
{ ADD_LEN( MBEDTLS_OID_AT_SERIAL_NUMBER ),"id-at-serialNumber", "Serial number" },
"serialNumber",
},
{
OID_DESCRIPTOR( MBEDTLS_OID_AT_POSTAL_ADDRESS,"id-at-postalAddress", "Postal address" ),
{ ADD_LEN( MBEDTLS_OID_AT_POSTAL_ADDRESS ),"id-at-postalAddress", "Postal address" },
"postalAddress",
},
{
OID_DESCRIPTOR( MBEDTLS_OID_AT_POSTAL_CODE, "id-at-postalCode", "Postal code" ),
{ ADD_LEN( MBEDTLS_OID_AT_POSTAL_CODE ), "id-at-postalCode", "Postal code" },
"postalCode",
},
{
OID_DESCRIPTOR( MBEDTLS_OID_AT_SUR_NAME, "id-at-surName", "Surname" ),
{ ADD_LEN( MBEDTLS_OID_AT_SUR_NAME ), "id-at-surName", "Surname" },
"SN",
},
{
OID_DESCRIPTOR( MBEDTLS_OID_AT_GIVEN_NAME, "id-at-givenName", "Given name" ),
{ ADD_LEN( MBEDTLS_OID_AT_GIVEN_NAME ), "id-at-givenName", "Given name" },
"GN",
},
{
OID_DESCRIPTOR( MBEDTLS_OID_AT_INITIALS, "id-at-initials", "Initials" ),
{ ADD_LEN( MBEDTLS_OID_AT_INITIALS ), "id-at-initials", "Initials" },
"initials",
},
{
OID_DESCRIPTOR( MBEDTLS_OID_AT_GENERATION_QUALIFIER, "id-at-generationQualifier", "Generation qualifier" ),
{ ADD_LEN( MBEDTLS_OID_AT_GENERATION_QUALIFIER ), "id-at-generationQualifier", "Generation qualifier" },
"generationQualifier",
},
{
OID_DESCRIPTOR( MBEDTLS_OID_AT_TITLE, "id-at-title", "Title" ),
{ ADD_LEN( MBEDTLS_OID_AT_TITLE ), "id-at-title", "Title" },
"title",
},
{
OID_DESCRIPTOR( MBEDTLS_OID_AT_DN_QUALIFIER,"id-at-dnQualifier", "Distinguished Name qualifier" ),
{ ADD_LEN( MBEDTLS_OID_AT_DN_QUALIFIER ),"id-at-dnQualifier", "Distinguished Name qualifier" },
"dnQualifier",
},
{
OID_DESCRIPTOR( MBEDTLS_OID_AT_PSEUDONYM, "id-at-pseudonym", "Pseudonym" ),
{ ADD_LEN( MBEDTLS_OID_AT_PSEUDONYM ), "id-at-pseudonym", "Pseudonym" },
"pseudonym",
},
{
OID_DESCRIPTOR( MBEDTLS_OID_DOMAIN_COMPONENT, "id-domainComponent", "Domain component" ),
{ ADD_LEN( MBEDTLS_OID_DOMAIN_COMPONENT ), "id-domainComponent", "Domain component" },
"DC",
},
{
OID_DESCRIPTOR( MBEDTLS_OID_AT_UNIQUE_IDENTIFIER, "id-at-uniqueIdentifier", "Unique Identifier" ),
{ ADD_LEN( MBEDTLS_OID_AT_UNIQUE_IDENTIFIER ), "id-at-uniqueIdentifier", "Unique Identifier" },
"uniqueIdentifier",
},
{
NULL_OID_DESCRIPTOR,
{ NULL, 0, NULL, NULL },
NULL,
}
};
@ -275,27 +259,27 @@ typedef struct {
static const oid_x509_ext_t oid_x509_ext[] =
{
{
OID_DESCRIPTOR( MBEDTLS_OID_BASIC_CONSTRAINTS, "id-ce-basicConstraints", "Basic Constraints" ),
{ ADD_LEN( MBEDTLS_OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" },
MBEDTLS_X509_EXT_BASIC_CONSTRAINTS,
},
{
OID_DESCRIPTOR( MBEDTLS_OID_KEY_USAGE, "id-ce-keyUsage", "Key Usage" ),
{ ADD_LEN( MBEDTLS_OID_KEY_USAGE ), "id-ce-keyUsage", "Key Usage" },
MBEDTLS_X509_EXT_KEY_USAGE,
},
{
OID_DESCRIPTOR( MBEDTLS_OID_EXTENDED_KEY_USAGE, "id-ce-extKeyUsage", "Extended Key Usage" ),
{ ADD_LEN( MBEDTLS_OID_EXTENDED_KEY_USAGE ), "id-ce-extKeyUsage", "Extended Key Usage" },
MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE,
},
{
OID_DESCRIPTOR( MBEDTLS_OID_SUBJECT_ALT_NAME, "id-ce-subjectAltName", "Subject Alt Name" ),
{ ADD_LEN( MBEDTLS_OID_SUBJECT_ALT_NAME ), "id-ce-subjectAltName", "Subject Alt Name" },
MBEDTLS_X509_EXT_SUBJECT_ALT_NAME,
},
{
OID_DESCRIPTOR( MBEDTLS_OID_NS_CERT_TYPE, "id-netscape-certtype", "Netscape Certificate Type" ),
{ ADD_LEN( MBEDTLS_OID_NS_CERT_TYPE ), "id-netscape-certtype", "Netscape Certificate Type" },
MBEDTLS_X509_EXT_NS_CERT_TYPE,
},
{
NULL_OID_DESCRIPTOR,
{ NULL, 0, NULL, NULL },
0,
},
};
@ -303,22 +287,19 @@ static const oid_x509_ext_t oid_x509_ext[] =
FN_OID_TYPED_FROM_ASN1(oid_x509_ext_t, x509_ext, oid_x509_ext)
FN_OID_GET_ATTR1(mbedtls_oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, ext_type)
#if !defined(MBEDTLS_X509_REMOVE_INFO)
static const mbedtls_oid_descriptor_t oid_ext_key_usage[] =
{
OID_DESCRIPTOR( MBEDTLS_OID_SERVER_AUTH, "id-kp-serverAuth", "TLS Web Server Authentication" ),
OID_DESCRIPTOR( MBEDTLS_OID_CLIENT_AUTH, "id-kp-clientAuth", "TLS Web Client Authentication" ),
OID_DESCRIPTOR( MBEDTLS_OID_CODE_SIGNING, "id-kp-codeSigning", "Code Signing" ),
OID_DESCRIPTOR( MBEDTLS_OID_EMAIL_PROTECTION, "id-kp-emailProtection", "E-mail Protection" ),
OID_DESCRIPTOR( MBEDTLS_OID_TIME_STAMPING, "id-kp-timeStamping", "Time Stamping" ),
OID_DESCRIPTOR( MBEDTLS_OID_OCSP_SIGNING, "id-kp-OCSPSigning", "OCSP Signing" ),
NULL_OID_DESCRIPTOR,
{ ADD_LEN( MBEDTLS_OID_SERVER_AUTH ), "id-kp-serverAuth", "TLS Web Server Authentication" },
{ ADD_LEN( MBEDTLS_OID_CLIENT_AUTH ), "id-kp-clientAuth", "TLS Web Client Authentication" },
{ ADD_LEN( MBEDTLS_OID_CODE_SIGNING ), "id-kp-codeSigning", "Code Signing" },
{ ADD_LEN( MBEDTLS_OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" },
{ ADD_LEN( MBEDTLS_OID_TIME_STAMPING ), "id-kp-timeStamping", "Time Stamping" },
{ ADD_LEN( MBEDTLS_OID_OCSP_SIGNING ), "id-kp-OCSPSigning", "OCSP Signing" },
{ NULL, 0, NULL, NULL },
};
FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, ext_key_usage, oid_ext_key_usage)
FN_OID_GET_ATTR1(mbedtls_oid_get_extended_key_usage, mbedtls_oid_descriptor_t, ext_key_usage, const char *, description)
#endif /* !MBEDTLS_X509_REMOVE_INFO */
#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
#if defined(MBEDTLS_MD_C)
@ -336,101 +317,97 @@ static const oid_sig_alg_t oid_sig_alg[] =
#if defined(MBEDTLS_RSA_C)
#if defined(MBEDTLS_MD2_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_MD2, "md2WithRSAEncryption", "RSA with MD2" ),
{ ADD_LEN( MBEDTLS_OID_PKCS1_MD2 ), "md2WithRSAEncryption", "RSA with MD2" },
MBEDTLS_MD_MD2, MBEDTLS_PK_RSA,
},
#endif /* MBEDTLS_MD2_C */
#if defined(MBEDTLS_MD4_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_MD4, "md4WithRSAEncryption", "RSA with MD4" ),
{ ADD_LEN( MBEDTLS_OID_PKCS1_MD4 ), "md4WithRSAEncryption", "RSA with MD4" },
MBEDTLS_MD_MD4, MBEDTLS_PK_RSA,
},
#endif /* MBEDTLS_MD4_C */
#if defined(MBEDTLS_MD5_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_MD5, "md5WithRSAEncryption", "RSA with MD5" ),
{ ADD_LEN( MBEDTLS_OID_PKCS1_MD5 ), "md5WithRSAEncryption", "RSA with MD5" },
MBEDTLS_MD_MD5, MBEDTLS_PK_RSA,
},
#endif /* MBEDTLS_MD5_C */
#if defined(MBEDTLS_SHA1_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_SHA1, "sha-1WithRSAEncryption", "RSA with SHA1" ),
{ ADD_LEN( MBEDTLS_OID_PKCS1_SHA1 ), "sha-1WithRSAEncryption", "RSA with SHA1" },
MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA,
},
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA256_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_SHA224, "sha224WithRSAEncryption", "RSA with SHA-224" ),
{ ADD_LEN( MBEDTLS_OID_PKCS1_SHA224 ), "sha224WithRSAEncryption", "RSA with SHA-224" },
MBEDTLS_MD_SHA224, MBEDTLS_PK_RSA,
},
{
OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_SHA256, "sha256WithRSAEncryption", "RSA with SHA-256" ),
{ ADD_LEN( MBEDTLS_OID_PKCS1_SHA256 ), "sha256WithRSAEncryption", "RSA with SHA-256" },
MBEDTLS_MD_SHA256, MBEDTLS_PK_RSA,
},
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_SHA384, "sha384WithRSAEncryption", "RSA with SHA-384" ),
{ ADD_LEN( MBEDTLS_OID_PKCS1_SHA384 ), "sha384WithRSAEncryption", "RSA with SHA-384" },
MBEDTLS_MD_SHA384, MBEDTLS_PK_RSA,
},
{
OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_SHA512, "sha512WithRSAEncryption", "RSA with SHA-512" ),
{ ADD_LEN( MBEDTLS_OID_PKCS1_SHA512 ), "sha512WithRSAEncryption", "RSA with SHA-512" },
MBEDTLS_MD_SHA512, MBEDTLS_PK_RSA,
},
#endif /* MBEDTLS_SHA512_C */
#if defined(MBEDTLS_SHA1_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_RSA_SHA_OBS, "sha-1WithRSAEncryption", "RSA with SHA1" ),
{ ADD_LEN( MBEDTLS_OID_RSA_SHA_OBS ), "sha-1WithRSAEncryption", "RSA with SHA1" },
MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA,
},
#endif /* MBEDTLS_SHA1_C */
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_USE_TINYCRYPT)
#if defined(MBEDTLS_ECDSA_C)
#if defined(MBEDTLS_SHA1_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_ECDSA_SHA1, "ecdsa-with-SHA1", "ECDSA with SHA1" ),
{ ADD_LEN( MBEDTLS_OID_ECDSA_SHA1 ), "ecdsa-with-SHA1", "ECDSA with SHA1" },
MBEDTLS_MD_SHA1, MBEDTLS_PK_ECDSA,
},
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA256_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_ECDSA_SHA224, "ecdsa-with-SHA224", "ECDSA with SHA224" ),
{ ADD_LEN( MBEDTLS_OID_ECDSA_SHA224 ), "ecdsa-with-SHA224", "ECDSA with SHA224" },
MBEDTLS_MD_SHA224, MBEDTLS_PK_ECDSA,
},
{
OID_DESCRIPTOR( MBEDTLS_OID_ECDSA_SHA256, "ecdsa-with-SHA256", "ECDSA with SHA256" ),
{ ADD_LEN( MBEDTLS_OID_ECDSA_SHA256 ), "ecdsa-with-SHA256", "ECDSA with SHA256" },
MBEDTLS_MD_SHA256, MBEDTLS_PK_ECDSA,
},
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_ECDSA_SHA384, "ecdsa-with-SHA384", "ECDSA with SHA384" ),
{ ADD_LEN( MBEDTLS_OID_ECDSA_SHA384 ), "ecdsa-with-SHA384", "ECDSA with SHA384" },
MBEDTLS_MD_SHA384, MBEDTLS_PK_ECDSA,
},
{
OID_DESCRIPTOR( MBEDTLS_OID_ECDSA_SHA512, "ecdsa-with-SHA512", "ECDSA with SHA512" ),
{ ADD_LEN( MBEDTLS_OID_ECDSA_SHA512 ), "ecdsa-with-SHA512", "ECDSA with SHA512" },
MBEDTLS_MD_SHA512, MBEDTLS_PK_ECDSA,
},
#endif /* MBEDTLS_SHA512_C */
#endif /* MBEDTLS_ECDSA_C || MBEDTLS_USE_TINYCRYPT */
#endif /* MBEDTLS_ECDSA_C */
#if defined(MBEDTLS_RSA_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_RSASSA_PSS, "RSASSA-PSS", "RSASSA-PSS" ),
{ ADD_LEN( MBEDTLS_OID_RSASSA_PSS ), "RSASSA-PSS", "RSASSA-PSS" },
MBEDTLS_MD_NONE, MBEDTLS_PK_RSASSA_PSS,
},
#endif /* MBEDTLS_RSA_C */
{
NULL_OID_DESCRIPTOR,
{ NULL, 0, NULL, NULL },
MBEDTLS_MD_NONE, MBEDTLS_PK_NONE,
},
};
FN_OID_TYPED_FROM_ASN1(oid_sig_alg_t, sig_alg, oid_sig_alg)
#if !defined(MBEDTLS_X509_REMOVE_INFO)
FN_OID_GET_DESCRIPTOR_ATTR1(mbedtls_oid_get_sig_alg_desc, oid_sig_alg_t, sig_alg, const char *, description)
#endif
FN_OID_GET_ATTR2(mbedtls_oid_get_sig_alg, oid_sig_alg_t, sig_alg, mbedtls_md_type_t, md_alg, mbedtls_pk_type_t, pk_alg)
FN_OID_GET_OID_BY_ATTR2(mbedtls_oid_get_oid_by_sig_alg, oid_sig_alg_t, oid_sig_alg, mbedtls_pk_type_t, pk_alg, mbedtls_md_type_t, md_alg)
#endif /* MBEDTLS_MD_C */
@ -446,19 +423,19 @@ typedef struct {
static const oid_pk_alg_t oid_pk_alg[] =
{
{
OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_RSA, "rsaEncryption", "RSA" ),
{ ADD_LEN( MBEDTLS_OID_PKCS1_RSA ), "rsaEncryption", "RSA" },
MBEDTLS_PK_RSA,
},
{
OID_DESCRIPTOR( MBEDTLS_OID_EC_ALG_UNRESTRICTED, "id-ecPublicKey", "Generic EC key" ),
{ ADD_LEN( MBEDTLS_OID_EC_ALG_UNRESTRICTED ), "id-ecPublicKey", "Generic EC key" },
MBEDTLS_PK_ECKEY,
},
{
OID_DESCRIPTOR( MBEDTLS_OID_EC_ALG_ECDH, "id-ecDH", "EC key for ECDH" ),
{ ADD_LEN( MBEDTLS_OID_EC_ALG_ECDH ), "id-ecDH", "EC key for ECDH" },
MBEDTLS_PK_ECKEY_DH,
},
{
NULL_OID_DESCRIPTOR,
{ NULL, 0, NULL, NULL },
MBEDTLS_PK_NONE,
},
};
@ -467,12 +444,6 @@ FN_OID_TYPED_FROM_ASN1(oid_pk_alg_t, pk_alg, oid_pk_alg)
FN_OID_GET_ATTR1(mbedtls_oid_get_pk_alg, oid_pk_alg_t, pk_alg, mbedtls_pk_type_t, pk_alg)
FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_pk_alg, oid_pk_alg_t, oid_pk_alg, mbedtls_pk_type_t, pk_alg)
#if defined(MBEDTLS_USE_TINYCRYPT)
typedef struct {
mbedtls_oid_descriptor_t descriptor;
mbedtls_uecc_group_id grp_id;
} oid_ecp_grp_t;
#else
#if defined(MBEDTLS_ECP_C)
/*
* For namedCurve (RFC 5480)
@ -481,96 +452,77 @@ typedef struct {
mbedtls_oid_descriptor_t descriptor;
mbedtls_ecp_group_id grp_id;
} oid_ecp_grp_t;
#endif
#endif
#if defined(MBEDTLS_USE_TINYCRYPT)
static const oid_ecp_grp_t oid_ecp_grp[] =
{
{
OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_SECP256R1 , "secp256r1", "secp256r1" ),
MBEDTLS_UECC_DP_SECP256R1,
},
{
NULL_OID_DESCRIPTOR,
MBEDTLS_UECC_DP_NONE,
},
};
FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp)
FN_OID_GET_ATTR1(mbedtls_oid_get_ec_grp, oid_ecp_grp_t, grp_id, mbedtls_uecc_group_id, grp_id)
FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_ec_grp, oid_ecp_grp_t, oid_ecp_grp, mbedtls_uecc_group_id, grp_id)
#else
#if defined(MBEDTLS_ECP_C)
static const oid_ecp_grp_t oid_ecp_grp[] =
{
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
{
OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_SECP192R1, "secp192r1", "secp192r1" ),
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192R1 ), "secp192r1", "secp192r1" },
MBEDTLS_ECP_DP_SECP192R1,
},
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
{
OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_SECP224R1, "secp224r1", "secp224r1" ),
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224R1 ), "secp224r1", "secp224r1" },
MBEDTLS_ECP_DP_SECP224R1,
},
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
{
OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_SECP256R1, "secp256r1", "secp256r1" ),
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256R1 ), "secp256r1", "secp256r1" },
MBEDTLS_ECP_DP_SECP256R1,
},
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
{
OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_SECP384R1, "secp384r1", "secp384r1" ),
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP384R1 ), "secp384r1", "secp384r1" },
MBEDTLS_ECP_DP_SECP384R1,
},
#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
{
OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_SECP521R1, "secp521r1", "secp521r1" ),
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP521R1 ), "secp521r1", "secp521r1" },
MBEDTLS_ECP_DP_SECP521R1,
},
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
{
OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_SECP192K1, "secp192k1", "secp192k1" ),
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192K1 ), "secp192k1", "secp192k1" },
MBEDTLS_ECP_DP_SECP192K1,
},
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
{
OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_SECP224K1, "secp224k1", "secp224k1" ),
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224K1 ), "secp224k1", "secp224k1" },
MBEDTLS_ECP_DP_SECP224K1,
},
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
{
OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_SECP256K1, "secp256k1", "secp256k1" ),
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256K1 ), "secp256k1", "secp256k1" },
MBEDTLS_ECP_DP_SECP256K1,
},
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
{
OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_BP256R1, "brainpoolP256r1","brainpool256r1" ),
{ ADD_LEN( MBEDTLS_OID_EC_GRP_BP256R1 ), "brainpoolP256r1","brainpool256r1" },
MBEDTLS_ECP_DP_BP256R1,
},
#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
{
OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_BP384R1, "brainpoolP384r1","brainpool384r1" ),
{ ADD_LEN( MBEDTLS_OID_EC_GRP_BP384R1 ), "brainpoolP384r1","brainpool384r1" },
MBEDTLS_ECP_DP_BP384R1,
},
#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
{
OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_BP512R1, "brainpoolP512r1","brainpool512r1" ),
{ ADD_LEN( MBEDTLS_OID_EC_GRP_BP512R1 ), "brainpoolP512r1","brainpool512r1" },
MBEDTLS_ECP_DP_BP512R1,
},
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
{
NULL_OID_DESCRIPTOR,
{ NULL, 0, NULL, NULL },
MBEDTLS_ECP_DP_NONE,
},
};
@ -579,7 +531,6 @@ FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp)
FN_OID_GET_ATTR1(mbedtls_oid_get_ec_grp, oid_ecp_grp_t, grp_id, mbedtls_ecp_group_id, grp_id)
FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_ec_grp, oid_ecp_grp_t, oid_ecp_grp, mbedtls_ecp_group_id, grp_id)
#endif /* MBEDTLS_ECP_C */
#endif
#if defined(MBEDTLS_CIPHER_C)
/*
@ -593,15 +544,15 @@ typedef struct {
static const oid_cipher_alg_t oid_cipher_alg[] =
{
{
OID_DESCRIPTOR( MBEDTLS_OID_DES_CBC, "desCBC", "DES-CBC" ),
{ ADD_LEN( MBEDTLS_OID_DES_CBC ), "desCBC", "DES-CBC" },
MBEDTLS_CIPHER_DES_CBC,
},
{
OID_DESCRIPTOR( MBEDTLS_OID_DES_EDE3_CBC, "des-ede3-cbc", "DES-EDE3-CBC" ),
{ ADD_LEN( MBEDTLS_OID_DES_EDE3_CBC ), "des-ede3-cbc", "DES-EDE3-CBC" },
MBEDTLS_CIPHER_DES_EDE3_CBC,
},
{
NULL_OID_DESCRIPTOR,
{ NULL, 0, NULL, NULL },
MBEDTLS_CIPHER_NONE,
},
};
@ -623,50 +574,50 @@ static const oid_md_alg_t oid_md_alg[] =
{
#if defined(MBEDTLS_MD2_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_MD2, "id-md2", "MD2" ),
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD2 ), "id-md2", "MD2" },
MBEDTLS_MD_MD2,
},
#endif /* MBEDTLS_MD2_C */
#if defined(MBEDTLS_MD4_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_MD4, "id-md4", "MD4" ),
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD4 ), "id-md4", "MD4" },
MBEDTLS_MD_MD4,
},
#endif /* MBEDTLS_MD4_C */
#if defined(MBEDTLS_MD5_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_MD5, "id-md5", "MD5" ),
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD5 ), "id-md5", "MD5" },
MBEDTLS_MD_MD5,
},
#endif /* MBEDTLS_MD5_C */
#if defined(MBEDTLS_SHA1_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_SHA1, "id-sha1", "SHA-1" ),
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA1 ), "id-sha1", "SHA-1" },
MBEDTLS_MD_SHA1,
},
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA256_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_SHA224, "id-sha224", "SHA-224" ),
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA224 ), "id-sha224", "SHA-224" },
MBEDTLS_MD_SHA224,
},
{
OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_SHA256, "id-sha256", "SHA-256" ),
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA256 ), "id-sha256", "SHA-256" },
MBEDTLS_MD_SHA256,
},
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_SHA384, "id-sha384", "SHA-384" ),
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA384 ), "id-sha384", "SHA-384" },
MBEDTLS_MD_SHA384,
},
{
OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_SHA512, "id-sha512", "SHA-512" ),
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA512 ), "id-sha512", "SHA-512" },
MBEDTLS_MD_SHA512,
},
#endif /* MBEDTLS_SHA512_C */
{
NULL_OID_DESCRIPTOR,
{ NULL, 0, NULL, NULL },
MBEDTLS_MD_NONE,
},
};
@ -687,32 +638,32 @@ static const oid_md_hmac_t oid_md_hmac[] =
{
#if defined(MBEDTLS_SHA1_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_HMAC_SHA1, "hmacSHA1", "HMAC-SHA-1" ),
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA1 ), "hmacSHA1", "HMAC-SHA-1" },
MBEDTLS_MD_SHA1,
},
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA256_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_HMAC_SHA224, "hmacSHA224", "HMAC-SHA-224" ),
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA224 ), "hmacSHA224", "HMAC-SHA-224" },
MBEDTLS_MD_SHA224,
},
{
OID_DESCRIPTOR( MBEDTLS_OID_HMAC_SHA256, "hmacSHA256", "HMAC-SHA-256" ),
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA256 ), "hmacSHA256", "HMAC-SHA-256" },
MBEDTLS_MD_SHA256,
},
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
{
OID_DESCRIPTOR( MBEDTLS_OID_HMAC_SHA384, "hmacSHA384", "HMAC-SHA-384" ),
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA384 ), "hmacSHA384", "HMAC-SHA-384" },
MBEDTLS_MD_SHA384,
},
{
OID_DESCRIPTOR( MBEDTLS_OID_HMAC_SHA512, "hmacSHA512", "HMAC-SHA-512" ),
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA512 ), "hmacSHA512", "HMAC-SHA-512" },
MBEDTLS_MD_SHA512,
},
#endif /* MBEDTLS_SHA512_C */
{
NULL_OID_DESCRIPTOR,
{ NULL, 0, NULL, NULL },
MBEDTLS_MD_NONE,
},
};
@ -734,15 +685,15 @@ typedef struct {
static const oid_pkcs12_pbe_alg_t oid_pkcs12_pbe_alg[] =
{
{
OID_DESCRIPTOR( MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC, "pbeWithSHAAnd3-KeyTripleDES-CBC", "PBE with SHA1 and 3-Key 3DES" ),
{ ADD_LEN( MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC ), "pbeWithSHAAnd3-KeyTripleDES-CBC", "PBE with SHA1 and 3-Key 3DES" },
MBEDTLS_MD_SHA1, MBEDTLS_CIPHER_DES_EDE3_CBC,
},
{
OID_DESCRIPTOR( MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC, "pbeWithSHAAnd2-KeyTripleDES-CBC", "PBE with SHA1 and 2-Key 3DES" ),
{ ADD_LEN( MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC ), "pbeWithSHAAnd2-KeyTripleDES-CBC", "PBE with SHA1 and 2-Key 3DES" },
MBEDTLS_MD_SHA1, MBEDTLS_CIPHER_DES_EDE_CBC,
},
{
NULL_OID_DESCRIPTOR,
{ NULL, 0, NULL, NULL },
MBEDTLS_MD_NONE, MBEDTLS_CIPHER_NONE,
},
};

View File

@ -97,8 +97,6 @@
/* ISO arc for standard certificate and CRL extensions */
#define MBEDTLS_OID_ID_CE MBEDTLS_OID_ISO_CCITT_DS "\x1D" /**< id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29} */
#define MBEDTLS_OID_NIST_ALG MBEDTLS_OID_GOV "\x03\x04" /** { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) */
/**
* Private Internet Extensions
* { iso(1) identified-organization(3) dod(6) internet(1)
@ -221,12 +219,12 @@
#define MBEDTLS_OID_DIGEST_ALG_MD4 MBEDTLS_OID_RSA_COMPANY "\x02\x04" /**< id-mbedtls_md4 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 4 } */
#define MBEDTLS_OID_DIGEST_ALG_MD5 MBEDTLS_OID_RSA_COMPANY "\x02\x05" /**< id-mbedtls_md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 } */
#define MBEDTLS_OID_DIGEST_ALG_SHA1 MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_OIW_SECSIG_SHA1 /**< id-mbedtls_sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } */
#define MBEDTLS_OID_DIGEST_ALG_SHA224 MBEDTLS_OID_NIST_ALG "\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 MBEDTLS_OID_DIGEST_ALG_SHA256 MBEDTLS_OID_NIST_ALG "\x02\x01" /**< id-mbedtls_sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */
#define MBEDTLS_OID_DIGEST_ALG_SHA224 MBEDTLS_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 MBEDTLS_OID_DIGEST_ALG_SHA256 MBEDTLS_OID_GOV "\x03\x04\x02\x01" /**< id-mbedtls_sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */
#define MBEDTLS_OID_DIGEST_ALG_SHA384 MBEDTLS_OID_NIST_ALG "\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 MBEDTLS_OID_DIGEST_ALG_SHA384 MBEDTLS_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 MBEDTLS_OID_DIGEST_ALG_SHA512 MBEDTLS_OID_NIST_ALG "\x02\x03" /**< id-mbedtls_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */
#define MBEDTLS_OID_DIGEST_ALG_SHA512 MBEDTLS_OID_GOV "\x03\x04\x02\x03" /**< id-mbedtls_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */
#define MBEDTLS_OID_HMAC_SHA1 MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */
@ -243,20 +241,7 @@
*/
#define MBEDTLS_OID_DES_CBC MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_OIW_SECSIG_ALG "\x07" /**< desCBC OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 7 } */
#define MBEDTLS_OID_DES_EDE3_CBC MBEDTLS_OID_RSA_COMPANY "\x03\x07" /**< des-ede3-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2) -- us(840) rsadsi(113549) encryptionAlgorithm(3) 7 } */
#define MBEDTLS_OID_AES MBEDTLS_OID_NIST_ALG "\x01" /** aes OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) 1 } */
/*
* Key Wrapping algorithms
*/
/*
* RFC 5649
*/
#define MBEDTLS_OID_AES128_KW MBEDTLS_OID_AES "\x05" /** id-aes128-wrap OBJECT IDENTIFIER ::= { aes 5 } */
#define MBEDTLS_OID_AES128_KWP MBEDTLS_OID_AES "\x08" /** id-aes128-wrap-pad OBJECT IDENTIFIER ::= { aes 8 } */
#define MBEDTLS_OID_AES192_KW MBEDTLS_OID_AES "\x19" /** id-aes192-wrap OBJECT IDENTIFIER ::= { aes 25 } */
#define MBEDTLS_OID_AES192_KWP MBEDTLS_OID_AES "\x1c" /** id-aes192-wrap-pad OBJECT IDENTIFIER ::= { aes 28 } */
#define MBEDTLS_OID_AES256_KW MBEDTLS_OID_AES "\x2d" /** id-aes256-wrap OBJECT IDENTIFIER ::= { aes 45 } */
#define MBEDTLS_OID_AES256_KWP MBEDTLS_OID_AES "\x30" /** id-aes256-wrap-pad OBJECT IDENTIFIER ::= { aes 48 } */
/*
* PKCS#5 OIDs
*/
@ -403,14 +388,11 @@ extern "C" {
/**
* \brief Base OID descriptor structure
*/
typedef struct mbedtls_oid_descriptor_t
{
typedef struct {
const char *asn1; /*!< OID ASN.1 representation */
size_t asn1_len; /*!< length of asn1 */
#if !defined(MBEDTLS_X509_REMOVE_INFO)
const char *name; /*!< official name (e.g. from RFC) */
const char *description; /*!< human friendly description */
#endif
} mbedtls_oid_descriptor_t;
/**
@ -471,18 +453,6 @@ int mbedtls_oid_get_pk_alg( const mbedtls_asn1_buf *oid, mbedtls_pk_type_t *pk_a
int mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_type_t pk_alg,
const char **oid, size_t *olen );
#if defined(MBEDTLS_USE_TINYCRYPT)
typedef enum
{
MBEDTLS_UECC_DP_NONE = 0, /*!< Curve not defined. */
MBEDTLS_UECC_DP_SECP256R1, /*!< Domain parameters for the 256-bit curve defined by FIPS 186-4 and SEC1. */
} mbedtls_uecc_group_id;
int mbedtls_oid_get_ec_grp( const mbedtls_asn1_buf *oid, mbedtls_uecc_group_id *grp_id );
int mbedtls_oid_get_oid_by_ec_grp( mbedtls_uecc_group_id grp_id,
const char **oid, size_t *olen);
#else
#if defined(MBEDTLS_ECP_C)
/**
* \brief Translate NamedCurve OID into an EC group identifier
@ -506,7 +476,6 @@ int mbedtls_oid_get_ec_grp( const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *g
int mbedtls_oid_get_oid_by_ec_grp( mbedtls_ecp_group_id grp_id,
const char **oid, size_t *olen );
#endif /* MBEDTLS_ECP_C */
#endif
#if defined(MBEDTLS_MD_C)
/**
@ -565,7 +534,6 @@ int mbedtls_oid_get_md_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_a
int mbedtls_oid_get_md_hmac( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_hmac );
#endif /* MBEDTLS_MD_C */
#if !defined(MBEDTLS_X509_REMOVE_INFO)
/**
* \brief Translate Extended Key Usage OID into description
*
@ -575,7 +543,6 @@ int mbedtls_oid_get_md_hmac( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_extended_key_usage( const mbedtls_asn1_buf *oid, const char **desc );
#endif
/**
* \brief Translate md_type into hash algorithm OID

View File

@ -0,0 +1,170 @@
/*
* VIA PadLock support 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 TLS (https://tls.mbed.org)
*/
/*
* This implementation is based on the VIA PadLock Programming Guide:
*
* http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/
* programming_guide.pdf
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_PADLOCK_C)
#include "padlock.h"
#include <string.h>
#ifndef asm
#define asm __asm
#endif
#if defined(MBEDTLS_HAVE_X86)
/*
* PadLock detection routine
*/
int mbedtls_padlock_has_support( int feature )
{
static int flags = -1;
int ebx = 0, edx = 0;
if( flags == -1 )
{
asm( "movl %%ebx, %0 \n\t"
"movl $0xC0000000, %%eax \n\t"
"cpuid \n\t"
"cmpl $0xC0000001, %%eax \n\t"
"movl $0, %%edx \n\t"
"jb unsupported \n\t"
"movl $0xC0000001, %%eax \n\t"
"cpuid \n\t"
"unsupported: \n\t"
"movl %%edx, %1 \n\t"
"movl %2, %%ebx \n\t"
: "=m" (ebx), "=m" (edx)
: "m" (ebx)
: "eax", "ecx", "edx" );
flags = edx;
}
return( flags & feature );
}
/*
* PadLock AES-ECB block en(de)cryption
*/
int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] )
{
int ebx = 0;
uint32_t *rk;
uint32_t *blk;
uint32_t *ctrl;
unsigned char buf[256];
rk = ctx->rk;
blk = MBEDTLS_PADLOCK_ALIGN16( buf );
memcpy( blk, input, 16 );
ctrl = blk + 4;
*ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 );
asm( "pushfl \n\t"
"popfl \n\t"
"movl %%ebx, %0 \n\t"
"movl $1, %%ecx \n\t"
"movl %2, %%edx \n\t"
"movl %3, %%ebx \n\t"
"movl %4, %%esi \n\t"
"movl %4, %%edi \n\t"
".byte 0xf3,0x0f,0xa7,0xc8 \n\t"
"movl %1, %%ebx \n\t"
: "=m" (ebx)
: "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk)
: "memory", "ecx", "edx", "esi", "edi" );
memcpy( output, blk, 16 );
return( 0 );
}
/*
* PadLock AES-CBC buffer en(de)cryption
*/
int mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output )
{
int ebx = 0;
size_t count;
uint32_t *rk;
uint32_t *iw;
uint32_t *ctrl;
unsigned char buf[256];
if( ( (long) input & 15 ) != 0 ||
( (long) output & 15 ) != 0 )
return( MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED );
rk = ctx->rk;
iw = MBEDTLS_PADLOCK_ALIGN16( buf );
memcpy( iw, iv, 16 );
ctrl = iw + 4;
*ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode ^ 1 ) - 10 ) << 9 );
count = ( length + 15 ) >> 4;
asm( "pushfl \n\t"
"popfl \n\t"
"movl %%ebx, %0 \n\t"
"movl %2, %%ecx \n\t"
"movl %3, %%edx \n\t"
"movl %4, %%ebx \n\t"
"movl %5, %%esi \n\t"
"movl %6, %%edi \n\t"
"movl %7, %%eax \n\t"
".byte 0xf3,0x0f,0xa7,0xd0 \n\t"
"movl %1, %%ebx \n\t"
: "=m" (ebx)
: "m" (ebx), "m" (count), "m" (ctrl),
"m" (rk), "m" (input), "m" (output), "m" (iw)
: "memory", "eax", "ecx", "edx", "esi", "edi" );
memcpy( iv, iw, 16 );
return( 0 );
}
#endif /* MBEDTLS_HAVE_X86 */
#endif /* MBEDTLS_PADLOCK_C */

View File

@ -3,9 +3,6 @@
*
* \brief VIA PadLock ACE for HW encryption/decryption supported by some
* processors
*
* \warning These functions are only for internal use by other library
* functions; you must not call them directly.
*/
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
@ -59,17 +56,14 @@
#define MBEDTLS_PADLOCK_PHE 0x0C00
#define MBEDTLS_PADLOCK_PMM 0x3000
#define MBEDTLS_PADLOCK_ALIGN16(x) (uint32_t *) (16 + ((int32_t) (x) & ~15))
#define MBEDTLS_PADLOCK_ALIGN16(x) (uint32_t *) (16 + ((int32_t) x & ~15))
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Internal PadLock detection routine
*
* \note This function is only for internal use by other library
* functions; you must not call it directly.
* \brief PadLock detection routine
*
* \param feature The feature to detect
*
@ -78,10 +72,7 @@ extern "C" {
int mbedtls_padlock_has_support( int feature );
/**
* \brief Internal PadLock AES-ECB block en(de)cryption
*
* \note This function is only for internal use by other library
* functions; you must not call it directly.
* \brief PadLock AES-ECB block en(de)cryption
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
@ -91,15 +82,12 @@ int mbedtls_padlock_has_support( int feature );
* \return 0 if success, 1 if operation failed
*/
int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
int mode,
const unsigned char input[16],
unsigned char output[16] );
/**
* \brief Internal PadLock AES-CBC buffer en(de)cryption
*
* \note This function is only for internal use by other library
* functions; you must not call it directly.
* \brief PadLock AES-CBC buffer en(de)cryption
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
@ -111,11 +99,11 @@ int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx,
* \return 0 if success, 1 if operation failed
*/
int mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#ifdef __cplusplus
}

View File

@ -33,7 +33,6 @@
#include "aes.h"
#include "md5.h"
#include "cipher.h"
#include "platform_util.h"
#include <string.h>
@ -46,9 +45,14 @@
#endif
#if defined(MBEDTLS_PEM_PARSE_C)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
void mbedtls_pem_init( mbedtls_pem_context *ctx )
{
mbedtls_platform_memset( ctx, 0, sizeof( mbedtls_pem_context ) );
memset( ctx, 0, sizeof( mbedtls_pem_context ) );
}
#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \
@ -61,7 +65,7 @@ static int pem_get_iv( const unsigned char *s, unsigned char *iv,
{
size_t i, j, k;
mbedtls_platform_memset( iv, 0, iv_len );
memset( iv, 0, iv_len );
for( i = 0; i < iv_len * 2; i++, s++ )
{
@ -103,11 +107,11 @@ static int pem_pbkdf1( unsigned char *key, size_t keylen,
if( keylen <= 16 )
{
mbedtls_platform_memcpy( key, md5sum, keylen );
memcpy( key, md5sum, keylen );
goto exit;
}
mbedtls_platform_memcpy( key, md5sum, 16 );
memcpy( key, md5sum, 16 );
/*
* key[16..23] = MD5(key[ 0..15] || pwd || IV])
@ -127,11 +131,11 @@ static int pem_pbkdf1( unsigned char *key, size_t keylen,
if( keylen < 32 )
use_len = keylen - 16;
mbedtls_platform_memcpy( key + 16, md5sum, use_len );
memcpy( key + 16, md5sum, use_len );
exit:
mbedtls_md5_free( &md5_ctx );
mbedtls_platform_zeroize( md5sum, 16 );
mbedtls_zeroize( md5sum, 16 );
return( ret );
}
@ -160,7 +164,7 @@ static int pem_des_decrypt( unsigned char des_iv[8],
exit:
mbedtls_des_free( &des_ctx );
mbedtls_platform_zeroize( des_key, 8 );
mbedtls_zeroize( des_key, 8 );
return( ret );
}
@ -188,7 +192,7 @@ static int pem_des3_decrypt( unsigned char des3_iv[8],
exit:
mbedtls_des3_free( &des3_ctx );
mbedtls_platform_zeroize( des3_key, 24 );
mbedtls_zeroize( des3_key, 24 );
return( ret );
}
@ -218,7 +222,7 @@ static int pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen,
exit:
mbedtls_aes_free( &aes_ctx );
mbedtls_platform_zeroize( aes_key, keylen );
mbedtls_zeroize( aes_key, keylen );
return( ret );
}
@ -273,7 +277,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
enc = 0;
if( s2 - s1 >= 22 && mbedtls_platform_memequal( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
if( s2 - s1 >= 22 && memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
{
#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \
( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
@ -286,7 +290,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
#if defined(MBEDTLS_DES_C)
if( s2 - s1 >= 23 && mbedtls_platform_memequal( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 )
if( s2 - s1 >= 23 && memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 )
{
enc_alg = MBEDTLS_CIPHER_DES_EDE3_CBC;
@ -296,7 +300,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
s1 += 16;
}
else if( s2 - s1 >= 18 && mbedtls_platform_memequal( s1, "DEK-Info: DES-CBC,", 18 ) == 0 )
else if( s2 - s1 >= 18 && memcmp( s1, "DEK-Info: DES-CBC,", 18 ) == 0 )
{
enc_alg = MBEDTLS_CIPHER_DES_CBC;
@ -309,15 +313,15 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
#endif /* MBEDTLS_DES_C */
#if defined(MBEDTLS_AES_C)
if( s2 - s1 >= 14 && mbedtls_platform_memequal( s1, "DEK-Info: AES-", 14 ) == 0 )
if( s2 - s1 >= 14 && memcmp( s1, "DEK-Info: AES-", 14 ) == 0 )
{
if( s2 - s1 < 22 )
return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG );
else if( mbedtls_platform_memequal( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 )
else if( memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 )
enc_alg = MBEDTLS_CIPHER_AES_128_CBC;
else if( mbedtls_platform_memequal( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 )
else if( memcmp( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 )
enc_alg = MBEDTLS_CIPHER_AES_192_CBC;
else if( mbedtls_platform_memequal( s1, "DEK-Info: AES-256-CBC,", 22 ) == 0 )
else if( memcmp( s1, "DEK-Info: AES-256-CBC,", 22 ) == 0 )
enc_alg = MBEDTLS_CIPHER_AES_256_CBC;
else
return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG );
@ -355,7 +359,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
if( ( ret = mbedtls_base64_decode( buf, len, &len, s1, s2 - s1 ) ) != 0 )
{
mbedtls_platform_zeroize( buf, len );
mbedtls_zeroize( buf, len );
mbedtls_free( buf );
return( MBEDTLS_ERR_PEM_INVALID_DATA + ret );
}
@ -366,7 +370,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
if( pwd == NULL )
{
mbedtls_platform_zeroize( buf, len );
mbedtls_zeroize( buf, len );
mbedtls_free( buf );
return( MBEDTLS_ERR_PEM_PASSWORD_REQUIRED );
}
@ -399,16 +403,16 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
* The result will be ASN.1 starting with a SEQUENCE tag, with 1 to 3
* length bytes (allow 4 to be sure) in all known use cases.
*
* Use that as a heuristic to try to detect password mismatches.
* Use that as heurisitic to try detecting password mismatchs.
*/
if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 )
{
mbedtls_platform_zeroize( buf, len );
mbedtls_zeroize( buf, len );
mbedtls_free( buf );
return( MBEDTLS_ERR_PEM_PASSWORD_MISMATCH );
}
#else
mbedtls_platform_zeroize( buf, len );
mbedtls_zeroize( buf, len );
mbedtls_free( buf );
return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE );
#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
@ -423,14 +427,12 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
void mbedtls_pem_free( mbedtls_pem_context *ctx )
{
if ( ctx->buf != NULL )
{
mbedtls_platform_zeroize( ctx->buf, ctx->buflen );
mbedtls_free( ctx->buf );
}
if( ctx->buf != NULL )
mbedtls_zeroize( ctx->buf, ctx->buflen );
mbedtls_free( ctx->buf );
mbedtls_free( ctx->info );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pem_context ) );
mbedtls_zeroize( ctx, sizeof( mbedtls_pem_context ) );
}
#endif /* MBEDTLS_PEM_PARSE_C */
@ -463,21 +465,21 @@ int mbedtls_pem_write_buffer( const char *header, const char *footer,
return( ret );
}
mbedtls_platform_memcpy( p, header, strlen( header ) );
memcpy( p, header, strlen( header ) );
p += strlen( header );
c = encode_buf;
while( use_len )
{
len = ( use_len > 64 ) ? 64 : use_len;
mbedtls_platform_memcpy( p, c, len );
memcpy( p, c, len );
use_len -= len;
p += len;
c += len;
*p++ = '\n';
}
mbedtls_platform_memcpy( p, footer, strlen( footer ) );
memcpy( p, footer, strlen( footer ) );
p += strlen( footer );
*p++ = '\0';

View File

@ -57,7 +57,7 @@ extern "C" {
/**
* \brief PEM context structure
*/
typedef struct mbedtls_pem_context
typedef struct
{
unsigned char *buf; /*!< buffer for decoded data */
size_t buflen; /*!< length of the buffer */

File diff suppressed because it is too large Load Diff

View File

@ -45,14 +45,6 @@
#include "ecdsa.h"
#endif
#if defined(MBEDTLS_USE_TINYCRYPT)
#include "tinycrypt/ecc.h"
#endif
#if defined(MBEDTLS_PK_SINGLE_TYPE)
#include "pk_internal.h"
#endif
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
@ -72,8 +64,6 @@
#define MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE -0x3A00 /**< Elliptic curve is unsupported (only NIST curves are supported). */
#define MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -0x3980 /**< Unavailable feature, e.g. RSA disabled for RSA key. */
#define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH -0x3900 /**< The buffer contains a valid signature followed by more data. */
/* MBEDTLS_ERR_PK_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_PK_HW_ACCEL_FAILED -0x3880 /**< PK hardware accelerator failed. */
#ifdef __cplusplus
@ -97,7 +87,7 @@ typedef enum {
* \brief Options for RSASSA-PSS signature verification.
* See \c mbedtls_rsa_rsassa_pss_verify_ext()
*/
typedef struct mbedtls_pk_rsassa_pss_options
typedef struct
{
mbedtls_md_type_t mgf1_hash_id;
int expected_salt_len;
@ -117,7 +107,7 @@ typedef enum
/**
* \brief Item to send to the debug module
*/
typedef struct mbedtls_pk_debug_item
typedef struct
{
mbedtls_pk_debug_type type;
const char *name;
@ -130,54 +120,16 @@ typedef struct mbedtls_pk_debug_item
/**
* \brief Public key information and operations
*/
#if defined(MBEDTLS_PK_SINGLE_TYPE)
typedef enum {
MBEDTLS_PK_INVALID_HANDLE,
MBEDTLS_PK_UNIQUE_VALID_HANDLE,
} mbedtls_pk_handle_t;
#else /* MBEDTLS_PK_SINGLE_TYPE */
typedef struct mbedtls_pk_info_t mbedtls_pk_info_t;
typedef const mbedtls_pk_info_t *mbedtls_pk_handle_t;
#define MBEDTLS_PK_INVALID_HANDLE ( (mbedtls_pk_handle_t) NULL )
#endif /* MBEDTLS_PK_SINGLE_TYPE */
#if defined(MBEDTLS_USE_TINYCRYPT)
typedef struct
{
uint8_t private_key[NUM_ECC_BYTES];
uint8_t public_key[2*NUM_ECC_BYTES];
} mbedtls_uecc_keypair;
#endif
/**
* \brief Public key container
*/
typedef struct mbedtls_pk_context
{
#if defined(MBEDTLS_PK_SINGLE_TYPE)
/* This is an array to make access to it more uniform with the case where
* it's a pointer to void - either way it needs casting before use. */
unsigned char pk_ctx[sizeof(
MBEDTLS_PK_INFO_CONTEXT( MBEDTLS_PK_SINGLE_TYPE ) )];
#else
mbedtls_pk_handle_t pk_info; /**< Public key information */
void * pk_ctx; /**< Underlying public key context */
#endif
} mbedtls_pk_context;
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief Context for resuming operations
*/
typedef struct
{
mbedtls_pk_handle_t pk_info; /**< Public key information */
void * rs_ctx; /**< Underlying restart context */
} mbedtls_pk_restart_ctx;
#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
/* Now we can declare functions that take a pointer to that */
typedef void mbedtls_pk_restart_ctx;
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
const mbedtls_pk_info_t * pk_info; /**< Public key informations */
void * pk_ctx; /**< Underlying public key context */
} mbedtls_pk_context;
#if defined(MBEDTLS_RSA_C)
/**
@ -192,20 +144,6 @@ static inline mbedtls_rsa_context *mbedtls_pk_rsa( const mbedtls_pk_context pk )
}
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_USE_TINYCRYPT)
#if !defined(MBEDTLS_PK_SINGLE_TYPE)
static inline mbedtls_uecc_keypair *mbedtls_pk_uecc( const mbedtls_pk_context pk )
{
return( (mbedtls_uecc_keypair *) (pk).pk_ctx );
}
#else
/* Go with a macro in order to avoid making a copy of the struct (the argument
* is not a pointer so it's passed by value) and then returning an address
* inside that copy, which would be undefined behaviour. */
#define mbedtls_pk_uecc( pk ) ( (mbedtls_uecc_keypair *) (pk).pk_ctx )
#endif
#endif /* MBEDTLS_USE_TINYCRYPT */
#if defined(MBEDTLS_ECP_C)
/**
* Quick access to an EC context inside a PK context.
@ -240,48 +178,23 @@ typedef size_t (*mbedtls_pk_rsa_alt_key_len_func)( void *ctx );
*
* \return The PK info associated with the type or NULL if not found.
*/
mbedtls_pk_handle_t mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type );
const mbedtls_pk_info_t *mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type );
/**
* \brief Initialize a #mbedtls_pk_context (as NONE).
*
* \param ctx The context to initialize.
* This must not be \c NULL.
* \brief Initialize a mbedtls_pk_context (as NONE)
*/
void mbedtls_pk_init( mbedtls_pk_context *ctx );
/**
* \brief Free the components of a #mbedtls_pk_context.
*
* \param ctx The context to clear. It must have been initialized.
* If this is \c NULL, this function does nothing.
* \brief Free a mbedtls_pk_context
*/
void mbedtls_pk_free( mbedtls_pk_context *ctx );
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief Initialize a restart context
*
* \param ctx The context to initialize.
* This must not be \c NULL.
*/
void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx );
/**
* \brief Free the components of a restart context
*
* \param ctx The context to clear. It must have been initialized.
* If this is \c NULL, this function does nothing.
*/
void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx );
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
/**
* \brief Initialize a PK context with the information given
* and allocates the type-specific PK subcontext.
*
* \param ctx Context to initialize. It must not have been set
* up yet (type #MBEDTLS_PK_NONE).
* \param ctx Context to initialize. Must be empty (type NONE).
* \param info Information to use
*
* \return 0 on success,
@ -291,14 +204,13 @@ void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx );
* \note For contexts holding an RSA-alt key, use
* \c mbedtls_pk_setup_rsa_alt() instead.
*/
int mbedtls_pk_setup( mbedtls_pk_context *ctx, mbedtls_pk_handle_t info );
int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info );
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
/**
* \brief Initialize an RSA-alt context
*
* \param ctx Context to initialize. It must not have been set
* up yet (type #MBEDTLS_PK_NONE).
* \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
@ -318,7 +230,7 @@ int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
/**
* \brief Get the size in bits of the underlying key
*
* \param ctx The context to query. It must have been initialized.
* \param ctx Context to use
*
* \return Key size in bits, or 0 on error
*/
@ -326,8 +238,7 @@ size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx );
/**
* \brief Get the length in bytes of the underlying key
*
* \param ctx The context to query. It must have been initialized.
* \param ctx Context to use
*
* \return Key length in bytes, or 0 on error
*/
@ -339,21 +250,18 @@ static inline size_t mbedtls_pk_get_len( const mbedtls_pk_context *ctx )
/**
* \brief Tell if a context can do the operation given by type
*
* \param ctx The context to query. It must have been initialized.
* \param type The desired type.
* \param ctx Context to test
* \param type Target type
*
* \return 1 if the context can do operations on the given type.
* \return 0 if the context cannot do the operations on the given
* type. This is always the case for a context that has
* been initialized but not set up, or that has been
* cleared with mbedtls_pk_free().
* \return 0 if context can't do the operations,
* 1 otherwise.
*/
int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type );
/**
* \brief Verify signature (including padding if relevant).
*
* \param ctx The PK context to use. It must have been set up.
* \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)
@ -378,39 +286,13 @@ int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len );
/**
* \brief Restartable version of \c mbedtls_pk_verify()
*
* \note Performs the same job as \c mbedtls_pk_verify(), but can
* return early and restart according to the limit set with
* \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC
* operations. For RSA, same as \c mbedtls_pk_verify().
*
* \param ctx The PK context to use. It must have been set up.
* \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
* \param rs_ctx Restart context (NULL to disable restart)
*
* \return See \c mbedtls_pk_verify(), or
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
*/
int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len,
mbedtls_pk_restart_ctx *rs_ctx );
/**
* \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 The PK context to use. It must have been set up.
* \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)
@ -441,8 +323,7 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
/**
* \brief Make signature, including padding if relevant.
*
* \param ctx The PK context to use. It must have been set up
* with a private key.
* \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)
@ -462,55 +343,16 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
*
* \note For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0.
* For ECDSA, md_alg may never be MBEDTLS_MD_NONE.
*
* \note In order to ensure enough space for the signature, the
* \p sig buffer size must be of at least
* `max(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)` bytes.
*/
int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_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 Restartable version of \c mbedtls_pk_sign()
*
* \note Performs the same job as \c mbedtls_pk_sign(), but can
* return early and restart according to the limit set with
* \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC
* operations. For RSA, same as \c mbedtls_pk_sign().
*
* \note In order to ensure enough space for the signature, the
* \p sig buffer size must be of at least
* `max(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)` bytes.
*
* \param ctx The PK context to use. It must have been set up
* with 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
* \param rs_ctx Restart context (NULL to disable restart)
*
* \return See \c mbedtls_pk_sign(), or
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
*/
int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
mbedtls_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,
mbedtls_pk_restart_ctx *rs_ctx );
/**
* \brief Decrypt message (including padding if relevant).
*
* \param ctx The PK context to use. It must have been set up
* with a private key.
* \param ctx PK context to use - must hold a private key
* \param input Input to decrypt
* \param ilen Input size
* \param output Decrypted output
@ -531,7 +373,7 @@ int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
/**
* \brief Encrypt message (including padding if relevant).
*
* \param ctx The PK context to use. It must have been set up.
* \param ctx PK context to use
* \param input Message to encrypt
* \param ilen Message size
* \param output Encrypted output
@ -562,7 +404,7 @@ int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_conte
/**
* \brief Export debug information
*
* \param ctx The PK context to use. It must have been initialized.
* \param ctx Context to use
* \param items Place to write debug items
*
* \return 0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA
@ -572,7 +414,7 @@ int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *item
/**
* \brief Access the type name
*
* \param ctx The PK context to use. It must have been initialized.
* \param ctx Context to use
*
* \return Type name on success, or "invalid PK"
*/
@ -581,10 +423,9 @@ const char * mbedtls_pk_get_name( const mbedtls_pk_context *ctx );
/**
* \brief Get the key type
*
* \param ctx The PK context to use. It must have been initialized.
* \param ctx Context to use
*
* \return Type on success.
* \return #MBEDTLS_PK_NONE for a context that has not been set up.
* \return Type on success, or MBEDTLS_PK_NONE
*/
mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx );
@ -593,22 +434,12 @@ mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx );
/**
* \brief Parse a private key in PEM or DER format
*
* \param ctx The PK context to fill. It must have been initialized
* but not set up.
* \param key Input buffer to parse.
* The buffer must contain the input exactly, with no
* extra trailing material. For PEM, the buffer must
* contain a null-terminated string.
* \param keylen Size of \b key in bytes.
* For PEM data, this includes the terminating null byte,
* so \p keylen must be equal to `strlen(key) + 1`.
* \param pwd Optional password for decryption.
* Pass \c NULL if expecting a non-encrypted key.
* Pass a string of \p pwdlen bytes if expecting an encrypted
* key; a non-encrypted key will also be accepted.
* The empty password is not supported.
* \param pwdlen Size of the password in bytes.
* Ignored if \p pwd is \c NULL.
* \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 mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
@ -626,15 +457,10 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *ctx,
/**
* \brief Parse a public key in PEM or DER format
*
* \param ctx The PK context to fill. It must have been initialized
* but not set up.
* \param key Input buffer to parse.
* The buffer must contain the input exactly, with no
* extra trailing material. For PEM, the buffer must
* contain a null-terminated string.
* \param keylen Size of \b key in bytes.
* For PEM data, this includes the terminating null byte,
* so \p keylen must be equal to `strlen(key) + 1`.
* \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 mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
@ -652,14 +478,9 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
/**
* \brief Load and parse a private key
*
* \param ctx The PK context to fill. It must have been initialized
* but not set up.
* \param ctx key to be initialized
* \param path filename to read the private key from
* \param password Optional password to decrypt the file.
* Pass \c NULL if expecting a non-encrypted key.
* Pass a null-terminated string if expecting an encrypted
* key; a non-encrypted key will also be accepted.
* The empty password is not supported.
* \param password password to decrypt the file (can be NULL)
*
* \note On entry, ctx must be empty, either freshly initialised
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
@ -676,8 +497,7 @@ int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
/**
* \brief Load and parse a public key
*
* \param ctx The PK context to fill. It must have been initialized
* but not set up.
* \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
@ -700,7 +520,7 @@ int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path )
* return value to determine where you should start
* using the buffer
*
* \param ctx PK context which must contain a valid private key.
* \param ctx private to write away
* \param buf buffer to write to
* \param size size of the buffer
*
@ -715,7 +535,7 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *ctx, unsigned char *buf, size_
* return value to determine where you should start
* using the buffer
*
* \param ctx PK context which must contain a valid public or private key.
* \param ctx public key to write away
* \param buf buffer to write to
* \param size size of the buffer
*
@ -728,10 +548,9 @@ int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *ctx, unsigned char *buf, si
/**
* \brief Write a public key to a PEM string
*
* \param ctx PK context which must contain a valid public or private key.
* \param buf Buffer to write to. The output includes a
* terminating null byte.
* \param size Size of the buffer in bytes.
* \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
*/
@ -740,10 +559,9 @@ int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *ctx, unsigned char *buf, si
/**
* \brief Write a private key to a PKCS#1 or SEC1 PEM string
*
* \param ctx PK context which must contain a valid private key.
* \param buf Buffer to write to. The output includes a
* terminating null byte.
* \param size Size of the buffer in bytes.
* \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
*/
@ -762,8 +580,7 @@ int mbedtls_pk_write_key_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_
*
* \param p the position in the ASN.1 data
* \param end end of the buffer
* \param pk The PK context to fill. It must have been initialized
* but not set up.
* \param pk the key to fill
*
* \return 0 if successful, or a specific PK error code
*/
@ -778,7 +595,7 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
*
* \param p reference to current position pointer
* \param start start of the buffer (for bounds-checking)
* \param key PK context which must contain a valid public or private key.
* \param key public key to write away
*
* \return the length written or a negative error code
*/

View File

@ -33,90 +33,6 @@
#include "pk.h"
/*
* PK information macro definitions
*/
/*
* Each PK type that can be used with MBEDTLS_PK_SINGLE_TYPE needs to have
* the following MBEDTLS_PK_INFO_{FIELD} definitions, plus a dummy one for the
* base name. For now, only ECKEY with MBEDTLS_USE_TINYCRYPT is defined.
*
* For optional functions that are omitted, we need both the _FUNC field
* defined to NULL, and an extra macro _OMIT defined to 1.
*/
#if defined(MBEDTLS_USE_TINYCRYPT)
/* Dummy definition to keep check-names.sh happy - don't uncomment */
//#define MBEDTLS_PK_INFO_ECKEY
#define MBEDTLS_PK_INFO_ECKEY_CONTEXT mbedtls_uecc_keypair
#define MBEDTLS_PK_INFO_ECKEY_TYPE MBEDTLS_PK_ECKEY
#define MBEDTLS_PK_INFO_ECKEY_NAME "EC"
#define MBEDTLS_PK_INFO_ECKEY_GET_BITLEN uecc_eckey_get_bitlen
#define MBEDTLS_PK_INFO_ECKEY_CAN_DO uecc_eckey_can_do
#define MBEDTLS_PK_INFO_ECKEY_VERIFY_FUNC uecc_eckey_verify_wrap
#define MBEDTLS_PK_INFO_ECKEY_SIGN_FUNC uecc_eckey_sign_wrap
#define MBEDTLS_PK_INFO_ECKEY_DECRYPT_FUNC NULL
#define MBEDTLS_PK_INFO_ECKEY_DECRYPT_OMIT 1
#define MBEDTLS_PK_INFO_ECKEY_ENCRYPT_FUNC NULL
#define MBEDTLS_PK_INFO_ECKEY_ENCRYPT_OMIT 1
#define MBEDTLS_PK_INFO_ECKEY_CHECK_PAIR_FUNC uecc_eckey_check_pair
#define MBEDTLS_PK_INFO_ECKEY_CTX_ALLOC_FUNC uecc_eckey_alloc_wrap
#define MBEDTLS_PK_INFO_ECKEY_CTX_FREE_FUNC uecc_eckey_free_wrap
#define MBEDTLS_PK_INFO_ECKEY_DEBUG_FUNC NULL
#define MBEDTLS_PK_INFO_ECKEY_DEBUG_OMIT 1
#endif /* MBEDTLS_USE_TINYCRYPT */
/*
* Helper macros to extract fields from PK types
*/
#define MBEDTLS_PK_INFO_CONTEXT_T( PK ) PK ## _CONTEXT
#define MBEDTLS_PK_INFO_TYPE_T( PK ) PK ## _TYPE
#define MBEDTLS_PK_INFO_NAME_T( PK ) PK ## _NAME
#define MBEDTLS_PK_INFO_GET_BITLEN_T( PK ) PK ## _GET_BITLEN
#define MBEDTLS_PK_INFO_CAN_DO_T( PK ) PK ## _CAN_DO
#define MBEDTLS_PK_INFO_VERIFY_FUNC_T( PK ) PK ## _VERIFY_FUNC
#define MBEDTLS_PK_INFO_VERIFY_OMIT_T( PK ) PK ## _VERIFY_OMIT
#define MBEDTLS_PK_INFO_SIGN_FUNC_T( PK ) PK ## _SIGN_FUNC
#define MBEDTLS_PK_INFO_SIGN_OMIT_T( PK ) PK ## _SIGN_OMIT
#define MBEDTLS_PK_INFO_DECRYPT_FUNC_T( PK ) PK ## _DECRYPT_FUNC
#define MBEDTLS_PK_INFO_DECRYPT_OMIT_T( PK ) PK ## _DECRYPT_OMIT
#define MBEDTLS_PK_INFO_ENCRYPT_FUNC_T( PK ) PK ## _ENCRYPT_FUNC
#define MBEDTLS_PK_INFO_ENCRYPT_OMIT_T( PK ) PK ## _ENCRYPT_OMIT
#define MBEDTLS_PK_INFO_CHECK_PAIR_FUNC_T( PK ) PK ## _CHECK_PAIR_FUNC
#define MBEDTLS_PK_INFO_CHECK_PAIR_OMIT_T( PK ) PK ## _CHECK_PAIR_OMIT
#define MBEDTLS_PK_INFO_CTX_ALLOC_FUNC_T( PK ) PK ## _CTX_ALLOC_FUNC
#define MBEDTLS_PK_INFO_CTX_FREE_FUNC_T( PK ) PK ## _CTX_FREE_FUNC
#define MBEDTLS_PK_INFO_DEBUG_FUNC_T( PK ) PK ## _DEBUG_FUNC
#define MBEDTLS_PK_INFO_DEBUG_OMIT_T( PK ) PK ## _DEBUG_OMIT
/* Wrappers around MBEDTLS_PK_INFO_{FIELD}_T() which makes sure that
* the argument is macro-expanded before concatenated with the
* field name. This allows to call these macros as
* MBEDTLS_PK_INFO_{FIELD}( MBEDTLS_PK_SINGLE_TYPE ).
* where MBEDTLS_PK_SINGLE_TYPE expands to MBEDTLS_PK_INFO_{TYPE}. */
#define MBEDTLS_PK_INFO_CONTEXT( PK ) MBEDTLS_PK_INFO_CONTEXT_T( PK )
#define MBEDTLS_PK_INFO_TYPE( PK ) MBEDTLS_PK_INFO_TYPE_T( PK )
#define MBEDTLS_PK_INFO_NAME( PK ) MBEDTLS_PK_INFO_NAME_T( PK )
#define MBEDTLS_PK_INFO_GET_BITLEN( PK ) MBEDTLS_PK_INFO_GET_BITLEN_T( PK )
#define MBEDTLS_PK_INFO_CAN_DO( PK ) MBEDTLS_PK_INFO_CAN_DO_T( PK )
#define MBEDTLS_PK_INFO_VERIFY_FUNC( PK ) MBEDTLS_PK_INFO_VERIFY_FUNC_T( PK )
#define MBEDTLS_PK_INFO_VERIFY_OMIT( PK ) MBEDTLS_PK_INFO_VERIFY_OMIT_T( PK )
#define MBEDTLS_PK_INFO_SIGN_FUNC( PK ) MBEDTLS_PK_INFO_SIGN_FUNC_T( PK )
#define MBEDTLS_PK_INFO_SIGN_OMIT( PK ) MBEDTLS_PK_INFO_SIGN_OMIT_T( PK )
#define MBEDTLS_PK_INFO_DECRYPT_FUNC( PK ) MBEDTLS_PK_INFO_DECRYPT_FUNC_T( PK )
#define MBEDTLS_PK_INFO_DECRYPT_OMIT( PK ) MBEDTLS_PK_INFO_DECRYPT_OMIT_T( PK )
#define MBEDTLS_PK_INFO_ENCRYPT_FUNC( PK ) MBEDTLS_PK_INFO_ENCRYPT_FUNC_T( PK )
#define MBEDTLS_PK_INFO_ENCRYPT_OMIT( PK ) MBEDTLS_PK_INFO_ENCRYPT_OMIT_T( PK )
#define MBEDTLS_PK_INFO_CHECK_PAIR_FUNC( PK ) MBEDTLS_PK_INFO_CHECK_PAIR_FUNC_T( PK )
#define MBEDTLS_PK_INFO_CHECK_PAIR_OMIT( PK ) MBEDTLS_PK_INFO_CHECK_PAIR_OMIT_T( PK )
#define MBEDTLS_PK_INFO_CTX_ALLOC_FUNC( PK ) MBEDTLS_PK_INFO_CTX_ALLOC_FUNC_T( PK )
#define MBEDTLS_PK_INFO_CTX_FREE_FUNC( PK ) MBEDTLS_PK_INFO_CTX_FREE_FUNC_T( PK )
#define MBEDTLS_PK_INFO_DEBUG_FUNC( PK ) MBEDTLS_PK_INFO_DEBUG_FUNC_T( PK )
#define MBEDTLS_PK_INFO_DEBUG_OMIT( PK ) MBEDTLS_PK_INFO_DEBUG_OMIT_T( PK )
#if !defined(MBEDTLS_PK_SINGLE_TYPE)
struct mbedtls_pk_info_t
{
/** Public key type */
@ -125,128 +41,49 @@ struct mbedtls_pk_info_t
/** Type name */
const char *name;
/** Get key size in bits (must be valid)*/
/** Get key size in bits */
size_t (*get_bitlen)( const void * );
/** Tell if the context implements this type (e.g. ECKEY can do ECDSA)
* (must be valid) */
/** Tell if the context implements this type (e.g. ECKEY can do ECDSA) */
int (*can_do)( mbedtls_pk_type_t type );
/** Verify signature (may be NULL) */
/** Verify signature */
int (*verify_func)( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len );
/** Make signature (may be NULL)*/
/** Make signature */
int (*sign_func)( void *ctx, mbedtls_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 );
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/** Verify signature (restartable) (may be NULL) */
int (*verify_rs_func)( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len,
void *rs_ctx );
/** Make signature (restartable) (may be NULL) */
int (*sign_rs_func)( void *ctx, mbedtls_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, void *rs_ctx );
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
/** Decrypt message (may be NULL) */
/** 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 (may be NULL ) */
/** 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 (may be NULL) */
/** Check public-private key pair */
int (*check_pair_func)( const void *pub, const void *prv );
/** Allocate a new context (must be valid) */
/** Allocate a new context */
void * (*ctx_alloc_func)( void );
/** Free the given context (must be valid) */
/** Free the given context */
void (*ctx_free_func)( void *ctx );
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/** Allocate the restart context (may be NULL)*/
void * (*rs_alloc_func)( void );
/** Free the restart context (may be NULL) */
void (*rs_free_func)( void *rs_ctx );
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
/** Interface with the debug module (may be NULL) */
/** Interface with the debug module */
void (*debug_func)( const void *ctx, mbedtls_pk_debug_item *items );
};
/**
* \brief This macro builds an instance of ::mbedtls_pk_info_t
* from an \c MBEDTLS_PK_INFO_{TYPE} identifier.
*/
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
#define MBEDTLS_PK_INFO( PK ) \
{ \
MBEDTLS_PK_INFO_TYPE( PK ), \
MBEDTLS_PK_INFO_NAME( PK ), \
MBEDTLS_PK_INFO_GET_BITLEN( PK ), \
MBEDTLS_PK_INFO_CAN_DO( PK ), \
MBEDTLS_PK_INFO_VERIFY_FUNC( PK ), \
MBEDTLS_PK_INFO_SIGN_FUNC( PK ), \
NULL, \
NULL, \
MBEDTLS_PK_INFO_DECRYPT_FUNC( PK ), \
MBEDTLS_PK_INFO_ENCRYPT_FUNC( PK ), \
MBEDTLS_PK_INFO_CHECK_PAIR_FUNC( PK ), \
MBEDTLS_PK_INFO_CTX_ALLOC_FUNC( PK ), \
MBEDTLS_PK_INFO_CTX_FREE_FUNC( PK ), \
NULL, \
NULL, \
MBEDTLS_PK_INFO_DEBUG_FUNC( PK ), \
}
#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
#define MBEDTLS_PK_INFO( PK ) \
{ \
MBEDTLS_PK_INFO_TYPE( PK ), \
MBEDTLS_PK_INFO_NAME( PK ), \
MBEDTLS_PK_INFO_GET_BITLEN( PK ), \
MBEDTLS_PK_INFO_CAN_DO( PK ), \
MBEDTLS_PK_INFO_VERIFY_FUNC( PK ), \
MBEDTLS_PK_INFO_SIGN_FUNC( PK ), \
MBEDTLS_PK_INFO_DECRYPT_FUNC( PK ), \
MBEDTLS_PK_INFO_ENCRYPT_FUNC( PK ), \
MBEDTLS_PK_INFO_CHECK_PAIR_FUNC( PK ), \
MBEDTLS_PK_INFO_CTX_ALLOC_FUNC( PK ), \
MBEDTLS_PK_INFO_CTX_FREE_FUNC( PK ), \
MBEDTLS_PK_INFO_DEBUG_FUNC( PK ), \
}
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
#endif /* MBEDTLS_PK_SINGLE_TYPE */
/*
* Macros to access pk_info
*/
#if defined(MBEDTLS_PK_SINGLE_TYPE)
#define MBEDTLS_PK_CTX_INFO( ctx ) MBEDTLS_PK_UNIQUE_VALID_HANDLE
#else
#define MBEDTLS_PK_CTX_INFO( ctx ) ( (ctx)->pk_info )
#endif
#define MBEDTLS_PK_CTX_IS_VALID( ctx ) \
( MBEDTLS_PK_CTX_INFO( (ctx) ) != MBEDTLS_PK_INVALID_HANDLE )
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
/* Container for RSA-alt */
typedef struct
@ -258,7 +95,6 @@ typedef struct
} mbedtls_rsa_alt_context;
#endif
#if !defined(MBEDTLS_PK_SINGLE_TYPE)
#if defined(MBEDTLS_RSA_C)
extern const mbedtls_pk_info_t mbedtls_rsa_info;
#endif
@ -272,13 +108,8 @@ extern const mbedtls_pk_info_t mbedtls_eckeydh_info;
extern const mbedtls_pk_info_t mbedtls_ecdsa_info;
#endif
#if defined(MBEDTLS_USE_TINYCRYPT)
extern const mbedtls_pk_info_t mbedtls_uecc_eckey_info;
#endif
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
extern const mbedtls_pk_info_t mbedtls_rsa_alt_info;
#endif
#endif /* MBEDTLS_PK_SINGLE_TYPE */
#endif /* MBEDTLS_PK_WRAP_H */

View File

@ -0,0 +1,526 @@
/*
* 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 TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_PK_C)
#include "pk_internal.h"
/* Even if RSA not activated, for the sake of RSA-alt */
#include "rsa.h"
#include <string.h>
#if defined(MBEDTLS_ECP_C)
#include "ecp.h"
#endif
#if defined(MBEDTLS_ECDSA_C)
#include "ecdsa.h"
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "platform.h"
#else
#include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
#include <limits.h>
#include <stdint.h>
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
#endif
#if defined(MBEDTLS_RSA_C)
static int rsa_can_do( mbedtls_pk_type_t type )
{
return( type == MBEDTLS_PK_RSA ||
type == MBEDTLS_PK_RSASSA_PSS );
}
static size_t rsa_get_bitlen( const void *ctx )
{
const mbedtls_rsa_context * rsa = (const mbedtls_rsa_context *) ctx;
return( 8 * mbedtls_rsa_get_len( rsa ) );
}
static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len )
{
int ret;
mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
size_t rsa_len = mbedtls_rsa_get_len( rsa );
#if SIZE_MAX > UINT_MAX
if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
#endif /* SIZE_MAX > UINT_MAX */
if( sig_len < rsa_len )
return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL,
MBEDTLS_RSA_PUBLIC, md_alg,
(unsigned int) hash_len, hash, sig ) ) != 0 )
return( ret );
/* The buffer contains a valid signature followed by extra data.
* We have a special error code for that so that so that callers can
* use mbedtls_pk_verify() to check "Does the buffer start with a
* valid signature?" and not just "Does the buffer contain a valid
* signature?". */
if( sig_len > rsa_len )
return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
return( 0 );
}
static int rsa_sign_wrap( void *ctx, mbedtls_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 )
{
mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
#if SIZE_MAX > UINT_MAX
if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
#endif /* SIZE_MAX > UINT_MAX */
*sig_len = mbedtls_rsa_get_len( rsa );
return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
md_alg, (unsigned int) hash_len, hash, sig ) );
}
static int rsa_decrypt_wrap( 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 )
{
mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
if( ilen != mbedtls_rsa_get_len( rsa ) )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng,
MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
}
static int rsa_encrypt_wrap( 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 )
{
mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
*olen = mbedtls_rsa_get_len( rsa );
if( *olen > osize )
return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC,
ilen, input, output ) );
}
static int rsa_check_pair_wrap( const void *pub, const void *prv )
{
return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub,
(const mbedtls_rsa_context *) prv ) );
}
static void *rsa_alloc_wrap( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) );
if( ctx != NULL )
mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 );
return( ctx );
}
static void rsa_free_wrap( void *ctx )
{
mbedtls_rsa_free( (mbedtls_rsa_context *) ctx );
mbedtls_free( ctx );
}
static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items )
{
items->type = MBEDTLS_PK_DEBUG_MPI;
items->name = "rsa.N";
items->value = &( ((mbedtls_rsa_context *) ctx)->N );
items++;
items->type = MBEDTLS_PK_DEBUG_MPI;
items->name = "rsa.E";
items->value = &( ((mbedtls_rsa_context *) ctx)->E );
}
const mbedtls_pk_info_t mbedtls_rsa_info = {
MBEDTLS_PK_RSA,
"RSA",
rsa_get_bitlen,
rsa_can_do,
rsa_verify_wrap,
rsa_sign_wrap,
rsa_decrypt_wrap,
rsa_encrypt_wrap,
rsa_check_pair_wrap,
rsa_alloc_wrap,
rsa_free_wrap,
rsa_debug,
};
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_C)
/*
* Generic EC key
*/
static int eckey_can_do( mbedtls_pk_type_t type )
{
return( type == MBEDTLS_PK_ECKEY ||
type == MBEDTLS_PK_ECKEY_DH ||
type == MBEDTLS_PK_ECDSA );
}
static size_t eckey_get_bitlen( const void *ctx )
{
return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits );
}
#if defined(MBEDTLS_ECDSA_C)
/* Forward declarations */
static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len );
static int ecdsa_sign_wrap( void *ctx, mbedtls_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 );
static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len )
{
int ret;
mbedtls_ecdsa_context ecdsa;
mbedtls_ecdsa_init( &ecdsa );
if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );
mbedtls_ecdsa_free( &ecdsa );
return( ret );
}
static int eckey_sign_wrap( void *ctx, mbedtls_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 )
{
int ret;
mbedtls_ecdsa_context ecdsa;
mbedtls_ecdsa_init( &ecdsa );
if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
f_rng, p_rng );
mbedtls_ecdsa_free( &ecdsa );
return( ret );
}
#endif /* MBEDTLS_ECDSA_C */
static int eckey_check_pair( const void *pub, const void *prv )
{
return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub,
(const mbedtls_ecp_keypair *) prv ) );
}
static void *eckey_alloc_wrap( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
if( ctx != NULL )
mbedtls_ecp_keypair_init( ctx );
return( ctx );
}
static void eckey_free_wrap( void *ctx )
{
mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx );
mbedtls_free( ctx );
}
static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items )
{
items->type = MBEDTLS_PK_DEBUG_ECP;
items->name = "eckey.Q";
items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q );
}
const mbedtls_pk_info_t mbedtls_eckey_info = {
MBEDTLS_PK_ECKEY,
"EC",
eckey_get_bitlen,
eckey_can_do,
#if defined(MBEDTLS_ECDSA_C)
eckey_verify_wrap,
eckey_sign_wrap,
#else
NULL,
NULL,
#endif
NULL,
NULL,
eckey_check_pair,
eckey_alloc_wrap,
eckey_free_wrap,
eckey_debug,
};
/*
* EC key restricted to ECDH
*/
static int eckeydh_can_do( mbedtls_pk_type_t type )
{
return( type == MBEDTLS_PK_ECKEY ||
type == MBEDTLS_PK_ECKEY_DH );
}
const mbedtls_pk_info_t mbedtls_eckeydh_info = {
MBEDTLS_PK_ECKEY_DH,
"EC_DH",
eckey_get_bitlen, /* Same underlying key structure */
eckeydh_can_do,
NULL,
NULL,
NULL,
NULL,
eckey_check_pair,
eckey_alloc_wrap, /* Same underlying key structure */
eckey_free_wrap, /* Same underlying key structure */
eckey_debug, /* Same underlying key structure */
};
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_ECDSA_C)
static int ecdsa_can_do( mbedtls_pk_type_t type )
{
return( type == MBEDTLS_PK_ECDSA );
}
static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len )
{
int ret;
((void) md_alg);
ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,
hash, hash_len, sig, sig_len );
if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
return( ret );
}
static int ecdsa_sign_wrap( void *ctx, mbedtls_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 )
{
return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,
md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
}
static void *ecdsa_alloc_wrap( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );
if( ctx != NULL )
mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx );
return( ctx );
}
static void ecdsa_free_wrap( void *ctx )
{
mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx );
mbedtls_free( ctx );
}
const mbedtls_pk_info_t mbedtls_ecdsa_info = {
MBEDTLS_PK_ECDSA,
"ECDSA",
eckey_get_bitlen, /* Compatible key structures */
ecdsa_can_do,
ecdsa_verify_wrap,
ecdsa_sign_wrap,
NULL,
NULL,
eckey_check_pair, /* Compatible key structures */
ecdsa_alloc_wrap,
ecdsa_free_wrap,
eckey_debug, /* Compatible key structures */
};
#endif /* MBEDTLS_ECDSA_C */
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
/*
* Support for alternative RSA-private implementations
*/
static int rsa_alt_can_do( mbedtls_pk_type_t type )
{
return( type == MBEDTLS_PK_RSA );
}
static size_t rsa_alt_get_bitlen( const void *ctx )
{
const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );
}
static int rsa_alt_sign_wrap( void *ctx, mbedtls_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 )
{
mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
#if SIZE_MAX > UINT_MAX
if( UINT_MAX < hash_len )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
#endif /* SIZE_MAX > UINT_MAX */
*sig_len = rsa_alt->key_len_func( rsa_alt->key );
return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
md_alg, (unsigned int) hash_len, hash, sig ) );
}
static int rsa_alt_decrypt_wrap( 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 )
{
mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
((void) f_rng);
((void) p_rng);
if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
return( rsa_alt->decrypt_func( rsa_alt->key,
MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
}
#if defined(MBEDTLS_RSA_C)
static int rsa_alt_check_pair( const void *pub, const void *prv )
{
unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
unsigned char hash[32];
size_t sig_len = 0;
int ret;
if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) )
return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
memset( hash, 0x2a, sizeof( hash ) );
if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
hash, sizeof( hash ),
sig, &sig_len, NULL, NULL ) ) != 0 )
{
return( ret );
}
if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE,
hash, sizeof( hash ), sig, sig_len ) != 0 )
{
return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
}
return( 0 );
}
#endif /* MBEDTLS_RSA_C */
static void *rsa_alt_alloc_wrap( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) );
if( ctx != NULL )
memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) );
return( ctx );
}
static void rsa_alt_free_wrap( void *ctx )
{
mbedtls_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
mbedtls_free( ctx );
}
const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
MBEDTLS_PK_RSA_ALT,
"RSA-alt",
rsa_alt_get_bitlen,
rsa_alt_can_do,
NULL,
rsa_alt_sign_wrap,
rsa_alt_decrypt_wrap,
NULL,
#if defined(MBEDTLS_RSA_C)
rsa_alt_check_pair,
#else
NULL,
#endif
rsa_alt_alloc_wrap,
rsa_alt_free_wrap,
NULL,
};
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
#endif /* MBEDTLS_PK_C */

View File

@ -0,0 +1,240 @@
/**
* \file pkcs11.c
*
* \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 TLS (https://tls.mbed.org)
*/
#include "pkcs11.h"
#if defined(MBEDTLS_PKCS11_C)
#include "md.h"
#include "oid.h"
#include "x509_crt.h"
#if defined(MBEDTLS_PLATFORM_C)
#include "platform.h"
#else
#include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
#include <string.h>
void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_pkcs11_context ) );
}
int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert, pkcs11h_certificate_t pkcs11_cert )
{
int ret = 1;
unsigned char *cert_blob = NULL;
size_t cert_blob_size = 0;
if( cert == NULL )
{
ret = 2;
goto cleanup;
}
if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL,
&cert_blob_size ) != CKR_OK )
{
ret = 3;
goto cleanup;
}
cert_blob = mbedtls_calloc( 1, cert_blob_size );
if( NULL == cert_blob )
{
ret = 4;
goto cleanup;
}
if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob,
&cert_blob_size ) != CKR_OK )
{
ret = 5;
goto cleanup;
}
if( 0 != mbedtls_x509_crt_parse( cert, cert_blob, cert_blob_size ) )
{
ret = 6;
goto cleanup;
}
ret = 0;
cleanup:
if( NULL != cert_blob )
mbedtls_free( cert_blob );
return( ret );
}
int mbedtls_pkcs11_priv_key_bind( mbedtls_pkcs11_context *priv_key,
pkcs11h_certificate_t pkcs11_cert )
{
int ret = 1;
mbedtls_x509_crt cert;
mbedtls_x509_crt_init( &cert );
if( priv_key == NULL )
goto cleanup;
if( 0 != mbedtls_pkcs11_x509_cert_bind( &cert, pkcs11_cert ) )
goto cleanup;
priv_key->len = mbedtls_pk_get_len( &cert.pk );
priv_key->pkcs11h_cert = pkcs11_cert;
ret = 0;
cleanup:
mbedtls_x509_crt_free( &cert );
return( ret );
}
void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key )
{
if( NULL != priv_key )
pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert );
}
int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx,
int mode, size_t *olen,
const unsigned char *input,
unsigned char *output,
size_t output_max_len )
{
size_t input_len, output_len;
if( NULL == ctx )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
if( MBEDTLS_RSA_PRIVATE != mode )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
output_len = input_len = ctx->len;
if( input_len < 16 || input_len > output_max_len )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
/* Determine size of output buffer */
if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
input_len, NULL, &output_len ) != CKR_OK )
{
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
}
if( output_len > output_max_len )
return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
input_len, output, &output_len ) != CKR_OK )
{
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
}
*olen = output_len;
return( 0 );
}
int mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx,
int mode,
mbedtls_md_type_t md_alg,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig )
{
size_t sig_len = 0, asn_len = 0, oid_size = 0;
unsigned char *p = sig;
const char *oid;
if( NULL == ctx )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
if( MBEDTLS_RSA_PRIVATE != mode )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
if( md_alg != MBEDTLS_MD_NONE )
{
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
if( md_info == NULL )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
hashlen = mbedtls_md_get_size( md_info );
asn_len = 10 + oid_size;
}
sig_len = ctx->len;
if( hashlen > sig_len || asn_len > sig_len ||
hashlen + asn_len > sig_len )
{
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
}
if( md_alg != MBEDTLS_MD_NONE )
{
/*
* DigestInfo ::= SEQUENCE {
* digestAlgorithm DigestAlgorithmIdentifier,
* digest Digest }
*
* DigestAlgorithmIdentifier ::= AlgorithmIdentifier
*
* Digest ::= OCTET STRING
*/
*p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
*p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
*p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
*p++ = (unsigned char) ( 0x04 + oid_size );
*p++ = MBEDTLS_ASN1_OID;
*p++ = oid_size & 0xFF;
memcpy( p, oid, oid_size );
p += oid_size;
*p++ = MBEDTLS_ASN1_NULL;
*p++ = 0x00;
*p++ = MBEDTLS_ASN1_OCTET_STRING;
*p++ = hashlen;
}
memcpy( p, hash, hashlen );
if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig,
asn_len + hashlen, sig, &sig_len ) != CKR_OK )
{
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
}
return( 0 );
}
#endif /* defined(MBEDTLS_PKCS11_C) */

View File

@ -50,8 +50,7 @@ extern "C" {
/**
* Context for PKCS #11 private keys.
*/
typedef struct mbedtls_pkcs11_context
{
typedef struct {
pkcs11h_certificate_t pkcs11h_cert;
int len;
} mbedtls_pkcs11_context;

View File

@ -36,7 +36,6 @@
#include "pkcs12.h"
#include "asn1.h"
#include "cipher.h"
#include "platform_util.h"
#include <string.h>
@ -48,6 +47,11 @@
#include "des.h"
#endif
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
#if defined(MBEDTLS_ASN1_PARSE_C)
static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params,
@ -99,8 +103,8 @@ static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_ty
if( pwdlen > PKCS12_MAX_PWDLEN )
return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA );
mbedtls_platform_memset( &salt, 0, sizeof(mbedtls_asn1_buf) );
mbedtls_platform_memset( &unipwd, 0, sizeof(unipwd) );
memset( &salt, 0, sizeof(mbedtls_asn1_buf) );
memset( &unipwd, 0, sizeof(unipwd) );
if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt,
&iterations ) ) != 0 )
@ -164,7 +168,7 @@ int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode,
goto exit;
exit:
mbedtls_platform_zeroize( key, sizeof( key ) );
mbedtls_zeroize( key, sizeof( key ) );
mbedtls_arc4_free( &ctx );
return( ret );
@ -221,8 +225,8 @@ int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode,
ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH;
exit:
mbedtls_platform_zeroize( key, sizeof( key ) );
mbedtls_platform_zeroize( iv, sizeof( iv ) );
mbedtls_zeroize( key, sizeof( key ) );
mbedtls_zeroize( iv, sizeof( iv ) );
mbedtls_cipher_free( &cipher_ctx );
return( ret );
@ -239,7 +243,7 @@ static void pkcs12_fill_buffer( unsigned char *data, size_t data_len,
while( data_len > 0 )
{
use_len = ( data_len > fill_len ) ? fill_len : data_len;
mbedtls_platform_memcpy( p, filler, use_len );
memcpy( p, filler, use_len );
p += use_len;
data_len -= use_len;
}
@ -261,7 +265,7 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
size_t hlen, use_len, v, i;
mbedtls_md_handle_t md_info;
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
// This version only allows max of 64 bytes of password or salt
@ -269,7 +273,7 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA );
md_info = mbedtls_md_info_from_type( md_type );
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
if( md_info == NULL )
return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
mbedtls_md_init( &md_ctx );
@ -283,7 +287,7 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
else
v = 128;
mbedtls_platform_memset( diversifier, (unsigned char) id, v );
memset( diversifier, (unsigned char) id, v );
pkcs12_fill_buffer( salt_block, v, salt, saltlen );
pkcs12_fill_buffer( pwd_block, v, pwd, pwdlen );
@ -315,7 +319,7 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
}
use_len = ( datalen > hlen ) ? hlen : datalen;
mbedtls_platform_memcpy( p, hash_output, use_len );
memcpy( p, hash_output, use_len );
datalen -= use_len;
p += use_len;
@ -352,10 +356,10 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
ret = 0;
exit:
mbedtls_platform_zeroize( salt_block, sizeof( salt_block ) );
mbedtls_platform_zeroize( pwd_block, sizeof( pwd_block ) );
mbedtls_platform_zeroize( hash_block, sizeof( hash_block ) );
mbedtls_platform_zeroize( hash_output, sizeof( hash_output ) );
mbedtls_zeroize( salt_block, sizeof( salt_block ) );
mbedtls_zeroize( pwd_block, sizeof( pwd_block ) );
mbedtls_zeroize( hash_block, sizeof( hash_block ) );
mbedtls_zeroize( hash_output, sizeof( hash_output ) );
mbedtls_md_free( &md_ctx );

View File

@ -46,7 +46,6 @@
#endif /* MBEDTLS_ASN1_PARSE_C */
#include <string.h>
#include "platform_util.h"
#if defined(MBEDTLS_PLATFORM_C)
#include "platform.h"
@ -123,7 +122,7 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1;
unsigned char key[32], iv[32];
size_t olen = 0;
mbedtls_md_handle_t md_info;
const mbedtls_md_info_t *md_info;
const mbedtls_cipher_info_t *cipher_info;
mbedtls_md_context_t md_ctx;
mbedtls_cipher_type_t cipher_alg;
@ -158,7 +157,7 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
}
md_info = mbedtls_md_info_from_type( md_type );
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
if( md_info == NULL )
return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
if( ( ret = mbedtls_asn1_get_alg( &p, end, &enc_scheme_oid,
@ -189,7 +188,7 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
mbedtls_md_init( &md_ctx );
mbedtls_cipher_init( &cipher_ctx );
mbedtls_platform_memcpy( iv, enc_scheme_params.p, enc_scheme_params.len );
memcpy( iv, enc_scheme_params.p, enc_scheme_params.len );
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
goto exit;
@ -227,12 +226,12 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
unsigned int i;
unsigned char md1[MBEDTLS_MD_MAX_SIZE];
unsigned char work[MBEDTLS_MD_MAX_SIZE];
unsigned char md_size = mbedtls_md_get_size( mbedtls_md_get_handle( ctx ) );
unsigned char md_size = mbedtls_md_get_size( ctx->md_info );
size_t use_len;
unsigned char *out_p = output;
unsigned char counter[4];
mbedtls_platform_memset( counter, 0, 4 );
memset( counter, 0, 4 );
counter[3] = 1;
#if UINT_MAX > 0xFFFFFFFF
@ -256,7 +255,7 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
if( ( ret = mbedtls_md_hmac_finish( ctx, work ) ) != 0 )
return( ret );
mbedtls_platform_memcpy( md1, work, md_size );
memcpy( md1, work, md_size );
for( i = 1; i < iteration_count; i++ )
{
@ -278,7 +277,7 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
}
use_len = ( key_length < md_size ) ? key_length : md_size;
mbedtls_platform_memcpy( out_p, work, use_len );
memcpy( out_p, work, use_len );
key_length -= (uint32_t) use_len;
out_p += use_len;
@ -357,14 +356,14 @@ static const unsigned char result_key[MAX_TESTS][32] =
int mbedtls_pkcs5_self_test( int verbose )
{
mbedtls_md_context_t sha1_ctx;
mbedtls_md_handle_t info_sha1;
const mbedtls_md_info_t *info_sha1;
int ret, i;
unsigned char key[64];
mbedtls_md_init( &sha1_ctx );
info_sha1 = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
if( info_sha1 == MBEDTLS_MD_INVALID_HANDLE )
if( info_sha1 == NULL )
{
ret = 1;
goto exit;
@ -384,7 +383,7 @@ int mbedtls_pkcs5_self_test( int verbose )
ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, password[i], plen[i], salt[i],
slen[i], it_cnt[i], key_len[i], key );
if( ret != 0 ||
memcmp( result_key[i], key, key_len[i] ) != 0 )
memcmp( result_key[i], key, key_len[i] ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );

Some files were not shown because too many files have changed in this diff Show More