forked from xuos/xiuos
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:
parent
4167f1f0f9
commit
7079f86acb
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
@ -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 */
|
|
@ -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)
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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" );
|
||||
|
|
|
@ -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
|
@ -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 */
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
@ -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 )
|
||||
|
|
|
@ -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 ) */
|
||||
|
|
|
@ -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
|
@ -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 */
|
|
@ -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 §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 §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 §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 §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 §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 ) );
|
||||
|
|
|
@ -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 *,
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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 */
|
|
@ -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 public–private 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 public–private 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
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
@ -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
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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.)
|
||||
*/
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
|
@ -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];
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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
|
||||
|
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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 */
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
|
@ -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) */
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue