mbedtls 2.26.0
This commit is contained in:
@@ -20,7 +20,6 @@ add_library(pm3rrg_rdv4_mbedtls STATIC
|
|||||||
../../common/mbedtls/des.c
|
../../common/mbedtls/des.c
|
||||||
../../common/mbedtls/ecdsa.c
|
../../common/mbedtls/ecdsa.c
|
||||||
../../common/mbedtls/md.c
|
../../common/mbedtls/md.c
|
||||||
../../common/mbedtls/md_wrap.c
|
|
||||||
../../common/mbedtls/md5.c
|
../../common/mbedtls/md5.c
|
||||||
../../common/mbedtls/oid.c
|
../../common/mbedtls/oid.c
|
||||||
../../common/mbedtls/pem.c
|
../../common/mbedtls/pem.c
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ MYSRCS = \
|
|||||||
des.c \
|
des.c \
|
||||||
ecdsa.c \
|
ecdsa.c \
|
||||||
md.c \
|
md.c \
|
||||||
md_wrap.c \
|
|
||||||
md5.c \
|
md5.c \
|
||||||
oid.c \
|
oid.c \
|
||||||
pem.c \
|
pem.c \
|
||||||
|
|||||||
1964
common/mbedtls/aes.c
1964
common/mbedtls/aes.c
File diff suppressed because it is too large
Load Diff
@@ -20,31 +20,28 @@
|
|||||||
* <https://ieeexplore.ieee.org/servlet/opac?punumber=4375278>.
|
* <https://ieeexplore.ieee.org/servlet/opac?punumber=4375278>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
|
/*
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of Mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MBEDTLS_AES_H
|
#ifndef MBEDTLS_AES_H
|
||||||
#define MBEDTLS_AES_H
|
#define MBEDTLS_AES_H
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
#include "config.h"
|
#include "mbedtls/config.h"
|
||||||
#else
|
#else
|
||||||
#include MBEDTLS_CONFIG_FILE
|
#include MBEDTLS_CONFIG_FILE
|
||||||
#endif
|
#endif
|
||||||
@@ -62,7 +59,11 @@
|
|||||||
|
|
||||||
/* Error codes in range 0x0021-0x0025 */
|
/* Error codes in range 0x0021-0x0025 */
|
||||||
#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021 /**< Invalid input data. */
|
#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021 /**< Invalid input data. */
|
||||||
|
|
||||||
|
/* MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE is deprecated and should not be used. */
|
||||||
#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE -0x0023 /**< Feature not available. For example, an unsupported AES key size. */
|
#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. */
|
#define MBEDTLS_ERR_AES_HW_ACCEL_FAILED -0x0025 /**< AES hardware accelerator failed. */
|
||||||
|
|
||||||
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
|
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
|
||||||
@@ -81,7 +82,8 @@ extern "C" {
|
|||||||
/**
|
/**
|
||||||
* \brief The AES context-type definition.
|
* \brief The AES context-type definition.
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_aes_context {
|
typedef struct mbedtls_aes_context
|
||||||
|
{
|
||||||
int nr; /*!< The number of rounds. */
|
int nr; /*!< The number of rounds. */
|
||||||
uint32_t *rk; /*!< AES round keys. */
|
uint32_t *rk; /*!< AES round keys. */
|
||||||
uint32_t buf[68]; /*!< Unaligned data buffer. This buffer can
|
uint32_t buf[68]; /*!< Unaligned data buffer. This buffer can
|
||||||
@@ -99,7 +101,8 @@ mbedtls_aes_context;
|
|||||||
/**
|
/**
|
||||||
* \brief The AES XTS context-type definition.
|
* \brief The AES XTS context-type definition.
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_aes_xts_context {
|
typedef struct mbedtls_aes_xts_context
|
||||||
|
{
|
||||||
mbedtls_aes_context crypt; /*!< The AES context to use for AES block
|
mbedtls_aes_context crypt; /*!< The AES context to use for AES block
|
||||||
encryption or decryption. */
|
encryption or decryption. */
|
||||||
mbedtls_aes_context tweak; /*!< The AES context used for tweak
|
mbedtls_aes_context tweak; /*!< The AES context used for tweak
|
||||||
@@ -117,16 +120,18 @@ typedef struct mbedtls_aes_xts_context {
|
|||||||
* It must be the first API called before using
|
* It must be the first API called before using
|
||||||
* the context.
|
* the context.
|
||||||
*
|
*
|
||||||
* \param ctx The AES context to initialize.
|
* \param ctx The AES context to initialize. This must not be \c NULL.
|
||||||
*/
|
*/
|
||||||
void mbedtls_aes_init(mbedtls_aes_context *ctx);
|
void mbedtls_aes_init( mbedtls_aes_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function releases and clears the specified AES context.
|
* \brief This function releases and clears the specified AES context.
|
||||||
*
|
*
|
||||||
* \param ctx The AES context to clear.
|
* \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);
|
void mbedtls_aes_free( mbedtls_aes_context *ctx );
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||||
/**
|
/**
|
||||||
@@ -135,23 +140,27 @@ void mbedtls_aes_free(mbedtls_aes_context *ctx);
|
|||||||
* It must be the first API called before using
|
* It must be the first API called before using
|
||||||
* the context.
|
* the context.
|
||||||
*
|
*
|
||||||
* \param ctx The AES XTS context to initialize.
|
* \param ctx The AES XTS context to initialize. This must not be \c NULL.
|
||||||
*/
|
*/
|
||||||
void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx);
|
void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function releases and clears the specified AES XTS context.
|
* \brief This function releases and clears the specified AES XTS context.
|
||||||
*
|
*
|
||||||
* \param ctx The AES XTS context to clear.
|
* \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);
|
void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx );
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function sets the encryption key.
|
* \brief This function sets the encryption key.
|
||||||
*
|
*
|
||||||
* \param ctx The AES context to which the key should be bound.
|
* \param ctx The AES context to which the key should be bound.
|
||||||
|
* It must be initialized.
|
||||||
* \param key The encryption key.
|
* \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:
|
* \param keybits The size of data passed in bits. Valid options are:
|
||||||
* <ul><li>128 bits</li>
|
* <ul><li>128 bits</li>
|
||||||
* <li>192 bits</li>
|
* <li>192 bits</li>
|
||||||
@@ -160,14 +169,16 @@ void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx);
|
|||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
|
int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
|
||||||
unsigned int keybits);
|
unsigned int keybits );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function sets the decryption key.
|
* \brief This function sets the decryption key.
|
||||||
*
|
*
|
||||||
* \param ctx The AES context to which the key should be bound.
|
* \param ctx The AES context to which the key should be bound.
|
||||||
|
* It must be initialized.
|
||||||
* \param key The decryption key.
|
* \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:
|
* \param keybits The size of data passed. Valid options are:
|
||||||
* <ul><li>128 bits</li>
|
* <ul><li>128 bits</li>
|
||||||
* <li>192 bits</li>
|
* <li>192 bits</li>
|
||||||
@@ -176,8 +187,8 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
|
|||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
|
int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
|
||||||
unsigned int keybits);
|
unsigned int keybits );
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||||
/**
|
/**
|
||||||
@@ -185,8 +196,10 @@ int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
|
|||||||
* sets the encryption key.
|
* sets the encryption key.
|
||||||
*
|
*
|
||||||
* \param ctx The AES XTS context to which the key should be bound.
|
* \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
|
* \param key The encryption key. This is comprised of the XTS key1
|
||||||
* concatenated with the XTS key2.
|
* 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:
|
* \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>
|
* <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>
|
* <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
|
||||||
@@ -194,17 +207,19 @@ int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
|
|||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
|
int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
|
||||||
const unsigned char *key,
|
const unsigned char *key,
|
||||||
unsigned int keybits);
|
unsigned int keybits );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function prepares an XTS context for decryption and
|
* \brief This function prepares an XTS context for decryption and
|
||||||
* sets the decryption key.
|
* sets the decryption key.
|
||||||
*
|
*
|
||||||
* \param ctx The AES XTS context to which the key should be bound.
|
* \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
|
* \param key The decryption key. This is comprised of the XTS key1
|
||||||
* concatenated with the XTS key2.
|
* 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:
|
* \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>
|
* <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>
|
* <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
|
||||||
@@ -212,9 +227,9 @@ int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
|
|||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
|
int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
|
||||||
const unsigned char *key,
|
const unsigned char *key,
|
||||||
unsigned int keybits);
|
unsigned int keybits );
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -230,17 +245,20 @@ int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
|
|||||||
* call to this API with the same context.
|
* call to this API with the same context.
|
||||||
*
|
*
|
||||||
* \param ctx The AES context to use for encryption or decryption.
|
* \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
|
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
|
||||||
* #MBEDTLS_AES_DECRYPT.
|
* #MBEDTLS_AES_DECRYPT.
|
||||||
* \param input The 16-Byte buffer holding the input data.
|
* \param input The buffer holding the input data.
|
||||||
* \param output The 16-Byte buffer holding the output data.
|
* It must be readable and at least \c 16 Bytes long.
|
||||||
|
* \param output The buffer where the output data will be written.
|
||||||
|
* It must be writeable and at least \c 16 Bytes long.
|
||||||
|
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
*/
|
*/
|
||||||
int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
|
int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
|
||||||
int mode,
|
int mode,
|
||||||
const unsigned char input[16],
|
const unsigned char input[16],
|
||||||
unsigned char output[16]);
|
unsigned char output[16] );
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||||
/**
|
/**
|
||||||
@@ -256,8 +274,8 @@ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
|
|||||||
* mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called
|
* mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called
|
||||||
* before the first call to this API with the same context.
|
* before the first call to this API with the same context.
|
||||||
*
|
*
|
||||||
* \note This function operates on aligned blocks, that is, the input size
|
* \note This function operates on full blocks, that is, the input size
|
||||||
* must be a multiple of the AES block size of 16 Bytes.
|
* must be a multiple of the AES block size of \c 16 Bytes.
|
||||||
*
|
*
|
||||||
* \note Upon exit, the content of the IV is updated so that you can
|
* \note Upon exit, the content of the IV is updated so that you can
|
||||||
* call the same function again on the next
|
* call the same function again on the next
|
||||||
@@ -268,24 +286,28 @@ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* \param ctx The AES context to use for encryption or decryption.
|
* \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
|
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
|
||||||
* #MBEDTLS_AES_DECRYPT.
|
* #MBEDTLS_AES_DECRYPT.
|
||||||
* \param length The length of the input data in Bytes. This must be a
|
* \param length The length of the input data in Bytes. This must be a
|
||||||
* multiple of the block size (16 Bytes).
|
* multiple of the block size (\c 16 Bytes).
|
||||||
* \param iv Initialization vector (updated after use).
|
* \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.
|
* \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.
|
* \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.
|
||||||
* \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
|
* \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
|
||||||
* on failure.
|
* on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
|
int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
|
||||||
int mode,
|
int mode,
|
||||||
size_t length,
|
size_t length,
|
||||||
unsigned char iv[16],
|
unsigned char iv[16],
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||||
@@ -302,9 +324,10 @@ int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
|
|||||||
* returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH.
|
* returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH.
|
||||||
*
|
*
|
||||||
* \param ctx The AES XTS context to use for AES XTS operations.
|
* \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
|
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
|
||||||
* #MBEDTLS_AES_DECRYPT.
|
* #MBEDTLS_AES_DECRYPT.
|
||||||
* \param length The length of a data unit in bytes. This can be any
|
* \param length The length of a data unit in Bytes. This can be any
|
||||||
* length between 16 bytes and 2^24 bytes inclusive
|
* length between 16 bytes and 2^24 bytes inclusive
|
||||||
* (between 1 and 2^20 block cipher blocks).
|
* (between 1 and 2^20 block cipher blocks).
|
||||||
* \param data_unit The address of the data unit encoded as an array of 16
|
* \param data_unit The address of the data unit encoded as an array of 16
|
||||||
@@ -312,23 +335,23 @@ int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
|
|||||||
* is typically the index of the block device sector that
|
* is typically the index of the block device sector that
|
||||||
* contains the data.
|
* contains the data.
|
||||||
* \param input The buffer holding the input data (which is an entire
|
* \param input The buffer holding the input data (which is an entire
|
||||||
* data unit). This function reads \p length bytes from \p
|
* data unit). This function reads \p length Bytes from \p
|
||||||
* input.
|
* input.
|
||||||
* \param output The buffer holding the output data (which is an entire
|
* \param output The buffer holding the output data (which is an entire
|
||||||
* data unit). This function writes \p length bytes to \p
|
* data unit). This function writes \p length Bytes to \p
|
||||||
* output.
|
* output.
|
||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is
|
* \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is
|
||||||
* smaller than an AES block in size (16 bytes) or if \p
|
* smaller than an AES block in size (16 Bytes) or if \p
|
||||||
* length is larger than 2^20 blocks (16 MiB).
|
* length is larger than 2^20 blocks (16 MiB).
|
||||||
*/
|
*/
|
||||||
int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
|
int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
|
||||||
int mode,
|
int mode,
|
||||||
size_t length,
|
size_t length,
|
||||||
const unsigned char data_unit[16],
|
const unsigned char data_unit[16],
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||||
@@ -356,23 +379,28 @@ int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* \param ctx The AES context to use for encryption or decryption.
|
* \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
|
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
|
||||||
* #MBEDTLS_AES_DECRYPT.
|
* #MBEDTLS_AES_DECRYPT.
|
||||||
* \param length The length of the input data.
|
* \param length The length of the input data in Bytes.
|
||||||
* \param iv_off The offset in IV (updated after use).
|
* \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).
|
* \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.
|
* \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.
|
* \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_cfb128(mbedtls_aes_context *ctx,
|
int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
|
||||||
int mode,
|
int mode,
|
||||||
size_t length,
|
size_t length,
|
||||||
size_t *iv_off,
|
size_t *iv_off,
|
||||||
unsigned char iv[16],
|
unsigned char iv[16],
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function performs an AES-CFB8 encryption or decryption
|
* \brief This function performs an AES-CFB8 encryption or decryption
|
||||||
@@ -397,21 +425,25 @@ int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* \param ctx The AES context to use for encryption or decryption.
|
* \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
|
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
|
||||||
* #MBEDTLS_AES_DECRYPT
|
* #MBEDTLS_AES_DECRYPT
|
||||||
* \param length The length of the input data.
|
* \param length The length of the input data.
|
||||||
* \param iv The initialization vector (updated after use).
|
* \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.
|
* \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.
|
* \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_cfb8(mbedtls_aes_context *ctx,
|
int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
|
||||||
int mode,
|
int mode,
|
||||||
size_t length,
|
size_t length,
|
||||||
unsigned char iv[16],
|
unsigned char iv[16],
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
#endif /*MBEDTLS_CIPHER_MODE_CFB */
|
#endif /*MBEDTLS_CIPHER_MODE_CFB */
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_OFB)
|
#if defined(MBEDTLS_CIPHER_MODE_OFB)
|
||||||
@@ -447,20 +479,25 @@ int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
|
|||||||
* will compromise security.
|
* will compromise security.
|
||||||
*
|
*
|
||||||
* \param ctx The AES context to use for encryption or decryption.
|
* \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 length The length of the input data.
|
||||||
* \param iv_off The offset in IV (updated after use).
|
* \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).
|
* \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.
|
* \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.
|
* \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_ofb(mbedtls_aes_context *ctx,
|
int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
|
||||||
size_t length,
|
size_t length,
|
||||||
size_t *iv_off,
|
size_t *iv_off,
|
||||||
unsigned char iv[16],
|
unsigned char iv[16],
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
|
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_OFB */
|
#endif /* MBEDTLS_CIPHER_MODE_OFB */
|
||||||
|
|
||||||
@@ -523,25 +560,31 @@ int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
|
|||||||
* securely discarded as soon as it's no longer needed.
|
* securely discarded as soon as it's no longer needed.
|
||||||
*
|
*
|
||||||
* \param ctx The AES context to use for encryption or decryption.
|
* \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 length The length of the input data.
|
||||||
* \param nc_off The offset in the current \p stream_block, for
|
* \param nc_off The offset in the current \p stream_block, for
|
||||||
* resuming within the current cipher stream. The
|
* resuming within the current cipher stream. The
|
||||||
* offset pointer should be 0 at the start of a stream.
|
* 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.
|
* \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
|
* \param stream_block The saved stream block for resuming. This is
|
||||||
* overwritten by the function.
|
* overwritten by the function.
|
||||||
|
* It must be a readable-writeable buffer of \c 16 Bytes.
|
||||||
* \param input The buffer holding the input data.
|
* \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.
|
* \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,
|
int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
|
||||||
size_t length,
|
size_t length,
|
||||||
size_t *nc_off,
|
size_t *nc_off,
|
||||||
unsigned char nonce_counter[16],
|
unsigned char nonce_counter[16],
|
||||||
unsigned char stream_block[16],
|
unsigned char stream_block[16],
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -555,9 +598,9 @@ int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
|
|||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
*/
|
*/
|
||||||
int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
|
int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
|
||||||
const unsigned char input[16],
|
const unsigned char input[16],
|
||||||
unsigned char output[16]);
|
unsigned char output[16] );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Internal AES block decryption function. This is only
|
* \brief Internal AES block decryption function. This is only
|
||||||
@@ -570,9 +613,9 @@ int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
|
|||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
*/
|
*/
|
||||||
int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
|
int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
|
||||||
const unsigned char input[16],
|
const unsigned char input[16],
|
||||||
unsigned char output[16]);
|
unsigned char output[16] );
|
||||||
|
|
||||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
||||||
@@ -584,40 +627,44 @@ int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
|
|||||||
* \brief Deprecated internal AES block encryption function
|
* \brief Deprecated internal AES block encryption function
|
||||||
* without return value.
|
* without return value.
|
||||||
*
|
*
|
||||||
* \deprecated Superseded by mbedtls_aes_encrypt_ext() in 2.5.0.
|
* \deprecated Superseded by mbedtls_internal_aes_encrypt()
|
||||||
*
|
*
|
||||||
* \param ctx The AES context to use for encryption.
|
* \param ctx The AES context to use for encryption.
|
||||||
* \param input Plaintext block.
|
* \param input Plaintext block.
|
||||||
* \param output Output (ciphertext) block.
|
* \param output Output (ciphertext) block.
|
||||||
*/
|
*/
|
||||||
MBEDTLS_DEPRECATED void mbedtls_aes_encrypt(mbedtls_aes_context *ctx,
|
MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
|
||||||
const unsigned char input[16],
|
const unsigned char input[16],
|
||||||
unsigned char output[16]);
|
unsigned char output[16] );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Deprecated internal AES block decryption function
|
* \brief Deprecated internal AES block decryption function
|
||||||
* without return value.
|
* without return value.
|
||||||
*
|
*
|
||||||
* \deprecated Superseded by mbedtls_aes_decrypt_ext() in 2.5.0.
|
* \deprecated Superseded by mbedtls_internal_aes_decrypt()
|
||||||
*
|
*
|
||||||
* \param ctx The AES context to use for decryption.
|
* \param ctx The AES context to use for decryption.
|
||||||
* \param input Ciphertext block.
|
* \param input Ciphertext block.
|
||||||
* \param output Output (plaintext) block.
|
* \param output Output (plaintext) block.
|
||||||
*/
|
*/
|
||||||
MBEDTLS_DEPRECATED void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
|
MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
|
||||||
const unsigned char input[16],
|
const unsigned char input[16],
|
||||||
unsigned char output[16]);
|
unsigned char output[16] );
|
||||||
|
|
||||||
#undef MBEDTLS_DEPRECATED
|
#undef MBEDTLS_DEPRECATED
|
||||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
/**
|
/**
|
||||||
* \brief Checkup routine.
|
* \brief Checkup routine.
|
||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return \c 1 on failure.
|
* \return \c 1 on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_aes_self_test(int verbose);
|
int mbedtls_aes_self_test( int verbose );
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
464
common/mbedtls/aesni.c
Normal file
464
common/mbedtls/aesni.c
Normal file
@@ -0,0 +1,464 @@
|
|||||||
|
/*
|
||||||
|
* AES-NI support functions
|
||||||
|
*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* [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/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_AESNI_C)
|
||||||
|
|
||||||
|
#if defined(__has_feature)
|
||||||
|
#if __has_feature(memory_sanitizer)
|
||||||
|
#warning "MBEDTLS_AESNI_C is known to cause spurious error reports with some memory sanitizers as they do not understand the assembly code."
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mbedtls/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 */
|
||||||
136
common/mbedtls/aesni.h
Normal file
136
common/mbedtls/aesni.h
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
/**
|
||||||
|
* \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 The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef MBEDTLS_AESNI_H
|
||||||
|
#define MBEDTLS_AESNI_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mbedtls/aes.h"
|
||||||
|
|
||||||
|
#define MBEDTLS_AESNI_AES 0x02000000u
|
||||||
|
#define MBEDTLS_AESNI_CLMUL 0x00000002u
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \
|
||||||
|
( defined(__amd64__) || defined(__x86_64__) ) && \
|
||||||
|
! defined(MBEDTLS_HAVE_X86_64)
|
||||||
|
#define MBEDTLS_HAVE_X86_64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_HAVE_X86_64)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* \param what The feature to detect
|
||||||
|
* (MBEDTLS_AESNI_AES or MBEDTLS_AESNI_CLMUL)
|
||||||
|
*
|
||||||
|
* \return 1 if CPU has support for the feature, 0 otherwise
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* \param ctx AES context
|
||||||
|
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
|
||||||
|
* \param input 16-byte input block
|
||||||
|
* \param output 16-byte output block
|
||||||
|
*
|
||||||
|
* \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] );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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.
|
||||||
|
*
|
||||||
|
* \param c Result
|
||||||
|
* \param a First operand
|
||||||
|
* \param b Second operand
|
||||||
|
*
|
||||||
|
* \note Both operands and result are bit strings interpreted as
|
||||||
|
* elements of GF(2^128) as per the GCM spec.
|
||||||
|
*/
|
||||||
|
void mbedtls_aesni_gcm_mult( unsigned char c[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.
|
||||||
|
*
|
||||||
|
* \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 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Internal key expansion for encryption
|
||||||
|
*
|
||||||
|
* \note This function is only for internal use by other library
|
||||||
|
* functions; you must not call it directly.
|
||||||
|
*
|
||||||
|
* \param rk Destination buffer where the round keys are written
|
||||||
|
* \param key Encryption key
|
||||||
|
* \param bits Key size in bits (must be 128, 192 or 256)
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
|
||||||
|
*/
|
||||||
|
int mbedtls_aesni_setkey_enc( unsigned char *rk,
|
||||||
|
const unsigned char *key,
|
||||||
|
size_t bits );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_HAVE_X86_64 */
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_AESNI_H */
|
||||||
@@ -1,24 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
* An implementation of the ARCFOUR algorithm
|
* An implementation of the ARCFOUR algorithm
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* The ARCFOUR algorithm was publicly disclosed on 94/09.
|
* The ARCFOUR algorithm was publicly disclosed on 94/09.
|
||||||
@@ -26,11 +22,7 @@
|
|||||||
* http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0
|
* http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#include "common.h"
|
||||||
#include "mbedtls/config.h"
|
|
||||||
#else
|
|
||||||
#include MBEDTLS_CONFIG_FILE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_ARC4_C)
|
#if defined(MBEDTLS_ARC4_C)
|
||||||
|
|
||||||
@@ -50,22 +42,25 @@
|
|||||||
|
|
||||||
#if !defined(MBEDTLS_ARC4_ALT)
|
#if !defined(MBEDTLS_ARC4_ALT)
|
||||||
|
|
||||||
void mbedtls_arc4_init(mbedtls_arc4_context *ctx) {
|
void mbedtls_arc4_init( mbedtls_arc4_context *ctx )
|
||||||
memset(ctx, 0, sizeof(mbedtls_arc4_context));
|
{
|
||||||
|
memset( ctx, 0, sizeof( mbedtls_arc4_context ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void mbedtls_arc4_free(mbedtls_arc4_context *ctx) {
|
void mbedtls_arc4_free( mbedtls_arc4_context *ctx )
|
||||||
if (ctx == NULL)
|
{
|
||||||
|
if( ctx == NULL )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_arc4_context));
|
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_arc4_context ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ARC4 key schedule
|
* ARC4 key schedule
|
||||||
*/
|
*/
|
||||||
void mbedtls_arc4_setup(mbedtls_arc4_context *ctx, const unsigned char *key,
|
void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key,
|
||||||
unsigned int keylen) {
|
unsigned int keylen )
|
||||||
|
{
|
||||||
int i, j, a;
|
int i, j, a;
|
||||||
unsigned int k;
|
unsigned int k;
|
||||||
unsigned char *m;
|
unsigned char *m;
|
||||||
@@ -74,16 +69,17 @@ void mbedtls_arc4_setup(mbedtls_arc4_context *ctx, const unsigned char *key,
|
|||||||
ctx->y = 0;
|
ctx->y = 0;
|
||||||
m = ctx->m;
|
m = ctx->m;
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
for( i = 0; i < 256; i++ )
|
||||||
m[i] = (unsigned char) i;
|
m[i] = (unsigned char) i;
|
||||||
|
|
||||||
j = k = 0;
|
j = k = 0;
|
||||||
|
|
||||||
for (i = 0; i < 256; i++, k++) {
|
for( i = 0; i < 256; i++, k++ )
|
||||||
if (k >= keylen) k = 0;
|
{
|
||||||
|
if( k >= keylen ) k = 0;
|
||||||
|
|
||||||
a = m[i];
|
a = m[i];
|
||||||
j = (j + a + key[k]) & 0xFF;
|
j = ( j + a + key[k] ) & 0xFF;
|
||||||
m[i] = m[j];
|
m[i] = m[j];
|
||||||
m[j] = (unsigned char) a;
|
m[j] = (unsigned char) a;
|
||||||
}
|
}
|
||||||
@@ -92,8 +88,9 @@ void mbedtls_arc4_setup(mbedtls_arc4_context *ctx, const unsigned char *key,
|
|||||||
/*
|
/*
|
||||||
* ARC4 cipher function
|
* ARC4 cipher function
|
||||||
*/
|
*/
|
||||||
int mbedtls_arc4_crypt(mbedtls_arc4_context *ctx, size_t length, const unsigned char *input,
|
int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input,
|
||||||
unsigned char *output) {
|
unsigned char *output )
|
||||||
|
{
|
||||||
int x, y, a, b;
|
int x, y, a, b;
|
||||||
size_t i;
|
size_t i;
|
||||||
unsigned char *m;
|
unsigned char *m;
|
||||||
@@ -102,23 +99,22 @@ int mbedtls_arc4_crypt(mbedtls_arc4_context *ctx, size_t length, const unsigned
|
|||||||
y = ctx->y;
|
y = ctx->y;
|
||||||
m = ctx->m;
|
m = ctx->m;
|
||||||
|
|
||||||
for (i = 0; i < length; i++) {
|
for( i = 0; i < length; i++ )
|
||||||
x = (x + 1) & 0xFF;
|
{
|
||||||
a = m[x];
|
x = ( x + 1 ) & 0xFF; a = m[x];
|
||||||
y = (y + a) & 0xFF;
|
y = ( y + a ) & 0xFF; b = m[y];
|
||||||
b = m[y];
|
|
||||||
|
|
||||||
m[x] = (unsigned char) b;
|
m[x] = (unsigned char) b;
|
||||||
m[y] = (unsigned char) a;
|
m[y] = (unsigned char) a;
|
||||||
|
|
||||||
output[i] = (unsigned char)
|
output[i] = (unsigned char)
|
||||||
(input[i] ^ m[(unsigned char)(a + b)]);
|
( input[i] ^ m[(unsigned char)( a + b )] );
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->x = x;
|
ctx->x = x;
|
||||||
ctx->y = y;
|
ctx->y = y;
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !MBEDTLS_ARC4_ALT */
|
#endif /* !MBEDTLS_ARC4_ALT */
|
||||||
@@ -129,19 +125,22 @@ int mbedtls_arc4_crypt(mbedtls_arc4_context *ctx, size_t length, const unsigned
|
|||||||
*
|
*
|
||||||
* http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0
|
* http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0
|
||||||
*/
|
*/
|
||||||
static const unsigned char arc4_test_key[3][8] = {
|
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 },
|
||||||
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
|
{ 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_pt[3][8] = {
|
static const unsigned char arc4_test_pt[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 },
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
{ 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] = {
|
static const unsigned char arc4_test_ct[3][8] =
|
||||||
|
{
|
||||||
{ 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 },
|
{ 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 },
|
||||||
{ 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 },
|
{ 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 },
|
||||||
{ 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A }
|
{ 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A }
|
||||||
@@ -150,42 +149,45 @@ static const unsigned char arc4_test_ct[3][8] = {
|
|||||||
/*
|
/*
|
||||||
* Checkup routine
|
* Checkup routine
|
||||||
*/
|
*/
|
||||||
int mbedtls_arc4_self_test(int verbose) {
|
int mbedtls_arc4_self_test( int verbose )
|
||||||
|
{
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
unsigned char ibuf[8];
|
unsigned char ibuf[8];
|
||||||
unsigned char obuf[8];
|
unsigned char obuf[8];
|
||||||
mbedtls_arc4_context ctx;
|
mbedtls_arc4_context ctx;
|
||||||
|
|
||||||
mbedtls_arc4_init(&ctx);
|
mbedtls_arc4_init( &ctx );
|
||||||
|
|
||||||
for (i = 0; i < 3; i++) {
|
for( i = 0; i < 3; i++ )
|
||||||
if (verbose != 0)
|
{
|
||||||
mbedtls_printf(" ARC4 test #%d: ", i + 1);
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( " ARC4 test #%d: ", i + 1 );
|
||||||
|
|
||||||
memcpy(ibuf, arc4_test_pt[i], 8);
|
memcpy( ibuf, arc4_test_pt[i], 8 );
|
||||||
|
|
||||||
mbedtls_arc4_setup(&ctx, arc4_test_key[i], 8);
|
mbedtls_arc4_setup( &ctx, arc4_test_key[i], 8 );
|
||||||
mbedtls_arc4_crypt(&ctx, 8, ibuf, obuf);
|
mbedtls_arc4_crypt( &ctx, 8, ibuf, obuf );
|
||||||
|
|
||||||
if (memcmp(obuf, arc4_test_ct[i], 8) != 0) {
|
if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 )
|
||||||
if (verbose != 0)
|
{
|
||||||
mbedtls_printf("failed\n");
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( "failed\n" );
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose != 0)
|
if( verbose != 0 )
|
||||||
mbedtls_printf("passed\n");
|
mbedtls_printf( "passed\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose != 0)
|
if( verbose != 0 )
|
||||||
mbedtls_printf("\n");
|
mbedtls_printf( "\n" );
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
mbedtls_arc4_free(&ctx);
|
mbedtls_arc4_free( &ctx );
|
||||||
|
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MBEDTLS_SELF_TEST */
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|||||||
@@ -7,37 +7,34 @@
|
|||||||
* security risk. We recommend considering stronger ciphers instead.
|
* security risk. We recommend considering stronger ciphers instead.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifndef MBEDTLS_ARC4_H
|
#ifndef MBEDTLS_ARC4_H
|
||||||
#define MBEDTLS_ARC4_H
|
#define MBEDTLS_ARC4_H
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
#include "config.h"
|
#include "mbedtls/config.h"
|
||||||
#else
|
#else
|
||||||
#include MBEDTLS_CONFIG_FILE
|
#include MBEDTLS_CONFIG_FILE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stddef.h>
|
#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. */
|
#define MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED -0x0019 /**< ARC4 hardware accelerator failed. */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -55,7 +52,8 @@ extern "C" {
|
|||||||
* security risk. We recommend considering stronger ciphers instead.
|
* security risk. We recommend considering stronger ciphers instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_arc4_context {
|
typedef struct mbedtls_arc4_context
|
||||||
|
{
|
||||||
int x; /*!< permutation index */
|
int x; /*!< permutation index */
|
||||||
int y; /*!< permutation index */
|
int y; /*!< permutation index */
|
||||||
unsigned char m[256]; /*!< permutation table */
|
unsigned char m[256]; /*!< permutation table */
|
||||||
@@ -76,7 +74,7 @@ mbedtls_arc4_context;
|
|||||||
* instead.
|
* instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void mbedtls_arc4_init(mbedtls_arc4_context *ctx);
|
void mbedtls_arc4_init( mbedtls_arc4_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Clear ARC4 context
|
* \brief Clear ARC4 context
|
||||||
@@ -88,7 +86,7 @@ void mbedtls_arc4_init(mbedtls_arc4_context *ctx);
|
|||||||
* instead.
|
* instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void mbedtls_arc4_free(mbedtls_arc4_context *ctx);
|
void mbedtls_arc4_free( mbedtls_arc4_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief ARC4 key schedule
|
* \brief ARC4 key schedule
|
||||||
@@ -102,8 +100,8 @@ void mbedtls_arc4_free(mbedtls_arc4_context *ctx);
|
|||||||
* instead.
|
* instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void mbedtls_arc4_setup(mbedtls_arc4_context *ctx, const unsigned char *key,
|
void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key,
|
||||||
unsigned int keylen);
|
unsigned int keylen );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief ARC4 cipher function
|
* \brief ARC4 cipher function
|
||||||
@@ -120,8 +118,10 @@ void mbedtls_arc4_setup(mbedtls_arc4_context *ctx, const unsigned char *key,
|
|||||||
* instead.
|
* instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int mbedtls_arc4_crypt(mbedtls_arc4_context *ctx, size_t length, const unsigned char *input,
|
int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Checkup routine
|
* \brief Checkup routine
|
||||||
@@ -133,7 +133,9 @@ int mbedtls_arc4_crypt(mbedtls_arc4_context *ctx, size_t length, const unsigned
|
|||||||
* instead.
|
* instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int mbedtls_arc4_self_test(int verbose);
|
int mbedtls_arc4_self_test( int verbose );
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
1073
common/mbedtls/aria.c
Normal file
1073
common/mbedtls/aria.c
Normal file
File diff suppressed because it is too large
Load Diff
369
common/mbedtls/aria.h
Normal file
369
common/mbedtls/aria.h
Normal file
@@ -0,0 +1,369 @@
|
|||||||
|
/**
|
||||||
|
* \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 The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MBEDTLS_ARIA_H
|
||||||
|
#define MBEDTLS_ARIA_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "mbedtls/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 */
|
||||||
@@ -4,30 +4,26 @@
|
|||||||
* \brief Generic ASN.1 parsing
|
* \brief Generic ASN.1 parsing
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef MBEDTLS_ASN1_H
|
#ifndef MBEDTLS_ASN1_H
|
||||||
#define MBEDTLS_ASN1_H
|
#define MBEDTLS_ASN1_H
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
#include "config.h"
|
#include "mbedtls/config.h"
|
||||||
#else
|
#else
|
||||||
#include MBEDTLS_CONFIG_FILE
|
#include MBEDTLS_CONFIG_FILE
|
||||||
#endif
|
#endif
|
||||||
@@ -35,7 +31,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#if defined(MBEDTLS_BIGNUM_C)
|
#if defined(MBEDTLS_BIGNUM_C)
|
||||||
#include "bignum.h"
|
#include "mbedtls/bignum.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,7 +50,7 @@
|
|||||||
#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG -0x0062 /**< ASN1 tag was of an unexpected value. */
|
#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG -0x0062 /**< ASN1 tag was of an unexpected value. */
|
||||||
#define MBEDTLS_ERR_ASN1_INVALID_LENGTH -0x0064 /**< Error when trying to determine the length or invalid length. */
|
#define MBEDTLS_ERR_ASN1_INVALID_LENGTH -0x0064 /**< Error when trying to determine the length or invalid length. */
|
||||||
#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH -0x0066 /**< Actual length differs from expected length. */
|
#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH -0x0066 /**< Actual length differs from expected length. */
|
||||||
#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. (not used) */
|
#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. */
|
||||||
#define MBEDTLS_ERR_ASN1_ALLOC_FAILED -0x006A /**< Memory allocation failed */
|
#define MBEDTLS_ERR_ASN1_ALLOC_FAILED -0x006A /**< Memory allocation failed */
|
||||||
#define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -0x006C /**< Buffer too small when writing ASN.1 data structure. */
|
#define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -0x006C /**< Buffer too small when writing ASN.1 data structure. */
|
||||||
|
|
||||||
@@ -77,6 +73,7 @@
|
|||||||
#define MBEDTLS_ASN1_OCTET_STRING 0x04
|
#define MBEDTLS_ASN1_OCTET_STRING 0x04
|
||||||
#define MBEDTLS_ASN1_NULL 0x05
|
#define MBEDTLS_ASN1_NULL 0x05
|
||||||
#define MBEDTLS_ASN1_OID 0x06
|
#define MBEDTLS_ASN1_OID 0x06
|
||||||
|
#define MBEDTLS_ASN1_ENUMERATED 0x0A
|
||||||
#define MBEDTLS_ASN1_UTF8_STRING 0x0C
|
#define MBEDTLS_ASN1_UTF8_STRING 0x0C
|
||||||
#define MBEDTLS_ASN1_SEQUENCE 0x10
|
#define MBEDTLS_ASN1_SEQUENCE 0x10
|
||||||
#define MBEDTLS_ASN1_SET 0x11
|
#define MBEDTLS_ASN1_SET 0x11
|
||||||
@@ -91,6 +88,18 @@
|
|||||||
#define MBEDTLS_ASN1_CONSTRUCTED 0x20
|
#define MBEDTLS_ASN1_CONSTRUCTED 0x20
|
||||||
#define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80
|
#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
|
* 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",
|
* ITU X.690 (08/2015), section 8.1 "General rules for encoding",
|
||||||
@@ -118,8 +127,12 @@
|
|||||||
* 'unsigned char *oid' here!
|
* 'unsigned char *oid' here!
|
||||||
*/
|
*/
|
||||||
#define MBEDTLS_OID_CMP(oid_str, oid_buf) \
|
#define MBEDTLS_OID_CMP(oid_str, oid_buf) \
|
||||||
( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) || \
|
( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) || \
|
||||||
memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 )
|
memcmp( (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) ) || \
|
||||||
|
memcmp( (oid_str), (oid_buf), (oid_buf_len) ) != 0 )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -133,7 +146,8 @@ extern "C" {
|
|||||||
/**
|
/**
|
||||||
* Type-length-value structure that allows for ASN1 using DER.
|
* Type-length-value structure that allows for ASN1 using DER.
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_asn1_buf {
|
typedef struct mbedtls_asn1_buf
|
||||||
|
{
|
||||||
int tag; /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */
|
int tag; /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */
|
||||||
size_t len; /**< ASN1 length, in octets. */
|
size_t len; /**< ASN1 length, in octets. */
|
||||||
unsigned char *p; /**< ASN1 data, e.g. in ASCII. */
|
unsigned char *p; /**< ASN1 data, e.g. in ASCII. */
|
||||||
@@ -143,7 +157,8 @@ mbedtls_asn1_buf;
|
|||||||
/**
|
/**
|
||||||
* Container for ASN1 bit strings.
|
* Container for ASN1 bit strings.
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_asn1_bitstring {
|
typedef struct mbedtls_asn1_bitstring
|
||||||
|
{
|
||||||
size_t len; /**< ASN1 length, in octets. */
|
size_t len; /**< ASN1 length, in octets. */
|
||||||
unsigned char unused_bits; /**< Number of unused bits at the end of the string */
|
unsigned char unused_bits; /**< Number of unused bits at the end of the string */
|
||||||
unsigned char *p; /**< Raw ASN1 data for the bit string */
|
unsigned char *p; /**< Raw ASN1 data for the bit string */
|
||||||
@@ -153,7 +168,8 @@ mbedtls_asn1_bitstring;
|
|||||||
/**
|
/**
|
||||||
* Container for a sequence of ASN.1 items
|
* Container for a sequence of ASN.1 items
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_asn1_sequence {
|
typedef struct mbedtls_asn1_sequence
|
||||||
|
{
|
||||||
mbedtls_asn1_buf buf; /**< Buffer containing the given ASN.1 item. */
|
mbedtls_asn1_buf buf; /**< Buffer containing the given ASN.1 item. */
|
||||||
struct mbedtls_asn1_sequence *next; /**< The next entry in the sequence. */
|
struct mbedtls_asn1_sequence *next; /**< The next entry in the sequence. */
|
||||||
}
|
}
|
||||||
@@ -162,7 +178,8 @@ mbedtls_asn1_sequence;
|
|||||||
/**
|
/**
|
||||||
* Container for a sequence or list of 'named' ASN.1 data items
|
* Container for a sequence or list of 'named' ASN.1 data items
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_asn1_named_data {
|
typedef struct mbedtls_asn1_named_data
|
||||||
|
{
|
||||||
mbedtls_asn1_buf oid; /**< The object identifier. */
|
mbedtls_asn1_buf oid; /**< The object identifier. */
|
||||||
mbedtls_asn1_buf val; /**< The named value. */
|
mbedtls_asn1_buf val; /**< The named value. */
|
||||||
struct mbedtls_asn1_named_data *next; /**< The next entry in the sequence. */
|
struct mbedtls_asn1_named_data *next; /**< The next entry in the sequence. */
|
||||||
@@ -174,119 +191,342 @@ mbedtls_asn1_named_data;
|
|||||||
* \brief Get the length of an ASN.1 element.
|
* \brief Get the length of an ASN.1 element.
|
||||||
* Updates the pointer to immediately behind the length.
|
* Updates the pointer to immediately behind the length.
|
||||||
*
|
*
|
||||||
* \param p The position in the ASN.1 data
|
* \param p On entry, \c *p points to the first byte of the length,
|
||||||
* \param end End of data
|
* i.e. immediately after the tag.
|
||||||
* \param len The variable that will receive the value
|
* On successful completion, \c *p points to the first byte
|
||||||
|
* after the length, i.e. the first byte of the content.
|
||||||
|
* On error, the value of \c *p is undefined.
|
||||||
|
* \param end End of data.
|
||||||
|
* \param len On successful completion, \c *len contains the length
|
||||||
|
* read from the ASN.1 input.
|
||||||
*
|
*
|
||||||
* \return 0 if successful, MBEDTLS_ERR_ASN1_OUT_OF_DATA on reaching
|
* \return 0 if successful.
|
||||||
* end of data, MBEDTLS_ERR_ASN1_INVALID_LENGTH if length is
|
* \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element
|
||||||
* unparseable.
|
* would end beyond \p end.
|
||||||
|
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparseable.
|
||||||
*/
|
*/
|
||||||
int mbedtls_asn1_get_len(unsigned char **p,
|
int mbedtls_asn1_get_len( unsigned char **p,
|
||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
size_t *len);
|
size_t *len );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Get the tag and length of the tag. Check for the requested tag.
|
* \brief Get the tag and length of the element.
|
||||||
|
* Check for the requested tag.
|
||||||
* Updates the pointer to immediately behind the tag and length.
|
* Updates the pointer to immediately behind the tag and length.
|
||||||
*
|
*
|
||||||
* \param p The position in the ASN.1 data
|
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||||
* \param end End of data
|
* On successful completion, \c *p points to the first byte
|
||||||
* \param len The variable that will receive the length
|
* after the length, i.e. the first byte of the content.
|
||||||
* \param tag The expected tag
|
* On error, the value of \c *p is undefined.
|
||||||
|
* \param end End of data.
|
||||||
|
* \param len On successful completion, \c *len contains the length
|
||||||
|
* read from the ASN.1 input.
|
||||||
|
* \param tag The expected tag.
|
||||||
*
|
*
|
||||||
* \return 0 if successful, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if tag did
|
* \return 0 if successful.
|
||||||
* not match requested tag, or another specific ASN.1 error code.
|
* \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the data does not start
|
||||||
|
* with the requested tag.
|
||||||
|
* \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element
|
||||||
|
* would end beyond \p end.
|
||||||
|
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparseable.
|
||||||
*/
|
*/
|
||||||
int mbedtls_asn1_get_tag(unsigned char **p,
|
int mbedtls_asn1_get_tag( unsigned char **p,
|
||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
size_t *len, int tag);
|
size_t *len, int tag );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Retrieve a boolean ASN.1 tag and its value.
|
* \brief Retrieve a boolean ASN.1 tag and its value.
|
||||||
* Updates the pointer to immediately behind the full tag.
|
* Updates the pointer to immediately behind the full tag.
|
||||||
*
|
*
|
||||||
* \param p The position in the ASN.1 data
|
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||||
* \param end End of data
|
* On successful completion, \c *p points to the first byte
|
||||||
* \param val The variable that will receive the value
|
* beyond the ASN.1 element.
|
||||||
|
* On error, the value of \c *p is undefined.
|
||||||
|
* \param end End of data.
|
||||||
|
* \param val On success, the parsed value (\c 0 or \c 1).
|
||||||
*
|
*
|
||||||
* \return 0 if successful or a specific ASN.1 error code.
|
* \return 0 if successful.
|
||||||
|
* \return An ASN.1 error code if the input does not start with
|
||||||
|
* a valid ASN.1 BOOLEAN.
|
||||||
*/
|
*/
|
||||||
int mbedtls_asn1_get_bool(unsigned char **p,
|
int mbedtls_asn1_get_bool( unsigned char **p,
|
||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
int *val);
|
int *val );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Retrieve an integer ASN.1 tag and its value.
|
* \brief Retrieve an integer ASN.1 tag and its value.
|
||||||
* Updates the pointer to immediately behind the full tag.
|
* Updates the pointer to immediately behind the full tag.
|
||||||
*
|
*
|
||||||
* \param p The position in the ASN.1 data
|
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||||
* \param end End of data
|
* On successful completion, \c *p points to the first byte
|
||||||
* \param val The variable that will receive the value
|
* beyond the ASN.1 element.
|
||||||
|
* On error, the value of \c *p is undefined.
|
||||||
|
* \param end End of data.
|
||||||
|
* \param val On success, the parsed value.
|
||||||
*
|
*
|
||||||
* \return 0 if successful or a specific ASN.1 error code.
|
* \return 0 if successful.
|
||||||
|
* \return An ASN.1 error code if the input does not start with
|
||||||
|
* a valid ASN.1 INTEGER.
|
||||||
|
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
|
||||||
|
* not fit in an \c int.
|
||||||
*/
|
*/
|
||||||
int mbedtls_asn1_get_int(unsigned char **p,
|
int mbedtls_asn1_get_int( unsigned char **p,
|
||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
int *val);
|
int *val );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieve an enumerated ASN.1 tag and its value.
|
||||||
|
* Updates the pointer to immediately behind the full tag.
|
||||||
|
*
|
||||||
|
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||||
|
* On successful completion, \c *p points to the first byte
|
||||||
|
* beyond the ASN.1 element.
|
||||||
|
* On error, the value of \c *p is undefined.
|
||||||
|
* \param end End of data.
|
||||||
|
* \param val On success, the parsed value.
|
||||||
|
*
|
||||||
|
* \return 0 if successful.
|
||||||
|
* \return An ASN.1 error code if the input does not start with
|
||||||
|
* a valid ASN.1 ENUMERATED.
|
||||||
|
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
|
||||||
|
* not fit in an \c int.
|
||||||
|
*/
|
||||||
|
int mbedtls_asn1_get_enum( unsigned char **p,
|
||||||
|
const unsigned char *end,
|
||||||
|
int *val );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Retrieve a bitstring ASN.1 tag and its value.
|
* \brief Retrieve a bitstring ASN.1 tag and its value.
|
||||||
* Updates the pointer to immediately behind the full tag.
|
* Updates the pointer to immediately behind the full tag.
|
||||||
*
|
*
|
||||||
* \param p The position in the ASN.1 data
|
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||||
* \param end End of data
|
* On successful completion, \c *p is equal to \p end.
|
||||||
* \param bs The variable that will receive the value
|
* On error, the value of \c *p is undefined.
|
||||||
|
* \param end End of data.
|
||||||
|
* \param bs On success, ::mbedtls_asn1_bitstring information about
|
||||||
|
* the parsed value.
|
||||||
*
|
*
|
||||||
* \return 0 if successful or a specific ASN.1 error code.
|
* \return 0 if successful.
|
||||||
|
* \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains
|
||||||
|
* extra data after a valid BIT STRING.
|
||||||
|
* \return An ASN.1 error code if the input does not start with
|
||||||
|
* a valid ASN.1 BIT STRING.
|
||||||
*/
|
*/
|
||||||
int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end,
|
int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
|
||||||
mbedtls_asn1_bitstring *bs);
|
mbedtls_asn1_bitstring *bs );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Retrieve a bitstring ASN.1 tag without unused bits and its
|
* \brief Retrieve a bitstring ASN.1 tag without unused bits and its
|
||||||
* value.
|
* value.
|
||||||
* Updates the pointer to the beginning of the bit/octet string.
|
* Updates the pointer to the beginning of the bit/octet string.
|
||||||
*
|
*
|
||||||
* \param p The position in the ASN.1 data
|
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||||
* \param end End of data
|
* On successful completion, \c *p points to the first byte
|
||||||
* \param len Length of the actual bit/octect string in bytes
|
* of the content of the BIT STRING.
|
||||||
|
* On error, the value of \c *p is undefined.
|
||||||
|
* \param end End of data.
|
||||||
|
* \param len On success, \c *len is the length of the content in bytes.
|
||||||
*
|
*
|
||||||
* \return 0 if successful or a specific ASN.1 error code.
|
* \return 0 if successful.
|
||||||
|
* \return #MBEDTLS_ERR_ASN1_INVALID_DATA if the input starts with
|
||||||
|
* a valid BIT STRING with a nonzero number of unused bits.
|
||||||
|
* \return An ASN.1 error code if the input does not start with
|
||||||
|
* a valid ASN.1 BIT STRING.
|
||||||
*/
|
*/
|
||||||
int mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end,
|
int mbedtls_asn1_get_bitstring_null( unsigned char **p,
|
||||||
size_t *len);
|
const unsigned char *end,
|
||||||
|
size_t *len );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>"
|
* \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>".
|
||||||
* Updated the pointer to immediately behind the full sequence tag.
|
* Updates the pointer to immediately behind the full sequence tag.
|
||||||
*
|
*
|
||||||
* \param p The position in the ASN.1 data
|
* This function allocates memory for the sequence elements. You can free
|
||||||
* \param end End of data
|
* the allocated memory with mbedtls_asn1_sequence_free().
|
||||||
* \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.
|
* \note On error, this function may return a partial list in \p cur.
|
||||||
|
* You must set `cur->next = NULL` before calling this function!
|
||||||
|
* Otherwise it is impossible to distinguish a previously non-null
|
||||||
|
* pointer from a pointer to an object allocated by this function.
|
||||||
|
*
|
||||||
|
* \note If the sequence is empty, this function does not modify
|
||||||
|
* \c *cur. If the sequence is valid and non-empty, this
|
||||||
|
* function sets `cur->buf.tag` to \p tag. This allows
|
||||||
|
* callers to distinguish between an empty sequence and
|
||||||
|
* a one-element sequence.
|
||||||
|
*
|
||||||
|
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||||
|
* On successful completion, \c *p is equal to \p end.
|
||||||
|
* On error, the value of \c *p is undefined.
|
||||||
|
* \param end End of data.
|
||||||
|
* \param cur A ::mbedtls_asn1_sequence which this function fills.
|
||||||
|
* When this function returns, \c *cur is the head of a linked
|
||||||
|
* list. Each node in this list is allocated with
|
||||||
|
* mbedtls_calloc() apart from \p cur itself, and should
|
||||||
|
* therefore be freed with mbedtls_free().
|
||||||
|
* The list describes the content of the sequence.
|
||||||
|
* The head of the list (i.e. \c *cur itself) describes the
|
||||||
|
* first element, `*cur->next` describes the second element, etc.
|
||||||
|
* For each element, `buf.tag == tag`, `buf.len` is the length
|
||||||
|
* of the content of the content of the element, and `buf.p`
|
||||||
|
* points to the first byte of the content (i.e. immediately
|
||||||
|
* past the length of the element).
|
||||||
|
* Note that list elements may be allocated even on error.
|
||||||
|
* \param tag Each element of the sequence must have this tag.
|
||||||
|
*
|
||||||
|
* \return 0 if successful.
|
||||||
|
* \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains
|
||||||
|
* extra data after a valid SEQUENCE OF \p tag.
|
||||||
|
* \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts with
|
||||||
|
* an ASN.1 SEQUENCE in which an element has a tag that
|
||||||
|
* is different from \p tag.
|
||||||
|
* \return #MBEDTLS_ERR_ASN1_ALLOC_FAILED if a memory allocation failed.
|
||||||
|
* \return An ASN.1 error code if the input does not start with
|
||||||
|
* a valid ASN.1 SEQUENCE.
|
||||||
*/
|
*/
|
||||||
int mbedtls_asn1_get_sequence_of(unsigned char **p,
|
int mbedtls_asn1_get_sequence_of( unsigned char **p,
|
||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
mbedtls_asn1_sequence *cur,
|
mbedtls_asn1_sequence *cur,
|
||||||
int tag);
|
int tag );
|
||||||
|
/**
|
||||||
|
* \brief Free a heap-allocated linked list presentation of
|
||||||
|
* an ASN.1 sequence, including the first element.
|
||||||
|
*
|
||||||
|
* There are two common ways to manage the memory used for the representation
|
||||||
|
* of a parsed ASN.1 sequence:
|
||||||
|
* - Allocate a head node `mbedtls_asn1_sequence *head` with mbedtls_calloc().
|
||||||
|
* Pass this node as the `cur` argument to mbedtls_asn1_get_sequence_of().
|
||||||
|
* When you have finished processing the sequence,
|
||||||
|
* call mbedtls_asn1_sequence_free() on `head`.
|
||||||
|
* - Allocate a head node `mbedtls_asn1_sequence *head` in any manner,
|
||||||
|
* for example on the stack. Make sure that `head->next == NULL`.
|
||||||
|
* Pass `head` as the `cur` argument to mbedtls_asn1_get_sequence_of().
|
||||||
|
* When you have finished processing the sequence,
|
||||||
|
* call mbedtls_asn1_sequence_free() on `head->cur`,
|
||||||
|
* then free `head` itself in the appropriate manner.
|
||||||
|
*
|
||||||
|
* \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 Traverse an ASN.1 SEQUENCE container and
|
||||||
|
* call a callback for each entry.
|
||||||
|
*
|
||||||
|
* This function checks that the input is a SEQUENCE of elements that
|
||||||
|
* each have a "must" tag, and calls a callback function on the elements
|
||||||
|
* that have a "may" tag.
|
||||||
|
*
|
||||||
|
* For example, to validate that the input is a SEQUENCE of `tag1` and call
|
||||||
|
* `cb` on each element, use
|
||||||
|
* ```
|
||||||
|
* mbedtls_asn1_traverse_sequence_of(&p, end, 0xff, tag1, 0, 0, cb, ctx);
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* To validate that the input is a SEQUENCE of ANY and call `cb` on
|
||||||
|
* each element, use
|
||||||
|
* ```
|
||||||
|
* mbedtls_asn1_traverse_sequence_of(&p, end, 0, 0, 0, 0, cb, ctx);
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* To validate that the input is a SEQUENCE of CHOICE {NULL, OCTET STRING}
|
||||||
|
* and call `cb` on each element that is an OCTET STRING, use
|
||||||
|
* ```
|
||||||
|
* mbedtls_asn1_traverse_sequence_of(&p, end, 0xfe, 0x04, 0xff, 0x04, cb, ctx);
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* The callback is called on the elements with a "may" tag from left to
|
||||||
|
* right. If the input is not a valid SEQUENCE of elements with a "must" tag,
|
||||||
|
* the callback is called on the elements up to the leftmost point where
|
||||||
|
* the input is invalid.
|
||||||
|
*
|
||||||
|
* \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 that matches \p tag_may_val.
|
||||||
|
* The callback function is called with the following
|
||||||
|
* parameters:
|
||||||
|
* - \p ctx.
|
||||||
|
* - The tag of the current element.
|
||||||
|
* - A pointer to the start of the current element's
|
||||||
|
* content inside the input.
|
||||||
|
* - The length of the content of the current element.
|
||||||
|
* 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 #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input
|
||||||
|
* contains extra data after a valid SEQUENCE
|
||||||
|
* of elements with an accepted tag.
|
||||||
|
* \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts
|
||||||
|
* with an ASN.1 SEQUENCE in which an element has a tag
|
||||||
|
* that is not accepted.
|
||||||
|
* \return An ASN.1 error code if the input does not start with
|
||||||
|
* a valid ASN.1 SEQUENCE.
|
||||||
|
* \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,
|
||||||
|
unsigned char tag_must_mask, unsigned char tag_must_val,
|
||||||
|
unsigned char tag_may_mask, unsigned char tag_may_val,
|
||||||
|
int (*cb)( void *ctx, int tag,
|
||||||
|
unsigned char* start, size_t len ),
|
||||||
|
void *ctx );
|
||||||
|
|
||||||
#if defined(MBEDTLS_BIGNUM_C)
|
#if defined(MBEDTLS_BIGNUM_C)
|
||||||
/**
|
/**
|
||||||
* \brief Retrieve a MPI value from an integer ASN.1 tag.
|
* \brief Retrieve an integer ASN.1 tag and its value.
|
||||||
* Updates the pointer to immediately behind the full tag.
|
* Updates the pointer to immediately behind the full tag.
|
||||||
*
|
*
|
||||||
* \param p The position in the ASN.1 data
|
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||||
* \param end End of data
|
* On successful completion, \c *p points to the first byte
|
||||||
* \param X The MPI that will receive the value
|
* beyond the ASN.1 element.
|
||||||
|
* On error, the value of \c *p is undefined.
|
||||||
|
* \param end End of data.
|
||||||
|
* \param X On success, the parsed value.
|
||||||
*
|
*
|
||||||
* \return 0 if successful or a specific ASN.1 or MPI error code.
|
* \return 0 if successful.
|
||||||
|
* \return An ASN.1 error code if the input does not start with
|
||||||
|
* a valid ASN.1 INTEGER.
|
||||||
|
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
|
||||||
|
* not fit in an \c int.
|
||||||
|
* \return An MPI error code if the parsed value is too large.
|
||||||
*/
|
*/
|
||||||
int mbedtls_asn1_get_mpi(unsigned char **p,
|
int mbedtls_asn1_get_mpi( unsigned char **p,
|
||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
mbedtls_mpi *X);
|
mbedtls_mpi *X );
|
||||||
#endif /* MBEDTLS_BIGNUM_C */
|
#endif /* MBEDTLS_BIGNUM_C */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -294,16 +534,20 @@ int mbedtls_asn1_get_mpi(unsigned char **p,
|
|||||||
* Updates the pointer to immediately behind the full
|
* Updates the pointer to immediately behind the full
|
||||||
* AlgorithmIdentifier.
|
* AlgorithmIdentifier.
|
||||||
*
|
*
|
||||||
* \param p The position in the ASN.1 data
|
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||||
* \param end End of data
|
* On successful completion, \c *p points to the first byte
|
||||||
* \param alg The buffer to receive the OID
|
* beyond the AlgorithmIdentifier element.
|
||||||
* \param params The buffer to receive the params (if any)
|
* On error, the value of \c *p is undefined.
|
||||||
|
* \param end End of data.
|
||||||
|
* \param alg The buffer to receive the OID.
|
||||||
|
* \param params The buffer to receive the parameters.
|
||||||
|
* This is zeroized if there are no parameters.
|
||||||
*
|
*
|
||||||
* \return 0 if successful or a specific ASN.1 or MPI error code.
|
* \return 0 if successful or a specific ASN.1 or MPI error code.
|
||||||
*/
|
*/
|
||||||
int mbedtls_asn1_get_alg(unsigned char **p,
|
int mbedtls_asn1_get_alg( unsigned char **p,
|
||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params);
|
mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no
|
* \brief Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no
|
||||||
@@ -311,15 +555,18 @@ int mbedtls_asn1_get_alg(unsigned char **p,
|
|||||||
* Updates the pointer to immediately behind the full
|
* Updates the pointer to immediately behind the full
|
||||||
* AlgorithmIdentifier.
|
* AlgorithmIdentifier.
|
||||||
*
|
*
|
||||||
* \param p The position in the ASN.1 data
|
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||||
* \param end End of data
|
* On successful completion, \c *p points to the first byte
|
||||||
* \param alg The buffer to receive the OID
|
* beyond the AlgorithmIdentifier element.
|
||||||
|
* On error, the value of \c *p is undefined.
|
||||||
|
* \param end End of data.
|
||||||
|
* \param alg The buffer to receive the OID.
|
||||||
*
|
*
|
||||||
* \return 0 if successful or a specific ASN.1 or MPI error code.
|
* \return 0 if successful or a specific ASN.1 or MPI error code.
|
||||||
*/
|
*/
|
||||||
int mbedtls_asn1_get_alg_null(unsigned char **p,
|
int mbedtls_asn1_get_alg_null( unsigned char **p,
|
||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
mbedtls_asn1_buf *alg);
|
mbedtls_asn1_buf *alg );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Find a specific named_data entry in a sequence or list based on
|
* \brief Find a specific named_data entry in a sequence or list based on
|
||||||
@@ -331,23 +578,27 @@ int mbedtls_asn1_get_alg_null(unsigned char **p,
|
|||||||
*
|
*
|
||||||
* \return NULL if not found, or a pointer to the existing entry.
|
* \return NULL if not found, or a pointer to the existing entry.
|
||||||
*/
|
*/
|
||||||
mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(mbedtls_asn1_named_data *list,
|
mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list,
|
||||||
const char *oid, size_t len);
|
const char *oid, size_t len );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Free a mbedtls_asn1_named_data entry
|
* \brief Free a mbedtls_asn1_named_data entry
|
||||||
*
|
*
|
||||||
* \param entry The named data entry to free
|
* \param entry The named data entry to free.
|
||||||
|
* This function calls mbedtls_free() on
|
||||||
|
* `entry->oid.p` and `entry->val.p`.
|
||||||
*/
|
*/
|
||||||
void mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *entry);
|
void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Free all entries in a mbedtls_asn1_named_data list
|
* \brief Free all entries in a mbedtls_asn1_named_data list.
|
||||||
* Head will be set to NULL
|
|
||||||
*
|
*
|
||||||
* \param head Pointer to the head of the list of named data entries to free
|
* \param head Pointer to the head of the list of named data entries to free.
|
||||||
|
* This function calls mbedtls_asn1_free_named_data() and
|
||||||
|
* mbedtls_free() on each list element and
|
||||||
|
* sets \c *head to \c NULL.
|
||||||
*/
|
*/
|
||||||
void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head);
|
void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +1,29 @@
|
|||||||
/*
|
/*
|
||||||
* Generic ASN.1 parsing
|
* Generic ASN.1 parsing
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#include "common.h"
|
||||||
#include "mbedtls/config.h"
|
|
||||||
#else
|
|
||||||
#include MBEDTLS_CONFIG_FILE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_ASN1_PARSE_C)
|
#if defined(MBEDTLS_ASN1_PARSE_C)
|
||||||
|
|
||||||
#include "mbedtls/asn1.h"
|
#include "mbedtls/asn1.h"
|
||||||
#include "mbedtls/platform_util.h"
|
#include "mbedtls/platform_util.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -49,321 +42,440 @@
|
|||||||
/*
|
/*
|
||||||
* ASN.1 DER decoding routines
|
* ASN.1 DER decoding routines
|
||||||
*/
|
*/
|
||||||
int mbedtls_asn1_get_len(unsigned char **p,
|
int mbedtls_asn1_get_len( unsigned char **p,
|
||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
size_t *len) {
|
size_t *len )
|
||||||
if ((end - *p) < 1)
|
{
|
||||||
return (MBEDTLS_ERR_ASN1_OUT_OF_DATA);
|
if( ( end - *p ) < 1 )
|
||||||
|
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||||
|
|
||||||
if ((**p & 0x80) == 0)
|
if( ( **p & 0x80 ) == 0 )
|
||||||
*len = *(*p)++;
|
*len = *(*p)++;
|
||||||
else {
|
else
|
||||||
switch (**p & 0x7F) {
|
{
|
||||||
case 1:
|
switch( **p & 0x7F )
|
||||||
if ((end - *p) < 2)
|
{
|
||||||
return (MBEDTLS_ERR_ASN1_OUT_OF_DATA);
|
case 1:
|
||||||
|
if( ( end - *p ) < 2 )
|
||||||
|
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||||
|
|
||||||
*len = (*p)[1];
|
*len = (*p)[1];
|
||||||
(*p) += 2;
|
(*p) += 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
if ((end - *p) < 3)
|
if( ( end - *p ) < 3 )
|
||||||
return (MBEDTLS_ERR_ASN1_OUT_OF_DATA);
|
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||||
|
|
||||||
*len = ((size_t)(*p)[1] << 8) | (*p)[2];
|
*len = ( (size_t)(*p)[1] << 8 ) | (*p)[2];
|
||||||
(*p) += 3;
|
(*p) += 3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
if ((end - *p) < 4)
|
if( ( end - *p ) < 4 )
|
||||||
return (MBEDTLS_ERR_ASN1_OUT_OF_DATA);
|
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||||
|
|
||||||
*len = ((size_t)(*p)[1] << 16) |
|
*len = ( (size_t)(*p)[1] << 16 ) |
|
||||||
((size_t)(*p)[2] << 8) | (*p)[3];
|
( (size_t)(*p)[2] << 8 ) | (*p)[3];
|
||||||
(*p) += 4;
|
(*p) += 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
if ((end - *p) < 5)
|
if( ( end - *p ) < 5 )
|
||||||
return (MBEDTLS_ERR_ASN1_OUT_OF_DATA);
|
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||||
|
|
||||||
*len = ((size_t)(*p)[1] << 24) | ((size_t)(*p)[2] << 16) |
|
*len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) |
|
||||||
((size_t)(*p)[3] << 8) | (*p)[4];
|
( (size_t)(*p)[3] << 8 ) | (*p)[4];
|
||||||
(*p) += 5;
|
(*p) += 5;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return (MBEDTLS_ERR_ASN1_INVALID_LENGTH);
|
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*len > (size_t)(end - *p))
|
if( *len > (size_t) ( end - *p ) )
|
||||||
return (MBEDTLS_ERR_ASN1_OUT_OF_DATA);
|
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_asn1_get_tag(unsigned char **p,
|
int mbedtls_asn1_get_tag( unsigned char **p,
|
||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
size_t *len, int tag) {
|
size_t *len, int tag )
|
||||||
if ((end - *p) < 1)
|
{
|
||||||
return (MBEDTLS_ERR_ASN1_OUT_OF_DATA);
|
if( ( end - *p ) < 1 )
|
||||||
|
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||||
|
|
||||||
if (**p != tag)
|
if( **p != tag )
|
||||||
return (MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
|
return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
|
||||||
|
|
||||||
(*p)++;
|
(*p)++;
|
||||||
|
|
||||||
return (mbedtls_asn1_get_len(p, end, len));
|
return( mbedtls_asn1_get_len( p, end, len ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_asn1_get_bool(unsigned char **p,
|
int mbedtls_asn1_get_bool( unsigned char **p,
|
||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
int *val) {
|
int *val )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0)
|
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
|
|
||||||
if (len != 1)
|
if( len != 1 )
|
||||||
return (MBEDTLS_ERR_ASN1_INVALID_LENGTH);
|
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||||
|
|
||||||
*val = (**p != 0) ? 1 : 0;
|
*val = ( **p != 0 ) ? 1 : 0;
|
||||||
(*p)++;
|
(*p)++;
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_asn1_get_int(unsigned char **p,
|
static int asn1_get_tagged_int( unsigned char **p,
|
||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
int *val) {
|
int tag, int *val )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0)
|
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, tag ) ) != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
|
|
||||||
if (len == 0 || len > sizeof(int) || (**p & 0x80) != 0)
|
/*
|
||||||
return (MBEDTLS_ERR_ASN1_INVALID_LENGTH);
|
* len==0 is malformed (0 must be represented as 020100 for INTEGER,
|
||||||
|
* or 0A0100 for ENUMERATED tags
|
||||||
|
*/
|
||||||
|
if( len == 0 )
|
||||||
|
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||||
|
/* This is a cryptography library. Reject negative integers. */
|
||||||
|
if( ( **p & 0x80 ) != 0 )
|
||||||
|
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||||
|
|
||||||
|
/* Skip leading zeros. */
|
||||||
|
while( len > 0 && **p == 0 )
|
||||||
|
{
|
||||||
|
++( *p );
|
||||||
|
--len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reject integers that don't fit in an int. This code assumes that
|
||||||
|
* the int type has no padding bit. */
|
||||||
|
if( len > sizeof( int ) )
|
||||||
|
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||||
|
if( len == sizeof( int ) && ( **p & 0x80 ) != 0 )
|
||||||
|
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||||
|
|
||||||
*val = 0;
|
*val = 0;
|
||||||
|
while( len-- > 0 )
|
||||||
while (len-- > 0) {
|
{
|
||||||
*val = (*val << 8) | **p;
|
*val = ( *val << 8 ) | **p;
|
||||||
(*p)++;
|
(*p)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_asn1_get_int( unsigned char **p,
|
||||||
|
const unsigned char *end,
|
||||||
|
int *val )
|
||||||
|
{
|
||||||
|
return( asn1_get_tagged_int( p, end, MBEDTLS_ASN1_INTEGER, val) );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_asn1_get_enum( unsigned char **p,
|
||||||
|
const unsigned char *end,
|
||||||
|
int *val )
|
||||||
|
{
|
||||||
|
return( asn1_get_tagged_int( p, end, MBEDTLS_ASN1_ENUMERATED, val) );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MBEDTLS_BIGNUM_C)
|
#if defined(MBEDTLS_BIGNUM_C)
|
||||||
int mbedtls_asn1_get_mpi(unsigned char **p,
|
int mbedtls_asn1_get_mpi( unsigned char **p,
|
||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
mbedtls_mpi *X) {
|
mbedtls_mpi *X )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0)
|
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
|
|
||||||
ret = mbedtls_mpi_read_binary(X, *p, len);
|
ret = mbedtls_mpi_read_binary( X, *p, len );
|
||||||
|
|
||||||
*p += len;
|
*p += len;
|
||||||
|
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_BIGNUM_C */
|
#endif /* MBEDTLS_BIGNUM_C */
|
||||||
|
|
||||||
int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end,
|
int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
|
||||||
mbedtls_asn1_bitstring *bs) {
|
mbedtls_asn1_bitstring *bs)
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
/* Certificate type is a single byte bitstring */
|
/* Certificate type is a single byte bitstring */
|
||||||
if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING)) != 0)
|
if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
|
|
||||||
/* Check length, subtract one for actual bit string length */
|
/* Check length, subtract one for actual bit string length */
|
||||||
if (bs->len < 1)
|
if( bs->len < 1 )
|
||||||
return (MBEDTLS_ERR_ASN1_OUT_OF_DATA);
|
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||||
bs->len -= 1;
|
bs->len -= 1;
|
||||||
|
|
||||||
/* Get number of unused bits, ensure unused bits <= 7 */
|
/* Get number of unused bits, ensure unused bits <= 7 */
|
||||||
bs->unused_bits = **p;
|
bs->unused_bits = **p;
|
||||||
if (bs->unused_bits > 7)
|
if( bs->unused_bits > 7 )
|
||||||
return (MBEDTLS_ERR_ASN1_INVALID_LENGTH);
|
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||||
(*p)++;
|
(*p)++;
|
||||||
|
|
||||||
/* Get actual bitstring */
|
/* Get actual bitstring */
|
||||||
bs->p = *p;
|
bs->p = *p;
|
||||||
*p += bs->len;
|
*p += bs->len;
|
||||||
|
|
||||||
if (*p != end)
|
if( *p != end )
|
||||||
return (MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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,
|
||||||
|
unsigned char tag_must_mask, unsigned char tag_must_val,
|
||||||
|
unsigned char tag_may_mask, unsigned char 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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get a bit string without unused bits
|
* Get a bit string without unused bits
|
||||||
*/
|
*/
|
||||||
int mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end,
|
int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
|
||||||
size_t *len) {
|
size_t *len )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0)
|
if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
|
|
||||||
if ((*len)-- < 2 || *(*p)++ != 0)
|
if( *len == 0 )
|
||||||
return (MBEDTLS_ERR_ASN1_INVALID_DATA);
|
return( MBEDTLS_ERR_ASN1_INVALID_DATA );
|
||||||
|
--( *len );
|
||||||
|
|
||||||
return (0);
|
if( **p != 0 )
|
||||||
|
return( MBEDTLS_ERR_ASN1_INVALID_DATA );
|
||||||
|
++( *p );
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parses and splits an ASN.1 "SEQUENCE OF <tag>"
|
* Parses and splits an ASN.1 "SEQUENCE OF <tag>"
|
||||||
*/
|
*/
|
||||||
int mbedtls_asn1_get_sequence_of(unsigned char **p,
|
int mbedtls_asn1_get_sequence_of( unsigned char **p,
|
||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
mbedtls_asn1_sequence *cur,
|
mbedtls_asn1_sequence *cur,
|
||||||
int tag) {
|
int tag)
|
||||||
int ret;
|
{
|
||||||
size_t len;
|
asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
|
||||||
mbedtls_asn1_buf *buf;
|
memset( cur, 0, sizeof( mbedtls_asn1_sequence ) );
|
||||||
|
return( mbedtls_asn1_traverse_sequence_of(
|
||||||
/* Get main sequence tag */
|
p, end, 0xFF, tag, 0, 0,
|
||||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
asn1_get_sequence_of_cb, &cb_ctx ) );
|
||||||
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,
|
int mbedtls_asn1_get_alg( unsigned char **p,
|
||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params) {
|
mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
|
||||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0)
|
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
|
|
||||||
if ((end - *p) < 1)
|
if( ( end - *p ) < 1 )
|
||||||
return (MBEDTLS_ERR_ASN1_OUT_OF_DATA);
|
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||||
|
|
||||||
alg->tag = **p;
|
alg->tag = **p;
|
||||||
end = *p + len;
|
end = *p + len;
|
||||||
|
|
||||||
if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0)
|
if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
|
|
||||||
alg->p = *p;
|
alg->p = *p;
|
||||||
*p += alg->len;
|
*p += alg->len;
|
||||||
|
|
||||||
if (*p == end) {
|
if( *p == end )
|
||||||
mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf));
|
{
|
||||||
return (0);
|
mbedtls_platform_zeroize( params, sizeof(mbedtls_asn1_buf) );
|
||||||
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
params->tag = **p;
|
params->tag = **p;
|
||||||
(*p)++;
|
(*p)++;
|
||||||
|
|
||||||
if ((ret = mbedtls_asn1_get_len(p, end, ¶ms->len)) != 0)
|
if( ( ret = mbedtls_asn1_get_len( p, end, ¶ms->len ) ) != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
|
|
||||||
params->p = *p;
|
params->p = *p;
|
||||||
*p += params->len;
|
*p += params->len;
|
||||||
|
|
||||||
if (*p != end)
|
if( *p != end )
|
||||||
return (MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_asn1_get_alg_null(unsigned char **p,
|
int mbedtls_asn1_get_alg_null( unsigned char **p,
|
||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
mbedtls_asn1_buf *alg) {
|
mbedtls_asn1_buf *alg )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
mbedtls_asn1_buf params;
|
mbedtls_asn1_buf params;
|
||||||
|
|
||||||
memset(¶ms, 0, sizeof(mbedtls_asn1_buf));
|
memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) );
|
||||||
|
|
||||||
if ((ret = mbedtls_asn1_get_alg(p, end, alg, ¶ms)) != 0)
|
if( ( ret = mbedtls_asn1_get_alg( p, end, alg, ¶ms ) ) != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
|
|
||||||
if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0)
|
if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 )
|
||||||
return (MBEDTLS_ERR_ASN1_INVALID_DATA);
|
return( MBEDTLS_ERR_ASN1_INVALID_DATA );
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur) {
|
void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur )
|
||||||
if (cur == NULL)
|
{
|
||||||
|
if( cur == NULL )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mbedtls_free(cur->oid.p);
|
mbedtls_free( cur->oid.p );
|
||||||
mbedtls_free(cur->val.p);
|
mbedtls_free( cur->val.p );
|
||||||
|
|
||||||
mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data));
|
mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head) {
|
void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head )
|
||||||
|
{
|
||||||
mbedtls_asn1_named_data *cur;
|
mbedtls_asn1_named_data *cur;
|
||||||
|
|
||||||
while ((cur = *head) != NULL) {
|
while( ( cur = *head ) != NULL )
|
||||||
|
{
|
||||||
*head = cur->next;
|
*head = cur->next;
|
||||||
mbedtls_asn1_free_named_data(cur);
|
mbedtls_asn1_free_named_data( cur );
|
||||||
mbedtls_free(cur);
|
mbedtls_free( cur );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(mbedtls_asn1_named_data *list,
|
mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list,
|
||||||
const char *oid, size_t len) {
|
const char *oid, size_t len )
|
||||||
while (list != NULL) {
|
{
|
||||||
if (list->oid.len == len &&
|
while( list != NULL )
|
||||||
memcmp(list->oid.p, oid, len) == 0) {
|
{
|
||||||
|
if( list->oid.len == len &&
|
||||||
|
memcmp( list->oid.p, oid, len ) == 0 )
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (list);
|
return( list );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MBEDTLS_ASN1_PARSE_C */
|
#endif /* MBEDTLS_ASN1_PARSE_C */
|
||||||
|
|||||||
@@ -1,35 +1,28 @@
|
|||||||
/*
|
/*
|
||||||
* ASN.1 buffer writing functionality
|
* ASN.1 buffer writing functionality
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#include "common.h"
|
||||||
#include "mbedtls/config.h"
|
|
||||||
#else
|
|
||||||
#include MBEDTLS_CONFIG_FILE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_ASN1_WRITE_C)
|
#if defined(MBEDTLS_ASN1_WRITE_C)
|
||||||
|
|
||||||
#include "mbedtls/asn1write.h"
|
#include "mbedtls/asn1write.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -41,327 +34,447 @@
|
|||||||
#define mbedtls_free free
|
#define mbedtls_free free
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int mbedtls_asn1_write_len(unsigned char **p, unsigned char *start, size_t len) {
|
int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len )
|
||||||
if (len < 0x80) {
|
{
|
||||||
if (*p - start < 1)
|
if( len < 0x80 )
|
||||||
return (MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
|
{
|
||||||
|
if( *p - start < 1 )
|
||||||
|
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
|
||||||
|
|
||||||
*--(*p) = (unsigned char) len;
|
*--(*p) = (unsigned char) len;
|
||||||
return (1);
|
return( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len <= 0xFF) {
|
if( len <= 0xFF )
|
||||||
if (*p - start < 2)
|
{
|
||||||
return (MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
|
if( *p - start < 2 )
|
||||||
|
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
|
||||||
|
|
||||||
*--(*p) = (unsigned char) len;
|
*--(*p) = (unsigned char) len;
|
||||||
*--(*p) = 0x81;
|
*--(*p) = 0x81;
|
||||||
return (2);
|
return( 2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len <= 0xFFFF) {
|
if( len <= 0xFFFF )
|
||||||
if (*p - start < 3)
|
{
|
||||||
return (MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
|
if( *p - start < 3 )
|
||||||
|
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
|
||||||
|
|
||||||
*--(*p) = (len) & 0xFF;
|
*--(*p) = ( len ) & 0xFF;
|
||||||
*--(*p) = (len >> 8) & 0xFF;
|
*--(*p) = ( len >> 8 ) & 0xFF;
|
||||||
*--(*p) = 0x82;
|
*--(*p) = 0x82;
|
||||||
return (3);
|
return( 3 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len <= 0xFFFFFF) {
|
if( len <= 0xFFFFFF )
|
||||||
if (*p - start < 4)
|
{
|
||||||
return (MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
|
if( *p - start < 4 )
|
||||||
|
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
|
||||||
|
|
||||||
*--(*p) = (len) & 0xFF;
|
*--(*p) = ( len ) & 0xFF;
|
||||||
*--(*p) = (len >> 8) & 0xFF;
|
*--(*p) = ( len >> 8 ) & 0xFF;
|
||||||
*--(*p) = (len >> 16) & 0xFF;
|
*--(*p) = ( len >> 16 ) & 0xFF;
|
||||||
*--(*p) = 0x83;
|
*--(*p) = 0x83;
|
||||||
return (4);
|
return( 4 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SIZE_MAX > 0xFFFFFFFF
|
#if SIZE_MAX > 0xFFFFFFFF
|
||||||
if (len <= 0xFFFFFFFF)
|
if( len <= 0xFFFFFFFF )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (*p - start < 5)
|
if( *p - start < 5 )
|
||||||
return (MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
|
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
|
||||||
|
|
||||||
*--(*p) = (len) & 0xFF;
|
*--(*p) = ( len ) & 0xFF;
|
||||||
*--(*p) = (len >> 8) & 0xFF;
|
*--(*p) = ( len >> 8 ) & 0xFF;
|
||||||
*--(*p) = (len >> 16) & 0xFF;
|
*--(*p) = ( len >> 16 ) & 0xFF;
|
||||||
*--(*p) = (len >> 24) & 0xFF;
|
*--(*p) = ( len >> 24 ) & 0xFF;
|
||||||
*--(*p) = 0x84;
|
*--(*p) = 0x84;
|
||||||
return (5);
|
return( 5 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SIZE_MAX > 0xFFFFFFFF
|
#if SIZE_MAX > 0xFFFFFFFF
|
||||||
return (MBEDTLS_ERR_ASN1_INVALID_LENGTH);
|
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_asn1_write_tag(unsigned char **p, unsigned char *start, unsigned char tag) {
|
int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag )
|
||||||
if (*p - start < 1)
|
{
|
||||||
return (MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
|
if( *p - start < 1 )
|
||||||
|
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
|
||||||
|
|
||||||
*--(*p) = tag;
|
*--(*p) = tag;
|
||||||
|
|
||||||
return (1);
|
return( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_asn1_write_raw_buffer(unsigned char **p, unsigned char *start,
|
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 )
|
||||||
|
{
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
if (*p < start || (size_t)(*p - start) < size)
|
if( *p < start || (size_t)( *p - start ) < size )
|
||||||
return (MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
|
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
|
||||||
|
|
||||||
len = size;
|
len = size;
|
||||||
(*p) -= len;
|
(*p) -= len;
|
||||||
memcpy(*p, buf, len);
|
memcpy( *p, buf, len );
|
||||||
|
|
||||||
return ((int) len);
|
return( (int) len );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MBEDTLS_BIGNUM_C)
|
#if defined(MBEDTLS_BIGNUM_C)
|
||||||
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 )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
// Write the MPI
|
// Write the MPI
|
||||||
//
|
//
|
||||||
len = mbedtls_mpi_size(X);
|
len = mbedtls_mpi_size( X );
|
||||||
|
|
||||||
if (*p < start || (size_t)(*p - start) < len)
|
if( *p < start || (size_t)( *p - start ) < len )
|
||||||
return (MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
|
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
|
||||||
|
|
||||||
(*p) -= len;
|
(*p) -= len;
|
||||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(X, *p, len));
|
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, *p, len ) );
|
||||||
|
|
||||||
// DER format assumes 2s complement for numbers, so the leftmost bit
|
// DER format assumes 2s complement for numbers, so the leftmost bit
|
||||||
// should be 0 for positive numbers and 1 for negative numbers.
|
// should be 0 for positive numbers and 1 for negative numbers.
|
||||||
//
|
//
|
||||||
if (X->s == 1 && **p & 0x80) {
|
if( X->s ==1 && **p & 0x80 )
|
||||||
if (*p - start < 1)
|
{
|
||||||
return (MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
|
if( *p - start < 1 )
|
||||||
|
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
|
||||||
|
|
||||||
*--(*p) = 0x00;
|
*--(*p) = 0x00;
|
||||||
len += 1;
|
len += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, 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_INTEGER));
|
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) );
|
||||||
|
|
||||||
ret = (int) len;
|
ret = (int) len;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_BIGNUM_C */
|
#endif /* MBEDTLS_BIGNUM_C */
|
||||||
|
|
||||||
int mbedtls_asn1_write_null(unsigned char **p, unsigned char *start) {
|
int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
// Write NULL
|
// Write NULL
|
||||||
//
|
//
|
||||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, 0));
|
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, 0) );
|
||||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_NULL));
|
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_NULL ) );
|
||||||
|
|
||||||
return ((int) len);
|
return( (int) len );
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_asn1_write_oid(unsigned char **p, unsigned char *start,
|
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 )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start,
|
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
|
||||||
(const unsigned char *) oid, oid_len));
|
(const unsigned char *) oid, oid_len ) );
|
||||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, 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_OID));
|
MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) );
|
||||||
|
|
||||||
return ((int) len);
|
return( (int) len );
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_asn1_write_algorithm_identifier(unsigned char **p, unsigned char *start,
|
int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
|
||||||
const char *oid, size_t oid_len,
|
const char *oid, size_t oid_len,
|
||||||
size_t par_len) {
|
size_t par_len )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
if (par_len == 0)
|
if( par_len == 0 )
|
||||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_null(p, start));
|
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_null( p, start ) );
|
||||||
else
|
else
|
||||||
len += par_len;
|
len += par_len;
|
||||||
|
|
||||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(p, start, oid, oid_len));
|
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) );
|
||||||
|
|
||||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, 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_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
|
||||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
|
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
|
||||||
|
|
||||||
return ((int) len);
|
return( (int) len );
|
||||||
}
|
}
|
||||||
|
|
||||||
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 )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
if (*p - start < 1)
|
if( *p - start < 1 )
|
||||||
return (MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
|
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
|
||||||
|
|
||||||
*--(*p) = (boolean) ? 255 : 0;
|
*--(*p) = (boolean) ? 255 : 0;
|
||||||
len++;
|
len++;
|
||||||
|
|
||||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, 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_BOOLEAN));
|
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BOOLEAN ) );
|
||||||
|
|
||||||
return ((int) len);
|
return( (int) len );
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_asn1_write_int(unsigned char **p, unsigned char *start, int val) {
|
static int asn1_write_tagged_int( unsigned char **p, unsigned char *start, int val, int tag )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
if (*p - start < 1)
|
do
|
||||||
return (MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
|
{
|
||||||
|
if( *p - start < 1 )
|
||||||
len += 1;
|
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
|
||||||
*--(*p) = val;
|
len += 1;
|
||||||
|
*--(*p) = val & 0xff;
|
||||||
if (val > 0 && **p & 0x80) {
|
val >>= 8;
|
||||||
if (*p - start < 1)
|
}
|
||||||
return (MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
|
while( val > 0 );
|
||||||
|
|
||||||
|
if( **p & 0x80 )
|
||||||
|
{
|
||||||
|
if( *p - start < 1 )
|
||||||
|
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
|
||||||
*--(*p) = 0x00;
|
*--(*p) = 0x00;
|
||||||
len += 1;
|
len += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, 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_INTEGER));
|
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, tag ) );
|
||||||
|
|
||||||
return ((int) len);
|
return( (int) len );
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_asn1_write_printable_string(unsigned char **p, unsigned char *start,
|
int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val )
|
||||||
const char *text, size_t text_len) {
|
{
|
||||||
int ret;
|
return( asn1_write_tagged_int( p, start, val, MBEDTLS_ASN1_INTEGER ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_asn1_write_enum( unsigned char **p, unsigned char *start, int val )
|
||||||
|
{
|
||||||
|
return( asn1_write_tagged_int( p, start, val, MBEDTLS_ASN1_ENUMERATED ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start, int tag,
|
||||||
|
const char *text, size_t text_len )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start,
|
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_len( p, start, len ) );
|
||||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_PRINTABLE_STRING));
|
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, tag ) );
|
||||||
|
|
||||||
return ((int) len);
|
return( (int) len );
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_asn1_write_ia5_string(unsigned char **p, unsigned char *start,
|
int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start,
|
||||||
const char *text, size_t text_len) {
|
const char *text, size_t text_len )
|
||||||
int ret;
|
{
|
||||||
|
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 mbedtls_asn1_write_named_bitstring( unsigned char **p,
|
||||||
|
unsigned char *start,
|
||||||
|
const unsigned char *buf,
|
||||||
|
size_t bits )
|
||||||
|
{
|
||||||
|
size_t unused_bits, byte_len;
|
||||||
|
const unsigned char *cur_byte;
|
||||||
|
unsigned char cur_byte_shifted;
|
||||||
|
unsigned char bit;
|
||||||
|
|
||||||
|
byte_len = ( bits + 7 ) / 8;
|
||||||
|
unused_bits = ( byte_len * 8 ) - bits;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Named bitstrings require that trailing 0s are excluded in the encoding
|
||||||
|
* of the bitstring. Trailing 0s are considered part of the 'unused' bits
|
||||||
|
* when encoding this value in the first content octet
|
||||||
|
*/
|
||||||
|
if( bits != 0 )
|
||||||
|
{
|
||||||
|
cur_byte = buf + byte_len - 1;
|
||||||
|
cur_byte_shifted = *cur_byte >> unused_bits;
|
||||||
|
|
||||||
|
for( ; ; )
|
||||||
|
{
|
||||||
|
bit = cur_byte_shifted & 0x1;
|
||||||
|
cur_byte_shifted >>= 1;
|
||||||
|
|
||||||
|
if( bit != 0 )
|
||||||
|
break;
|
||||||
|
|
||||||
|
bits--;
|
||||||
|
if( bits == 0 )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if( bits % 8 == 0 )
|
||||||
|
cur_byte_shifted = *--cur_byte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return( mbedtls_asn1_write_bitstring( p, start, buf, bits ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
|
||||||
|
const unsigned char *buf, size_t bits )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
size_t len = 0;
|
||||||
|
size_t unused_bits, byte_len;
|
||||||
|
|
||||||
|
byte_len = ( bits + 7 ) / 8;
|
||||||
|
unused_bits = ( byte_len * 8 ) - bits;
|
||||||
|
|
||||||
|
if( *p < start || (size_t)( *p - start ) < byte_len + 1 )
|
||||||
|
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
|
||||||
|
|
||||||
|
len = byte_len + 1;
|
||||||
|
|
||||||
|
/* Write the bitstring. Ensure the unused bits are zeroed */
|
||||||
|
if( byte_len > 0 )
|
||||||
|
{
|
||||||
|
byte_len--;
|
||||||
|
*--( *p ) = buf[byte_len] & ~( ( 0x1 << unused_bits ) - 1 );
|
||||||
|
( *p ) -= byte_len;
|
||||||
|
memcpy( *p, buf, byte_len );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write unused bits */
|
||||||
|
*--( *p ) = (unsigned char)unused_bits;
|
||||||
|
|
||||||
|
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_BIT_STRING ) );
|
||||||
|
|
||||||
|
return( (int) len );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
|
||||||
|
const unsigned char *buf, size_t size )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start,
|
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, buf, size ) );
|
||||||
(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_len( p, start, len ) );
|
||||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_IA5_STRING));
|
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) );
|
||||||
|
|
||||||
return ((int) len);
|
return( (int) len );
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_asn1_write_bitstring(unsigned char **p, unsigned char *start,
|
|
||||||
const unsigned char *buf, size_t bits) {
|
|
||||||
int ret;
|
|
||||||
size_t len = 0, size;
|
|
||||||
|
|
||||||
size = (bits / 8) + ((bits % 8) ? 1 : 0);
|
/* This is a copy of the ASN.1 parsing function mbedtls_asn1_find_named_data(),
|
||||||
|
* which is replicated to avoid a dependency ASN1_WRITE_C on ASN1_PARSE_C. */
|
||||||
// Calculate byte length
|
static mbedtls_asn1_named_data *asn1_find_named_data(
|
||||||
//
|
mbedtls_asn1_named_data *list,
|
||||||
if (*p < start || (size_t)(*p - start) < size + 1)
|
const char *oid, size_t len )
|
||||||
return (MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
|
{
|
||||||
|
while( list != NULL )
|
||||||
len = size + 1;
|
{
|
||||||
(*p) -= size;
|
if( list->oid.len == len &&
|
||||||
memcpy(*p, buf, size);
|
memcmp( list->oid.p, oid, len ) == 0 )
|
||||||
|
{
|
||||||
// Write unused bits
|
break;
|
||||||
//
|
|
||||||
*--(*p) = (unsigned char)(size * 8 - bits);
|
|
||||||
|
|
||||||
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_BIT_STRING));
|
|
||||||
|
|
||||||
return ((int) len);
|
|
||||||
}
|
|
||||||
|
|
||||||
int mbedtls_asn1_write_octet_string(unsigned char **p, unsigned char *start,
|
|
||||||
const unsigned char *buf, size_t size) {
|
|
||||||
int ret;
|
|
||||||
size_t len = 0;
|
|
||||||
|
|
||||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, buf, size));
|
|
||||||
|
|
||||||
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_OCTET_STRING));
|
|
||||||
|
|
||||||
return ((int) len);
|
|
||||||
}
|
|
||||||
|
|
||||||
mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(mbedtls_asn1_named_data **head,
|
|
||||||
const char *oid, size_t oid_len,
|
|
||||||
const unsigned char *val,
|
|
||||||
size_t val_len) {
|
|
||||||
mbedtls_asn1_named_data *cur;
|
|
||||||
|
|
||||||
if ((cur = mbedtls_asn1_find_named_data(*head, oid, oid_len)) == NULL) {
|
|
||||||
// Add new entry if not present yet based on OID
|
|
||||||
//
|
|
||||||
cur = (mbedtls_asn1_named_data *)mbedtls_calloc(1,
|
|
||||||
sizeof(mbedtls_asn1_named_data));
|
|
||||||
if (cur == NULL)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
cur->oid.len = oid_len;
|
|
||||||
cur->oid.p = mbedtls_calloc(1, oid_len);
|
|
||||||
if (cur->oid.p == NULL) {
|
|
||||||
mbedtls_free(cur);
|
|
||||||
return (NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(cur->oid.p, oid, oid_len);
|
list = list->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return( list );
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(
|
||||||
|
mbedtls_asn1_named_data **head,
|
||||||
|
const char *oid, size_t oid_len,
|
||||||
|
const unsigned char *val,
|
||||||
|
size_t val_len )
|
||||||
|
{
|
||||||
|
mbedtls_asn1_named_data *cur;
|
||||||
|
|
||||||
|
if( ( cur = asn1_find_named_data( *head, oid, oid_len ) ) == NULL )
|
||||||
|
{
|
||||||
|
// Add new entry if not present yet based on OID
|
||||||
|
//
|
||||||
|
cur = (mbedtls_asn1_named_data*)mbedtls_calloc( 1,
|
||||||
|
sizeof(mbedtls_asn1_named_data) );
|
||||||
|
if( cur == NULL )
|
||||||
|
return( NULL );
|
||||||
|
|
||||||
|
cur->oid.len = oid_len;
|
||||||
|
cur->oid.p = mbedtls_calloc( 1, oid_len );
|
||||||
|
if( cur->oid.p == NULL )
|
||||||
|
{
|
||||||
|
mbedtls_free( cur );
|
||||||
|
return( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy( cur->oid.p, oid, oid_len );
|
||||||
|
|
||||||
cur->val.len = val_len;
|
cur->val.len = val_len;
|
||||||
cur->val.p = mbedtls_calloc(1, val_len);
|
if( val_len != 0 )
|
||||||
if (cur->val.p == NULL) {
|
{
|
||||||
mbedtls_free(cur->oid.p);
|
cur->val.p = mbedtls_calloc( 1, val_len );
|
||||||
mbedtls_free(cur);
|
if( cur->val.p == NULL )
|
||||||
return (NULL);
|
{
|
||||||
|
mbedtls_free( cur->oid.p );
|
||||||
|
mbedtls_free( cur );
|
||||||
|
return( NULL );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cur->next = *head;
|
cur->next = *head;
|
||||||
*head = cur;
|
*head = cur;
|
||||||
} else if (cur->val.len < val_len) {
|
}
|
||||||
|
else if( val_len == 0 )
|
||||||
|
{
|
||||||
|
mbedtls_free( cur->val.p );
|
||||||
|
cur->val.p = NULL;
|
||||||
|
}
|
||||||
|
else if( cur->val.len != val_len )
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* Enlarge existing value buffer if needed
|
* Enlarge existing value buffer if needed
|
||||||
* Preserve old data until the allocation succeeded, to leave list in
|
* Preserve old data until the allocation succeeded, to leave list in
|
||||||
* a consistent state in case allocation fails.
|
* a consistent state in case allocation fails.
|
||||||
*/
|
*/
|
||||||
void *p = mbedtls_calloc(1, val_len);
|
void *p = mbedtls_calloc( 1, val_len );
|
||||||
if (p == NULL)
|
if( p == NULL )
|
||||||
return (NULL);
|
return( NULL );
|
||||||
|
|
||||||
mbedtls_free(cur->val.p);
|
mbedtls_free( cur->val.p );
|
||||||
cur->val.p = p;
|
cur->val.p = p;
|
||||||
cur->val.len = val_len;
|
cur->val.len = val_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val != NULL)
|
if( val != NULL )
|
||||||
memcpy(cur->val.p, val, val_len);
|
memcpy( cur->val.p, val, val_len );
|
||||||
|
|
||||||
return (cur);
|
return( cur );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_ASN1_WRITE_C */
|
#endif /* MBEDTLS_ASN1_WRITE_C */
|
||||||
|
|||||||
@@ -4,215 +4,338 @@
|
|||||||
* \brief ASN.1 buffer writing functionality
|
* \brief ASN.1 buffer writing functionality
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef MBEDTLS_ASN1_WRITE_H
|
#ifndef MBEDTLS_ASN1_WRITE_H
|
||||||
#define MBEDTLS_ASN1_WRITE_H
|
#define MBEDTLS_ASN1_WRITE_H
|
||||||
|
|
||||||
#include "asn1.h"
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MBEDTLS_ASN1_CHK_ADD(g, f) do { if( ( ret = f ) < 0 ) return( ret ); else \
|
#include "mbedtls/asn1.h"
|
||||||
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
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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
|
|
||||||
*
|
*
|
||||||
* \param p reference to current position pointer
|
* \note This function works backwards in data buffer.
|
||||||
* \param start start of the buffer (for bounds-checking)
|
|
||||||
* \param len the length to write
|
|
||||||
*
|
*
|
||||||
* \return the length written or a negative error code
|
* \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.
|
||||||
*/
|
*/
|
||||||
int mbedtls_asn1_write_len(unsigned char **p, unsigned char *start, size_t len);
|
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 );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Write a ASN.1 tag in ASN.1 format
|
* \brief Write raw buffer data.
|
||||||
* Note: function works backwards in data buffer
|
|
||||||
*
|
*
|
||||||
* \param p reference to current position pointer
|
* \note This function works backwards in data buffer.
|
||||||
* \param start start of the buffer (for bounds-checking)
|
|
||||||
* \param tag the tag to write
|
|
||||||
*
|
*
|
||||||
* \return the length written or a negative error code
|
* \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 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,
|
int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
|
||||||
unsigned char tag);
|
const unsigned char *buf, size_t size );
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Write raw buffer data
|
|
||||||
* Note: function works backwards in data buffer
|
|
||||||
*
|
|
||||||
* \param p reference to current position pointer
|
|
||||||
* \param start start of the buffer (for bounds-checking)
|
|
||||||
* \param buf data buffer to write
|
|
||||||
* \param size length of the data buffer
|
|
||||||
*
|
|
||||||
* \return the length written or a negative error code
|
|
||||||
*/
|
|
||||||
int mbedtls_asn1_write_raw_buffer(unsigned char **p, unsigned char *start,
|
|
||||||
const unsigned char *buf, size_t size);
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_BIGNUM_C)
|
#if defined(MBEDTLS_BIGNUM_C)
|
||||||
/**
|
/**
|
||||||
* \brief Write a big number (MBEDTLS_ASN1_INTEGER) in ASN.1 format
|
* \brief Write a arbitrary-precision number (#MBEDTLS_ASN1_INTEGER)
|
||||||
* Note: function works backwards in data buffer
|
* in ASN.1 format.
|
||||||
*
|
*
|
||||||
* \param p reference to current position pointer
|
* \note This function works backwards in data buffer.
|
||||||
* \param start start of the buffer (for bounds-checking)
|
|
||||||
* \param X the MPI to write
|
|
||||||
*
|
*
|
||||||
* \return the length written or a negative error code
|
* \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.
|
||||||
|
* It must be non-negative.
|
||||||
|
*
|
||||||
|
* \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_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 */
|
#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
|
||||||
* Note: function works backwards in data buffer
|
* in ASN.1 format.
|
||||||
*
|
*
|
||||||
* \param p reference to current position pointer
|
* \note This function works backwards in data buffer.
|
||||||
* \param start start of the buffer (for bounds-checking)
|
|
||||||
*
|
*
|
||||||
* \return the length written or a negative error code
|
* \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.
|
||||||
*/
|
*/
|
||||||
int mbedtls_asn1_write_null(unsigned char **p, unsigned char *start);
|
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
|
||||||
* Note: function works backwards in data buffer
|
* in ASN.1 format.
|
||||||
*
|
*
|
||||||
* \param p reference to current position pointer
|
* \note This function works backwards in data buffer.
|
||||||
* \param start start of the buffer (for bounds-checking)
|
|
||||||
* \param oid the OID to write
|
|
||||||
* \param oid_len length of the OID
|
|
||||||
*
|
*
|
||||||
* \return the length written or a negative error code
|
* \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.
|
||||||
*/
|
*/
|
||||||
int mbedtls_asn1_write_oid(unsigned char **p, unsigned char *start,
|
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
|
|
||||||
*
|
*
|
||||||
* \param p reference to current position pointer
|
* \note This function works backwards in data buffer.
|
||||||
* \param start start of the buffer (for bounds-checking)
|
*
|
||||||
* \param oid the OID of the algorithm
|
* \param p The reference to the current position pointer.
|
||||||
* \param oid_len length of the OID
|
* \param start The start of the buffer, for bounds-checking.
|
||||||
* \param par_len length of parameters, which must be already written.
|
* \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.
|
||||||
* If 0, NULL parameters are added
|
* If 0, NULL parameters are added
|
||||||
*
|
*
|
||||||
* \return the length written or a negative error code
|
* \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_algorithm_identifier(unsigned char **p, unsigned char *start,
|
int mbedtls_asn1_write_algorithm_identifier( unsigned char **p,
|
||||||
const char *oid, size_t oid_len,
|
unsigned char *start,
|
||||||
size_t par_len);
|
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
|
||||||
* Note: function works backwards in data buffer
|
* in ASN.1 format.
|
||||||
*
|
*
|
||||||
* \param p reference to current position pointer
|
* \note This function works backwards in data buffer.
|
||||||
* \param start start of the buffer (for bounds-checking)
|
|
||||||
* \param boolean 0 or 1
|
|
||||||
*
|
*
|
||||||
* \return the length written or a negative error code
|
* \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.
|
||||||
*/
|
*/
|
||||||
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
|
||||||
* Note: function works backwards in data buffer
|
* in ASN.1 format.
|
||||||
*
|
*
|
||||||
* \param p reference to current position pointer
|
* \note This function works backwards in data buffer.
|
||||||
* \param start start of the buffer (for bounds-checking)
|
|
||||||
* \param val the integer value
|
|
||||||
*
|
*
|
||||||
* \return the length written or a negative error code
|
* \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.
|
||||||
|
* It must be non-negative.
|
||||||
|
*
|
||||||
|
* \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_int(unsigned char **p, unsigned char *start, int val);
|
int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Write a printable string tag (MBEDTLS_ASN1_PRINTABLE_STRING) and
|
* \brief Write an enum tag (#MBEDTLS_ASN1_ENUMERATED) and value
|
||||||
* value in ASN.1 format
|
* in ASN.1 format.
|
||||||
* Note: function works backwards in data buffer
|
|
||||||
*
|
*
|
||||||
* \param p reference to current position pointer
|
* \note This function works backwards in data buffer.
|
||||||
* \param start start of the buffer (for bounds-checking)
|
|
||||||
* \param text the text to write
|
|
||||||
* \param text_len length of the text
|
|
||||||
*
|
*
|
||||||
* \return the length written or a negative error code
|
* \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.
|
||||||
*/
|
*/
|
||||||
int mbedtls_asn1_write_printable_string(unsigned char **p, unsigned char *start,
|
int mbedtls_asn1_write_enum( unsigned char **p, unsigned char *start, int val );
|
||||||
const char *text, size_t text_len);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Write an IA5 string tag (MBEDTLS_ASN1_IA5_STRING) and
|
* \brief Write a string in ASN.1 format using a specific
|
||||||
* value in ASN.1 format
|
* string encoding tag.
|
||||||
* Note: function works backwards in data buffer
|
|
||||||
|
* \note This function works backwards in data buffer.
|
||||||
*
|
*
|
||||||
* \param p reference to current position pointer
|
* \param p The reference to the current position pointer.
|
||||||
* \param start start of the buffer (for bounds-checking)
|
* \param start The start of the buffer, for bounds-checking.
|
||||||
* \param text the text to write
|
* \param tag The string encoding tag to write, e.g.
|
||||||
* \param text_len length of the text
|
* #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).
|
||||||
*
|
*
|
||||||
* \return the length written or a negative error code
|
* \return The number of bytes written to \p p on success.
|
||||||
|
* \return A negative error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_asn1_write_ia5_string(unsigned char **p, unsigned char *start,
|
int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start,
|
||||||
const char *text, size_t text_len);
|
int tag, const char *text,
|
||||||
|
size_t text_len );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Write a bitstring tag (MBEDTLS_ASN1_BIT_STRING) and
|
* \brief Write a string in ASN.1 format using the PrintableString
|
||||||
* value in ASN.1 format
|
* string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING).
|
||||||
* Note: function works backwards in data buffer
|
|
||||||
*
|
*
|
||||||
* \param p reference to current position pointer
|
* \note This function works backwards in data buffer.
|
||||||
* \param start start of the buffer (for bounds-checking)
|
|
||||||
* \param buf the bitstring
|
|
||||||
* \param bits the total number of bits in the bitstring
|
|
||||||
*
|
*
|
||||||
* \return the length written or a negative error code
|
* \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_bitstring(unsigned char **p, unsigned char *start,
|
int mbedtls_asn1_write_printable_string( unsigned char **p,
|
||||||
const unsigned char *buf, size_t bits);
|
unsigned char *start,
|
||||||
|
const char *text, size_t text_len );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Write an octet string tag (MBEDTLS_ASN1_OCTET_STRING) and
|
* \brief Write a UTF8 string in ASN.1 format using the UTF8String
|
||||||
* value in ASN.1 format
|
* string encoding tag (#MBEDTLS_ASN1_UTF8_STRING).
|
||||||
* Note: function works backwards in data buffer
|
|
||||||
*
|
*
|
||||||
* \param p reference to current position pointer
|
* \note This function works backwards in data buffer.
|
||||||
* \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
|
* \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_octet_string(unsigned char **p, unsigned char *start,
|
int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start,
|
||||||
const unsigned char *buf, size_t size);
|
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.
|
||||||
|
*/
|
||||||
|
int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start,
|
||||||
|
const char *text, size_t text_len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Write a bitstring tag (#MBEDTLS_ASN1_BIT_STRING) and
|
||||||
|
* value 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 buf The bitstring to write.
|
||||||
|
* \param bits The total number of bits in the bitstring.
|
||||||
|
*
|
||||||
|
* \return The number of bytes written to \p p on success.
|
||||||
|
* \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 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function writes a named bitstring tag
|
||||||
|
* (#MBEDTLS_ASN1_BIT_STRING) and value in ASN.1 format.
|
||||||
|
*
|
||||||
|
* As stated in RFC 5280 Appendix B, trailing zeroes are
|
||||||
|
* omitted when encoding named bitstrings in DER.
|
||||||
|
*
|
||||||
|
* \note This function works backwards within the data buffer.
|
||||||
|
*
|
||||||
|
* \param p The reference to the current position pointer.
|
||||||
|
* \param start The start of the buffer which is used for bounds-checking.
|
||||||
|
* \param buf The bitstring to write.
|
||||||
|
* \param bits The total number of bits in the bitstring.
|
||||||
|
*
|
||||||
|
* \return The number of bytes written to \p p on success.
|
||||||
|
* \return A negative error code on failure.
|
||||||
|
*/
|
||||||
|
int mbedtls_asn1_write_named_bitstring( unsigned char **p,
|
||||||
|
unsigned char *start,
|
||||||
|
const unsigned char *buf,
|
||||||
|
size_t bits );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Write an octet string tag (#MBEDTLS_ASN1_OCTET_STRING)
|
||||||
|
* and value 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 buf The buffer holding the data to write.
|
||||||
|
* \param size The length of the data buffer \p buf.
|
||||||
|
*
|
||||||
|
* \return The number of bytes written to \p p on success.
|
||||||
|
* \return A negative error code on failure.
|
||||||
|
*/
|
||||||
|
int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
|
||||||
|
const unsigned char *buf, size_t size );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Create or find a specific named_data entry for writing in a
|
* \brief Create or find a specific named_data entry for writing in a
|
||||||
@@ -220,20 +343,25 @@ int mbedtls_asn1_write_octet_string(unsigned char **p, unsigned char *start,
|
|||||||
* a new entry is added to the head of the list.
|
* a new entry is added to the head of the list.
|
||||||
* Warning: Destructive behaviour for the val data!
|
* Warning: Destructive behaviour for the val data!
|
||||||
*
|
*
|
||||||
* \param list Pointer to the location of the head of the list to seek
|
* \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)
|
* through (will be updated in case of a new entry).
|
||||||
* \param oid The OID to look for
|
* \param oid The OID to look for.
|
||||||
* \param oid_len Size of the OID
|
* \param oid_len The size of the OID.
|
||||||
* \param val Data to store (can be NULL if you want to fill it by hand)
|
* \param val The associated data to store. If this is \c NULL,
|
||||||
* \param val_len Minimum length of the data buffer needed
|
* no data is copied to the new or existing buffer.
|
||||||
|
* \param val_len The minimum length of the data buffer needed.
|
||||||
|
* If this is 0, do not allocate a buffer for the associated
|
||||||
|
* data.
|
||||||
|
* If the OID was already present, enlarge, shrink or free
|
||||||
|
* the existing buffer to fit \p val_len.
|
||||||
*
|
*
|
||||||
* \return NULL if if there was a memory allocation error, or a pointer
|
* \return A pointer to the new / existing entry on success.
|
||||||
* to the new / existing entry.
|
* \return \c NULL if if there was a memory allocation error.
|
||||||
*/
|
*/
|
||||||
mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(mbedtls_asn1_named_data **list,
|
mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **list,
|
||||||
const char *oid, size_t oid_len,
|
const char *oid, size_t oid_len,
|
||||||
const unsigned char *val,
|
const unsigned char *val,
|
||||||
size_t val_len);
|
size_t val_len );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* RFC 1521 base64 encoding/decoding
|
* RFC 1521 base64 encoding/decoding
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#include "common.h"
|
||||||
#include "mbedtls/config.h"
|
|
||||||
#else
|
|
||||||
#include MBEDTLS_CONFIG_FILE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_BASE64_C)
|
#if defined(MBEDTLS_BASE64_C)
|
||||||
|
|
||||||
@@ -43,7 +35,8 @@
|
|||||||
#endif /* MBEDTLS_PLATFORM_C */
|
#endif /* MBEDTLS_PLATFORM_C */
|
||||||
#endif /* MBEDTLS_SELF_TEST */
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
static const unsigned char base64_enc_map[64] = {
|
static const unsigned char base64_enc_map[64] =
|
||||||
|
{
|
||||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
||||||
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
|
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
|
||||||
'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
|
'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
|
||||||
@@ -53,74 +46,185 @@ static const unsigned char base64_enc_map[64] = {
|
|||||||
'8', '9', '+', '/'
|
'8', '9', '+', '/'
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned char base64_dec_map[128] = {
|
static const unsigned char base64_dec_map[128] =
|
||||||
|
{
|
||||||
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
|
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
|
||||||
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
|
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
|
||||||
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
|
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
|
||||||
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
|
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
|
||||||
127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
|
127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
|
||||||
54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
|
54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
|
||||||
127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
|
127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
|
||||||
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||||
25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
|
25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
|
||||||
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
|
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
|
||||||
39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
|
39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
|
||||||
49, 50, 51, 127, 127, 127, 127, 127
|
49, 50, 51, 127, 127, 127, 127, 127
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
|
#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constant flow conditional assignment to unsigned char
|
||||||
|
*/
|
||||||
|
static void mbedtls_base64_cond_assign_uchar( unsigned char * dest, const unsigned char * const src,
|
||||||
|
unsigned char condition )
|
||||||
|
{
|
||||||
|
/* MSVC has a warning about unary minus on unsigned integer types,
|
||||||
|
* but this is well-defined and precisely what we want to do here. */
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning( push )
|
||||||
|
#pragma warning( disable : 4146 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Generate bitmask from condition, mask will either be 0xFF or 0 */
|
||||||
|
unsigned char mask = ( condition | -condition );
|
||||||
|
mask >>= 7;
|
||||||
|
mask = -mask;
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning( pop )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*dest = ( ( *src ) & mask ) | ( ( *dest ) & ~mask );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constant flow conditional assignment to uint_32
|
||||||
|
*/
|
||||||
|
static void mbedtls_base64_cond_assign_uint32( uint32_t * dest, const uint32_t src,
|
||||||
|
uint32_t condition )
|
||||||
|
{
|
||||||
|
/* MSVC has a warning about unary minus on unsigned integer types,
|
||||||
|
* but this is well-defined and precisely what we want to do here. */
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning( push )
|
||||||
|
#pragma warning( disable : 4146 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Generate bitmask from condition, mask will either be 0xFFFFFFFF or 0 */
|
||||||
|
uint32_t mask = ( condition | -condition );
|
||||||
|
mask >>= 31;
|
||||||
|
mask = -mask;
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning( pop )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*dest = ( src & mask ) | ( ( *dest ) & ~mask );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constant flow check for equality
|
||||||
|
*/
|
||||||
|
static unsigned char mbedtls_base64_eq( size_t in_a, size_t in_b )
|
||||||
|
{
|
||||||
|
size_t difference = in_a ^ in_b;
|
||||||
|
|
||||||
|
/* MSVC has a warning about unary minus on unsigned integer types,
|
||||||
|
* but this is well-defined and precisely what we want to do here. */
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning( push )
|
||||||
|
#pragma warning( disable : 4146 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
difference |= -difference;
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning( pop )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* cope with the varying size of size_t per platform */
|
||||||
|
difference >>= ( sizeof( difference ) * 8 - 1 );
|
||||||
|
|
||||||
|
return (unsigned char) ( 1 ^ difference );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constant flow lookup into table.
|
||||||
|
*/
|
||||||
|
static unsigned char mbedtls_base64_table_lookup( const unsigned char * const table,
|
||||||
|
const size_t table_size, const size_t table_index )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
unsigned char result = 0;
|
||||||
|
|
||||||
|
for( i = 0; i < table_size; ++i )
|
||||||
|
{
|
||||||
|
mbedtls_base64_cond_assign_uchar( &result, &table[i], mbedtls_base64_eq( i, table_index ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Encode a buffer into base64 format
|
* Encode a buffer into base64 format
|
||||||
*/
|
*/
|
||||||
int mbedtls_base64_encode(unsigned char *dst, size_t dlen, size_t *olen,
|
int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
|
||||||
const unsigned char *src, size_t slen) {
|
const unsigned char *src, size_t slen )
|
||||||
|
{
|
||||||
size_t i, n;
|
size_t i, n;
|
||||||
int C1, C2, C3;
|
int C1, C2, C3;
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
|
|
||||||
if (slen == 0) {
|
if( slen == 0 )
|
||||||
|
{
|
||||||
*olen = 0;
|
*olen = 0;
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
n = slen / 3 + (slen % 3 != 0);
|
n = slen / 3 + ( slen % 3 != 0 );
|
||||||
|
|
||||||
if (n > (BASE64_SIZE_T_MAX - 1) / 4) {
|
if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 )
|
||||||
|
{
|
||||||
*olen = BASE64_SIZE_T_MAX;
|
*olen = BASE64_SIZE_T_MAX;
|
||||||
return (MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL);
|
return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
|
||||||
}
|
}
|
||||||
|
|
||||||
n *= 4;
|
n *= 4;
|
||||||
|
|
||||||
if ((dlen < n + 1) || (NULL == dst)) {
|
if( ( dlen < n + 1 ) || ( NULL == dst ) )
|
||||||
|
{
|
||||||
*olen = n + 1;
|
*olen = n + 1;
|
||||||
return (MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL);
|
return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
|
||||||
}
|
}
|
||||||
|
|
||||||
n = (slen / 3) * 3;
|
n = ( slen / 3 ) * 3;
|
||||||
|
|
||||||
for (i = 0, p = dst; i < n; i += 3) {
|
for( i = 0, p = dst; i < n; i += 3 )
|
||||||
|
{
|
||||||
C1 = *src++;
|
C1 = *src++;
|
||||||
C2 = *src++;
|
C2 = *src++;
|
||||||
C3 = *src++;
|
C3 = *src++;
|
||||||
|
|
||||||
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
|
*p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
|
||||||
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
|
( ( C1 >> 2 ) & 0x3F ) );
|
||||||
*p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
|
|
||||||
*p++ = base64_enc_map[C3 & 0x3F];
|
*p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
|
||||||
|
( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) );
|
||||||
|
|
||||||
|
*p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
|
||||||
|
( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) ) & 0x3F ) );
|
||||||
|
|
||||||
|
*p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
|
||||||
|
( C3 & 0x3F ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < slen) {
|
if( i < slen )
|
||||||
|
{
|
||||||
C1 = *src++;
|
C1 = *src++;
|
||||||
C2 = ((i + 1) < slen) ? *src++ : 0;
|
C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
|
||||||
|
|
||||||
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
|
*p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
|
||||||
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
|
( ( C1 >> 2 ) & 0x3F ) );
|
||||||
|
|
||||||
if ((i + 1) < slen)
|
*p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
|
||||||
*p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
|
( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) );
|
||||||
|
|
||||||
|
if( ( i + 1 ) < slen )
|
||||||
|
*p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
|
||||||
|
( ( ( C2 & 15 ) << 2 ) & 0x3F ) );
|
||||||
else *p++ = '=';
|
else *p++ = '=';
|
||||||
|
|
||||||
*p++ = '=';
|
*p++ = '=';
|
||||||
@@ -129,94 +233,107 @@ int mbedtls_base64_encode(unsigned char *dst, size_t dlen, size_t *olen,
|
|||||||
*olen = p - dst;
|
*olen = p - dst;
|
||||||
*p = 0;
|
*p = 0;
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decode a base64-formatted buffer
|
* Decode a base64-formatted buffer
|
||||||
*/
|
*/
|
||||||
int mbedtls_base64_decode(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) {
|
const unsigned char *src, size_t slen )
|
||||||
|
{
|
||||||
size_t i, n;
|
size_t i, n;
|
||||||
uint32_t j, x;
|
uint32_t j, x;
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
|
unsigned char dec_map_lookup;
|
||||||
|
|
||||||
/* First pass: check for validity and get output length */
|
/* First pass: check for validity and get output length */
|
||||||
for (i = n = j = 0; i < slen; i++) {
|
for( i = n = j = 0; i < slen; i++ )
|
||||||
|
{
|
||||||
/* Skip spaces before checking for EOL */
|
/* Skip spaces before checking for EOL */
|
||||||
x = 0;
|
x = 0;
|
||||||
while (i < slen && src[i] == ' ') {
|
while( i < slen && src[i] == ' ' )
|
||||||
|
{
|
||||||
++i;
|
++i;
|
||||||
++x;
|
++x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Spaces at end of buffer are OK */
|
/* Spaces at end of buffer are OK */
|
||||||
if (i == slen)
|
if( i == slen )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ((slen - i) >= 2 &&
|
if( ( slen - i ) >= 2 &&
|
||||||
src[i] == '\r' && src[i + 1] == '\n')
|
src[i] == '\r' && src[i + 1] == '\n' )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (src[i] == '\n')
|
if( src[i] == '\n' )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Space inside a line is an error */
|
/* Space inside a line is an error */
|
||||||
if (x != 0)
|
if( x != 0 )
|
||||||
return (MBEDTLS_ERR_BASE64_INVALID_CHARACTER);
|
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
|
||||||
|
|
||||||
if (src[i] == '=' && ++j > 2)
|
if( src[i] == '=' && ++j > 2 )
|
||||||
return (MBEDTLS_ERR_BASE64_INVALID_CHARACTER);
|
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
|
||||||
|
|
||||||
if (src[i] > 127 || base64_dec_map[src[i]] == 127)
|
dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), src[i] );
|
||||||
return (MBEDTLS_ERR_BASE64_INVALID_CHARACTER);
|
|
||||||
|
|
||||||
if (base64_dec_map[src[i]] < 64 && j != 0)
|
if( src[i] > 127 || dec_map_lookup == 127 )
|
||||||
return (MBEDTLS_ERR_BASE64_INVALID_CHARACTER);
|
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
|
||||||
|
|
||||||
|
if( dec_map_lookup < 64 && j != 0 )
|
||||||
|
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
|
||||||
|
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n == 0) {
|
if( n == 0 )
|
||||||
|
{
|
||||||
*olen = 0;
|
*olen = 0;
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The following expression is to calculate the following formula without
|
/* The following expression is to calculate the following formula without
|
||||||
* risk of integer overflow in n:
|
* risk of integer overflow in n:
|
||||||
* n = ( ( n * 6 ) + 7 ) >> 3;
|
* n = ( ( n * 6 ) + 7 ) >> 3;
|
||||||
*/
|
*/
|
||||||
n = (6 * (n >> 3)) + ((6 * (n & 0x7) + 7) >> 3);
|
n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 );
|
||||||
n -= j;
|
n -= j;
|
||||||
|
|
||||||
if (dst == NULL || dlen < n) {
|
if( dst == NULL || dlen < n )
|
||||||
|
{
|
||||||
*olen = n;
|
*olen = n;
|
||||||
return (MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL);
|
return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 3, n = x = 0, p = dst; i > 0; i--, src++) {
|
for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
|
||||||
if (*src == '\r' || *src == '\n' || *src == ' ')
|
{
|
||||||
|
if( *src == '\r' || *src == '\n' || *src == ' ' )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
j -= (base64_dec_map[*src] == 64);
|
dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), *src );
|
||||||
x = (x << 6) | (base64_dec_map[*src] & 0x3F);
|
|
||||||
|
|
||||||
if (++n == 4) {
|
mbedtls_base64_cond_assign_uint32( &j, j - 1, mbedtls_base64_eq( dec_map_lookup, 64 ) );
|
||||||
|
x = ( x << 6 ) | ( dec_map_lookup & 0x3F );
|
||||||
|
|
||||||
|
if( ++n == 4 )
|
||||||
|
{
|
||||||
n = 0;
|
n = 0;
|
||||||
if (j > 0) *p++ = (unsigned char)(x >> 16);
|
if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
|
||||||
if (j > 1) *p++ = (unsigned char)(x >> 8);
|
if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
|
||||||
if (j > 2) *p++ = (unsigned char)(x);
|
if( j > 2 ) *p++ = (unsigned char)( x );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*olen = p - dst;
|
*olen = p - dst;
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MBEDTLS_SELF_TEST)
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
|
||||||
static const unsigned char base64_test_dec[64] = {
|
static const unsigned char base64_test_dec[64] =
|
||||||
|
{
|
||||||
0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
|
0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
|
||||||
0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
|
0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
|
||||||
0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
|
0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
|
||||||
@@ -234,41 +351,44 @@ static const unsigned char base64_test_enc[] =
|
|||||||
/*
|
/*
|
||||||
* Checkup routine
|
* Checkup routine
|
||||||
*/
|
*/
|
||||||
int mbedtls_base64_self_test(int verbose) {
|
int mbedtls_base64_self_test( int verbose )
|
||||||
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
const unsigned char *src;
|
const unsigned char *src;
|
||||||
unsigned char buffer[128];
|
unsigned char buffer[128];
|
||||||
|
|
||||||
if (verbose != 0)
|
if( verbose != 0 )
|
||||||
mbedtls_printf(" Base64 encoding test: ");
|
mbedtls_printf( " Base64 encoding test: " );
|
||||||
|
|
||||||
src = base64_test_dec;
|
src = base64_test_dec;
|
||||||
|
|
||||||
if (mbedtls_base64_encode(buffer, sizeof(buffer), &len, src, 64) != 0 ||
|
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");
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( "failed\n" );
|
||||||
|
|
||||||
return (1);
|
return( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose != 0)
|
if( verbose != 0 )
|
||||||
mbedtls_printf("passed\n Base64 decoding test: ");
|
mbedtls_printf( "passed\n Base64 decoding test: " );
|
||||||
|
|
||||||
src = base64_test_enc;
|
src = base64_test_enc;
|
||||||
|
|
||||||
if (mbedtls_base64_decode(buffer, sizeof(buffer), &len, src, 88) != 0 ||
|
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");
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( "failed\n" );
|
||||||
|
|
||||||
return (1);
|
return( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose != 0)
|
if( verbose != 0 )
|
||||||
mbedtls_printf("passed\n\n");
|
mbedtls_printf( "passed\n\n" );
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MBEDTLS_SELF_TEST */
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|||||||
@@ -4,28 +4,30 @@
|
|||||||
* \brief RFC 1521 base64 encoding/decoding
|
* \brief RFC 1521 base64 encoding/decoding
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef MBEDTLS_BASE64_H
|
#ifndef MBEDTLS_BASE64_H
|
||||||
#define MBEDTLS_BASE64_H
|
#define MBEDTLS_BASE64_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */
|
#define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */
|
||||||
@@ -54,8 +56,8 @@ extern "C" {
|
|||||||
* \note Call this function with dlen = 0 to obtain the
|
* \note Call this function with dlen = 0 to obtain the
|
||||||
* required buffer size in *olen
|
* required buffer size in *olen
|
||||||
*/
|
*/
|
||||||
int mbedtls_base64_encode(unsigned char *dst, size_t dlen, size_t *olen,
|
int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
|
||||||
const unsigned char *src, size_t slen);
|
const unsigned char *src, size_t slen );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Decode a base64-formatted buffer
|
* \brief Decode a base64-formatted buffer
|
||||||
@@ -74,15 +76,18 @@ int mbedtls_base64_encode(unsigned char *dst, size_t dlen, size_t *olen,
|
|||||||
* \note Call this function with *dst = NULL or dlen = 0 to obtain
|
* \note Call this function with *dst = NULL or dlen = 0 to obtain
|
||||||
* the required buffer size in *olen
|
* the required buffer size in *olen
|
||||||
*/
|
*/
|
||||||
int mbedtls_base64_decode(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);
|
const unsigned char *src, size_t slen );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
/**
|
/**
|
||||||
* \brief Checkup routine
|
* \brief Checkup routine
|
||||||
*
|
*
|
||||||
* \return 0 if successful, or 1 if the test failed
|
* \return 0 if successful, or 1 if the test failed
|
||||||
*/
|
*/
|
||||||
int mbedtls_base64_self_test(int verbose);
|
int mbedtls_base64_self_test( int verbose );
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,24 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
* Blowfish implementation
|
* Blowfish implementation
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* The Blowfish block cipher was designed by Bruce Schneier in 1993.
|
* The Blowfish block cipher was designed by Bruce Schneier in 1993.
|
||||||
@@ -27,11 +23,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#include "common.h"
|
||||||
#include "mbedtls/config.h"
|
|
||||||
#else
|
|
||||||
#include MBEDTLS_CONFIG_FILE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_BLOWFISH_C)
|
#if defined(MBEDTLS_BLOWFISH_C)
|
||||||
|
|
||||||
@@ -42,68 +34,77 @@
|
|||||||
|
|
||||||
#if !defined(MBEDTLS_BLOWFISH_ALT)
|
#if !defined(MBEDTLS_BLOWFISH_ALT)
|
||||||
|
|
||||||
|
/* Parameter validation macros */
|
||||||
|
#define BLOWFISH_VALIDATE_RET( cond ) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA )
|
||||||
|
#define BLOWFISH_VALIDATE( cond ) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 32-bit integer manipulation macros (big endian)
|
* 32-bit integer manipulation macros (big endian)
|
||||||
*/
|
*/
|
||||||
#ifndef GET_UINT32_BE
|
#ifndef GET_UINT32_BE
|
||||||
#define GET_UINT32_BE(n,b,i) \
|
#define GET_UINT32_BE(n,b,i) \
|
||||||
{ \
|
{ \
|
||||||
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
|
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
|
||||||
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
|
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
|
||||||
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
|
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
|
||||||
| ( (uint32_t) (b)[(i) + 3] ); \
|
| ( (uint32_t) (b)[(i) + 3] ); \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PUT_UINT32_BE
|
#ifndef PUT_UINT32_BE
|
||||||
#define PUT_UINT32_BE(n,b,i) \
|
#define PUT_UINT32_BE(n,b,i) \
|
||||||
{ \
|
{ \
|
||||||
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||||
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2] = {
|
static const uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2] = {
|
||||||
0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
|
0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
|
||||||
0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
|
0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
|
||||||
0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL,
|
0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL,
|
||||||
0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L,
|
0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L,
|
||||||
0x9216D5D9L, 0x8979FB1BL
|
0x9216D5D9L, 0x8979FB1BL
|
||||||
};
|
};
|
||||||
|
|
||||||
/* declarations of data at the end of this file */
|
/* declarations of data at the end of this file */
|
||||||
static const uint32_t S[4][256];
|
static const uint32_t S[4][256];
|
||||||
|
|
||||||
static uint32_t F(mbedtls_blowfish_context *ctx, uint32_t x) {
|
static uint32_t F( mbedtls_blowfish_context *ctx, uint32_t x )
|
||||||
unsigned short a, b, c, d;
|
{
|
||||||
uint32_t y;
|
unsigned short a, b, c, d;
|
||||||
|
uint32_t y;
|
||||||
|
|
||||||
d = (unsigned short)(x & 0xFF);
|
d = (unsigned short)(x & 0xFF);
|
||||||
x >>= 8;
|
x >>= 8;
|
||||||
c = (unsigned short)(x & 0xFF);
|
c = (unsigned short)(x & 0xFF);
|
||||||
x >>= 8;
|
x >>= 8;
|
||||||
b = (unsigned short)(x & 0xFF);
|
b = (unsigned short)(x & 0xFF);
|
||||||
x >>= 8;
|
x >>= 8;
|
||||||
a = (unsigned short)(x & 0xFF);
|
a = (unsigned short)(x & 0xFF);
|
||||||
y = ctx->S[0][a] + ctx->S[1][b];
|
y = ctx->S[0][a] + ctx->S[1][b];
|
||||||
y = y ^ ctx->S[2][c];
|
y = y ^ ctx->S[2][c];
|
||||||
y = y + ctx->S[3][d];
|
y = y + ctx->S[3][d];
|
||||||
|
|
||||||
return (y);
|
return( y );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void blowfish_enc(mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr) {
|
static void blowfish_enc( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr )
|
||||||
|
{
|
||||||
uint32_t Xl, Xr, temp;
|
uint32_t Xl, Xr, temp;
|
||||||
short i;
|
short i;
|
||||||
|
|
||||||
Xl = *xl;
|
Xl = *xl;
|
||||||
Xr = *xr;
|
Xr = *xr;
|
||||||
|
|
||||||
for (i = 0; i < MBEDTLS_BLOWFISH_ROUNDS; ++i) {
|
for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS; ++i )
|
||||||
|
{
|
||||||
Xl = Xl ^ ctx->P[i];
|
Xl = Xl ^ ctx->P[i];
|
||||||
Xr = F(ctx, Xl) ^ Xr;
|
Xr = F( ctx, Xl ) ^ Xr;
|
||||||
|
|
||||||
temp = Xl;
|
temp = Xl;
|
||||||
Xl = Xr;
|
Xl = Xr;
|
||||||
@@ -121,16 +122,18 @@ static void blowfish_enc(mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *
|
|||||||
*xr = Xr;
|
*xr = Xr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void blowfish_dec(mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr) {
|
static void blowfish_dec( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr )
|
||||||
|
{
|
||||||
uint32_t Xl, Xr, temp;
|
uint32_t Xl, Xr, temp;
|
||||||
short i;
|
short i;
|
||||||
|
|
||||||
Xl = *xl;
|
Xl = *xl;
|
||||||
Xr = *xr;
|
Xr = *xr;
|
||||||
|
|
||||||
for (i = MBEDTLS_BLOWFISH_ROUNDS + 1; i > 1; --i) {
|
for( i = MBEDTLS_BLOWFISH_ROUNDS + 1; i > 1; --i )
|
||||||
|
{
|
||||||
Xl = Xl ^ ctx->P[i];
|
Xl = Xl ^ ctx->P[i];
|
||||||
Xr = F(ctx, Xl) ^ Xr;
|
Xr = F( ctx, Xl ) ^ Xr;
|
||||||
|
|
||||||
temp = Xl;
|
temp = Xl;
|
||||||
Xl = Xr;
|
Xl = Xr;
|
||||||
@@ -148,43 +151,55 @@ static void blowfish_dec(mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *
|
|||||||
*xr = Xr;
|
*xr = Xr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mbedtls_blowfish_init(mbedtls_blowfish_context *ctx) {
|
void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx )
|
||||||
memset(ctx, 0, sizeof(mbedtls_blowfish_context));
|
{
|
||||||
|
BLOWFISH_VALIDATE( ctx != NULL );
|
||||||
|
memset( ctx, 0, sizeof( mbedtls_blowfish_context ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void mbedtls_blowfish_free(mbedtls_blowfish_context *ctx) {
|
void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx )
|
||||||
if (ctx == NULL)
|
{
|
||||||
|
if( ctx == NULL )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_blowfish_context));
|
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_blowfish_context ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Blowfish key schedule
|
* Blowfish key schedule
|
||||||
*/
|
*/
|
||||||
int mbedtls_blowfish_setkey(mbedtls_blowfish_context *ctx, const unsigned char *key,
|
int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx,
|
||||||
unsigned int keybits) {
|
const unsigned char *key,
|
||||||
|
unsigned int keybits )
|
||||||
|
{
|
||||||
unsigned int i, j, k;
|
unsigned int i, j, k;
|
||||||
uint32_t data, datal, datar;
|
uint32_t data, datal, datar;
|
||||||
|
BLOWFISH_VALIDATE_RET( ctx != NULL );
|
||||||
|
BLOWFISH_VALIDATE_RET( key != NULL );
|
||||||
|
|
||||||
if (keybits < MBEDTLS_BLOWFISH_MIN_KEY_BITS || keybits > MBEDTLS_BLOWFISH_MAX_KEY_BITS ||
|
if( keybits < MBEDTLS_BLOWFISH_MIN_KEY_BITS ||
|
||||||
(keybits % 8)) {
|
keybits > MBEDTLS_BLOWFISH_MAX_KEY_BITS ||
|
||||||
return (MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH);
|
keybits % 8 != 0 )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA );
|
||||||
}
|
}
|
||||||
|
|
||||||
keybits >>= 3;
|
keybits >>= 3;
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for( i = 0; i < 4; i++ )
|
||||||
for (j = 0; j < 256; j++)
|
{
|
||||||
|
for( j = 0; j < 256; j++ )
|
||||||
ctx->S[i][j] = S[i][j];
|
ctx->S[i][j] = S[i][j];
|
||||||
}
|
}
|
||||||
|
|
||||||
j = 0;
|
j = 0;
|
||||||
for (i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; ++i) {
|
for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; ++i )
|
||||||
|
{
|
||||||
data = 0x00000000;
|
data = 0x00000000;
|
||||||
for (k = 0; k < 4; ++k) {
|
for( k = 0; k < 4; ++k )
|
||||||
data = (data << 8) | key[j++];
|
{
|
||||||
if (j >= keybits)
|
data = ( data << 8 ) | key[j++];
|
||||||
|
if( j >= keybits )
|
||||||
j = 0;
|
j = 0;
|
||||||
}
|
}
|
||||||
ctx->P[i] = P[i] ^ data;
|
ctx->P[i] = P[i] ^ data;
|
||||||
@@ -193,83 +208,107 @@ int mbedtls_blowfish_setkey(mbedtls_blowfish_context *ctx, const unsigned char *
|
|||||||
datal = 0x00000000;
|
datal = 0x00000000;
|
||||||
datar = 0x00000000;
|
datar = 0x00000000;
|
||||||
|
|
||||||
for (i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; i += 2) {
|
for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; i += 2 )
|
||||||
blowfish_enc(ctx, &datal, &datar);
|
{
|
||||||
|
blowfish_enc( ctx, &datal, &datar );
|
||||||
ctx->P[i] = datal;
|
ctx->P[i] = datal;
|
||||||
ctx->P[i + 1] = datar;
|
ctx->P[i + 1] = datar;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for( i = 0; i < 4; i++ )
|
||||||
for (j = 0; j < 256; j += 2) {
|
{
|
||||||
blowfish_enc(ctx, &datal, &datar);
|
for( j = 0; j < 256; j += 2 )
|
||||||
|
{
|
||||||
|
blowfish_enc( ctx, &datal, &datar );
|
||||||
ctx->S[i][j] = datal;
|
ctx->S[i][j] = datal;
|
||||||
ctx->S[i][j + 1] = datar;
|
ctx->S[i][j + 1] = datar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Blowfish-ECB block encryption/decryption
|
* Blowfish-ECB block encryption/decryption
|
||||||
*/
|
*/
|
||||||
int mbedtls_blowfish_crypt_ecb(mbedtls_blowfish_context *ctx,
|
int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
|
||||||
int mode,
|
int mode,
|
||||||
const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
||||||
unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE]) {
|
unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] )
|
||||||
|
{
|
||||||
uint32_t X0, X1;
|
uint32_t X0, X1;
|
||||||
|
BLOWFISH_VALIDATE_RET( ctx != NULL );
|
||||||
|
BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT ||
|
||||||
|
mode == MBEDTLS_BLOWFISH_DECRYPT );
|
||||||
|
BLOWFISH_VALIDATE_RET( input != NULL );
|
||||||
|
BLOWFISH_VALIDATE_RET( output != NULL );
|
||||||
|
|
||||||
GET_UINT32_BE(X0, input, 0);
|
GET_UINT32_BE( X0, input, 0 );
|
||||||
GET_UINT32_BE(X1, input, 4);
|
GET_UINT32_BE( X1, input, 4 );
|
||||||
|
|
||||||
if (mode == MBEDTLS_BLOWFISH_DECRYPT) {
|
if( mode == MBEDTLS_BLOWFISH_DECRYPT )
|
||||||
blowfish_dec(ctx, &X0, &X1);
|
{
|
||||||
} else { /* MBEDTLS_BLOWFISH_ENCRYPT */
|
blowfish_dec( ctx, &X0, &X1 );
|
||||||
blowfish_enc(ctx, &X0, &X1);
|
}
|
||||||
|
else /* MBEDTLS_BLOWFISH_ENCRYPT */
|
||||||
|
{
|
||||||
|
blowfish_enc( ctx, &X0, &X1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
PUT_UINT32_BE(X0, output, 0);
|
PUT_UINT32_BE( X0, output, 0 );
|
||||||
PUT_UINT32_BE(X1, output, 4);
|
PUT_UINT32_BE( X1, output, 4 );
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||||
/*
|
/*
|
||||||
* Blowfish-CBC buffer encryption/decryption
|
* Blowfish-CBC buffer encryption/decryption
|
||||||
*/
|
*/
|
||||||
int mbedtls_blowfish_crypt_cbc(mbedtls_blowfish_context *ctx,
|
int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx,
|
||||||
int mode,
|
int mode,
|
||||||
size_t length,
|
size_t length,
|
||||||
unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output) {
|
unsigned char *output )
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned char temp[MBEDTLS_BLOWFISH_BLOCKSIZE];
|
unsigned char temp[MBEDTLS_BLOWFISH_BLOCKSIZE];
|
||||||
|
BLOWFISH_VALIDATE_RET( ctx != NULL );
|
||||||
|
BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT ||
|
||||||
|
mode == MBEDTLS_BLOWFISH_DECRYPT );
|
||||||
|
BLOWFISH_VALIDATE_RET( iv != NULL );
|
||||||
|
BLOWFISH_VALIDATE_RET( length == 0 || input != NULL );
|
||||||
|
BLOWFISH_VALIDATE_RET( length == 0 || output != NULL );
|
||||||
|
|
||||||
if (length % MBEDTLS_BLOWFISH_BLOCKSIZE)
|
if( length % MBEDTLS_BLOWFISH_BLOCKSIZE )
|
||||||
return (MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH);
|
return( MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH );
|
||||||
|
|
||||||
if (mode == MBEDTLS_BLOWFISH_DECRYPT) {
|
if( mode == MBEDTLS_BLOWFISH_DECRYPT )
|
||||||
while (length > 0) {
|
{
|
||||||
memcpy(temp, input, MBEDTLS_BLOWFISH_BLOCKSIZE);
|
while( length > 0 )
|
||||||
mbedtls_blowfish_crypt_ecb(ctx, mode, input, output);
|
{
|
||||||
|
memcpy( temp, input, MBEDTLS_BLOWFISH_BLOCKSIZE );
|
||||||
|
mbedtls_blowfish_crypt_ecb( ctx, mode, input, output );
|
||||||
|
|
||||||
for (i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE; i++)
|
for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE;i++ )
|
||||||
output[i] = (unsigned char)(output[i] ^ iv[i]);
|
output[i] = (unsigned char)( output[i] ^ iv[i] );
|
||||||
|
|
||||||
memcpy(iv, temp, MBEDTLS_BLOWFISH_BLOCKSIZE);
|
memcpy( iv, temp, MBEDTLS_BLOWFISH_BLOCKSIZE );
|
||||||
|
|
||||||
input += MBEDTLS_BLOWFISH_BLOCKSIZE;
|
input += MBEDTLS_BLOWFISH_BLOCKSIZE;
|
||||||
output += MBEDTLS_BLOWFISH_BLOCKSIZE;
|
output += MBEDTLS_BLOWFISH_BLOCKSIZE;
|
||||||
length -= MBEDTLS_BLOWFISH_BLOCKSIZE;
|
length -= MBEDTLS_BLOWFISH_BLOCKSIZE;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
while (length > 0) {
|
else
|
||||||
for (i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE; i++)
|
{
|
||||||
output[i] = (unsigned char)(input[i] ^ iv[i]);
|
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);
|
mbedtls_blowfish_crypt_ecb( ctx, mode, output, output );
|
||||||
memcpy(iv, output, MBEDTLS_BLOWFISH_BLOCKSIZE);
|
memcpy( iv, output, MBEDTLS_BLOWFISH_BLOCKSIZE );
|
||||||
|
|
||||||
input += MBEDTLS_BLOWFISH_BLOCKSIZE;
|
input += MBEDTLS_BLOWFISH_BLOCKSIZE;
|
||||||
output += MBEDTLS_BLOWFISH_BLOCKSIZE;
|
output += MBEDTLS_BLOWFISH_BLOCKSIZE;
|
||||||
@@ -277,7 +316,7 @@ int mbedtls_blowfish_crypt_cbc(mbedtls_blowfish_context *ctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||||
|
|
||||||
@@ -285,41 +324,59 @@ int mbedtls_blowfish_crypt_cbc(mbedtls_blowfish_context *ctx,
|
|||||||
/*
|
/*
|
||||||
* Blowfish CFB buffer encryption/decryption
|
* Blowfish CFB buffer encryption/decryption
|
||||||
*/
|
*/
|
||||||
int mbedtls_blowfish_crypt_cfb64(mbedtls_blowfish_context *ctx,
|
int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx,
|
||||||
int mode,
|
int mode,
|
||||||
size_t length,
|
size_t length,
|
||||||
size_t *iv_off,
|
size_t *iv_off,
|
||||||
unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output) {
|
unsigned char *output )
|
||||||
|
{
|
||||||
int c;
|
int c;
|
||||||
size_t n = *iv_off;
|
size_t n;
|
||||||
|
|
||||||
if (mode == MBEDTLS_BLOWFISH_DECRYPT) {
|
BLOWFISH_VALIDATE_RET( ctx != NULL );
|
||||||
while (length--) {
|
BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT ||
|
||||||
if (n == 0)
|
mode == MBEDTLS_BLOWFISH_DECRYPT );
|
||||||
mbedtls_blowfish_crypt_ecb(ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv);
|
BLOWFISH_VALIDATE_RET( iv != NULL );
|
||||||
|
BLOWFISH_VALIDATE_RET( iv_off != NULL );
|
||||||
|
BLOWFISH_VALIDATE_RET( length == 0 || input != NULL );
|
||||||
|
BLOWFISH_VALIDATE_RET( length == 0 || output != NULL );
|
||||||
|
|
||||||
|
n = *iv_off;
|
||||||
|
if( n >= 8 )
|
||||||
|
return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
if( mode == MBEDTLS_BLOWFISH_DECRYPT )
|
||||||
|
{
|
||||||
|
while( length-- )
|
||||||
|
{
|
||||||
|
if( n == 0 )
|
||||||
|
mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv );
|
||||||
|
|
||||||
c = *input++;
|
c = *input++;
|
||||||
*output++ = (unsigned char)(c ^ iv[n]);
|
*output++ = (unsigned char)( c ^ iv[n] );
|
||||||
iv[n] = (unsigned char) c;
|
iv[n] = (unsigned char) c;
|
||||||
|
|
||||||
n = (n + 1) % MBEDTLS_BLOWFISH_BLOCKSIZE;
|
n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
while (length--) {
|
else
|
||||||
if (n == 0)
|
{
|
||||||
mbedtls_blowfish_crypt_ecb(ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv);
|
while( length-- )
|
||||||
|
{
|
||||||
|
if( n == 0 )
|
||||||
|
mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv );
|
||||||
|
|
||||||
iv[n] = *output++ = (unsigned char)(iv[n] ^ *input++);
|
iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
|
||||||
|
|
||||||
n = (n + 1) % MBEDTLS_BLOWFISH_BLOCKSIZE;
|
n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*iv_off = n;
|
*iv_off = n;
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
#endif /*MBEDTLS_CIPHER_MODE_CFB */
|
#endif /*MBEDTLS_CIPHER_MODE_CFB */
|
||||||
|
|
||||||
@@ -327,40 +384,51 @@ int mbedtls_blowfish_crypt_cfb64(mbedtls_blowfish_context *ctx,
|
|||||||
/*
|
/*
|
||||||
* Blowfish CTR buffer encryption/decryption
|
* Blowfish CTR buffer encryption/decryption
|
||||||
*/
|
*/
|
||||||
int mbedtls_blowfish_crypt_ctr(mbedtls_blowfish_context *ctx,
|
int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx,
|
||||||
size_t length,
|
size_t length,
|
||||||
size_t *nc_off,
|
size_t *nc_off,
|
||||||
unsigned char nonce_counter[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
unsigned char nonce_counter[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
||||||
unsigned char stream_block[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
unsigned char stream_block[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output) {
|
unsigned char *output )
|
||||||
|
{
|
||||||
int c, i;
|
int c, i;
|
||||||
size_t n = *nc_off;
|
size_t n;
|
||||||
|
BLOWFISH_VALIDATE_RET( ctx != NULL );
|
||||||
|
BLOWFISH_VALIDATE_RET( nonce_counter != NULL );
|
||||||
|
BLOWFISH_VALIDATE_RET( stream_block != NULL );
|
||||||
|
BLOWFISH_VALIDATE_RET( nc_off != NULL );
|
||||||
|
BLOWFISH_VALIDATE_RET( length == 0 || input != NULL );
|
||||||
|
BLOWFISH_VALIDATE_RET( length == 0 || output != NULL );
|
||||||
|
|
||||||
while (length--) {
|
n = *nc_off;
|
||||||
if (n == 0) {
|
if( n >= 8 )
|
||||||
mbedtls_blowfish_crypt_ecb(ctx, MBEDTLS_BLOWFISH_ENCRYPT, nonce_counter,
|
return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA );
|
||||||
stream_block);
|
|
||||||
|
|
||||||
for (i = MBEDTLS_BLOWFISH_BLOCKSIZE; i > 0; i--)
|
while( length-- )
|
||||||
if (++nonce_counter[i - 1] != 0)
|
{
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
c = *input++;
|
c = *input++;
|
||||||
*output++ = (unsigned char)(c ^ stream_block[n]);
|
*output++ = (unsigned char)( c ^ stream_block[n] );
|
||||||
|
|
||||||
n = (n + 1) % MBEDTLS_BLOWFISH_BLOCKSIZE;
|
n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
*nc_off = n;
|
*nc_off = n;
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
||||||
|
|
||||||
static const uint32_t S[4][256] = {
|
static const uint32_t S[4][256] = {
|
||||||
{
|
{ 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L,
|
||||||
0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L,
|
|
||||||
0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L,
|
0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L,
|
||||||
0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L,
|
0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L,
|
||||||
0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL,
|
0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL,
|
||||||
@@ -423,10 +491,8 @@ static const uint32_t S[4][256] = {
|
|||||||
0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L,
|
0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L,
|
||||||
0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L,
|
0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L,
|
||||||
0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L,
|
0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L,
|
||||||
0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL
|
0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL },
|
||||||
},
|
{ 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L,
|
||||||
{
|
|
||||||
0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L,
|
|
||||||
0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L,
|
0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L,
|
||||||
0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L,
|
0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L,
|
||||||
0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL,
|
0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL,
|
||||||
@@ -489,10 +555,8 @@ static const uint32_t S[4][256] = {
|
|||||||
0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L,
|
0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L,
|
||||||
0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L,
|
0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L,
|
||||||
0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L,
|
0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L,
|
||||||
0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L
|
0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L },
|
||||||
},
|
{ 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L,
|
||||||
{
|
|
||||||
0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L,
|
|
||||||
0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L,
|
0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L,
|
||||||
0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL,
|
0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL,
|
||||||
0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L,
|
0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L,
|
||||||
@@ -555,10 +619,8 @@ static const uint32_t S[4][256] = {
|
|||||||
0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L,
|
0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L,
|
||||||
0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL,
|
0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL,
|
||||||
0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L,
|
0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L,
|
||||||
0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L
|
0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L },
|
||||||
},
|
{ 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL,
|
||||||
{
|
|
||||||
0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL,
|
|
||||||
0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL,
|
0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL,
|
||||||
0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL,
|
0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL,
|
||||||
0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L,
|
0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L,
|
||||||
@@ -621,8 +683,7 @@ static const uint32_t S[4][256] = {
|
|||||||
0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL,
|
0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL,
|
||||||
0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L,
|
0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L,
|
||||||
0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL,
|
0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL,
|
||||||
0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L
|
0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L }
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* !MBEDTLS_BLOWFISH_ALT */
|
#endif /* !MBEDTLS_BLOWFISH_ALT */
|
||||||
|
|||||||
@@ -4,30 +4,26 @@
|
|||||||
* \brief Blowfish block cipher
|
* \brief Blowfish block cipher
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef MBEDTLS_BLOWFISH_H
|
#ifndef MBEDTLS_BLOWFISH_H
|
||||||
#define MBEDTLS_BLOWFISH_H
|
#define MBEDTLS_BLOWFISH_H
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
#include "config.h"
|
#include "mbedtls/config.h"
|
||||||
#else
|
#else
|
||||||
#include MBEDTLS_CONFIG_FILE
|
#include MBEDTLS_CONFIG_FILE
|
||||||
#endif
|
#endif
|
||||||
@@ -35,6 +31,8 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
|
||||||
#define MBEDTLS_BLOWFISH_ENCRYPT 1
|
#define MBEDTLS_BLOWFISH_ENCRYPT 1
|
||||||
#define MBEDTLS_BLOWFISH_DECRYPT 0
|
#define MBEDTLS_BLOWFISH_DECRYPT 0
|
||||||
#define MBEDTLS_BLOWFISH_MAX_KEY_BITS 448
|
#define MBEDTLS_BLOWFISH_MAX_KEY_BITS 448
|
||||||
@@ -42,9 +40,16 @@
|
|||||||
#define MBEDTLS_BLOWFISH_ROUNDS 16 /**< Rounds to use. When increasing this value, make sure to extend the initialisation vectors */
|
#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 */
|
#define MBEDTLS_BLOWFISH_BLOCKSIZE 8 /* Blowfish uses 64 bit blocks */
|
||||||
|
|
||||||
#define MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH -0x0016 /**< Invalid key length. */
|
#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_HW_ACCEL_FAILED -0x0017 /**< Blowfish hardware accelerator failed. */
|
#define MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED -0x0017 /**< Blowfish hardware accelerator failed. */
|
||||||
#define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -57,7 +62,8 @@ extern "C" {
|
|||||||
/**
|
/**
|
||||||
* \brief Blowfish context structure
|
* \brief Blowfish context structure
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_blowfish_context {
|
typedef struct mbedtls_blowfish_context
|
||||||
|
{
|
||||||
uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2]; /*!< Blowfish round keys */
|
uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2]; /*!< Blowfish round keys */
|
||||||
uint32_t S[4][256]; /*!< key dependent S-boxes */
|
uint32_t S[4][256]; /*!< key dependent S-boxes */
|
||||||
}
|
}
|
||||||
@@ -68,51 +74,62 @@ mbedtls_blowfish_context;
|
|||||||
#endif /* MBEDTLS_BLOWFISH_ALT */
|
#endif /* MBEDTLS_BLOWFISH_ALT */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Initialize Blowfish context
|
* \brief Initialize a Blowfish context.
|
||||||
*
|
*
|
||||||
* \param ctx Blowfish context to be initialized
|
* \param ctx The Blowfish context to be initialized.
|
||||||
|
* This must not be \c NULL.
|
||||||
*/
|
*/
|
||||||
void mbedtls_blowfish_init(mbedtls_blowfish_context *ctx);
|
void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Clear Blowfish context
|
* \brief Clear a Blowfish context.
|
||||||
*
|
*
|
||||||
* \param ctx Blowfish context to be cleared
|
* \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.
|
||||||
*/
|
*/
|
||||||
void mbedtls_blowfish_free(mbedtls_blowfish_context *ctx);
|
void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Blowfish key schedule
|
* \brief Perform a Blowfish key schedule operation.
|
||||||
*
|
*
|
||||||
* \param ctx Blowfish context to be initialized
|
* \param ctx The Blowfish context to perform the key schedule on.
|
||||||
* \param key encryption key
|
* \param key The encryption key. This must be a readable buffer of
|
||||||
* \param keybits must be between 32 and 448 bits
|
* 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.
|
||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH
|
* \return \c 0 if successful.
|
||||||
|
* \return A negative error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_blowfish_setkey(mbedtls_blowfish_context *ctx, const unsigned char *key,
|
int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, const unsigned char *key,
|
||||||
unsigned int keybits);
|
unsigned int keybits );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Blowfish-ECB block encryption/decryption
|
* \brief Perform a Blowfish-ECB block encryption/decryption operation.
|
||||||
*
|
*
|
||||||
* \param ctx Blowfish context
|
* \param ctx The Blowfish context to use. This must be initialized
|
||||||
* \param mode MBEDTLS_BLOWFISH_ENCRYPT or MBEDTLS_BLOWFISH_DECRYPT
|
* and bound to a key.
|
||||||
* \param input 8-byte input block
|
* \param mode The mode of operation. Possible values are
|
||||||
* \param output 8-byte output block
|
* #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.
|
||||||
*
|
*
|
||||||
* \return 0 if successful
|
* \return \c 0 if successful.
|
||||||
|
* \return A negative error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_blowfish_crypt_ecb(mbedtls_blowfish_context *ctx,
|
int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
|
||||||
int mode,
|
int mode,
|
||||||
const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
||||||
unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE]);
|
unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] );
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||||
/**
|
/**
|
||||||
* \brief Blowfish-CBC buffer encryption/decryption
|
* \brief Perform a Blowfish-CBC buffer encryption/decryption operation.
|
||||||
* 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
|
* \note Upon exit, the content of the IV is updated so that you can
|
||||||
* call the function same function again on the following
|
* call the function same function again on the following
|
||||||
@@ -122,27 +139,34 @@ int mbedtls_blowfish_crypt_ecb(mbedtls_blowfish_context *ctx,
|
|||||||
* IV, you should either save it manually or use the cipher
|
* IV, you should either save it manually or use the cipher
|
||||||
* module instead.
|
* module instead.
|
||||||
*
|
*
|
||||||
* \param ctx Blowfish context
|
* \param ctx The Blowfish context to use. This must be initialized
|
||||||
* \param mode MBEDTLS_BLOWFISH_ENCRYPT or MBEDTLS_BLOWFISH_DECRYPT
|
* and bound to a key.
|
||||||
* \param length length of the input data
|
* \param mode The mode of operation. Possible values are
|
||||||
* \param iv initialization vector (updated after use)
|
* #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or
|
||||||
* \param input buffer holding the input data
|
* #MBEDTLS_BLOWFISH_DECRYPT for decryption.
|
||||||
* \param output buffer holding the output data
|
* \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.
|
||||||
*
|
*
|
||||||
* \return 0 if successful, or
|
* \return \c 0 if successful.
|
||||||
* MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH
|
* \return A negative error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_blowfish_crypt_cbc(mbedtls_blowfish_context *ctx,
|
int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx,
|
||||||
int mode,
|
int mode,
|
||||||
size_t length,
|
size_t length,
|
||||||
unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||||
/**
|
/**
|
||||||
* \brief Blowfish CFB buffer encryption/decryption.
|
* \brief Perform a Blowfish CFB buffer encryption/decryption operation.
|
||||||
*
|
*
|
||||||
* \note Upon exit, the content of the IV is updated so that you can
|
* \note Upon exit, the content of the IV is updated so that you can
|
||||||
* call the function same function again on the following
|
* call the function same function again on the following
|
||||||
@@ -152,28 +176,38 @@ int mbedtls_blowfish_crypt_cbc(mbedtls_blowfish_context *ctx,
|
|||||||
* IV, you should either save it manually or use the cipher
|
* IV, you should either save it manually or use the cipher
|
||||||
* module instead.
|
* module instead.
|
||||||
*
|
*
|
||||||
* \param ctx Blowfish context
|
* \param ctx The Blowfish context to use. This must be initialized
|
||||||
* \param mode MBEDTLS_BLOWFISH_ENCRYPT or MBEDTLS_BLOWFISH_DECRYPT
|
* and bound to a key.
|
||||||
* \param length length of the input data
|
* \param mode The mode of operation. Possible values are
|
||||||
* \param iv_off offset in IV (updated after use)
|
* #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or
|
||||||
* \param iv initialization vector (updated after use)
|
* #MBEDTLS_BLOWFISH_DECRYPT for decryption.
|
||||||
* \param input buffer holding the input data
|
* \param length The length of the input data in Bytes.
|
||||||
* \param output buffer holding the output data
|
* \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.
|
||||||
*
|
*
|
||||||
* \return 0 if successful
|
* \return \c 0 if successful.
|
||||||
|
* \return A negative error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_blowfish_crypt_cfb64(mbedtls_blowfish_context *ctx,
|
int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx,
|
||||||
int mode,
|
int mode,
|
||||||
size_t length,
|
size_t length,
|
||||||
size_t *iv_off,
|
size_t *iv_off,
|
||||||
unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
#endif /*MBEDTLS_CIPHER_MODE_CFB */
|
#endif /*MBEDTLS_CIPHER_MODE_CFB */
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
||||||
/**
|
/**
|
||||||
* \brief Blowfish-CTR buffer encryption/decryption
|
* \brief Perform a Blowfish-CTR buffer encryption/decryption operation.
|
||||||
*
|
*
|
||||||
* \warning You must never reuse a nonce value with the same key. Doing so
|
* \warning You must never reuse a nonce value with the same key. Doing so
|
||||||
* would void the encryption for the two messages encrypted with
|
* would void the encryption for the two messages encrypted with
|
||||||
@@ -216,26 +250,32 @@ int mbedtls_blowfish_crypt_cfb64(mbedtls_blowfish_context *ctx,
|
|||||||
* content must not be written to insecure storage and should be
|
* content must not be written to insecure storage and should be
|
||||||
* securely discarded as soon as it's no longer needed.
|
* securely discarded as soon as it's no longer needed.
|
||||||
*
|
*
|
||||||
* \param ctx Blowfish context
|
* \param ctx The Blowfish context to use. This must be initialized
|
||||||
* \param length The length of the data
|
* and bound to a key.
|
||||||
|
* \param length The length of the input data in Bytes.
|
||||||
* \param nc_off The offset in the current stream_block (for resuming
|
* \param nc_off The offset in the current stream_block (for resuming
|
||||||
* within current cipher stream). The offset pointer to
|
* within current cipher stream). The offset pointer
|
||||||
* should be 0 at the start of a stream.
|
* should be \c 0 at the start of a stream and must be
|
||||||
* \param nonce_counter The 64-bit nonce and counter.
|
* smaller than \c 8. It is updated by this function.
|
||||||
* \param stream_block The saved stream-block for resuming. Is overwritten
|
* \param nonce_counter The 64-bit nonce and counter. This must point to a
|
||||||
* by the function.
|
* read/write buffer of length \c 8 Bytes.
|
||||||
* \param input The input data stream
|
* \param stream_block The saved stream-block for resuming. This must point to
|
||||||
* \param output The output data stream
|
* 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.
|
||||||
*
|
*
|
||||||
* \return 0 if successful
|
* \return \c 0 if successful.
|
||||||
|
* \return A negative error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_blowfish_crypt_ctr(mbedtls_blowfish_context *ctx,
|
int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx,
|
||||||
size_t length,
|
size_t length,
|
||||||
size_t *nc_off,
|
size_t *nc_off,
|
||||||
unsigned char nonce_counter[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
unsigned char nonce_counter[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
||||||
unsigned char stream_block[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
unsigned char stream_block[MBEDTLS_BLOWFISH_BLOCKSIZE],
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -4,30 +4,26 @@
|
|||||||
* \brief Camellia block cipher
|
* \brief Camellia block cipher
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef MBEDTLS_CAMELLIA_H
|
#ifndef MBEDTLS_CAMELLIA_H
|
||||||
#define MBEDTLS_CAMELLIA_H
|
#define MBEDTLS_CAMELLIA_H
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
#include "config.h"
|
#include "mbedtls/config.h"
|
||||||
#else
|
#else
|
||||||
#include MBEDTLS_CONFIG_FILE
|
#include MBEDTLS_CONFIG_FILE
|
||||||
#endif
|
#endif
|
||||||
@@ -35,11 +31,20 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
|
||||||
#define MBEDTLS_CAMELLIA_ENCRYPT 1
|
#define MBEDTLS_CAMELLIA_ENCRYPT 1
|
||||||
#define MBEDTLS_CAMELLIA_DECRYPT 0
|
#define MBEDTLS_CAMELLIA_DECRYPT 0
|
||||||
|
|
||||||
#define MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH -0x0024 /**< Invalid key length. */
|
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
#define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 /**< Invalid data input length. */
|
#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_HW_ACCEL_FAILED -0x0027 /**< Camellia hardware accelerator failed. */
|
#define MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED -0x0027 /**< Camellia hardware accelerator failed. */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -53,7 +58,8 @@ extern "C" {
|
|||||||
/**
|
/**
|
||||||
* \brief CAMELLIA context structure
|
* \brief CAMELLIA context structure
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_camellia_context {
|
typedef struct mbedtls_camellia_context
|
||||||
|
{
|
||||||
int nr; /*!< number of rounds */
|
int nr; /*!< number of rounds */
|
||||||
uint32_t rk[68]; /*!< CAMELLIA round keys */
|
uint32_t rk[68]; /*!< CAMELLIA round keys */
|
||||||
}
|
}
|
||||||
@@ -64,63 +70,77 @@ mbedtls_camellia_context;
|
|||||||
#endif /* MBEDTLS_CAMELLIA_ALT */
|
#endif /* MBEDTLS_CAMELLIA_ALT */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Initialize CAMELLIA context
|
* \brief Initialize a CAMELLIA context.
|
||||||
*
|
*
|
||||||
* \param ctx CAMELLIA context to be initialized
|
* \param ctx The CAMELLIA context to be initialized.
|
||||||
|
* This must not be \c NULL.
|
||||||
*/
|
*/
|
||||||
void mbedtls_camellia_init(mbedtls_camellia_context *ctx);
|
void mbedtls_camellia_init( mbedtls_camellia_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Clear CAMELLIA context
|
* \brief Clear a CAMELLIA context.
|
||||||
*
|
*
|
||||||
* \param ctx CAMELLIA context to be cleared
|
* \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.
|
||||||
*/
|
*/
|
||||||
void mbedtls_camellia_free(mbedtls_camellia_context *ctx);
|
void mbedtls_camellia_free( mbedtls_camellia_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief CAMELLIA key schedule (encryption)
|
* \brief Perform a CAMELLIA key schedule operation for encryption.
|
||||||
*
|
*
|
||||||
* \param ctx CAMELLIA context to be initialized
|
* \param ctx The CAMELLIA context to use. This must be initialized.
|
||||||
* \param key encryption key
|
* \param key The encryption key to use. This must be a readable buffer
|
||||||
* \param keybits must be 128, 192 or 256
|
* 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.
|
||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH
|
* \return \c 0 if successful.
|
||||||
|
* \return A negative error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_camellia_setkey_enc(mbedtls_camellia_context *ctx, const unsigned char *key,
|
int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx,
|
||||||
unsigned int keybits);
|
const unsigned char *key,
|
||||||
|
unsigned int keybits );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief CAMELLIA key schedule (decryption)
|
* \brief Perform a CAMELLIA key schedule operation for decryption.
|
||||||
*
|
*
|
||||||
* \param ctx CAMELLIA context to be initialized
|
* \param ctx The CAMELLIA context to use. This must be initialized.
|
||||||
* \param key decryption key
|
* \param key The decryption key. This must be a readable buffer
|
||||||
* \param keybits must be 128, 192 or 256
|
* 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.
|
||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH
|
* \return \c 0 if successful.
|
||||||
|
* \return A negative error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_camellia_setkey_dec(mbedtls_camellia_context *ctx, const unsigned char *key,
|
int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx,
|
||||||
unsigned int keybits);
|
const unsigned char *key,
|
||||||
|
unsigned int keybits );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief CAMELLIA-ECB block encryption/decryption
|
* \brief Perform a CAMELLIA-ECB block encryption/decryption operation.
|
||||||
*
|
*
|
||||||
* \param ctx CAMELLIA context
|
* \param ctx The CAMELLIA context to use. This must be initialized
|
||||||
* \param mode MBEDTLS_CAMELLIA_ENCRYPT or MBEDTLS_CAMELLIA_DECRYPT
|
* and bound to a key.
|
||||||
* \param input 16-byte input block
|
* \param mode The mode of operation. This must be either
|
||||||
* \param output 16-byte output block
|
* #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.
|
||||||
*
|
*
|
||||||
* \return 0 if successful
|
* \return \c 0 if successful.
|
||||||
|
* \return A negative error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_camellia_crypt_ecb(mbedtls_camellia_context *ctx,
|
int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
|
||||||
int mode,
|
int mode,
|
||||||
const unsigned char input[16],
|
const unsigned char input[16],
|
||||||
unsigned char output[16]);
|
unsigned char output[16] );
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||||
/**
|
/**
|
||||||
* \brief CAMELLIA-CBC buffer encryption/decryption
|
* \brief Perform a CAMELLIA-CBC buffer encryption/decryption operation.
|
||||||
* 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
|
* \note Upon exit, the content of the IV is updated so that you can
|
||||||
* call the function same function again on the following
|
* call the function same function again on the following
|
||||||
@@ -130,31 +150,41 @@ int mbedtls_camellia_crypt_ecb(mbedtls_camellia_context *ctx,
|
|||||||
* IV, you should either save it manually or use the cipher
|
* IV, you should either save it manually or use the cipher
|
||||||
* module instead.
|
* module instead.
|
||||||
*
|
*
|
||||||
* \param ctx CAMELLIA context
|
* \param ctx The CAMELLIA context to use. This must be initialized
|
||||||
* \param mode MBEDTLS_CAMELLIA_ENCRYPT or MBEDTLS_CAMELLIA_DECRYPT
|
* and bound to a key.
|
||||||
* \param length length of the input data
|
* \param mode The mode of operation. This must be either
|
||||||
* \param iv initialization vector (updated after use)
|
* #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
|
||||||
* \param input buffer holding the input data
|
* \param length The length in Bytes of the input data \p input.
|
||||||
* \param output buffer holding the output data
|
* 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.
|
||||||
*
|
*
|
||||||
* \return 0 if successful, or
|
* \return \c 0 if successful.
|
||||||
* MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH
|
* \return A negative error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_camellia_crypt_cbc(mbedtls_camellia_context *ctx,
|
int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
|
||||||
int mode,
|
int mode,
|
||||||
size_t length,
|
size_t length,
|
||||||
unsigned char iv[16],
|
unsigned char iv[16],
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||||
/**
|
/**
|
||||||
* \brief CAMELLIA-CFB128 buffer encryption/decryption
|
* \brief Perform a CAMELLIA-CFB128 buffer encryption/decryption
|
||||||
|
* operation.
|
||||||
*
|
*
|
||||||
* Note: Due to the nature of CFB you should use the same key schedule for
|
* \note Due to the nature of CFB mode, you should use the same
|
||||||
* both encryption and decryption. So a context initialized with
|
* key for both encryption and decryption. In particular, calls
|
||||||
* mbedtls_camellia_setkey_enc() for both MBEDTLS_CAMELLIA_ENCRYPT and CAMELLIE_DECRYPT.
|
* 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 Upon exit, the content of the IV is updated so that you can
|
* \note Upon exit, the content of the IV is updated so that you can
|
||||||
* call the function same function again on the following
|
* call the function same function again on the following
|
||||||
@@ -164,33 +194,43 @@ int mbedtls_camellia_crypt_cbc(mbedtls_camellia_context *ctx,
|
|||||||
* IV, you should either save it manually or use the cipher
|
* IV, you should either save it manually or use the cipher
|
||||||
* module instead.
|
* module instead.
|
||||||
*
|
*
|
||||||
* \param ctx CAMELLIA context
|
* \param ctx The CAMELLIA context to use. This must be initialized
|
||||||
* \param mode MBEDTLS_CAMELLIA_ENCRYPT or MBEDTLS_CAMELLIA_DECRYPT
|
* and bound to a key.
|
||||||
* \param length length of the input data
|
* \param mode The mode of operation. This must be either
|
||||||
* \param iv_off offset in IV (updated after use)
|
* #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
|
||||||
* \param iv initialization vector (updated after use)
|
* \param length The length of the input data \p input. Any value is allowed.
|
||||||
* \param input buffer holding the input data
|
* \param iv_off The current offset in the IV. This must be smaller
|
||||||
* \param output buffer holding the output data
|
* 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.
|
||||||
*
|
*
|
||||||
* \return 0 if successful, or
|
* \return \c 0 if successful.
|
||||||
* MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH
|
* \return A negative error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_camellia_crypt_cfb128(mbedtls_camellia_context *ctx,
|
int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx,
|
||||||
int mode,
|
int mode,
|
||||||
size_t length,
|
size_t length,
|
||||||
size_t *iv_off,
|
size_t *iv_off,
|
||||||
unsigned char iv[16],
|
unsigned char iv[16],
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_CFB */
|
#endif /* MBEDTLS_CIPHER_MODE_CFB */
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
||||||
/**
|
/**
|
||||||
* \brief CAMELLIA-CTR buffer encryption/decryption
|
* \brief Perform a CAMELLIA-CTR buffer encryption/decryption operation.
|
||||||
*
|
*
|
||||||
* Note: Due to the nature of CTR you should use the same key schedule for
|
* *note Due to the nature of CTR mode, you should use the same
|
||||||
* both encryption and decryption. So a context initialized with
|
* key for both encryption and decryption. In particular, calls
|
||||||
* mbedtls_camellia_setkey_enc() for both MBEDTLS_CAMELLIA_ENCRYPT and MBEDTLS_CAMELLIA_DECRYPT.
|
* 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 must never reuse a nonce value with the same key. Doing so
|
* \warning You must never reuse a nonce value with the same key. Doing so
|
||||||
* would void the encryption for the two messages encrypted with
|
* would void the encryption for the two messages encrypted with
|
||||||
@@ -213,57 +253,69 @@ int mbedtls_camellia_crypt_cfb128(mbedtls_camellia_context *ctx,
|
|||||||
* per-message nonce, handled by yourself, and the second one
|
* per-message nonce, handled by yourself, and the second one
|
||||||
* updated by this function internally.
|
* updated by this function internally.
|
||||||
*
|
*
|
||||||
* For example, you might reserve the first 12 bytes for the
|
* For example, you might reserve the first \c 12 Bytes for the
|
||||||
* per-message nonce, and the last 4 bytes for internal use. In that
|
* per-message nonce, and the last \c 4 Bytes for internal use.
|
||||||
* case, before calling this function on a new message you need to
|
* In that case, before calling this function on a new message you
|
||||||
* set the first 12 bytes of \p nonce_counter to your chosen nonce
|
* need to set the first \c 12 Bytes of \p nonce_counter to your
|
||||||
* value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
|
* chosen nonce value, the last four to \c 0, and \p nc_off to \c 0
|
||||||
* stream_block to be ignored). That way, you can encrypt at most
|
* (which will cause \p stream_block to be ignored). That way, you
|
||||||
* 2**96 messages of up to 2**32 blocks each with the same key.
|
* 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
|
* The per-message nonce (or information sufficient to reconstruct
|
||||||
* it) needs to be communicated with the ciphertext and must be unique.
|
* it) needs to be communicated with the ciphertext and must be
|
||||||
* The recommended way to ensure uniqueness is to use a message
|
* unique. The recommended way to ensure uniqueness is to use a
|
||||||
* counter. An alternative is to generate random nonces, but this
|
* message counter. An alternative is to generate random nonces,
|
||||||
* limits the number of messages that can be securely encrypted:
|
* but this limits the number of messages that can be securely
|
||||||
* for example, with 96-bit random nonces, you should not encrypt
|
* encrypted: for example, with 96-bit random nonces, you should
|
||||||
* more than 2**32 messages with the same key.
|
* not encrypt more than 2**32 messages with the same key.
|
||||||
*
|
*
|
||||||
* Note that for both stategies, sizes are measured in blocks and
|
* Note that for both stategies, sizes are measured in blocks and
|
||||||
* that a CAMELLIA block is 16 bytes.
|
* that a CAMELLIA block is \c 16 Bytes.
|
||||||
*
|
*
|
||||||
* \warning Upon return, \p stream_block contains sensitive data. Its
|
* \warning Upon return, \p stream_block contains sensitive data. Its
|
||||||
* content must not be written to insecure storage and should be
|
* content must not be written to insecure storage and should be
|
||||||
* securely discarded as soon as it's no longer needed.
|
* securely discarded as soon as it's no longer needed.
|
||||||
*
|
*
|
||||||
* \param ctx CAMELLIA context
|
* \param ctx The CAMELLIA context to use. This must be initialized
|
||||||
* \param length The length of the data
|
* and bound to a key.
|
||||||
* \param nc_off The offset in the current stream_block (for resuming
|
* \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
|
||||||
* within current cipher stream). The offset pointer to
|
* within current cipher stream). The offset pointer to
|
||||||
* should be 0 at the start of a stream.
|
* should be \c 0 at the start of a stream. It is updated
|
||||||
* \param nonce_counter The 128-bit nonce and counter.
|
* at the end of this call.
|
||||||
* \param stream_block The saved stream-block for resuming. Is overwritten
|
* \param nonce_counter The 128-bit nonce and counter. This must be a read/write
|
||||||
* by the function.
|
* buffer of length \c 16 Bytes.
|
||||||
* \param input The input data stream
|
* \param stream_block The saved stream-block for resuming. This must be a
|
||||||
* \param output The output data stream
|
* 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.
|
||||||
*
|
*
|
||||||
* \return 0 if successful
|
* \return \c 0 if successful.
|
||||||
|
* \return A negative error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_camellia_crypt_ctr(mbedtls_camellia_context *ctx,
|
int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx,
|
||||||
size_t length,
|
size_t length,
|
||||||
size_t *nc_off,
|
size_t *nc_off,
|
||||||
unsigned char nonce_counter[16],
|
unsigned char nonce_counter[16],
|
||||||
unsigned char stream_block[16],
|
unsigned char stream_block[16],
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Checkup routine
|
* \brief Checkup routine
|
||||||
*
|
*
|
||||||
* \return 0 if successful, or 1 if the test failed
|
* \return 0 if successful, or 1 if the test failed
|
||||||
*/
|
*/
|
||||||
int mbedtls_camellia_self_test(int verbose);
|
int mbedtls_camellia_self_test( int verbose );
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
547
common/mbedtls/ccm.c
Normal file
547
common/mbedtls/ccm.c
Normal file
@@ -0,0 +1,547 @@
|
|||||||
|
/*
|
||||||
|
* NIST SP800-38C compliant CCM implementation
|
||||||
|
*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_CCM_C)
|
||||||
|
|
||||||
|
#include "mbedtls/ccm.h"
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
|
||||||
|
#if defined(MBEDTLS_PLATFORM_C)
|
||||||
|
#include "mbedtls/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)
|
||||||
|
|
||||||
|
#define CCM_VALIDATE_RET( cond ) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CCM_BAD_INPUT )
|
||||||
|
#define CCM_VALIDATE( cond ) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||||
|
|
||||||
|
#define CCM_ENCRYPT 0
|
||||||
|
#define CCM_DECRYPT 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize context
|
||||||
|
*/
|
||||||
|
void mbedtls_ccm_init( mbedtls_ccm_context *ctx )
|
||||||
|
{
|
||||||
|
CCM_VALIDATE( ctx != NULL );
|
||||||
|
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 = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
const mbedtls_cipher_info_t *cipher_info;
|
||||||
|
|
||||||
|
CCM_VALIDATE_RET( ctx != NULL );
|
||||||
|
CCM_VALIDATE_RET( key != NULL );
|
||||||
|
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
if( ctx == NULL )
|
||||||
|
return;
|
||||||
|
mbedtls_cipher_free( &ctx->cipher_ctx );
|
||||||
|
mbedtls_platform_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 ) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
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]; \
|
||||||
|
} while( 0 )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
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)
|
||||||
|
*
|
||||||
|
* Also, loosen the requirements to enable support for CCM* (IEEE 802.15.4).
|
||||||
|
*/
|
||||||
|
if( tag_len == 2 || 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_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
|
||||||
|
const unsigned char *iv, size_t iv_len,
|
||||||
|
const unsigned char *add, size_t add_len,
|
||||||
|
const unsigned char *input, unsigned char *output,
|
||||||
|
unsigned char *tag, size_t tag_len )
|
||||||
|
{
|
||||||
|
CCM_VALIDATE_RET( ctx != NULL );
|
||||||
|
CCM_VALIDATE_RET( iv != NULL );
|
||||||
|
CCM_VALIDATE_RET( add_len == 0 || add != NULL );
|
||||||
|
CCM_VALIDATE_RET( length == 0 || input != NULL );
|
||||||
|
CCM_VALIDATE_RET( length == 0 || output != NULL );
|
||||||
|
CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
|
||||||
|
return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len,
|
||||||
|
add, add_len, input, output, tag, tag_len ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
|
||||||
|
const unsigned char *iv, size_t iv_len,
|
||||||
|
const unsigned char *add, size_t add_len,
|
||||||
|
const unsigned char *input, unsigned char *output,
|
||||||
|
unsigned char *tag, size_t tag_len )
|
||||||
|
{
|
||||||
|
CCM_VALIDATE_RET( ctx != NULL );
|
||||||
|
CCM_VALIDATE_RET( iv != NULL );
|
||||||
|
CCM_VALIDATE_RET( add_len == 0 || add != NULL );
|
||||||
|
CCM_VALIDATE_RET( length == 0 || input != NULL );
|
||||||
|
CCM_VALIDATE_RET( length == 0 || output != NULL );
|
||||||
|
CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
|
||||||
|
if( tag_len == 0 )
|
||||||
|
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||||
|
|
||||||
|
return( mbedtls_ccm_star_encrypt_and_tag( ctx, length, iv, iv_len, add,
|
||||||
|
add_len, input, output, tag, tag_len ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Authenticated decryption
|
||||||
|
*/
|
||||||
|
int mbedtls_ccm_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 )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
unsigned char check_tag[16];
|
||||||
|
unsigned char i;
|
||||||
|
int diff;
|
||||||
|
|
||||||
|
CCM_VALIDATE_RET( ctx != NULL );
|
||||||
|
CCM_VALIDATE_RET( iv != NULL );
|
||||||
|
CCM_VALIDATE_RET( add_len == 0 || add != NULL );
|
||||||
|
CCM_VALIDATE_RET( length == 0 || input != NULL );
|
||||||
|
CCM_VALIDATE_RET( length == 0 || output != NULL );
|
||||||
|
CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
|
||||||
|
|
||||||
|
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_platform_zeroize( output, length );
|
||||||
|
return( MBEDTLS_ERR_CCM_AUTH_FAILED );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
|
||||||
|
const unsigned char *iv, size_t iv_len,
|
||||||
|
const unsigned char *add, size_t add_len,
|
||||||
|
const unsigned char *input, unsigned char *output,
|
||||||
|
const unsigned char *tag, size_t tag_len )
|
||||||
|
{
|
||||||
|
CCM_VALIDATE_RET( ctx != NULL );
|
||||||
|
CCM_VALIDATE_RET( iv != NULL );
|
||||||
|
CCM_VALIDATE_RET( add_len == 0 || add != NULL );
|
||||||
|
CCM_VALIDATE_RET( length == 0 || input != NULL );
|
||||||
|
CCM_VALIDATE_RET( length == 0 || output != NULL );
|
||||||
|
CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
|
||||||
|
|
||||||
|
if( tag_len == 0 )
|
||||||
|
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||||
|
|
||||||
|
return( mbedtls_ccm_star_auth_decrypt( ctx, length, iv, iv_len, add,
|
||||||
|
add_len, input, output, tag, tag_len ) );
|
||||||
|
}
|
||||||
|
#endif /* !MBEDTLS_CCM_ALT */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
|
||||||
|
/*
|
||||||
|
* 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_test_data[] = {
|
||||||
|
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||||
|
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char iv_test_data[] = {
|
||||||
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||||
|
0x18, 0x19, 0x1a, 0x1b
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char ad_test_data[] = {
|
||||||
|
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_test_data[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_test_data [NB_TESTS] = { 7, 8, 12 };
|
||||||
|
static const size_t add_len_test_data[NB_TESTS] = { 8, 16, 20 };
|
||||||
|
static const size_t msg_len_test_data[NB_TESTS] = { 4, 16, 24 };
|
||||||
|
static const size_t tag_len_test_data[NB_TESTS] = { 4, 6, 8 };
|
||||||
|
|
||||||
|
static const unsigned char res_test_data[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_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
|
mbedtls_ccm_init( &ctx );
|
||||||
|
|
||||||
|
if( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key_test_data,
|
||||||
|
8 * sizeof key_test_data ) != 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_test_data, msg_len_test_data[i] );
|
||||||
|
|
||||||
|
ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len_test_data[i],
|
||||||
|
iv_test_data, iv_len_test_data[i],
|
||||||
|
ad_test_data, add_len_test_data[i],
|
||||||
|
plaintext, ciphertext,
|
||||||
|
ciphertext + msg_len_test_data[i],
|
||||||
|
tag_len_test_data[i] );
|
||||||
|
|
||||||
|
if( ret != 0 ||
|
||||||
|
memcmp( ciphertext, res_test_data[i],
|
||||||
|
msg_len_test_data[i] + tag_len_test_data[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_test_data[i],
|
||||||
|
iv_test_data, iv_len_test_data[i],
|
||||||
|
ad_test_data, add_len_test_data[i],
|
||||||
|
ciphertext, plaintext,
|
||||||
|
ciphertext + msg_len_test_data[i],
|
||||||
|
tag_len_test_data[i] );
|
||||||
|
|
||||||
|
if( ret != 0 ||
|
||||||
|
memcmp( plaintext, msg_test_data, msg_len_test_data[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 */
|
||||||
308
common/mbedtls/ccm.h
Normal file
308
common/mbedtls/ccm.h
Normal file
@@ -0,0 +1,308 @@
|
|||||||
|
/**
|
||||||
|
* \file ccm.h
|
||||||
|
*
|
||||||
|
* \brief This file provides an API for the CCM authenticated encryption
|
||||||
|
* mode for block ciphers.
|
||||||
|
*
|
||||||
|
* CCM combines Counter mode encryption with CBC-MAC authentication
|
||||||
|
* for 128-bit block ciphers.
|
||||||
|
*
|
||||||
|
* Input to CCM includes the following elements:
|
||||||
|
* <ul><li>Payload - data that is both authenticated and encrypted.</li>
|
||||||
|
* <li>Associated data (Adata) - data that is authenticated but not
|
||||||
|
* encrypted, For example, a header.</li>
|
||||||
|
* <li>Nonce - A unique value that is assigned to the payload and the
|
||||||
|
* associated data.</li></ul>
|
||||||
|
*
|
||||||
|
* 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 The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MBEDTLS_CCM_H
|
||||||
|
#define MBEDTLS_CCM_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mbedtls/cipher.h"
|
||||||
|
|
||||||
|
#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
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief The CCM context-type definition. The CCM context is passed
|
||||||
|
* to the APIs called.
|
||||||
|
*/
|
||||||
|
typedef struct mbedtls_ccm_context
|
||||||
|
{
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
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 cipher The 128-bit block cipher to use.
|
||||||
|
* \param key The encryption key. This must not be \c NULL.
|
||||||
|
* \param keybits The key size in bits. This must be acceptable by the cipher.
|
||||||
|
*
|
||||||
|
* \return \c 0 on success.
|
||||||
|
* \return A CCM or cipher-specific error code on failure.
|
||||||
|
*/
|
||||||
|
int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
|
||||||
|
mbedtls_cipher_id_t cipher,
|
||||||
|
const unsigned char *key,
|
||||||
|
unsigned int keybits );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function releases and clears the specified CCM context
|
||||||
|
* and underlying cipher sub-context.
|
||||||
|
*
|
||||||
|
* \param ctx The CCM context to clear. If this is \c NULL, the function
|
||||||
|
* has no effect. Otherwise, this must be initialized.
|
||||||
|
*/
|
||||||
|
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 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 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
|
||||||
|
* writable buffer of at least \p tag_len Bytes.
|
||||||
|
* \param tag_len The length of the authentication field to generate in Bytes:
|
||||||
|
* 4, 6, 8, 10, 12, 14 or 16.
|
||||||
|
*
|
||||||
|
* \return \c 0 on success.
|
||||||
|
* \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
|
||||||
|
* writable 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,
|
||||||
|
const unsigned char *iv, size_t iv_len,
|
||||||
|
const unsigned char *add, size_t add_len,
|
||||||
|
const unsigned char *input, unsigned char *output,
|
||||||
|
unsigned char *tag, size_t tag_len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function performs a CCM authenticated decryption of a
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* \param ctx The CCM context to use for decryption. 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 to generate 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.
|
||||||
|
*/
|
||||||
|
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 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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 );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
|
||||||
|
/**
|
||||||
|
* \brief The CCM checkup routine.
|
||||||
|
*
|
||||||
|
* \return \c 0 on success.
|
||||||
|
* \return \c 1 on failure.
|
||||||
|
*/
|
||||||
|
int mbedtls_ccm_self_test( int verbose );
|
||||||
|
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_CCM_H */
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -4,96 +4,244 @@
|
|||||||
* \brief Sample certificates and DHM parameters for testing
|
* \brief Sample certificates and DHM parameters for testing
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef MBEDTLS_CERTS_H
|
#ifndef MBEDTLS_CERTS_H
|
||||||
#define MBEDTLS_CERTS_H
|
#define MBEDTLS_CERTS_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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)
|
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||||
/* Concatenation of all CA certificates in PEM format if available */
|
/* Concatenation of all CA certificates in PEM format if available */
|
||||||
extern const char mbedtls_test_cas_pem[];
|
extern const char mbedtls_test_cas_pem[];
|
||||||
extern const size_t mbedtls_test_cas_pem_len;
|
extern const size_t mbedtls_test_cas_pem_len;
|
||||||
#endif
|
#endif /* MBEDTLS_PEM_PARSE_C */
|
||||||
|
|
||||||
/* List of all CA certificates, terminated by NULL */
|
|
||||||
extern const char *mbedtls_test_cas[];
|
|
||||||
extern const size_t mbedtls_test_cas_len[];
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convenience for users who just want a certificate:
|
* CA test certificates
|
||||||
* RSA by default, or ECDSA if RSA is not available
|
|
||||||
*/
|
*/
|
||||||
extern const char *mbedtls_test_ca_crt;
|
|
||||||
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;
|
|
||||||
extern const char *mbedtls_test_srv_crt;
|
|
||||||
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 char *mbedtls_test_cli_crt;
|
|
||||||
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;
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECDSA_C)
|
extern const char mbedtls_test_ca_crt_ec_pem[];
|
||||||
extern const char mbedtls_test_ca_crt_ec[];
|
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_crt_ec_len;
|
||||||
extern const char mbedtls_test_ca_key_ec[];
|
|
||||||
extern const size_t mbedtls_test_ca_key_ec_len;
|
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 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 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 size_t mbedtls_test_ca_pwd_rsa_len;
|
||||||
extern const char mbedtls_test_srv_crt_rsa[];
|
extern const size_t mbedtls_test_ca_crt_rsa_sha1_len;
|
||||||
extern const size_t mbedtls_test_srv_crt_rsa_len;
|
extern const size_t mbedtls_test_ca_crt_rsa_sha256_len;
|
||||||
extern const char mbedtls_test_srv_key_rsa[];
|
|
||||||
|
/* 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 size_t mbedtls_test_ca_key_len;
|
||||||
|
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_key_rsa_len;
|
||||||
extern const char mbedtls_test_cli_crt_rsa[];
|
extern const size_t mbedtls_test_srv_pwd_rsa_len;
|
||||||
extern const size_t mbedtls_test_cli_crt_rsa_len;
|
extern const size_t mbedtls_test_srv_crt_rsa_sha1_len;
|
||||||
extern const char mbedtls_test_cli_key_rsa[];
|
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 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_key_rsa_len;
|
||||||
#endif
|
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 size_t mbedtls_test_cli_key_len;
|
||||||
|
extern const size_t mbedtls_test_cli_pwd_len;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
568
common/mbedtls/chacha20.c
Normal file
568
common/mbedtls/chacha20.c
Normal file
@@ -0,0 +1,568 @@
|
|||||||
|
/**
|
||||||
|
* \file chacha20.c
|
||||||
|
*
|
||||||
|
* \brief ChaCha20 cipher.
|
||||||
|
*
|
||||||
|
* \author Daniel King <damaki.gh@gmail.com>
|
||||||
|
*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_CHACHA20_C)
|
||||||
|
|
||||||
|
#include "mbedtls/chacha20.h"
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
#if defined(MBEDTLS_PLATFORM_C)
|
||||||
|
#include "mbedtls/platform.h"
|
||||||
|
#else
|
||||||
|
#include <stdio.h>
|
||||||
|
#define mbedtls_printf printf
|
||||||
|
#endif /* MBEDTLS_PLATFORM_C */
|
||||||
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CHACHA20_ALT)
|
||||||
|
|
||||||
|
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
|
||||||
|
!defined(inline) && !defined(__cplusplus)
|
||||||
|
#define inline __inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Parameter validation macros */
|
||||||
|
#define CHACHA20_VALIDATE_RET( cond ) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
|
||||||
|
#define CHACHA20_VALIDATE( cond ) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||||
|
|
||||||
|
#define BYTES_TO_U32_LE( data, offset ) \
|
||||||
|
( (uint32_t) (data)[offset] \
|
||||||
|
| (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \
|
||||||
|
| (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \
|
||||||
|
| (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define ROTL32( value, amount ) \
|
||||||
|
( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) )
|
||||||
|
|
||||||
|
#define CHACHA20_CTR_INDEX ( 12U )
|
||||||
|
|
||||||
|
#define CHACHA20_BLOCK_SIZE_BYTES ( 4U * 16U )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief ChaCha20 quarter round operation.
|
||||||
|
*
|
||||||
|
* The quarter round is defined as follows (from RFC 7539):
|
||||||
|
* 1. a += b; d ^= a; d <<<= 16;
|
||||||
|
* 2. c += d; b ^= c; b <<<= 12;
|
||||||
|
* 3. a += b; d ^= a; d <<<= 8;
|
||||||
|
* 4. c += d; b ^= c; b <<<= 7;
|
||||||
|
*
|
||||||
|
* \param state ChaCha20 state to modify.
|
||||||
|
* \param a The index of 'a' in the state.
|
||||||
|
* \param b The index of 'b' in the state.
|
||||||
|
* \param c The index of 'c' in the state.
|
||||||
|
* \param d The index of 'd' in the state.
|
||||||
|
*/
|
||||||
|
static inline void chacha20_quarter_round( uint32_t state[16],
|
||||||
|
size_t a,
|
||||||
|
size_t b,
|
||||||
|
size_t c,
|
||||||
|
size_t d )
|
||||||
|
{
|
||||||
|
/* a += b; d ^= a; d <<<= 16; */
|
||||||
|
state[a] += state[b];
|
||||||
|
state[d] ^= state[a];
|
||||||
|
state[d] = ROTL32( state[d], 16 );
|
||||||
|
|
||||||
|
/* c += d; b ^= c; b <<<= 12 */
|
||||||
|
state[c] += state[d];
|
||||||
|
state[b] ^= state[c];
|
||||||
|
state[b] = ROTL32( state[b], 12 );
|
||||||
|
|
||||||
|
/* a += b; d ^= a; d <<<= 8; */
|
||||||
|
state[a] += state[b];
|
||||||
|
state[d] ^= state[a];
|
||||||
|
state[d] = ROTL32( state[d], 8 );
|
||||||
|
|
||||||
|
/* c += d; b ^= c; b <<<= 7; */
|
||||||
|
state[c] += state[d];
|
||||||
|
state[b] ^= state[c];
|
||||||
|
state[b] = ROTL32( state[b], 7 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Perform the ChaCha20 inner block operation.
|
||||||
|
*
|
||||||
|
* This function performs two rounds: the column round and the
|
||||||
|
* diagonal round.
|
||||||
|
*
|
||||||
|
* \param state The ChaCha20 state to update.
|
||||||
|
*/
|
||||||
|
static void chacha20_inner_block( uint32_t state[16] )
|
||||||
|
{
|
||||||
|
chacha20_quarter_round( state, 0, 4, 8, 12 );
|
||||||
|
chacha20_quarter_round( state, 1, 5, 9, 13 );
|
||||||
|
chacha20_quarter_round( state, 2, 6, 10, 14 );
|
||||||
|
chacha20_quarter_round( state, 3, 7, 11, 15 );
|
||||||
|
|
||||||
|
chacha20_quarter_round( state, 0, 5, 10, 15 );
|
||||||
|
chacha20_quarter_round( state, 1, 6, 11, 12 );
|
||||||
|
chacha20_quarter_round( state, 2, 7, 8, 13 );
|
||||||
|
chacha20_quarter_round( state, 3, 4, 9, 14 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Generates a keystream block.
|
||||||
|
*
|
||||||
|
* \param initial_state The initial ChaCha20 state (key, nonce, counter).
|
||||||
|
* \param keystream Generated keystream bytes are written to this buffer.
|
||||||
|
*/
|
||||||
|
static void chacha20_block( const uint32_t initial_state[16],
|
||||||
|
unsigned char keystream[64] )
|
||||||
|
{
|
||||||
|
uint32_t working_state[16];
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
memcpy( working_state,
|
||||||
|
initial_state,
|
||||||
|
CHACHA20_BLOCK_SIZE_BYTES );
|
||||||
|
|
||||||
|
for( i = 0U; i < 10U; i++ )
|
||||||
|
chacha20_inner_block( working_state );
|
||||||
|
|
||||||
|
working_state[ 0] += initial_state[ 0];
|
||||||
|
working_state[ 1] += initial_state[ 1];
|
||||||
|
working_state[ 2] += initial_state[ 2];
|
||||||
|
working_state[ 3] += initial_state[ 3];
|
||||||
|
working_state[ 4] += initial_state[ 4];
|
||||||
|
working_state[ 5] += initial_state[ 5];
|
||||||
|
working_state[ 6] += initial_state[ 6];
|
||||||
|
working_state[ 7] += initial_state[ 7];
|
||||||
|
working_state[ 8] += initial_state[ 8];
|
||||||
|
working_state[ 9] += initial_state[ 9];
|
||||||
|
working_state[10] += initial_state[10];
|
||||||
|
working_state[11] += initial_state[11];
|
||||||
|
working_state[12] += initial_state[12];
|
||||||
|
working_state[13] += initial_state[13];
|
||||||
|
working_state[14] += initial_state[14];
|
||||||
|
working_state[15] += initial_state[15];
|
||||||
|
|
||||||
|
for( i = 0U; i < 16; i++ )
|
||||||
|
{
|
||||||
|
size_t offset = i * 4U;
|
||||||
|
|
||||||
|
keystream[offset ] = (unsigned char)( working_state[i] );
|
||||||
|
keystream[offset + 1U] = (unsigned char)( working_state[i] >> 8 );
|
||||||
|
keystream[offset + 2U] = (unsigned char)( working_state[i] >> 16 );
|
||||||
|
keystream[offset + 3U] = (unsigned char)( working_state[i] >> 24 );
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_platform_zeroize( working_state, sizeof( working_state ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx )
|
||||||
|
{
|
||||||
|
CHACHA20_VALIDATE( ctx != NULL );
|
||||||
|
|
||||||
|
mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
|
||||||
|
mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
|
||||||
|
|
||||||
|
/* Initially, there's no keystream bytes available */
|
||||||
|
ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx )
|
||||||
|
{
|
||||||
|
if( ctx != NULL )
|
||||||
|
{
|
||||||
|
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
|
||||||
|
const unsigned char key[32] )
|
||||||
|
{
|
||||||
|
CHACHA20_VALIDATE_RET( ctx != NULL );
|
||||||
|
CHACHA20_VALIDATE_RET( key != NULL );
|
||||||
|
|
||||||
|
/* ChaCha20 constants - the string "expand 32-byte k" */
|
||||||
|
ctx->state[0] = 0x61707865;
|
||||||
|
ctx->state[1] = 0x3320646e;
|
||||||
|
ctx->state[2] = 0x79622d32;
|
||||||
|
ctx->state[3] = 0x6b206574;
|
||||||
|
|
||||||
|
/* Set key */
|
||||||
|
ctx->state[4] = BYTES_TO_U32_LE( key, 0 );
|
||||||
|
ctx->state[5] = BYTES_TO_U32_LE( key, 4 );
|
||||||
|
ctx->state[6] = BYTES_TO_U32_LE( key, 8 );
|
||||||
|
ctx->state[7] = BYTES_TO_U32_LE( key, 12 );
|
||||||
|
ctx->state[8] = BYTES_TO_U32_LE( key, 16 );
|
||||||
|
ctx->state[9] = BYTES_TO_U32_LE( key, 20 );
|
||||||
|
ctx->state[10] = BYTES_TO_U32_LE( key, 24 );
|
||||||
|
ctx->state[11] = BYTES_TO_U32_LE( key, 28 );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
|
||||||
|
const unsigned char nonce[12],
|
||||||
|
uint32_t counter )
|
||||||
|
{
|
||||||
|
CHACHA20_VALIDATE_RET( ctx != NULL );
|
||||||
|
CHACHA20_VALIDATE_RET( nonce != NULL );
|
||||||
|
|
||||||
|
/* Counter */
|
||||||
|
ctx->state[12] = counter;
|
||||||
|
|
||||||
|
/* Nonce */
|
||||||
|
ctx->state[13] = BYTES_TO_U32_LE( nonce, 0 );
|
||||||
|
ctx->state[14] = BYTES_TO_U32_LE( nonce, 4 );
|
||||||
|
ctx->state[15] = BYTES_TO_U32_LE( nonce, 8 );
|
||||||
|
|
||||||
|
mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
|
||||||
|
|
||||||
|
/* Initially, there's no keystream bytes available */
|
||||||
|
ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
|
||||||
|
size_t size,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output )
|
||||||
|
{
|
||||||
|
size_t offset = 0U;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
CHACHA20_VALIDATE_RET( ctx != NULL );
|
||||||
|
CHACHA20_VALIDATE_RET( size == 0 || input != NULL );
|
||||||
|
CHACHA20_VALIDATE_RET( size == 0 || output != NULL );
|
||||||
|
|
||||||
|
/* Use leftover keystream bytes, if available */
|
||||||
|
while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES )
|
||||||
|
{
|
||||||
|
output[offset] = input[offset]
|
||||||
|
^ ctx->keystream8[ctx->keystream_bytes_used];
|
||||||
|
|
||||||
|
ctx->keystream_bytes_used++;
|
||||||
|
offset++;
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process full blocks */
|
||||||
|
while( size >= CHACHA20_BLOCK_SIZE_BYTES )
|
||||||
|
{
|
||||||
|
/* Generate new keystream block and increment counter */
|
||||||
|
chacha20_block( ctx->state, ctx->keystream8 );
|
||||||
|
ctx->state[CHACHA20_CTR_INDEX]++;
|
||||||
|
|
||||||
|
for( i = 0U; i < 64U; i += 8U )
|
||||||
|
{
|
||||||
|
output[offset + i ] = input[offset + i ] ^ ctx->keystream8[i ];
|
||||||
|
output[offset + i+1] = input[offset + i+1] ^ ctx->keystream8[i+1];
|
||||||
|
output[offset + i+2] = input[offset + i+2] ^ ctx->keystream8[i+2];
|
||||||
|
output[offset + i+3] = input[offset + i+3] ^ ctx->keystream8[i+3];
|
||||||
|
output[offset + i+4] = input[offset + i+4] ^ ctx->keystream8[i+4];
|
||||||
|
output[offset + i+5] = input[offset + i+5] ^ ctx->keystream8[i+5];
|
||||||
|
output[offset + i+6] = input[offset + i+6] ^ ctx->keystream8[i+6];
|
||||||
|
output[offset + i+7] = input[offset + i+7] ^ ctx->keystream8[i+7];
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += CHACHA20_BLOCK_SIZE_BYTES;
|
||||||
|
size -= CHACHA20_BLOCK_SIZE_BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Last (partial) block */
|
||||||
|
if( size > 0U )
|
||||||
|
{
|
||||||
|
/* Generate new keystream block and increment counter */
|
||||||
|
chacha20_block( ctx->state, ctx->keystream8 );
|
||||||
|
ctx->state[CHACHA20_CTR_INDEX]++;
|
||||||
|
|
||||||
|
for( i = 0U; i < size; i++)
|
||||||
|
{
|
||||||
|
output[offset + i] = input[offset + i] ^ ctx->keystream8[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->keystream_bytes_used = size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_chacha20_crypt( const unsigned char key[32],
|
||||||
|
const unsigned char nonce[12],
|
||||||
|
uint32_t counter,
|
||||||
|
size_t data_len,
|
||||||
|
const unsigned char* input,
|
||||||
|
unsigned char* output )
|
||||||
|
{
|
||||||
|
mbedtls_chacha20_context ctx;
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
|
CHACHA20_VALIDATE_RET( key != NULL );
|
||||||
|
CHACHA20_VALIDATE_RET( nonce != NULL );
|
||||||
|
CHACHA20_VALIDATE_RET( data_len == 0 || input != NULL );
|
||||||
|
CHACHA20_VALIDATE_RET( data_len == 0 || output != NULL );
|
||||||
|
|
||||||
|
mbedtls_chacha20_init( &ctx );
|
||||||
|
|
||||||
|
ret = mbedtls_chacha20_setkey( &ctx, key );
|
||||||
|
if( ret != 0 )
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = mbedtls_chacha20_starts( &ctx, nonce, counter );
|
||||||
|
if( ret != 0 )
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = mbedtls_chacha20_update( &ctx, data_len, input, output );
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
mbedtls_chacha20_free( &ctx );
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !MBEDTLS_CHACHA20_ALT */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
|
||||||
|
static const unsigned char test_keys[2][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
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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, 0x01
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char test_nonces[2][12] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x02
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint32_t test_counters[2] =
|
||||||
|
{
|
||||||
|
0U,
|
||||||
|
1U
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char test_input[2][375] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
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
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d,
|
||||||
|
0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74,
|
||||||
|
0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45,
|
||||||
|
0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e,
|
||||||
|
0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
|
||||||
|
0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72,
|
||||||
|
0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66,
|
||||||
|
0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69,
|
||||||
|
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
|
||||||
|
0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72,
|
||||||
|
0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66,
|
||||||
|
0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46,
|
||||||
|
0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
|
||||||
|
0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20,
|
||||||
|
0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61,
|
||||||
|
0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73,
|
||||||
|
0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
||||||
|
0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69,
|
||||||
|
0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
|
||||||
|
0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
|
||||||
|
0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49,
|
||||||
|
0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69,
|
||||||
|
0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20,
|
||||||
|
0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72,
|
||||||
|
0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49,
|
||||||
|
0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74,
|
||||||
|
0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
|
||||||
|
0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20,
|
||||||
|
0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
|
||||||
|
0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75,
|
||||||
|
0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20,
|
||||||
|
0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
|
||||||
|
0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45,
|
||||||
|
0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69,
|
||||||
|
0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20,
|
||||||
|
0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20,
|
||||||
|
0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20,
|
||||||
|
0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63,
|
||||||
|
0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,
|
||||||
|
0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61,
|
||||||
|
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61,
|
||||||
|
0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e,
|
||||||
|
0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,
|
||||||
|
0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c,
|
||||||
|
0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61,
|
||||||
|
0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65,
|
||||||
|
0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char test_output[2][375] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
|
||||||
|
0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
|
||||||
|
0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
|
||||||
|
0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
|
||||||
|
0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
|
||||||
|
0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
|
||||||
|
0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
|
||||||
|
0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde,
|
||||||
|
0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70,
|
||||||
|
0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd,
|
||||||
|
0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec,
|
||||||
|
0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15,
|
||||||
|
0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05,
|
||||||
|
0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f,
|
||||||
|
0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d,
|
||||||
|
0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa,
|
||||||
|
0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e,
|
||||||
|
0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7,
|
||||||
|
0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50,
|
||||||
|
0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05,
|
||||||
|
0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c,
|
||||||
|
0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05,
|
||||||
|
0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a,
|
||||||
|
0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0,
|
||||||
|
0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66,
|
||||||
|
0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4,
|
||||||
|
0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d,
|
||||||
|
0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91,
|
||||||
|
0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28,
|
||||||
|
0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87,
|
||||||
|
0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b,
|
||||||
|
0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2,
|
||||||
|
0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f,
|
||||||
|
0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76,
|
||||||
|
0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c,
|
||||||
|
0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b,
|
||||||
|
0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84,
|
||||||
|
0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd,
|
||||||
|
0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b,
|
||||||
|
0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe,
|
||||||
|
0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0,
|
||||||
|
0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80,
|
||||||
|
0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f,
|
||||||
|
0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3,
|
||||||
|
0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62,
|
||||||
|
0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91,
|
||||||
|
0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6,
|
||||||
|
0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64,
|
||||||
|
0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85,
|
||||||
|
0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41,
|
||||||
|
0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab,
|
||||||
|
0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba,
|
||||||
|
0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd,
|
||||||
|
0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const size_t test_lengths[2] =
|
||||||
|
{
|
||||||
|
64U,
|
||||||
|
375U
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Make sure no other definition is already present. */
|
||||||
|
#undef ASSERT
|
||||||
|
|
||||||
|
#define ASSERT( cond, args ) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if( ! ( cond ) ) \
|
||||||
|
{ \
|
||||||
|
if( verbose != 0 ) \
|
||||||
|
mbedtls_printf args; \
|
||||||
|
\
|
||||||
|
return( -1 ); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
while( 0 )
|
||||||
|
|
||||||
|
int mbedtls_chacha20_self_test( int verbose )
|
||||||
|
{
|
||||||
|
unsigned char output[381];
|
||||||
|
unsigned i;
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
|
for( i = 0U; i < 2U; i++ )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( " ChaCha20 test %u ", i );
|
||||||
|
|
||||||
|
ret = mbedtls_chacha20_crypt( test_keys[i],
|
||||||
|
test_nonces[i],
|
||||||
|
test_counters[i],
|
||||||
|
test_lengths[i],
|
||||||
|
test_input[i],
|
||||||
|
output );
|
||||||
|
|
||||||
|
ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
|
||||||
|
|
||||||
|
ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ),
|
||||||
|
( "failed (output)\n" ) );
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( "passed\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( "\n" );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
|
#endif /* !MBEDTLS_CHACHA20_C */
|
||||||
225
common/mbedtls/chacha20.h
Normal file
225
common/mbedtls/chacha20.h
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
/**
|
||||||
|
* \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 The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MBEDTLS_CHACHA20_H
|
||||||
|
#define MBEDTLS_CHACHA20_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/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 */
|
||||||
538
common/mbedtls/chachapoly.c
Normal file
538
common/mbedtls/chachapoly.c
Normal file
@@ -0,0 +1,538 @@
|
|||||||
|
/**
|
||||||
|
* \file chachapoly.c
|
||||||
|
*
|
||||||
|
* \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539.
|
||||||
|
*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_CHACHAPOLY_C)
|
||||||
|
|
||||||
|
#include "mbedtls/chachapoly.h"
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
#if defined(MBEDTLS_PLATFORM_C)
|
||||||
|
#include "mbedtls/platform.h"
|
||||||
|
#else
|
||||||
|
#include <stdio.h>
|
||||||
|
#define mbedtls_printf printf
|
||||||
|
#endif /* MBEDTLS_PLATFORM_C */
|
||||||
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CHACHAPOLY_ALT)
|
||||||
|
|
||||||
|
/* Parameter validation macros */
|
||||||
|
#define CHACHAPOLY_VALIDATE_RET( cond ) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
|
||||||
|
#define CHACHAPOLY_VALIDATE( cond ) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||||
|
|
||||||
|
#define CHACHAPOLY_STATE_INIT ( 0 )
|
||||||
|
#define CHACHAPOLY_STATE_AAD ( 1 )
|
||||||
|
#define CHACHAPOLY_STATE_CIPHERTEXT ( 2 ) /* Encrypting or decrypting */
|
||||||
|
#define CHACHAPOLY_STATE_FINISHED ( 3 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Adds nul bytes to pad the AAD for Poly1305.
|
||||||
|
*
|
||||||
|
* \param ctx The ChaCha20-Poly1305 context.
|
||||||
|
*/
|
||||||
|
static int chachapoly_pad_aad( mbedtls_chachapoly_context *ctx )
|
||||||
|
{
|
||||||
|
uint32_t partial_block_len = (uint32_t) ( ctx->aad_len % 16U );
|
||||||
|
unsigned char zeroes[15];
|
||||||
|
|
||||||
|
if( partial_block_len == 0U )
|
||||||
|
return( 0 );
|
||||||
|
|
||||||
|
memset( zeroes, 0, sizeof( zeroes ) );
|
||||||
|
|
||||||
|
return( mbedtls_poly1305_update( &ctx->poly1305_ctx,
|
||||||
|
zeroes,
|
||||||
|
16U - partial_block_len ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Adds nul bytes to pad the ciphertext for Poly1305.
|
||||||
|
*
|
||||||
|
* \param ctx The ChaCha20-Poly1305 context.
|
||||||
|
*/
|
||||||
|
static int chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx )
|
||||||
|
{
|
||||||
|
uint32_t partial_block_len = (uint32_t) ( ctx->ciphertext_len % 16U );
|
||||||
|
unsigned char zeroes[15];
|
||||||
|
|
||||||
|
if( partial_block_len == 0U )
|
||||||
|
return( 0 );
|
||||||
|
|
||||||
|
memset( zeroes, 0, sizeof( zeroes ) );
|
||||||
|
return( mbedtls_poly1305_update( &ctx->poly1305_ctx,
|
||||||
|
zeroes,
|
||||||
|
16U - partial_block_len ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx )
|
||||||
|
{
|
||||||
|
CHACHAPOLY_VALIDATE( ctx != NULL );
|
||||||
|
|
||||||
|
mbedtls_chacha20_init( &ctx->chacha20_ctx );
|
||||||
|
mbedtls_poly1305_init( &ctx->poly1305_ctx );
|
||||||
|
ctx->aad_len = 0U;
|
||||||
|
ctx->ciphertext_len = 0U;
|
||||||
|
ctx->state = CHACHAPOLY_STATE_INIT;
|
||||||
|
ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx )
|
||||||
|
{
|
||||||
|
if( ctx == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
mbedtls_chacha20_free( &ctx->chacha20_ctx );
|
||||||
|
mbedtls_poly1305_free( &ctx->poly1305_ctx );
|
||||||
|
ctx->aad_len = 0U;
|
||||||
|
ctx->ciphertext_len = 0U;
|
||||||
|
ctx->state = CHACHAPOLY_STATE_INIT;
|
||||||
|
ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
|
||||||
|
const unsigned char key[32] )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
|
||||||
|
CHACHAPOLY_VALIDATE_RET( key != NULL );
|
||||||
|
|
||||||
|
ret = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key );
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx,
|
||||||
|
const unsigned char nonce[12],
|
||||||
|
mbedtls_chachapoly_mode_t mode )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
unsigned char poly1305_key[64];
|
||||||
|
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
|
||||||
|
CHACHAPOLY_VALIDATE_RET( nonce != NULL );
|
||||||
|
|
||||||
|
/* Set counter = 0, will be update to 1 when generating Poly1305 key */
|
||||||
|
ret = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 0U );
|
||||||
|
if( ret != 0 )
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
/* Generate the Poly1305 key by getting the ChaCha20 keystream output with
|
||||||
|
* counter = 0. This is the same as encrypting a buffer of zeroes.
|
||||||
|
* Only the first 256-bits (32 bytes) of the key is used for Poly1305.
|
||||||
|
* The other 256 bits are discarded.
|
||||||
|
*/
|
||||||
|
memset( poly1305_key, 0, sizeof( poly1305_key ) );
|
||||||
|
ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, sizeof( poly1305_key ),
|
||||||
|
poly1305_key, poly1305_key );
|
||||||
|
if( ret != 0 )
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = mbedtls_poly1305_starts( &ctx->poly1305_ctx, poly1305_key );
|
||||||
|
|
||||||
|
if( ret == 0 )
|
||||||
|
{
|
||||||
|
ctx->aad_len = 0U;
|
||||||
|
ctx->ciphertext_len = 0U;
|
||||||
|
ctx->state = CHACHAPOLY_STATE_AAD;
|
||||||
|
ctx->mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
mbedtls_platform_zeroize( poly1305_key, 64U );
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx,
|
||||||
|
const unsigned char *aad,
|
||||||
|
size_t aad_len )
|
||||||
|
{
|
||||||
|
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
|
||||||
|
CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL );
|
||||||
|
|
||||||
|
if( ctx->state != CHACHAPOLY_STATE_AAD )
|
||||||
|
return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
|
||||||
|
|
||||||
|
ctx->aad_len += aad_len;
|
||||||
|
|
||||||
|
return( mbedtls_poly1305_update( &ctx->poly1305_ctx, aad, aad_len ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,
|
||||||
|
size_t len,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
|
||||||
|
CHACHAPOLY_VALIDATE_RET( len == 0 || input != NULL );
|
||||||
|
CHACHAPOLY_VALIDATE_RET( len == 0 || output != NULL );
|
||||||
|
|
||||||
|
if( ( ctx->state != CHACHAPOLY_STATE_AAD ) &&
|
||||||
|
( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ctx->state == CHACHAPOLY_STATE_AAD )
|
||||||
|
{
|
||||||
|
ctx->state = CHACHAPOLY_STATE_CIPHERTEXT;
|
||||||
|
|
||||||
|
ret = chachapoly_pad_aad( ctx );
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->ciphertext_len += len;
|
||||||
|
|
||||||
|
if( ctx->mode == MBEDTLS_CHACHAPOLY_ENCRYPT )
|
||||||
|
{
|
||||||
|
ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output );
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, output, len );
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
else /* DECRYPT */
|
||||||
|
{
|
||||||
|
ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, input, len );
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output );
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
|
||||||
|
unsigned char mac[16] )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
unsigned char len_block[16];
|
||||||
|
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
|
||||||
|
CHACHAPOLY_VALIDATE_RET( mac != NULL );
|
||||||
|
|
||||||
|
if( ctx->state == CHACHAPOLY_STATE_INIT )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ctx->state == CHACHAPOLY_STATE_AAD )
|
||||||
|
{
|
||||||
|
ret = chachapoly_pad_aad( ctx );
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
else if( ctx->state == CHACHAPOLY_STATE_CIPHERTEXT )
|
||||||
|
{
|
||||||
|
ret = chachapoly_pad_ciphertext( ctx );
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->state = CHACHAPOLY_STATE_FINISHED;
|
||||||
|
|
||||||
|
/* The lengths of the AAD and ciphertext are processed by
|
||||||
|
* Poly1305 as the final 128-bit block, encoded as little-endian integers.
|
||||||
|
*/
|
||||||
|
len_block[ 0] = (unsigned char)( ctx->aad_len );
|
||||||
|
len_block[ 1] = (unsigned char)( ctx->aad_len >> 8 );
|
||||||
|
len_block[ 2] = (unsigned char)( ctx->aad_len >> 16 );
|
||||||
|
len_block[ 3] = (unsigned char)( ctx->aad_len >> 24 );
|
||||||
|
len_block[ 4] = (unsigned char)( ctx->aad_len >> 32 );
|
||||||
|
len_block[ 5] = (unsigned char)( ctx->aad_len >> 40 );
|
||||||
|
len_block[ 6] = (unsigned char)( ctx->aad_len >> 48 );
|
||||||
|
len_block[ 7] = (unsigned char)( ctx->aad_len >> 56 );
|
||||||
|
len_block[ 8] = (unsigned char)( ctx->ciphertext_len );
|
||||||
|
len_block[ 9] = (unsigned char)( ctx->ciphertext_len >> 8 );
|
||||||
|
len_block[10] = (unsigned char)( ctx->ciphertext_len >> 16 );
|
||||||
|
len_block[11] = (unsigned char)( ctx->ciphertext_len >> 24 );
|
||||||
|
len_block[12] = (unsigned char)( ctx->ciphertext_len >> 32 );
|
||||||
|
len_block[13] = (unsigned char)( ctx->ciphertext_len >> 40 );
|
||||||
|
len_block[14] = (unsigned char)( ctx->ciphertext_len >> 48 );
|
||||||
|
len_block[15] = (unsigned char)( ctx->ciphertext_len >> 56 );
|
||||||
|
|
||||||
|
ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, len_block, 16U );
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
ret = mbedtls_poly1305_finish( &ctx->poly1305_ctx, mac );
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx,
|
||||||
|
mbedtls_chachapoly_mode_t mode,
|
||||||
|
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] )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
|
ret = mbedtls_chachapoly_starts( ctx, nonce, mode );
|
||||||
|
if( ret != 0 )
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = mbedtls_chachapoly_update_aad( ctx, aad, aad_len );
|
||||||
|
if( ret != 0 )
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = mbedtls_chachapoly_update( ctx, length, input, output );
|
||||||
|
if( ret != 0 )
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = mbedtls_chachapoly_finish( ctx, tag );
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
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] )
|
||||||
|
{
|
||||||
|
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
|
||||||
|
CHACHAPOLY_VALIDATE_RET( nonce != NULL );
|
||||||
|
CHACHAPOLY_VALIDATE_RET( tag != NULL );
|
||||||
|
CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL );
|
||||||
|
CHACHAPOLY_VALIDATE_RET( length == 0 || input != NULL );
|
||||||
|
CHACHAPOLY_VALIDATE_RET( length == 0 || output != NULL );
|
||||||
|
|
||||||
|
return( chachapoly_crypt_and_tag( ctx, MBEDTLS_CHACHAPOLY_ENCRYPT,
|
||||||
|
length, nonce, aad, aad_len,
|
||||||
|
input, output, tag ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
unsigned char check_tag[16];
|
||||||
|
size_t i;
|
||||||
|
int diff;
|
||||||
|
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
|
||||||
|
CHACHAPOLY_VALIDATE_RET( nonce != NULL );
|
||||||
|
CHACHAPOLY_VALIDATE_RET( tag != NULL );
|
||||||
|
CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL );
|
||||||
|
CHACHAPOLY_VALIDATE_RET( length == 0 || input != NULL );
|
||||||
|
CHACHAPOLY_VALIDATE_RET( length == 0 || output != NULL );
|
||||||
|
|
||||||
|
if( ( ret = chachapoly_crypt_and_tag( ctx,
|
||||||
|
MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce,
|
||||||
|
aad, aad_len, input, output, check_tag ) ) != 0 )
|
||||||
|
{
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check tag in "constant-time" */
|
||||||
|
for( diff = 0, i = 0; i < sizeof( check_tag ); i++ )
|
||||||
|
diff |= tag[i] ^ check_tag[i];
|
||||||
|
|
||||||
|
if( diff != 0 )
|
||||||
|
{
|
||||||
|
mbedtls_platform_zeroize( output, length );
|
||||||
|
return( MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_CHACHAPOLY_ALT */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
|
||||||
|
static const unsigned char test_key[1][32] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
||||||
|
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||||
|
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
||||||
|
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char test_nonce[1][12] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
0x07, 0x00, 0x00, 0x00, /* 32-bit common part */
|
||||||
|
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 /* 64-bit IV */
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char test_aad[1][12] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3,
|
||||||
|
0xc4, 0xc5, 0xc6, 0xc7
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const size_t test_aad_len[1] =
|
||||||
|
{
|
||||||
|
12U
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char test_input[1][114] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61,
|
||||||
|
0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c,
|
||||||
|
0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20,
|
||||||
|
0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73,
|
||||||
|
0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39,
|
||||||
|
0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63,
|
||||||
|
0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66,
|
||||||
|
0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f,
|
||||||
|
0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20,
|
||||||
|
0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20,
|
||||||
|
0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75,
|
||||||
|
0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73,
|
||||||
|
0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f,
|
||||||
|
0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69,
|
||||||
|
0x74, 0x2e
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char test_output[1][114] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb,
|
||||||
|
0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2,
|
||||||
|
0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe,
|
||||||
|
0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6,
|
||||||
|
0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12,
|
||||||
|
0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b,
|
||||||
|
0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29,
|
||||||
|
0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36,
|
||||||
|
0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c,
|
||||||
|
0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58,
|
||||||
|
0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94,
|
||||||
|
0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc,
|
||||||
|
0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d,
|
||||||
|
0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b,
|
||||||
|
0x61, 0x16
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const size_t test_input_len[1] =
|
||||||
|
{
|
||||||
|
114U
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char test_mac[1][16] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a,
|
||||||
|
0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Make sure no other definition is already present. */
|
||||||
|
#undef ASSERT
|
||||||
|
|
||||||
|
#define ASSERT( cond, args ) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if( ! ( cond ) ) \
|
||||||
|
{ \
|
||||||
|
if( verbose != 0 ) \
|
||||||
|
mbedtls_printf args; \
|
||||||
|
\
|
||||||
|
return( -1 ); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
while( 0 )
|
||||||
|
|
||||||
|
int mbedtls_chachapoly_self_test( int verbose )
|
||||||
|
{
|
||||||
|
mbedtls_chachapoly_context ctx;
|
||||||
|
unsigned i;
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
unsigned char output[200];
|
||||||
|
unsigned char mac[16];
|
||||||
|
|
||||||
|
for( i = 0U; i < 1U; i++ )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( " ChaCha20-Poly1305 test %u ", i );
|
||||||
|
|
||||||
|
mbedtls_chachapoly_init( &ctx );
|
||||||
|
|
||||||
|
ret = mbedtls_chachapoly_setkey( &ctx, test_key[i] );
|
||||||
|
ASSERT( 0 == ret, ( "setkey() error code: %i\n", ret ) );
|
||||||
|
|
||||||
|
ret = mbedtls_chachapoly_encrypt_and_tag( &ctx,
|
||||||
|
test_input_len[i],
|
||||||
|
test_nonce[i],
|
||||||
|
test_aad[i],
|
||||||
|
test_aad_len[i],
|
||||||
|
test_input[i],
|
||||||
|
output,
|
||||||
|
mac );
|
||||||
|
|
||||||
|
ASSERT( 0 == ret, ( "crypt_and_tag() error code: %i\n", ret ) );
|
||||||
|
|
||||||
|
ASSERT( 0 == memcmp( output, test_output[i], test_input_len[i] ),
|
||||||
|
( "failure (wrong output)\n" ) );
|
||||||
|
|
||||||
|
ASSERT( 0 == memcmp( mac, test_mac[i], 16U ),
|
||||||
|
( "failure (wrong MAC)\n" ) );
|
||||||
|
|
||||||
|
mbedtls_chachapoly_free( &ctx );
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( "passed\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( "\n" );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_CHACHAPOLY_C */
|
||||||
357
common/mbedtls/chachapoly.h
Normal file
357
common/mbedtls/chachapoly.h
Normal file
@@ -0,0 +1,357 @@
|
|||||||
|
/**
|
||||||
|
* \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 The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MBEDTLS_CHACHAPOLY_H
|
||||||
|
#define MBEDTLS_CHACHAPOLY_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* for shared error codes */
|
||||||
|
#include "mbedtls/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 "mbedtls/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,24 +4,20 @@
|
|||||||
* \brief Consistency checks for configuration options
|
* \brief Consistency checks for configuration options
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -47,11 +43,16 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Fix the config here. Not convenient to put an #ifdef _WIN32 in config.h as
|
/* Fix the config here. Not convenient to put an #ifdef _WIN32 in config.h as
|
||||||
* it would confuse config.pl. */
|
* it would confuse config.py. */
|
||||||
#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \
|
#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \
|
||||||
!defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
|
!defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
|
||||||
#define MBEDTLS_PLATFORM_SNPRINTF_ALT
|
#define MBEDTLS_PLATFORM_SNPRINTF_ALT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) && \
|
||||||
|
!defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
|
||||||
|
#define MBEDTLS_PLATFORM_VSNPRINTF_ALT
|
||||||
|
#endif
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
#if defined(TARGET_LIKE_MBED) && \
|
#if defined(TARGET_LIKE_MBED) && \
|
||||||
@@ -100,6 +101,17 @@
|
|||||||
|
|
||||||
#if defined(MBEDTLS_ECDSA_C) && \
|
#if defined(MBEDTLS_ECDSA_C) && \
|
||||||
( !defined(MBEDTLS_ECP_C) || \
|
( !defined(MBEDTLS_ECP_C) || \
|
||||||
|
!( 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_SECP192K1_ENABLED) || \
|
||||||
|
defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
|
||||||
|
defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) || \
|
||||||
|
defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
|
||||||
|
defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
|
||||||
|
defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) ) || \
|
||||||
!defined(MBEDTLS_ASN1_PARSE_C) || \
|
!defined(MBEDTLS_ASN1_PARSE_C) || \
|
||||||
!defined(MBEDTLS_ASN1_WRITE_C) )
|
!defined(MBEDTLS_ASN1_WRITE_C) )
|
||||||
#error "MBEDTLS_ECDSA_C defined, but not all prerequisites"
|
#error "MBEDTLS_ECDSA_C defined, but not all prerequisites"
|
||||||
@@ -110,12 +122,33 @@
|
|||||||
#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites"
|
#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE) && \
|
||||||
|
( defined(MBEDTLS_USE_PSA_CRYPTO) || \
|
||||||
|
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 or PSA-based ECP implementation"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE) && \
|
||||||
|
! defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||||
|
#error "MBEDTLS_ECP_RESTARTABLE defined, but not MBEDTLS_ECDH_LEGACY_CONTEXT"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) && \
|
||||||
|
defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||||
|
#error "MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED defined, but MBEDTLS_ECDH_LEGACY_CONTEXT not disabled"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C)
|
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C)
|
||||||
#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites"
|
#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \
|
#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \
|
||||||
!defined(MBEDTLS_ECP_DP_SECP128R1_ENABLED) && \
|
|
||||||
!defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \
|
!defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \
|
||||||
!defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \
|
!defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \
|
||||||
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \
|
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \
|
||||||
@@ -126,10 +159,24 @@
|
|||||||
!defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \
|
!defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \
|
||||||
!defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \
|
!defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \
|
||||||
!defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \
|
!defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \
|
||||||
!defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) )
|
!defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) && \
|
||||||
|
!defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) && \
|
||||||
|
!defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) ) )
|
||||||
#error "MBEDTLS_ECP_C defined, but not all prerequisites"
|
#error "MBEDTLS_ECP_C defined, but not all prerequisites"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_C) && !( \
|
||||||
|
defined(MBEDTLS_ECP_ALT) || \
|
||||||
|
defined(MBEDTLS_CTR_DRBG_C) || \
|
||||||
|
defined(MBEDTLS_HMAC_DRBG_C) || \
|
||||||
|
defined(MBEDTLS_ECP_NO_INTERNAL_RNG))
|
||||||
|
#error "MBEDTLS_ECP_C requires a DRBG module unless MBEDTLS_ECP_NO_INTERNAL_RNG is defined or an alternative implementation is used"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C)
|
||||||
|
#error "MBEDTLS_PK_PARSE_C defined, but not all prerequesites"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) && \
|
#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) && \
|
||||||
!defined(MBEDTLS_SHA256_C))
|
!defined(MBEDTLS_SHA256_C))
|
||||||
#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites"
|
#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites"
|
||||||
@@ -148,6 +195,16 @@
|
|||||||
#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites"
|
#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__has_feature)
|
||||||
|
#if __has_feature(memory_sanitizer)
|
||||||
|
#define MBEDTLS_HAS_MEMSAN
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) && !defined(MBEDTLS_HAS_MEMSAN)
|
||||||
|
#error "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN requires building with MemorySanitizer"
|
||||||
|
#endif
|
||||||
|
#undef MBEDTLS_HAS_MEMSAN
|
||||||
|
|
||||||
#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
|
#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
|
||||||
( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) )
|
( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) )
|
||||||
#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites"
|
#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites"
|
||||||
@@ -159,7 +216,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_GCM_C) && ( \
|
#if defined(MBEDTLS_GCM_C) && ( \
|
||||||
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) )
|
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) && !defined(MBEDTLS_ARIA_C) )
|
||||||
#error "MBEDTLS_GCM_C defined, but not all prerequisites"
|
#error "MBEDTLS_GCM_C defined, but not all prerequisites"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -195,6 +252,10 @@
|
|||||||
#error "MBEDTLS_ECP_NORMALIZE_MXZ_ALT defined, but not all prerequisites"
|
#error "MBEDTLS_ECP_NORMALIZE_MXZ_ALT defined, but not all prerequisites"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_NO_FALLBACK) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
|
||||||
|
#error "MBEDTLS_ECP_NO_FALLBACK defined, but no alternative implementation enabled"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C)
|
#if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C)
|
||||||
#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites"
|
#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites"
|
||||||
#endif
|
#endif
|
||||||
@@ -208,12 +269,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \
|
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \
|
||||||
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
|
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \
|
||||||
|
!defined(MBEDTLS_X509_CRT_PARSE_C) )
|
||||||
#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
|
#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
|
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
|
||||||
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
|
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \
|
||||||
|
!defined(MBEDTLS_X509_CRT_PARSE_C) )
|
||||||
#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites"
|
#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -262,11 +325,27 @@
|
|||||||
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
|
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
|
||||||
#endif
|
#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 requires MBEDTLS_SHA512_C, MBEDTLS_SHA256_C or MBEDTLS_SHA1_C"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
|
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
|
||||||
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
|
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
|
||||||
#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites"
|
#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites"
|
||||||
#endif
|
#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)
|
#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
|
||||||
#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
|
#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
|
||||||
#endif
|
#endif
|
||||||
@@ -296,6 +375,14 @@
|
|||||||
#error "MBEDTLS_PKCS11_C defined, but not all prerequisites"
|
#error "MBEDTLS_PKCS11_C defined, but not all prerequisites"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PKCS11_C)
|
||||||
|
#if defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
|
#error "MBEDTLS_PKCS11_C is deprecated and will be removed in a future version of Mbed TLS"
|
||||||
|
#elif defined(MBEDTLS_DEPRECATED_WARNING)
|
||||||
|
#warning "MBEDTLS_PKCS11_C is deprecated and will be removed in a future version of Mbed TLS"
|
||||||
|
#endif
|
||||||
|
#endif /* MBEDTLS_PKCS11_C */
|
||||||
|
|
||||||
#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C)
|
#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C)
|
||||||
#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites"
|
#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites"
|
||||||
#endif
|
#endif
|
||||||
@@ -489,6 +576,54 @@
|
|||||||
#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously"
|
#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PSA_CRYPTO_C) && \
|
||||||
|
!( ( ( defined(MBEDTLS_CTR_DRBG_C) || defined(MBEDTLS_HMAC_DRBG_C) ) && \
|
||||||
|
defined(MBEDTLS_ENTROPY_C) ) || \
|
||||||
|
defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) )
|
||||||
|
#error "MBEDTLS_PSA_CRYPTO_C defined, but not all prerequisites (missing RNG)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PSA_CRYPTO_SPM) && !defined(MBEDTLS_PSA_CRYPTO_C)
|
||||||
|
#error "MBEDTLS_PSA_CRYPTO_SPM defined, but not all prerequisites"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PSA_CRYPTO_SE_C) && \
|
||||||
|
! ( defined(MBEDTLS_PSA_CRYPTO_C) && \
|
||||||
|
defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) )
|
||||||
|
#error "MBEDTLS_PSA_CRYPTO_SE_C defined, but not all prerequisites"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \
|
||||||
|
! defined(MBEDTLS_PSA_CRYPTO_C)
|
||||||
|
#error "MBEDTLS_PSA_CRYPTO_STORAGE_C defined, but not all prerequisites"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
|
||||||
|
!( defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \
|
||||||
|
defined(MBEDTLS_ENTROPY_NV_SEED) )
|
||||||
|
#error "MBEDTLS_PSA_INJECT_ENTROPY defined, but not all prerequisites"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
|
||||||
|
!defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
|
||||||
|
#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with actual entropy sources"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
|
||||||
|
defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
|
||||||
|
#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PSA_ITS_FILE_C) && \
|
||||||
|
!defined(MBEDTLS_FS_IO)
|
||||||
|
#error "MBEDTLS_PSA_ITS_FILE_C defined, but not all prerequisites"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) && \
|
||||||
|
defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||||
|
#error "MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined, but it cannot coexist with MBEDTLS_USE_PSA_CRYPTO."
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
|
#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
|
||||||
!defined(MBEDTLS_OID_C) )
|
!defined(MBEDTLS_OID_C) )
|
||||||
#error "MBEDTLS_RSA_C defined, but not all prerequisites"
|
#error "MBEDTLS_RSA_C defined, but not all prerequisites"
|
||||||
@@ -504,6 +639,10 @@
|
|||||||
#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites"
|
#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SHA512_NO_SHA384) && !defined(MBEDTLS_SHA512_C)
|
||||||
|
#error "MBEDTLS_SHA512_NO_SHA384 defined without MBEDTLS_SHA512_C"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_SSL_PROTO_SSL3) && ( !defined(MBEDTLS_MD5_C) || \
|
#if defined(MBEDTLS_SSL_PROTO_SSL3) && ( !defined(MBEDTLS_MD5_C) || \
|
||||||
!defined(MBEDTLS_SHA1_C) )
|
!defined(MBEDTLS_SHA1_C) )
|
||||||
#error "MBEDTLS_SSL_PROTO_SSL3 defined, but not all prerequisites"
|
#error "MBEDTLS_SSL_PROTO_SSL3 defined, but not all prerequisites"
|
||||||
@@ -524,6 +663,28 @@
|
|||||||
#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
|
#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) && ( !defined(MBEDTLS_HKDF_C) && \
|
||||||
|
!defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA512_C) )
|
||||||
|
#error "MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL 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) && \
|
#if defined(MBEDTLS_SSL_PROTO_DTLS) && \
|
||||||
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
|
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
|
||||||
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||||
@@ -579,6 +740,23 @@
|
|||||||
#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites"
|
#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites"
|
||||||
#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_DTLS_BADMAC_LIMIT) && \
|
#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \
|
||||||
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
|
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
|
||||||
#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites"
|
#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites"
|
||||||
@@ -631,6 +809,10 @@
|
|||||||
#endif
|
#endif
|
||||||
#undef MBEDTLS_THREADING_IMPL
|
#undef MBEDTLS_THREADING_IMPL
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_PSA_CRYPTO_C)
|
||||||
|
#error "MBEDTLS_USE_PSA_CRYPTO defined, but not all prerequisites"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C)
|
#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C)
|
||||||
#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites"
|
#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites"
|
||||||
#endif
|
#endif
|
||||||
@@ -647,6 +829,10 @@
|
|||||||
#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites"
|
#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites"
|
||||||
#endif
|
#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) )
|
#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
|
||||||
#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites"
|
#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites"
|
||||||
#endif
|
#endif
|
||||||
@@ -676,10 +862,42 @@
|
|||||||
#error "MBEDTLS_HAVE_INT32/MBEDTLS_HAVE_INT64 and MBEDTLS_HAVE_ASM cannot be defined simultaneously"
|
#error "MBEDTLS_HAVE_INT32/MBEDTLS_HAVE_INT64 and MBEDTLS_HAVE_ASM cannot be defined simultaneously"
|
||||||
#endif /* (MBEDTLS_HAVE_INT32 || MBEDTLS_HAVE_INT64) && MBEDTLS_HAVE_ASM */
|
#endif /* (MBEDTLS_HAVE_INT32 || MBEDTLS_HAVE_INT64) && MBEDTLS_HAVE_ASM */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SSL_PROTO_SSL3)
|
||||||
|
#if defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
|
#error "MBEDTLS_SSL_PROTO_SSL3 is deprecated and will be removed in a future version of Mbed TLS"
|
||||||
|
#elif defined(MBEDTLS_DEPRECATED_WARNING)
|
||||||
|
#warning "MBEDTLS_SSL_PROTO_SSL3 is deprecated and will be removed in a future version of Mbed TLS"
|
||||||
|
#endif
|
||||||
|
#endif /* MBEDTLS_SSL_PROTO_SSL3 */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
|
||||||
|
#if defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
|
#error "MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO is deprecated and will be removed in a future version of Mbed TLS"
|
||||||
|
#elif defined(MBEDTLS_DEPRECATED_WARNING)
|
||||||
|
#warning "MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO is deprecated and will be removed in a future version of Mbed TLS"
|
||||||
|
#endif
|
||||||
|
#endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
|
||||||
|
#if defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
|
#error "MBEDTLS_SSL_HW_RECORD_ACCEL is deprecated and will be removed in a future version of Mbed TLS"
|
||||||
|
#elif defined(MBEDTLS_DEPRECATED_WARNING)
|
||||||
|
#warning "MBEDTLS_SSL_HW_RECORD_ACCEL is deprecated and will be removed in a future version of Mbed TLS"
|
||||||
|
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||||
|
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SSL_DTLS_SRTP) && ( !defined(MBEDTLS_SSL_PROTO_DTLS) )
|
||||||
|
#error "MBEDTLS_SSL_DTLS_SRTP defined, but not all prerequisites"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) && ( !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) )
|
||||||
|
#error "MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH defined, but not all prerequisites"
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Avoid warning from -pedantic. This is a convenient place for this
|
* Avoid warning from -pedantic. This is a convenient place for this
|
||||||
* workaround since this is included by every single file before the
|
* workaround since this is included by every single file before the
|
||||||
* #if defined(MBEDTLS_xxx_C) that results in emtpy translation units.
|
* #if defined(MBEDTLS_xxx_C) that results in empty translation units.
|
||||||
*/
|
*/
|
||||||
typedef int mbedtls_iso_c_forbids_empty_translation_units;
|
typedef int mbedtls_iso_c_forbids_empty_translation_units;
|
||||||
|
|
||||||
|
|||||||
72
common/mbedtls/check_crypto_config.h
Normal file
72
common/mbedtls/check_crypto_config.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* \file check_crypto_config.h
|
||||||
|
*
|
||||||
|
* \brief Consistency checks for PSA configuration options
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It is recommended to include this file from your crypto_config.h
|
||||||
|
* in order to catch dependency issues early.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MBEDTLS_CHECK_CRYPTO_CONFIG_H
|
||||||
|
#define MBEDTLS_CHECK_CRYPTO_CONFIG_H
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA) && \
|
||||||
|
!( defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) || \
|
||||||
|
defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) )
|
||||||
|
#error "PSA_WANT_ALG_DETERMINISTIC_ECDSA defined, but not all prerequisites"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_ECDSA) && \
|
||||||
|
!( defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) || \
|
||||||
|
defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) )
|
||||||
|
#error "PSA_WANT_ALG_ECDSA defined, but not all prerequisites"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT) && \
|
||||||
|
!( defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) || \
|
||||||
|
defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) )
|
||||||
|
#error "PSA_WANT_ALG_RSA_PKCS1V15_CRYPT defined, but not all prerequisites"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN) && \
|
||||||
|
!( defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) || \
|
||||||
|
defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) )
|
||||||
|
#error "PSA_WANT_ALG_RSA_PKCS1V15_SIGN defined, but not all prerequisites"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_RSA_OAEP) && \
|
||||||
|
!( defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) || \
|
||||||
|
defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) )
|
||||||
|
#error "PSA_WANT_ALG_RSA_OAEP defined, but not all prerequisites"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_RSA_PSS) && \
|
||||||
|
!( defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) || \
|
||||||
|
defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) )
|
||||||
|
#error "PSA_WANT_ALG_RSA_PSS defined, but not all prerequisites"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) && \
|
||||||
|
!defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||||
|
#error "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR defined, but not all prerequisites"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_CHECK_CRYPTO_CONFIG_H */
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -8,36 +8,33 @@
|
|||||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of Mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MBEDTLS_CIPHER_H
|
#ifndef MBEDTLS_CIPHER_H
|
||||||
#define MBEDTLS_CIPHER_H
|
#define MBEDTLS_CIPHER_H
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
#include "config.h"
|
#include "mbedtls/config.h"
|
||||||
#else
|
#else
|
||||||
#include MBEDTLS_CONFIG_FILE
|
#include MBEDTLS_CONFIG_FILE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include "mbedtls/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) || defined(MBEDTLS_CHACHAPOLY_C)
|
||||||
#define MBEDTLS_CIPHER_MODE_AEAD
|
#define MBEDTLS_CIPHER_MODE_AEAD
|
||||||
@@ -64,6 +61,8 @@
|
|||||||
#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */
|
#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_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. */
|
#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_ERR_CIPHER_HW_ACCEL_FAILED -0x6400 /**< Cipher hardware accelerator failed. */
|
||||||
|
|
||||||
#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length. */
|
#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length. */
|
||||||
@@ -175,21 +174,29 @@ typedef enum {
|
|||||||
MBEDTLS_CIPHER_AES_256_XTS, /**< AES 256-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, /**< ChaCha20 stream cipher. */
|
||||||
MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< ChaCha20-Poly1305 AEAD cipher. */
|
MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< ChaCha20-Poly1305 AEAD cipher. */
|
||||||
|
MBEDTLS_CIPHER_AES_128_KW, /**< AES cipher with 128-bit NIST KW mode. */
|
||||||
|
MBEDTLS_CIPHER_AES_192_KW, /**< AES cipher with 192-bit NIST KW mode. */
|
||||||
|
MBEDTLS_CIPHER_AES_256_KW, /**< AES cipher with 256-bit NIST KW mode. */
|
||||||
|
MBEDTLS_CIPHER_AES_128_KWP, /**< AES cipher with 128-bit NIST KWP mode. */
|
||||||
|
MBEDTLS_CIPHER_AES_192_KWP, /**< AES cipher with 192-bit NIST KWP mode. */
|
||||||
|
MBEDTLS_CIPHER_AES_256_KWP, /**< AES cipher with 256-bit NIST KWP mode. */
|
||||||
} mbedtls_cipher_type_t;
|
} mbedtls_cipher_type_t;
|
||||||
|
|
||||||
/** Supported cipher modes. */
|
/** Supported cipher modes. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
MBEDTLS_MODE_NONE = 0, /**< None. */
|
MBEDTLS_MODE_NONE = 0, /**< None. */
|
||||||
MBEDTLS_MODE_ECB, /**< The ECB cipher mode. */
|
MBEDTLS_MODE_ECB, /**< The ECB cipher mode. */
|
||||||
MBEDTLS_MODE_CBC, /**< The CBC cipher mode. */
|
MBEDTLS_MODE_CBC, /**< The CBC cipher mode. */
|
||||||
MBEDTLS_MODE_CFB, /**< The CFB cipher mode. */
|
MBEDTLS_MODE_CFB, /**< The CFB cipher mode. */
|
||||||
MBEDTLS_MODE_OFB, /**< The OFB cipher mode. */
|
MBEDTLS_MODE_OFB, /**< The OFB cipher mode. */
|
||||||
MBEDTLS_MODE_CTR, /**< The CTR cipher mode. */
|
MBEDTLS_MODE_CTR, /**< The CTR cipher mode. */
|
||||||
MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */
|
MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */
|
||||||
MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */
|
MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */
|
||||||
MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */
|
MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */
|
||||||
MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */
|
MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */
|
||||||
MBEDTLS_MODE_CHACHAPOLY, /**< The ChaCha-Poly cipher mode. */
|
MBEDTLS_MODE_CHACHAPOLY, /**< The ChaCha-Poly cipher mode. */
|
||||||
|
MBEDTLS_MODE_KW, /**< The SP800-38F KW mode */
|
||||||
|
MBEDTLS_MODE_KWP, /**< The SP800-38F KWP mode */
|
||||||
} mbedtls_cipher_mode_t;
|
} mbedtls_cipher_mode_t;
|
||||||
|
|
||||||
/** Supported cipher padding types. */
|
/** Supported cipher padding types. */
|
||||||
@@ -220,10 +227,30 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Maximum length of any IV, in Bytes. */
|
/** Maximum length of any IV, in Bytes. */
|
||||||
|
/* This should ideally be derived automatically from list of ciphers.
|
||||||
|
* This should be kept in sync with MBEDTLS_SSL_MAX_IV_LENGTH defined
|
||||||
|
* in ssl_internal.h. */
|
||||||
#define MBEDTLS_MAX_IV_LENGTH 16
|
#define MBEDTLS_MAX_IV_LENGTH 16
|
||||||
|
|
||||||
/** Maximum block size of any cipher, in Bytes. */
|
/** Maximum block size of any cipher, in Bytes. */
|
||||||
|
/* This should ideally be derived automatically from list of ciphers.
|
||||||
|
* This should be kept in sync with MBEDTLS_SSL_MAX_BLOCK_LENGTH defined
|
||||||
|
* in ssl_internal.h. */
|
||||||
#define MBEDTLS_MAX_BLOCK_LENGTH 16
|
#define MBEDTLS_MAX_BLOCK_LENGTH 16
|
||||||
|
|
||||||
|
/** Maximum key length, in Bytes. */
|
||||||
|
/* This should ideally be derived automatically from list of ciphers.
|
||||||
|
* For now, only check whether XTS is enabled which uses 64 Byte keys,
|
||||||
|
* and use 32 Bytes as an upper bound for the maximum key length otherwise.
|
||||||
|
* This should be kept in sync with MBEDTLS_SSL_MAX_BLOCK_LENGTH defined
|
||||||
|
* in ssl_internal.h, which however deliberately ignores the case of XTS
|
||||||
|
* since the latter isn't used in SSL/TLS. */
|
||||||
|
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||||
|
#define MBEDTLS_MAX_KEY_LENGTH 64
|
||||||
|
#else
|
||||||
|
#define MBEDTLS_MAX_KEY_LENGTH 32
|
||||||
|
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base cipher information (opaque struct).
|
* Base cipher information (opaque struct).
|
||||||
*/
|
*/
|
||||||
@@ -238,7 +265,8 @@ typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t;
|
|||||||
* Cipher information. Allows calling cipher functions
|
* Cipher information. Allows calling cipher functions
|
||||||
* in a generic way.
|
* in a generic way.
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_cipher_info_t {
|
typedef struct mbedtls_cipher_info_t
|
||||||
|
{
|
||||||
/** Full cipher identifier. For example,
|
/** Full cipher identifier. For example,
|
||||||
* MBEDTLS_CIPHER_AES_256_CBC.
|
* MBEDTLS_CIPHER_AES_256_CBC.
|
||||||
*/
|
*/
|
||||||
@@ -254,7 +282,7 @@ typedef struct mbedtls_cipher_info_t {
|
|||||||
unsigned int key_bitlen;
|
unsigned int key_bitlen;
|
||||||
|
|
||||||
/** Name of the cipher. */
|
/** Name of the cipher. */
|
||||||
const char *name;
|
const char * name;
|
||||||
|
|
||||||
/** IV or nonce size, in Bytes.
|
/** IV or nonce size, in Bytes.
|
||||||
* For ciphers that accept variable IV sizes,
|
* For ciphers that accept variable IV sizes,
|
||||||
@@ -279,7 +307,8 @@ typedef struct mbedtls_cipher_info_t {
|
|||||||
/**
|
/**
|
||||||
* Generic cipher context.
|
* Generic cipher context.
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_cipher_context_t {
|
typedef struct mbedtls_cipher_context_t
|
||||||
|
{
|
||||||
/** Information about the associated cipher. */
|
/** Information about the associated cipher. */
|
||||||
const mbedtls_cipher_info_t *cipher_info;
|
const mbedtls_cipher_info_t *cipher_info;
|
||||||
|
|
||||||
@@ -295,8 +324,8 @@ typedef struct mbedtls_cipher_context_t {
|
|||||||
/** Padding functions to use, if relevant for
|
/** Padding functions to use, if relevant for
|
||||||
* the specific cipher mode.
|
* the specific cipher mode.
|
||||||
*/
|
*/
|
||||||
void (*add_padding)(unsigned char *output, size_t olen, size_t data_len);
|
void (*add_padding)( unsigned char *output, size_t olen, size_t data_len );
|
||||||
int (*get_padding)(unsigned char *input, size_t ilen, size_t *data_len);
|
int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Buffer for input that has not been processed yet. */
|
/** Buffer for input that has not been processed yet. */
|
||||||
@@ -319,28 +348,47 @@ typedef struct mbedtls_cipher_context_t {
|
|||||||
/** CMAC-specific context. */
|
/** CMAC-specific context. */
|
||||||
mbedtls_cmac_context_t *cmac_ctx;
|
mbedtls_cmac_context_t *cmac_ctx;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||||
|
/** Indicates whether the cipher operations should be performed
|
||||||
|
* by Mbed TLS' own crypto library or an external implementation
|
||||||
|
* of the PSA Crypto API.
|
||||||
|
* This is unset if the cipher context was established through
|
||||||
|
* mbedtls_cipher_setup(), and set if it was established through
|
||||||
|
* mbedtls_cipher_setup_psa().
|
||||||
|
*/
|
||||||
|
unsigned char psa_enabled;
|
||||||
|
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||||
|
|
||||||
} mbedtls_cipher_context_t;
|
} mbedtls_cipher_context_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function retrieves the list of ciphers supported by the generic
|
* \brief This function retrieves the list of ciphers supported
|
||||||
* cipher module.
|
* by the generic cipher module.
|
||||||
*
|
*
|
||||||
* \return A statically-allocated array of ciphers. The last entry
|
* For any cipher identifier in the returned list, you can
|
||||||
* is zero.
|
* obtain the corresponding generic cipher information structure
|
||||||
|
* via mbedtls_cipher_info_from_type(), which can then be used
|
||||||
|
* to prepare a cipher context via mbedtls_cipher_setup().
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \return A statically-allocated array of cipher identifiers
|
||||||
|
* of type cipher_type_t. The last entry is zero.
|
||||||
*/
|
*/
|
||||||
const int *mbedtls_cipher_list(void);
|
const int *mbedtls_cipher_list( void );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function retrieves the cipher-information
|
* \brief This function retrieves the cipher-information
|
||||||
* structure associated with the given cipher name.
|
* structure associated with the given cipher name.
|
||||||
*
|
*
|
||||||
* \param cipher_name Name of the cipher to search for.
|
* \param cipher_name Name of the cipher to search for. This must not be
|
||||||
|
* \c NULL.
|
||||||
*
|
*
|
||||||
* \return The cipher information structure associated with the
|
* \return The cipher information structure associated with the
|
||||||
* given \p cipher_name.
|
* given \p cipher_name.
|
||||||
* \return NULL if the associated cipher information is not found.
|
* \return \c NULL if the associated cipher information is not found.
|
||||||
*/
|
*/
|
||||||
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string(const char *cipher_name);
|
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function retrieves the cipher-information
|
* \brief This function retrieves the cipher-information
|
||||||
@@ -350,9 +398,9 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string(const char *cipher_
|
|||||||
*
|
*
|
||||||
* \return The cipher information structure associated with the
|
* \return The cipher information structure associated with the
|
||||||
* given \p cipher_type.
|
* given \p cipher_type.
|
||||||
* \return NULL if the associated cipher information is not found.
|
* \return \c NULL if the associated cipher information is not found.
|
||||||
*/
|
*/
|
||||||
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type(const mbedtls_cipher_type_t cipher_type);
|
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function retrieves the cipher-information
|
* \brief This function retrieves the cipher-information
|
||||||
@@ -366,31 +414,36 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type(const mbedtls_cipher_
|
|||||||
*
|
*
|
||||||
* \return The cipher information structure associated with the
|
* \return The cipher information structure associated with the
|
||||||
* given \p cipher_id.
|
* given \p cipher_id.
|
||||||
* \return NULL if the associated cipher information is not found.
|
* \return \c NULL if the associated cipher information is not found.
|
||||||
*/
|
*/
|
||||||
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values(const mbedtls_cipher_id_t cipher_id,
|
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
|
||||||
int key_bitlen,
|
int key_bitlen,
|
||||||
const mbedtls_cipher_mode_t mode);
|
const mbedtls_cipher_mode_t mode );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function initializes a \p cipher_context as NONE.
|
* \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);
|
void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function frees and clears the cipher-specific
|
* \brief This function frees and clears the cipher-specific
|
||||||
* context of \p ctx. Freeing \p ctx itself remains the
|
* context of \p ctx. Freeing \p ctx itself remains the
|
||||||
* responsibility of the caller.
|
* 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);
|
void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function initializes and fills the cipher-context
|
* \brief This function initializes a cipher context for
|
||||||
* structure with the appropriate values. It also clears
|
* use with the given cipher primitive.
|
||||||
* the structure.
|
|
||||||
*
|
*
|
||||||
* \param ctx The context to initialize. May not be NULL.
|
* \param ctx The context to initialize. This must be initialized.
|
||||||
* \param cipher_info The cipher to use.
|
* \param cipher_info The cipher to use.
|
||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
@@ -403,18 +456,49 @@ void mbedtls_cipher_free(mbedtls_cipher_context_t *ctx);
|
|||||||
* In future versions, the caller will be required to call
|
* In future versions, the caller will be required to call
|
||||||
* mbedtls_cipher_init() on the structure first.
|
* 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 );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||||
|
/**
|
||||||
|
* \brief This function initializes a cipher context for
|
||||||
|
* PSA-based use with the given cipher primitive.
|
||||||
|
*
|
||||||
|
* \note See #MBEDTLS_USE_PSA_CRYPTO for information on PSA.
|
||||||
|
*
|
||||||
|
* \param ctx The context to initialize. May not be \c NULL.
|
||||||
|
* \param cipher_info The cipher to use.
|
||||||
|
* \param taglen For AEAD ciphers, the length in bytes of the
|
||||||
|
* authentication tag to use. Subsequent uses of
|
||||||
|
* mbedtls_cipher_auth_encrypt() or
|
||||||
|
* mbedtls_cipher_auth_decrypt() must provide
|
||||||
|
* the same tag length.
|
||||||
|
* For non-AEAD ciphers, the value must be \c 0.
|
||||||
|
*
|
||||||
|
* \return \c 0 on success.
|
||||||
|
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
|
||||||
|
* parameter-verification failure.
|
||||||
|
* \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
|
||||||
|
* cipher-specific context fails.
|
||||||
|
*/
|
||||||
|
int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx,
|
||||||
|
const mbedtls_cipher_info_t *cipher_info,
|
||||||
|
size_t taglen );
|
||||||
|
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function returns the block size of the given cipher.
|
* \brief This function returns the block size of the given cipher.
|
||||||
*
|
*
|
||||||
* \param ctx The context of the cipher. Must be initialized.
|
* \param ctx The context of the cipher. This must be initialized.
|
||||||
*
|
*
|
||||||
* \return The size of the blocks of the cipher.
|
* \return The block size of the underlying cipher.
|
||||||
* \return 0 if \p ctx has not been initialized.
|
* \return \c 0 if \p ctx has not been initialized.
|
||||||
*/
|
*/
|
||||||
static inline unsigned int mbedtls_cipher_get_block_size(const mbedtls_cipher_context_t *ctx) {
|
static inline unsigned int mbedtls_cipher_get_block_size(
|
||||||
if (NULL == ctx || NULL == ctx->cipher_info)
|
const mbedtls_cipher_context_t *ctx )
|
||||||
|
{
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
|
||||||
|
if( ctx->cipher_info == NULL )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return ctx->cipher_info->block_size;
|
return ctx->cipher_info->block_size;
|
||||||
@@ -424,13 +508,16 @@ static inline unsigned int mbedtls_cipher_get_block_size(const mbedtls_cipher_co
|
|||||||
* \brief This function returns the mode of operation for
|
* \brief This function returns the mode of operation for
|
||||||
* the cipher. For example, MBEDTLS_MODE_CBC.
|
* the cipher. For example, MBEDTLS_MODE_CBC.
|
||||||
*
|
*
|
||||||
* \param ctx The context of the cipher. Must be initialized.
|
* \param ctx The context of the cipher. This must be initialized.
|
||||||
*
|
*
|
||||||
* \return The mode of operation.
|
* \return The mode of operation.
|
||||||
* \return #MBEDTLS_MODE_NONE if \p ctx has not been initialized.
|
* \return #MBEDTLS_MODE_NONE if \p ctx has not been initialized.
|
||||||
*/
|
*/
|
||||||
static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode(const mbedtls_cipher_context_t *ctx) {
|
static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode(
|
||||||
if (NULL == ctx || NULL == ctx->cipher_info)
|
const mbedtls_cipher_context_t *ctx )
|
||||||
|
{
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, MBEDTLS_MODE_NONE );
|
||||||
|
if( ctx->cipher_info == NULL )
|
||||||
return MBEDTLS_MODE_NONE;
|
return MBEDTLS_MODE_NONE;
|
||||||
|
|
||||||
return ctx->cipher_info->mode;
|
return ctx->cipher_info->mode;
|
||||||
@@ -440,17 +527,20 @@ static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode(const mbedtls
|
|||||||
* \brief This function returns the size of the IV or nonce
|
* \brief This function returns the size of the IV or nonce
|
||||||
* of the cipher, in Bytes.
|
* of the cipher, in Bytes.
|
||||||
*
|
*
|
||||||
* \param ctx The context of the cipher. Must be initialized.
|
* \param ctx The context of the cipher. This must be initialized.
|
||||||
*
|
*
|
||||||
* \return The recommended IV size if no IV has been set.
|
* \return The recommended IV size if no IV has been set.
|
||||||
* \return \c 0 for ciphers not using an IV or a nonce.
|
* \return \c 0 for ciphers not using an IV or a nonce.
|
||||||
* \return The actual size if an IV has been set.
|
* \return The actual size if an IV has been set.
|
||||||
*/
|
*/
|
||||||
static inline int mbedtls_cipher_get_iv_size(const mbedtls_cipher_context_t *ctx) {
|
static inline int mbedtls_cipher_get_iv_size(
|
||||||
if (NULL == ctx || NULL == ctx->cipher_info)
|
const mbedtls_cipher_context_t *ctx )
|
||||||
|
{
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
|
||||||
|
if( ctx->cipher_info == NULL )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (ctx->iv_size != 0)
|
if( ctx->iv_size != 0 )
|
||||||
return (int) ctx->iv_size;
|
return (int) ctx->iv_size;
|
||||||
|
|
||||||
return (int) ctx->cipher_info->iv_size;
|
return (int) ctx->cipher_info->iv_size;
|
||||||
@@ -459,13 +549,17 @@ static inline int mbedtls_cipher_get_iv_size(const mbedtls_cipher_context_t *ctx
|
|||||||
/**
|
/**
|
||||||
* \brief This function returns the type of the given cipher.
|
* \brief This function returns the type of the given cipher.
|
||||||
*
|
*
|
||||||
* \param ctx The context of the cipher. Must be initialized.
|
* \param ctx The context of the cipher. This must be initialized.
|
||||||
*
|
*
|
||||||
* \return The type of the cipher.
|
* \return The type of the cipher.
|
||||||
* \return #MBEDTLS_CIPHER_NONE if \p ctx has not been initialized.
|
* \return #MBEDTLS_CIPHER_NONE if \p ctx has not been initialized.
|
||||||
*/
|
*/
|
||||||
static inline mbedtls_cipher_type_t mbedtls_cipher_get_type(const mbedtls_cipher_context_t *ctx) {
|
static inline mbedtls_cipher_type_t mbedtls_cipher_get_type(
|
||||||
if (NULL == ctx || NULL == ctx->cipher_info)
|
const mbedtls_cipher_context_t *ctx )
|
||||||
|
{
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE_RET(
|
||||||
|
ctx != NULL, MBEDTLS_CIPHER_NONE );
|
||||||
|
if( ctx->cipher_info == NULL )
|
||||||
return MBEDTLS_CIPHER_NONE;
|
return MBEDTLS_CIPHER_NONE;
|
||||||
|
|
||||||
return ctx->cipher_info->type;
|
return ctx->cipher_info->type;
|
||||||
@@ -475,13 +569,16 @@ static inline mbedtls_cipher_type_t mbedtls_cipher_get_type(const mbedtls_cipher
|
|||||||
* \brief This function returns the name of the given cipher
|
* \brief This function returns the name of the given cipher
|
||||||
* as a string.
|
* as a string.
|
||||||
*
|
*
|
||||||
* \param ctx The context of the cipher. Must be initialized.
|
* \param ctx The context of the cipher. This must be initialized.
|
||||||
*
|
*
|
||||||
* \return The name of the cipher.
|
* \return The name of the cipher.
|
||||||
* \return NULL if \p ctx has not been not initialized.
|
* \return 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(
|
||||||
if (NULL == ctx || NULL == ctx->cipher_info)
|
const mbedtls_cipher_context_t *ctx )
|
||||||
|
{
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
|
||||||
|
if( ctx->cipher_info == NULL )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return ctx->cipher_info->name;
|
return ctx->cipher_info->name;
|
||||||
@@ -490,14 +587,18 @@ static inline const char *mbedtls_cipher_get_name(const mbedtls_cipher_context_t
|
|||||||
/**
|
/**
|
||||||
* \brief This function returns the key length of the cipher.
|
* \brief This function returns the key length of the cipher.
|
||||||
*
|
*
|
||||||
* \param ctx The context of the cipher. Must be initialized.
|
* \param ctx The context of the cipher. This must be initialized.
|
||||||
*
|
*
|
||||||
* \return The key length of the cipher in bits.
|
* \return The key length of the cipher in bits.
|
||||||
* \return #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been
|
* \return #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been
|
||||||
* initialized.
|
* initialized.
|
||||||
*/
|
*/
|
||||||
static inline int mbedtls_cipher_get_key_bitlen(const mbedtls_cipher_context_t *ctx) {
|
static inline int mbedtls_cipher_get_key_bitlen(
|
||||||
if (NULL == ctx || NULL == ctx->cipher_info)
|
const mbedtls_cipher_context_t *ctx )
|
||||||
|
{
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE_RET(
|
||||||
|
ctx != NULL, MBEDTLS_KEY_LENGTH_NONE );
|
||||||
|
if( ctx->cipher_info == NULL )
|
||||||
return MBEDTLS_KEY_LENGTH_NONE;
|
return MBEDTLS_KEY_LENGTH_NONE;
|
||||||
|
|
||||||
return (int) ctx->cipher_info->key_bitlen;
|
return (int) ctx->cipher_info->key_bitlen;
|
||||||
@@ -506,13 +607,17 @@ static inline int mbedtls_cipher_get_key_bitlen(const mbedtls_cipher_context_t *
|
|||||||
/**
|
/**
|
||||||
* \brief This function returns the operation of the given cipher.
|
* \brief This function returns the operation of the given cipher.
|
||||||
*
|
*
|
||||||
* \param ctx The context of the cipher. Must be initialized.
|
* \param ctx The context of the cipher. This must be initialized.
|
||||||
*
|
*
|
||||||
* \return The type of operation: #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
|
* \return The type of operation: #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
|
||||||
* \return #MBEDTLS_OPERATION_NONE if \p ctx has not been initialized.
|
* \return #MBEDTLS_OPERATION_NONE if \p ctx has not been initialized.
|
||||||
*/
|
*/
|
||||||
static inline mbedtls_operation_t mbedtls_cipher_get_operation(const mbedtls_cipher_context_t *ctx) {
|
static inline mbedtls_operation_t mbedtls_cipher_get_operation(
|
||||||
if (NULL == ctx || NULL == ctx->cipher_info)
|
const mbedtls_cipher_context_t *ctx )
|
||||||
|
{
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE_RET(
|
||||||
|
ctx != NULL, MBEDTLS_OPERATION_NONE );
|
||||||
|
if( ctx->cipher_info == NULL )
|
||||||
return MBEDTLS_OPERATION_NONE;
|
return MBEDTLS_OPERATION_NONE;
|
||||||
|
|
||||||
return ctx->operation;
|
return ctx->operation;
|
||||||
@@ -521,11 +626,11 @@ static inline mbedtls_operation_t mbedtls_cipher_get_operation(const mbedtls_cip
|
|||||||
/**
|
/**
|
||||||
* \brief This function sets the key to use with the given context.
|
* \brief This function sets the key to use with the given context.
|
||||||
*
|
*
|
||||||
* \param ctx The generic cipher context. May not be NULL. Must have
|
* \param ctx The generic cipher context. This must be initialized and
|
||||||
* been initialized using mbedtls_cipher_info_from_type()
|
* bound to a cipher information structure.
|
||||||
* or mbedtls_cipher_info_from_string().
|
* \param key The key to use. This must be a readable buffer of at
|
||||||
* \param key The key to use.
|
* least \p key_bitlen Bits.
|
||||||
* \param key_bitlen The key length to use, in bits.
|
* \param key_bitlen The key length to use, in Bits.
|
||||||
* \param operation The operation that the key will be used for:
|
* \param operation The operation that the key will be used for:
|
||||||
* #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
|
* #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
|
||||||
*
|
*
|
||||||
@@ -534,8 +639,10 @@ static inline mbedtls_operation_t mbedtls_cipher_get_operation(const mbedtls_cip
|
|||||||
* parameter-verification failure.
|
* parameter-verification failure.
|
||||||
* \return A cipher-specific error code on failure.
|
* \return A cipher-specific error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx, const unsigned char *key,
|
int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
|
||||||
int key_bitlen, const mbedtls_operation_t operation);
|
const unsigned char *key,
|
||||||
|
int key_bitlen,
|
||||||
|
const mbedtls_operation_t operation );
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
|
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
|
||||||
/**
|
/**
|
||||||
@@ -544,7 +651,8 @@ int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx, const unsigned char *ke
|
|||||||
*
|
*
|
||||||
* The default passing mode is PKCS7 padding.
|
* The default passing mode is PKCS7 padding.
|
||||||
*
|
*
|
||||||
* \param ctx The generic cipher context.
|
* \param ctx The generic cipher context. This must be initialized and
|
||||||
|
* bound to a cipher information structure.
|
||||||
* \param mode The padding mode.
|
* \param mode The padding mode.
|
||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
@@ -553,7 +661,8 @@ int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx, const unsigned char *ke
|
|||||||
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode
|
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode
|
||||||
* does not support padding.
|
* 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 */
|
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -563,8 +672,10 @@ int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx, mbedtls_ciphe
|
|||||||
* \note Some ciphers do not use IVs nor nonce. For these
|
* \note Some ciphers do not use IVs nor nonce. For these
|
||||||
* ciphers, this function has no effect.
|
* ciphers, this function has no effect.
|
||||||
*
|
*
|
||||||
* \param ctx The generic cipher context.
|
* \param ctx The generic cipher context. This must be initialized and
|
||||||
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
|
* bound to a cipher information structure.
|
||||||
|
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. This
|
||||||
|
* must be a readable buffer of at least \p iv_len Bytes.
|
||||||
* \param iv_len The IV length for ciphers with variable-size IV.
|
* \param iv_len The IV length for ciphers with variable-size IV.
|
||||||
* This parameter is discarded by ciphers with fixed-size IV.
|
* This parameter is discarded by ciphers with fixed-size IV.
|
||||||
*
|
*
|
||||||
@@ -572,35 +683,38 @@ int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx, mbedtls_ciphe
|
|||||||
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
|
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
|
||||||
* parameter-verification failure.
|
* parameter-verification failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_cipher_set_iv(mbedtls_cipher_context_t *ctx,
|
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.
|
* \brief This function resets the cipher state.
|
||||||
*
|
*
|
||||||
* \param ctx The generic cipher context.
|
* \param ctx The generic cipher context. This must be initialized.
|
||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
|
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
|
||||||
* parameter-verification failure.
|
* parameter-verification failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_cipher_reset(mbedtls_cipher_context_t *ctx);
|
int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx );
|
||||||
|
|
||||||
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
|
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
|
||||||
/**
|
/**
|
||||||
* \brief This function adds additional data for AEAD ciphers.
|
* \brief This function adds additional data for AEAD ciphers.
|
||||||
* Currently supported with GCM and ChaCha20+Poly1305.
|
* Currently supported with GCM and ChaCha20+Poly1305.
|
||||||
* Must be called exactly once, after mbedtls_cipher_reset().
|
* This must be called exactly once, after
|
||||||
|
* mbedtls_cipher_reset().
|
||||||
*
|
*
|
||||||
* \param ctx The generic cipher context.
|
* \param ctx The generic cipher context. This must be initialized.
|
||||||
* \param ad The additional data to use.
|
* \param ad The additional data to use. This must be a readable
|
||||||
* \param ad_len the Length of \p ad.
|
* buffer of at least \p ad_len Bytes.
|
||||||
|
* \param ad_len The length of \p ad in Bytes.
|
||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return A specific error code on failure.
|
* \return A specific error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_cipher_update_ad(mbedtls_cipher_context_t *ctx,
|
int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
|
||||||
const unsigned char *ad, size_t ad_len);
|
const unsigned char *ad, size_t ad_len );
|
||||||
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
|
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -618,14 +732,17 @@ int mbedtls_cipher_update_ad(mbedtls_cipher_context_t *ctx,
|
|||||||
* mbedtls_cipher_finish(), must have \p ilen as a
|
* mbedtls_cipher_finish(), must have \p ilen as a
|
||||||
* multiple of the block size of the cipher.
|
* multiple of the block size of the cipher.
|
||||||
*
|
*
|
||||||
* \param ctx The generic cipher context.
|
* \param ctx The generic cipher context. This must be initialized and
|
||||||
* \param input The buffer holding the input data.
|
* bound to a key.
|
||||||
|
* \param input The buffer holding the input data. This must be a
|
||||||
|
* readable buffer of at least \p ilen Bytes.
|
||||||
* \param ilen The length of the input data.
|
* \param ilen The length of the input data.
|
||||||
* \param output The buffer for the output data. Must be able to hold at
|
* \param output The buffer for the output data. This must be able to
|
||||||
* least \p ilen + block_size. Must not be the same buffer
|
* hold at least `ilen + block_size`. This must not be the
|
||||||
* as input.
|
* same buffer as \p input.
|
||||||
* \param olen The length of the output data, to be updated with the
|
* \param olen The length of the output data, to be updated with the
|
||||||
* actual number of Bytes written.
|
* actual number of Bytes written. This must not be
|
||||||
|
* \c NULL.
|
||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
|
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
|
||||||
@@ -634,8 +751,10 @@ int mbedtls_cipher_update_ad(mbedtls_cipher_context_t *ctx,
|
|||||||
* unsupported mode for a cipher.
|
* unsupported mode for a cipher.
|
||||||
* \return A cipher-specific error code on failure.
|
* \return A cipher-specific error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *input,
|
int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx,
|
||||||
size_t ilen, unsigned char *output, size_t *olen);
|
const unsigned char *input,
|
||||||
|
size_t ilen, unsigned char *output,
|
||||||
|
size_t *olen );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief The generic cipher finalization function. If data still
|
* \brief The generic cipher finalization function. If data still
|
||||||
@@ -643,9 +762,12 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *in
|
|||||||
* contained in it is padded to the size of
|
* contained in it is padded to the size of
|
||||||
* the last block, and written to the \p output buffer.
|
* the last block, and written to the \p output buffer.
|
||||||
*
|
*
|
||||||
* \param ctx The generic cipher context.
|
* \param ctx The generic cipher context. This must be initialized and
|
||||||
* \param output The buffer to write data to. Needs block_size available.
|
* bound to a key.
|
||||||
|
* \param output The buffer to write data to. This needs to be a writable
|
||||||
|
* buffer of at least \p block_size Bytes.
|
||||||
* \param olen The length of the data written to the \p output buffer.
|
* \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 \c 0 on success.
|
||||||
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
|
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
|
||||||
@@ -656,57 +778,66 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *in
|
|||||||
* while decrypting.
|
* while decrypting.
|
||||||
* \return A cipher-specific error code on failure.
|
* \return A cipher-specific error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx,
|
int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
|
||||||
unsigned char *output, size_t *olen);
|
unsigned char *output, size_t *olen );
|
||||||
|
|
||||||
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
|
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
|
||||||
/**
|
/**
|
||||||
* \brief This function writes a tag for AEAD ciphers.
|
* \brief This function writes a tag for AEAD ciphers.
|
||||||
* Currently supported with GCM and ChaCha20+Poly1305.
|
* Currently supported with GCM and ChaCha20+Poly1305.
|
||||||
* Must be called after mbedtls_cipher_finish().
|
* This must be called after mbedtls_cipher_finish().
|
||||||
*
|
*
|
||||||
* \param ctx The generic cipher context.
|
* \param ctx The generic cipher context. This must be initialized,
|
||||||
* \param tag The buffer to write the tag to.
|
* bound to a key, and have just completed a cipher
|
||||||
|
* operation through mbedtls_cipher_finish() the tag for
|
||||||
|
* which should be written.
|
||||||
|
* \param tag The buffer to write the tag to. This must be a writable
|
||||||
|
* buffer of at least \p tag_len Bytes.
|
||||||
* \param tag_len The length of the tag to write.
|
* \param tag_len The length of the tag to write.
|
||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return A specific error code on failure.
|
* \return A specific error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_cipher_write_tag(mbedtls_cipher_context_t *ctx,
|
int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
|
||||||
unsigned char *tag, size_t tag_len);
|
unsigned char *tag, size_t tag_len );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function checks the tag for AEAD ciphers.
|
* \brief This function checks the tag for AEAD ciphers.
|
||||||
* Currently supported with GCM and ChaCha20+Poly1305.
|
* Currently supported with GCM and ChaCha20+Poly1305.
|
||||||
* Must be called after mbedtls_cipher_finish().
|
* This must be called after mbedtls_cipher_finish().
|
||||||
*
|
*
|
||||||
* \param ctx The generic cipher context.
|
* \param ctx The generic cipher context. This must be initialized.
|
||||||
* \param tag The buffer holding the tag.
|
* \param tag The buffer holding the tag. This must be a readable
|
||||||
|
* buffer of at least \p tag_len Bytes.
|
||||||
* \param tag_len The length of the tag to check.
|
* \param tag_len The length of the tag to check.
|
||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return A specific error code on failure.
|
* \return A specific error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_cipher_check_tag(mbedtls_cipher_context_t *ctx,
|
int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
|
||||||
const unsigned char *tag, size_t tag_len);
|
const unsigned char *tag, size_t tag_len );
|
||||||
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
|
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief The generic all-in-one encryption/decryption function,
|
* \brief The generic all-in-one encryption/decryption function,
|
||||||
* for all ciphers except AEAD constructs.
|
* for all ciphers except AEAD constructs.
|
||||||
*
|
*
|
||||||
* \param ctx The generic cipher context.
|
* \param ctx The generic cipher context. This must be initialized.
|
||||||
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
|
* \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.
|
* \param iv_len The IV length for ciphers with variable-size IV.
|
||||||
* This parameter is discarded by ciphers with fixed-size
|
* This parameter is discarded by ciphers with fixed-size
|
||||||
* IV.
|
* IV.
|
||||||
* \param input The buffer holding the input data.
|
* \param input The buffer holding the input data. This must be a
|
||||||
* \param ilen The length of the input data.
|
* readable buffer of at least \p ilen Bytes.
|
||||||
* \param output The buffer for the output data. Must be able to hold at
|
* \param ilen The length of the input data in Bytes.
|
||||||
* least \p ilen + block_size. Must not be the same buffer
|
* \param output The buffer for the output data. This must be able to
|
||||||
* as input.
|
* hold at least `ilen + block_size`. This must not be the
|
||||||
|
* same buffer as \p input.
|
||||||
* \param olen The length of the output data, to be updated with the
|
* \param olen The length of the output data, to be updated with the
|
||||||
* actual number of Bytes written.
|
* actual number of Bytes written. This must not be
|
||||||
|
* \c NULL.
|
||||||
*
|
*
|
||||||
* \note Some ciphers do not use IVs nor nonce. For these
|
* \note Some ciphers do not use IVs nor nonce. For these
|
||||||
* ciphers, use \p iv = NULL and \p iv_len = 0.
|
* ciphers, use \p iv = NULL and \p iv_len = 0.
|
||||||
@@ -720,63 +851,116 @@ int mbedtls_cipher_check_tag(mbedtls_cipher_context_t *ctx,
|
|||||||
* while decrypting.
|
* while decrypting.
|
||||||
* \return A cipher-specific error code on failure.
|
* \return A cipher-specific error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_cipher_crypt(mbedtls_cipher_context_t *ctx,
|
int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
|
||||||
const unsigned char *iv, size_t iv_len,
|
const unsigned char *iv, size_t iv_len,
|
||||||
const unsigned char *input, size_t ilen,
|
const unsigned char *input, size_t ilen,
|
||||||
unsigned char *output, size_t *olen);
|
unsigned char *output, size_t *olen );
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_AEAD)
|
#if defined(MBEDTLS_CIPHER_MODE_AEAD)
|
||||||
|
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
|
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
||||||
|
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
|
||||||
|
#else
|
||||||
|
#define MBEDTLS_DEPRECATED
|
||||||
|
#endif /* MBEDTLS_DEPRECATED_WARNING */
|
||||||
/**
|
/**
|
||||||
* \brief The generic autenticated encryption (AEAD) function.
|
* \brief The generic authenticated encryption (AEAD) function.
|
||||||
*
|
*
|
||||||
* \param ctx The generic cipher context.
|
* \deprecated Superseded by mbedtls_cipher_auth_encrypt_ext().
|
||||||
* \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.
|
* \note This function only supports AEAD algorithms, not key
|
||||||
* This parameter is discarded by ciphers with fixed-size IV.
|
* wrapping algorithms such as NIST_KW; for this, see
|
||||||
* \param ad The additional data to authenticate.
|
* mbedtls_cipher_auth_encrypt_ext().
|
||||||
|
*
|
||||||
|
* \param ctx The generic cipher context. This must be initialized and
|
||||||
|
* bound to a key associated with an AEAD algorithm.
|
||||||
|
* \param iv The nonce to use. This must be a readable buffer of
|
||||||
|
* at least \p iv_len Bytes and must not be \c NULL.
|
||||||
|
* \param iv_len The length of the nonce. This must satisfy the
|
||||||
|
* constraints imposed by the AEAD cipher used.
|
||||||
|
* \param ad The additional data to authenticate. This must be a
|
||||||
|
* readable buffer of at least \p ad_len Bytes, and may
|
||||||
|
* be \c NULL is \p ad_len is \c 0.
|
||||||
* \param ad_len The length of \p ad.
|
* \param ad_len The length of \p ad.
|
||||||
* \param input The buffer holding the input data.
|
* \param input The buffer holding the input data. This must be a
|
||||||
|
* readable buffer of at least \p ilen Bytes, and may be
|
||||||
|
* \c NULL if \p ilen is \c 0.
|
||||||
* \param ilen The length of the input data.
|
* \param ilen The length of the input data.
|
||||||
* \param output The buffer for the output data.
|
* \param output The buffer for the output data. This must be a
|
||||||
* Must be able to hold at least \p ilen.
|
* writable buffer of at least \p ilen Bytes, and must
|
||||||
* \param olen The length of the output data, to be updated with the
|
* not be \c NULL.
|
||||||
* actual number of Bytes written.
|
* \param olen This will be filled with the actual number of Bytes
|
||||||
* \param tag The buffer for the authentication tag.
|
* written to the \p output buffer. This must point to a
|
||||||
* \param tag_len The desired length of the authentication tag.
|
* writable object of type \c size_t.
|
||||||
|
* \param tag The buffer for the authentication tag. This must be a
|
||||||
|
* writable buffer of at least \p tag_len Bytes. See note
|
||||||
|
* below regarding restrictions with PSA-based contexts.
|
||||||
|
* \param tag_len The desired length of the authentication tag. This
|
||||||
|
* must match the constraints imposed by the AEAD cipher
|
||||||
|
* used, and in particular must not be \c 0.
|
||||||
|
*
|
||||||
|
* \note If the context is based on PSA (that is, it was set up
|
||||||
|
* with mbedtls_cipher_setup_psa()), then it is required
|
||||||
|
* that \c tag == output + ilen. That is, the tag must be
|
||||||
|
* appended to the ciphertext as recommended by RFC 5116.
|
||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
|
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
|
||||||
* parameter-verification failure.
|
* parameter-verification failure.
|
||||||
* \return A cipher-specific error code on failure.
|
* \return A cipher-specific error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_cipher_auth_encrypt(mbedtls_cipher_context_t *ctx,
|
int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
|
||||||
const unsigned char *iv, size_t iv_len,
|
const unsigned char *iv, size_t iv_len,
|
||||||
const unsigned char *ad, size_t ad_len,
|
const unsigned char *ad, size_t ad_len,
|
||||||
const unsigned char *input, size_t ilen,
|
const unsigned char *input, size_t ilen,
|
||||||
unsigned char *output, size_t *olen,
|
unsigned char *output, size_t *olen,
|
||||||
unsigned char *tag, size_t tag_len);
|
unsigned char *tag, size_t tag_len )
|
||||||
|
MBEDTLS_DEPRECATED;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief The generic autenticated decryption (AEAD) function.
|
* \brief The generic authenticated decryption (AEAD) function.
|
||||||
|
*
|
||||||
|
* \deprecated Superseded by mbedtls_cipher_auth_decrypt_ext().
|
||||||
|
*
|
||||||
|
* \note This function only supports AEAD algorithms, not key
|
||||||
|
* wrapping algorithms such as NIST_KW; for this, see
|
||||||
|
* mbedtls_cipher_auth_decrypt_ext().
|
||||||
*
|
*
|
||||||
* \note If the data is not authentic, then the output buffer
|
* \note If the data is not authentic, then the output buffer
|
||||||
* is zeroed out to prevent the unauthentic plaintext being
|
* is zeroed out to prevent the unauthentic plaintext being
|
||||||
* used, making this interface safer.
|
* used, making this interface safer.
|
||||||
*
|
*
|
||||||
* \param ctx The generic cipher context.
|
* \param ctx The generic cipher context. This must be initialized and
|
||||||
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
|
* bound to a key associated with an AEAD algorithm.
|
||||||
* \param iv_len The IV length for ciphers with variable-size IV.
|
* \param iv The nonce to use. This must be a readable buffer of
|
||||||
* This parameter is discarded by ciphers with fixed-size IV.
|
* at least \p iv_len Bytes and must not be \c NULL.
|
||||||
* \param ad The additional data to be authenticated.
|
* \param iv_len The length of the nonce. This must satisfy the
|
||||||
|
* constraints imposed by the AEAD cipher used.
|
||||||
|
* \param ad The additional data to authenticate. This must be a
|
||||||
|
* readable buffer of at least \p ad_len Bytes, and may
|
||||||
|
* be \c NULL is \p ad_len is \c 0.
|
||||||
* \param ad_len The length of \p ad.
|
* \param ad_len The length of \p ad.
|
||||||
* \param input The buffer holding the input data.
|
* \param input The buffer holding the input data. This must be a
|
||||||
|
* readable buffer of at least \p ilen Bytes, and may be
|
||||||
|
* \c NULL if \p ilen is \c 0.
|
||||||
* \param ilen The length of the input data.
|
* \param ilen The length of the input data.
|
||||||
* \param output The buffer for the output data.
|
* \param output The buffer for the output data. This must be a
|
||||||
* Must be able to hold at least \p ilen.
|
* writable buffer of at least \p ilen Bytes, and must
|
||||||
* \param olen The length of the output data, to be updated with the
|
* not be \c NULL.
|
||||||
* actual number of Bytes written.
|
* \param olen This will be filled with the actual number of Bytes
|
||||||
* \param tag The buffer holding the authentication tag.
|
* written to the \p output buffer. This must point to a
|
||||||
* \param tag_len The length of the authentication tag.
|
* writable object of type \c size_t.
|
||||||
|
* \param tag The buffer for the authentication tag. This must be a
|
||||||
|
* readable buffer of at least \p tag_len Bytes. See note
|
||||||
|
* below regarding restrictions with PSA-based contexts.
|
||||||
|
* \param tag_len The length of the authentication tag. This must match
|
||||||
|
* the constraints imposed by the AEAD cipher used, and in
|
||||||
|
* particular must not be \c 0.
|
||||||
|
*
|
||||||
|
* \note If the context is based on PSA (that is, it was set up
|
||||||
|
* with mbedtls_cipher_setup_psa()), then it is required
|
||||||
|
* that \c tag == input + len. That is, the tag must be
|
||||||
|
* appended to the ciphertext as recommended by RFC 5116.
|
||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
|
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
|
||||||
@@ -784,14 +968,125 @@ int mbedtls_cipher_auth_encrypt(mbedtls_cipher_context_t *ctx,
|
|||||||
* \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic.
|
* \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic.
|
||||||
* \return A cipher-specific error code on failure.
|
* \return A cipher-specific error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_cipher_auth_decrypt(mbedtls_cipher_context_t *ctx,
|
int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
|
||||||
const unsigned char *iv, size_t iv_len,
|
const unsigned char *iv, size_t iv_len,
|
||||||
const unsigned char *ad, size_t ad_len,
|
const unsigned char *ad, size_t ad_len,
|
||||||
const unsigned char *input, size_t ilen,
|
const unsigned char *input, size_t ilen,
|
||||||
unsigned char *output, size_t *olen,
|
unsigned char *output, size_t *olen,
|
||||||
const unsigned char *tag, size_t tag_len);
|
const unsigned char *tag, size_t tag_len )
|
||||||
|
MBEDTLS_DEPRECATED;
|
||||||
|
#undef MBEDTLS_DEPRECATED
|
||||||
|
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_AEAD */
|
#endif /* MBEDTLS_CIPHER_MODE_AEAD */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C)
|
||||||
|
/**
|
||||||
|
* \brief The authenticated encryption (AEAD/NIST_KW) function.
|
||||||
|
*
|
||||||
|
* \note For AEAD modes, the tag will be appended to the
|
||||||
|
* ciphertext, as recommended by RFC 5116.
|
||||||
|
* (NIST_KW doesn't have a separate tag.)
|
||||||
|
*
|
||||||
|
* \param ctx The generic cipher context. This must be initialized and
|
||||||
|
* bound to a key, with an AEAD algorithm or NIST_KW.
|
||||||
|
* \param iv The nonce to use. This must be a readable buffer of
|
||||||
|
* at least \p iv_len Bytes and may be \c NULL if \p
|
||||||
|
* iv_len is \c 0.
|
||||||
|
* \param iv_len The length of the nonce. For AEAD ciphers, this must
|
||||||
|
* satisfy the constraints imposed by the cipher used.
|
||||||
|
* For NIST_KW, this must be \c 0.
|
||||||
|
* \param ad The additional data to authenticate. This must be a
|
||||||
|
* readable buffer of at least \p ad_len Bytes, and may
|
||||||
|
* be \c NULL is \p ad_len is \c 0.
|
||||||
|
* \param ad_len The length of \p ad. For NIST_KW, this must be \c 0.
|
||||||
|
* \param input The buffer holding the input data. This must be a
|
||||||
|
* readable buffer of at least \p ilen Bytes, and may be
|
||||||
|
* \c NULL if \p ilen is \c 0.
|
||||||
|
* \param ilen The length of the input data.
|
||||||
|
* \param output The buffer for the output data. This must be a
|
||||||
|
* writable buffer of at least \p output_len Bytes, and
|
||||||
|
* must not be \c NULL.
|
||||||
|
* \param output_len The length of the \p output buffer in Bytes. For AEAD
|
||||||
|
* ciphers, this must be at least \p ilen + \p tag_len.
|
||||||
|
* For NIST_KW, this must be at least \p ilen + 8
|
||||||
|
* (rounded up to a multiple of 8 if KWP is used);
|
||||||
|
* \p ilen + 15 is always a safe value.
|
||||||
|
* \param olen This will be filled with the actual number of Bytes
|
||||||
|
* written to the \p output buffer. This must point to a
|
||||||
|
* writable object of type \c size_t.
|
||||||
|
* \param tag_len The desired length of the authentication tag. For AEAD
|
||||||
|
* ciphers, this must match the constraints imposed by
|
||||||
|
* the cipher used, and in particular must not be \c 0.
|
||||||
|
* For NIST_KW, this must be \c 0.
|
||||||
|
*
|
||||||
|
* \return \c 0 on success.
|
||||||
|
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
|
||||||
|
* parameter-verification failure.
|
||||||
|
* \return A cipher-specific error code on failure.
|
||||||
|
*/
|
||||||
|
int mbedtls_cipher_auth_encrypt_ext( mbedtls_cipher_context_t *ctx,
|
||||||
|
const unsigned char *iv, size_t iv_len,
|
||||||
|
const unsigned char *ad, size_t ad_len,
|
||||||
|
const unsigned char *input, size_t ilen,
|
||||||
|
unsigned char *output, size_t output_len,
|
||||||
|
size_t *olen, size_t tag_len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief The authenticated encryption (AEAD/NIST_KW) function.
|
||||||
|
*
|
||||||
|
* \note If the data is not authentic, then the output buffer
|
||||||
|
* is zeroed out to prevent the unauthentic plaintext being
|
||||||
|
* used, making this interface safer.
|
||||||
|
*
|
||||||
|
* \note For AEAD modes, the tag must be appended to the
|
||||||
|
* ciphertext, as recommended by RFC 5116.
|
||||||
|
* (NIST_KW doesn't have a separate tag.)
|
||||||
|
*
|
||||||
|
* \param ctx The generic cipher context. This must be initialized and
|
||||||
|
* bound to a key, with an AEAD algorithm or NIST_KW.
|
||||||
|
* \param iv The nonce to use. This must be a readable buffer of
|
||||||
|
* at least \p iv_len Bytes and may be \c NULL if \p
|
||||||
|
* iv_len is \c 0.
|
||||||
|
* \param iv_len The length of the nonce. For AEAD ciphers, this must
|
||||||
|
* satisfy the constraints imposed by the cipher used.
|
||||||
|
* For NIST_KW, this must be \c 0.
|
||||||
|
* \param ad The additional data to authenticate. This must be a
|
||||||
|
* readable buffer of at least \p ad_len Bytes, and may
|
||||||
|
* be \c NULL is \p ad_len is \c 0.
|
||||||
|
* \param ad_len The length of \p ad. For NIST_KW, this must be \c 0.
|
||||||
|
* \param input The buffer holding the input data. This must be a
|
||||||
|
* readable buffer of at least \p ilen Bytes, and may be
|
||||||
|
* \c NULL if \p ilen is \c 0.
|
||||||
|
* \param ilen The length of the input data. For AEAD ciphers this
|
||||||
|
* must be at least \p tag_len. For NIST_KW this must be
|
||||||
|
* at least \c 8.
|
||||||
|
* \param output The buffer for the output data. This must be a
|
||||||
|
* writable buffer of at least \p output_len Bytes, and
|
||||||
|
* may be \c NULL if \p output_len is \c 0.
|
||||||
|
* \param output_len The length of the \p output buffer in Bytes. For AEAD
|
||||||
|
* ciphers, this must be at least \p ilen - \p tag_len.
|
||||||
|
* For NIST_KW, this must be at least \p ilen - 8.
|
||||||
|
* \param olen This will be filled with the actual number of Bytes
|
||||||
|
* written to the \p output buffer. This must point to a
|
||||||
|
* writable object of type \c size_t.
|
||||||
|
* \param tag_len The actual length of the authentication tag. For AEAD
|
||||||
|
* ciphers, this must match the constraints imposed by
|
||||||
|
* the cipher used, and in particular must not be \c 0.
|
||||||
|
* For NIST_KW, this must be \c 0.
|
||||||
|
*
|
||||||
|
* \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_ext( mbedtls_cipher_context_t *ctx,
|
||||||
|
const unsigned char *iv, size_t iv_len,
|
||||||
|
const unsigned char *ad, size_t ad_len,
|
||||||
|
const unsigned char *input, size_t ilen,
|
||||||
|
unsigned char *output, size_t output_len,
|
||||||
|
size_t *olen, size_t tag_len );
|
||||||
|
#endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,35 +6,35 @@
|
|||||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef MBEDTLS_CIPHER_WRAP_H
|
#ifndef MBEDTLS_CIPHER_WRAP_H
|
||||||
#define MBEDTLS_CIPHER_WRAP_H
|
#define MBEDTLS_CIPHER_WRAP_H
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
#include "config.h"
|
#include "mbedtls/config.h"
|
||||||
#else
|
#else
|
||||||
#include MBEDTLS_CONFIG_FILE
|
#include MBEDTLS_CONFIG_FILE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "cipher.h"
|
#include "mbedtls/cipher.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||||
|
#include "psa/crypto.h"
|
||||||
|
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -43,77 +43,102 @@ extern "C" {
|
|||||||
/**
|
/**
|
||||||
* Base cipher information. The non-mode specific functions and values.
|
* Base cipher information. The non-mode specific functions and values.
|
||||||
*/
|
*/
|
||||||
struct mbedtls_cipher_base_t {
|
struct mbedtls_cipher_base_t
|
||||||
|
{
|
||||||
/** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */
|
/** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */
|
||||||
mbedtls_cipher_id_t cipher;
|
mbedtls_cipher_id_t cipher;
|
||||||
|
|
||||||
/** Encrypt using ECB */
|
/** Encrypt using ECB */
|
||||||
int (*ecb_func)(void *ctx, mbedtls_operation_t mode,
|
int (*ecb_func)( void *ctx, mbedtls_operation_t mode,
|
||||||
const unsigned char *input, unsigned char *output);
|
const unsigned char *input, unsigned char *output );
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||||
/** Encrypt using CBC */
|
/** Encrypt using CBC */
|
||||||
int (*cbc_func)(void *ctx, mbedtls_operation_t mode, size_t length,
|
int (*cbc_func)( void *ctx, mbedtls_operation_t mode, size_t length,
|
||||||
unsigned char *iv, const unsigned char *input,
|
unsigned char *iv, const unsigned char *input,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||||
/** Encrypt using CFB (Full length) */
|
/** Encrypt using CFB (Full length) */
|
||||||
int (*cfb_func)(void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off,
|
int (*cfb_func)( void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off,
|
||||||
unsigned char *iv, const unsigned char *input,
|
unsigned char *iv, const unsigned char *input,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_OFB)
|
#if defined(MBEDTLS_CIPHER_MODE_OFB)
|
||||||
/** Encrypt using OFB (Full length) */
|
/** Encrypt using OFB (Full length) */
|
||||||
int (*ofb_func)(void *ctx, size_t length, size_t *iv_off,
|
int (*ofb_func)( void *ctx, size_t length, size_t *iv_off,
|
||||||
unsigned char *iv,
|
unsigned char *iv,
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
||||||
/** Encrypt using CTR */
|
/** Encrypt using CTR */
|
||||||
int (*ctr_func)(void *ctx, size_t length, size_t *nc_off,
|
int (*ctr_func)( void *ctx, size_t length, size_t *nc_off,
|
||||||
unsigned char *nonce_counter, unsigned char *stream_block,
|
unsigned char *nonce_counter, unsigned char *stream_block,
|
||||||
const unsigned char *input, unsigned char *output);
|
const unsigned char *input, unsigned char *output );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||||
/** Encrypt or decrypt using XTS. */
|
/** Encrypt or decrypt using XTS. */
|
||||||
int (*xts_func)(void *ctx, mbedtls_operation_t mode, size_t length,
|
int (*xts_func)( void *ctx, mbedtls_operation_t mode, size_t length,
|
||||||
const unsigned char data_unit[16],
|
const unsigned char data_unit[16],
|
||||||
const unsigned char *input, unsigned char *output);
|
const unsigned char *input, unsigned char *output );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_STREAM)
|
#if defined(MBEDTLS_CIPHER_MODE_STREAM)
|
||||||
/** Encrypt using STREAM */
|
/** Encrypt using STREAM */
|
||||||
int (*stream_func)(void *ctx, size_t length,
|
int (*stream_func)( void *ctx, size_t length,
|
||||||
const unsigned char *input, unsigned char *output);
|
const unsigned char *input, unsigned char *output );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Set key for encryption purposes */
|
/** Set key for encryption purposes */
|
||||||
int (*setkey_enc_func)(void *ctx, const unsigned char *key,
|
int (*setkey_enc_func)( void *ctx, const unsigned char *key,
|
||||||
unsigned int key_bitlen);
|
unsigned int key_bitlen );
|
||||||
|
|
||||||
/** Set key for decryption purposes */
|
/** Set key for decryption purposes */
|
||||||
int (*setkey_dec_func)(void *ctx, const unsigned char *key,
|
int (*setkey_dec_func)( void *ctx, const unsigned char *key,
|
||||||
unsigned int key_bitlen);
|
unsigned int key_bitlen);
|
||||||
|
|
||||||
/** Allocate a new context */
|
/** Allocate a new context */
|
||||||
void *(*ctx_alloc_func)(void);
|
void * (*ctx_alloc_func)( void );
|
||||||
|
|
||||||
/** Free the given context */
|
/** Free the given context */
|
||||||
void (*ctx_free_func)(void *ctx);
|
void (*ctx_free_func)( void *ctx );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
mbedtls_cipher_type_t type;
|
mbedtls_cipher_type_t type;
|
||||||
const mbedtls_cipher_info_t *info;
|
const mbedtls_cipher_info_t *info;
|
||||||
} mbedtls_cipher_definition_t;
|
} mbedtls_cipher_definition_t;
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
MBEDTLS_CIPHER_PSA_KEY_UNSET = 0,
|
||||||
|
MBEDTLS_CIPHER_PSA_KEY_OWNED, /* Used for PSA-based cipher contexts which */
|
||||||
|
/* use raw key material internally imported */
|
||||||
|
/* as a volatile key, and which hence need */
|
||||||
|
/* to destroy that key when the context is */
|
||||||
|
/* freed. */
|
||||||
|
MBEDTLS_CIPHER_PSA_KEY_NOT_OWNED, /* Used for PSA-based cipher contexts */
|
||||||
|
/* which use a key provided by the */
|
||||||
|
/* user, and which hence will not be */
|
||||||
|
/* destroyed when the context is freed. */
|
||||||
|
} mbedtls_cipher_psa_key_ownership;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
psa_algorithm_t alg;
|
||||||
|
psa_key_id_t slot;
|
||||||
|
mbedtls_cipher_psa_key_ownership slot_state;
|
||||||
|
} mbedtls_cipher_context_psa;
|
||||||
|
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||||
|
|
||||||
extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[];
|
extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[];
|
||||||
|
|
||||||
extern int mbedtls_cipher_supported[];
|
extern int mbedtls_cipher_supported[];
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -7,35 +7,38 @@
|
|||||||
* Authentication is defined in <em>RFC-4493: The AES-CMAC Algorithm</em>.
|
* Authentication is defined in <em>RFC-4493: The AES-CMAC Algorithm</em>.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2018, Arm Limited (or its affiliates), All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of Mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MBEDTLS_CMAC_H
|
#ifndef MBEDTLS_CMAC_H
|
||||||
#define MBEDTLS_CMAC_H
|
#define MBEDTLS_CMAC_H
|
||||||
|
|
||||||
#include "cipher.h"
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mbedtls/cipher.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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_ERR_CMAC_HW_ACCEL_FAILED -0x007A /**< CMAC hardware accelerator failed. */
|
||||||
|
|
||||||
#define MBEDTLS_AES_BLOCK_SIZE 16
|
#define MBEDTLS_AES_BLOCK_SIZE 16
|
||||||
@@ -52,7 +55,8 @@ extern "C" {
|
|||||||
/**
|
/**
|
||||||
* The CMAC context structure.
|
* The CMAC context structure.
|
||||||
*/
|
*/
|
||||||
struct mbedtls_cmac_context_t {
|
struct mbedtls_cmac_context_t
|
||||||
|
{
|
||||||
/** The internal state of the CMAC algorithm. */
|
/** The internal state of the CMAC algorithm. */
|
||||||
unsigned char state[MBEDTLS_CIPHER_BLKSIZE_MAX];
|
unsigned char state[MBEDTLS_CIPHER_BLKSIZE_MAX];
|
||||||
|
|
||||||
@@ -84,8 +88,8 @@ struct mbedtls_cmac_context_t {
|
|||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return A cipher-specific error code on failure.
|
* \return A cipher-specific error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx,
|
int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
|
||||||
const unsigned char *key, size_t keybits);
|
const unsigned char *key, size_t keybits );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function feeds an input buffer into an ongoing CMAC
|
* \brief This function feeds an input buffer into an ongoing CMAC
|
||||||
@@ -103,8 +107,8 @@ int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx,
|
|||||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
|
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
|
||||||
* if parameter verification fails.
|
* if parameter verification fails.
|
||||||
*/
|
*/
|
||||||
int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
|
int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
|
||||||
const unsigned char *input, size_t ilen);
|
const unsigned char *input, size_t ilen );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function finishes the CMAC operation, and writes
|
* \brief This function finishes the CMAC operation, and writes
|
||||||
@@ -121,8 +125,8 @@ int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
|
|||||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
|
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
|
||||||
* if parameter verification fails.
|
* if parameter verification fails.
|
||||||
*/
|
*/
|
||||||
int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx,
|
int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function prepares the authentication of another
|
* \brief This function prepares the authentication of another
|
||||||
@@ -138,7 +142,7 @@ int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx,
|
|||||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
|
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
|
||||||
* if parameter verification fails.
|
* if parameter verification fails.
|
||||||
*/
|
*/
|
||||||
int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx);
|
int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function calculates the full generic CMAC
|
* \brief This function calculates the full generic CMAC
|
||||||
@@ -162,10 +166,10 @@ int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx);
|
|||||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
|
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
|
||||||
* if parameter verification fails.
|
* if parameter verification fails.
|
||||||
*/
|
*/
|
||||||
int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info,
|
int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
|
||||||
const unsigned char *key, size_t keylen,
|
const unsigned char *key, size_t keylen,
|
||||||
const unsigned char *input, size_t ilen,
|
const unsigned char *input, size_t ilen,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
|
|
||||||
#if defined(MBEDTLS_AES_C)
|
#if defined(MBEDTLS_AES_C)
|
||||||
/**
|
/**
|
||||||
@@ -185,9 +189,9 @@ int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info,
|
|||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
*/
|
*/
|
||||||
int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_len,
|
int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_len,
|
||||||
const unsigned char *input, size_t in_len,
|
const unsigned char *input, size_t in_len,
|
||||||
unsigned char *output);
|
unsigned char output[16] );
|
||||||
#endif /* MBEDTLS_AES_C */
|
#endif /* MBEDTLS_AES_C */
|
||||||
|
|
||||||
#if defined(MBEDTLS_SELF_TEST) && ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) )
|
#if defined(MBEDTLS_SELF_TEST) && ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) )
|
||||||
@@ -197,7 +201,7 @@ int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_len,
|
|||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return \c 1 on failure.
|
* \return \c 1 on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_cmac_self_test(int verbose);
|
int mbedtls_cmac_self_test( int verbose );
|
||||||
#endif /* MBEDTLS_SELF_TEST && ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
|
#endif /* MBEDTLS_SELF_TEST && ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
53
common/mbedtls/common.h
Normal file
53
common/mbedtls/common.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* \file common.h
|
||||||
|
*
|
||||||
|
* \brief Utility macros for internal use in the library
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MBEDTLS_LIBRARY_COMMON_H
|
||||||
|
#define MBEDTLS_LIBRARY_COMMON_H
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#else
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Helper to define a function as static except when building invasive tests.
|
||||||
|
*
|
||||||
|
* If a function is only used inside its own source file and should be
|
||||||
|
* declared `static` to allow the compiler to optimize for code size,
|
||||||
|
* but that function has unit tests, define it with
|
||||||
|
* ```
|
||||||
|
* MBEDTLS_STATIC_TESTABLE int mbedtls_foo(...) { ... }
|
||||||
|
* ```
|
||||||
|
* and declare it in a header in the `library/` directory with
|
||||||
|
* ```
|
||||||
|
* #if defined(MBEDTLS_TEST_HOOKS)
|
||||||
|
* int mbedtls_foo(...);
|
||||||
|
* #endif
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
#if defined(MBEDTLS_TEST_HOOKS)
|
||||||
|
#define MBEDTLS_STATIC_TESTABLE
|
||||||
|
#else
|
||||||
|
#define MBEDTLS_STATIC_TESTABLE static
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_LIBRARY_COMMON_H */
|
||||||
2529
common/mbedtls/compat-1.3.h
Normal file
2529
common/mbedtls/compat-1.3.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
544
common/mbedtls/config_psa.h
Normal file
544
common/mbedtls/config_psa.h
Normal file
@@ -0,0 +1,544 @@
|
|||||||
|
/**
|
||||||
|
* \file mbedtls/config_psa.h
|
||||||
|
* \brief PSA crypto configuration options (set of defines)
|
||||||
|
*
|
||||||
|
* This set of compile-time options takes settings defined in
|
||||||
|
* include/mbedtls/config.h and include/psa/crypto_config.h and uses
|
||||||
|
* those definitions to define symbols used in the library code.
|
||||||
|
*
|
||||||
|
* Users and integrators should not edit this file, please edit
|
||||||
|
* include/mbedtls/config.h for MBETLS_XXX settings or
|
||||||
|
* include/psa/crypto_config.h for PSA_WANT_XXX settings.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MBEDTLS_CONFIG_PSA_H
|
||||||
|
#define MBEDTLS_CONFIG_PSA_H
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
|
||||||
|
#include "psa/crypto_config.h"
|
||||||
|
#endif /* defined(MBEDTLS_PSA_CRYPTO_CONFIG) */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA 1
|
||||||
|
#define MBEDTLS_ECDSA_DETERMINISTIC
|
||||||
|
#define MBEDTLS_ECDSA_C
|
||||||
|
#define MBEDTLS_HMAC_DRBG_C
|
||||||
|
#define MBEDTLS_MD_C
|
||||||
|
#endif /* !MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA */
|
||||||
|
#endif /* PSA_WANT_ALG_DETERMINISTIC_ECDSA */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_ECDH)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_ALG_ECDH)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_ECDH 1
|
||||||
|
#define MBEDTLS_ECDH_C
|
||||||
|
#define MBEDTLS_ECP_C
|
||||||
|
#define MBEDTLS_BIGNUM_C
|
||||||
|
#endif /* !MBEDTLS_PSA_ACCEL_ALG_ECDH */
|
||||||
|
#endif /* PSA_WANT_ALG_ECDH */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_ECDSA)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_ECDSA 1
|
||||||
|
#define MBEDTLS_ECDSA_C
|
||||||
|
#endif /* !MBEDTLS_PSA_ACCEL_ALG_ECDSA */
|
||||||
|
#endif /* PSA_WANT_ALG_ECDSA */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_HKDF)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF 1
|
||||||
|
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF */
|
||||||
|
#endif /* PSA_WANT_ALG_HKDF */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_HMAC)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HMAC)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
|
||||||
|
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HMAC */
|
||||||
|
#endif /* PSA_WANT_ALG_HMAC */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_MD2) && !defined(MBEDTLS_PSA_ACCEL_ALG_MD2)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_MD2 1
|
||||||
|
#define MBEDTLS_MD2_C
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_MD4) && !defined(MBEDTLS_PSA_ACCEL_ALG_MD4)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_MD4 1
|
||||||
|
#define MBEDTLS_MD4_C
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_MD5) && !defined(MBEDTLS_PSA_ACCEL_ALG_MD5)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_MD5 1
|
||||||
|
#define MBEDTLS_MD5_C
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_RIPEMD160) && !defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160 1
|
||||||
|
#define MBEDTLS_RIPEMD160_C
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_RSA_OAEP)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP 1
|
||||||
|
#define MBEDTLS_RSA_C
|
||||||
|
#define MBEDTLS_BIGNUM_C
|
||||||
|
#define MBEDTLS_OID_C
|
||||||
|
#define MBEDTLS_PKCS1_V21
|
||||||
|
#define MBEDTLS_MD_C
|
||||||
|
#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP */
|
||||||
|
#endif /* PSA_WANT_ALG_RSA_OAEP */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT 1
|
||||||
|
#define MBEDTLS_RSA_C
|
||||||
|
#define MBEDTLS_BIGNUM_C
|
||||||
|
#define MBEDTLS_OID_C
|
||||||
|
#define MBEDTLS_PKCS1_V15
|
||||||
|
#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT */
|
||||||
|
#endif /* PSA_WANT_ALG_RSA_PKCS1V15_CRYPT */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN 1
|
||||||
|
#define MBEDTLS_RSA_C
|
||||||
|
#define MBEDTLS_BIGNUM_C
|
||||||
|
#define MBEDTLS_OID_C
|
||||||
|
#define MBEDTLS_PKCS1_V15
|
||||||
|
#define MBEDTLS_MD_C
|
||||||
|
#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN */
|
||||||
|
#endif /* PSA_WANT_ALG_RSA_PKCS1V15_SIGN */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_RSA_PSS)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PSS)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS 1
|
||||||
|
#define MBEDTLS_RSA_C
|
||||||
|
#define MBEDTLS_BIGNUM_C
|
||||||
|
#define MBEDTLS_OID_C
|
||||||
|
#define MBEDTLS_PKCS1_V21
|
||||||
|
#define MBEDTLS_MD_C
|
||||||
|
#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PSS */
|
||||||
|
#endif /* PSA_WANT_ALG_RSA_PSS */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_SHA_1) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_1 1
|
||||||
|
#define MBEDTLS_SHA1_C
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_SHA_224) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_224 1
|
||||||
|
#define MBEDTLS_SHA256_C
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_SHA_256) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_256 1
|
||||||
|
#define MBEDTLS_SHA256_C
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_SHA_384) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_384 1
|
||||||
|
#define MBEDTLS_SHA512_C
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_SHA_512) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_512 1
|
||||||
|
#define MBEDTLS_SHA512_C
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_TLS12_PRF)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF 1
|
||||||
|
#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF */
|
||||||
|
#endif /* PSA_WANT_ALG_TLS12_PRF */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_TLS12_PSK_TO_MS)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS 1
|
||||||
|
#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS */
|
||||||
|
#endif /* PSA_WANT_ALG_TLS12_PSK_TO_MS */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR 1
|
||||||
|
#define MBEDTLS_ECP_C
|
||||||
|
#define MBEDTLS_BIGNUM_C
|
||||||
|
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR */
|
||||||
|
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1
|
||||||
|
#define MBEDTLS_ECP_C
|
||||||
|
#define MBEDTLS_BIGNUM_C
|
||||||
|
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY */
|
||||||
|
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR 1
|
||||||
|
#define MBEDTLS_RSA_C
|
||||||
|
#define MBEDTLS_BIGNUM_C
|
||||||
|
#define MBEDTLS_OID_C
|
||||||
|
#define MBEDTLS_GENPRIME
|
||||||
|
#define MBEDTLS_PK_PARSE_C
|
||||||
|
#define MBEDTLS_PK_WRITE_C
|
||||||
|
#define MBEDTLS_PK_C
|
||||||
|
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR */
|
||||||
|
#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY 1
|
||||||
|
#define MBEDTLS_RSA_C
|
||||||
|
#define MBEDTLS_BIGNUM_C
|
||||||
|
#define MBEDTLS_OID_C
|
||||||
|
#define MBEDTLS_PK_PARSE_C
|
||||||
|
#define MBEDTLS_PK_WRITE_C
|
||||||
|
#define MBEDTLS_PK_C
|
||||||
|
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY */
|
||||||
|
#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY */
|
||||||
|
|
||||||
|
/* If any of the block modes are requested that don't have an
|
||||||
|
* associated HW assist, define PSA_HAVE_SOFT_BLOCK_MODE for checking
|
||||||
|
* in the block cipher key types. */
|
||||||
|
#if (defined(PSA_WANT_ALG_CTR) && !defined(MBEDTLS_PSA_ACCEL_ALG_CTR)) || \
|
||||||
|
(defined(PSA_WANT_ALG_CFB) && !defined(MBEDTLS_PSA_ACCEL_ALG_CFB)) || \
|
||||||
|
(defined(PSA_WANT_ALG_OFB) && !defined(MBEDTLS_PSA_ACCEL_ALG_OFB)) || \
|
||||||
|
(defined(PSA_WANT_ALG_XTS) && !defined(MBEDTLS_PSA_ACCEL_ALG_XTS)) || \
|
||||||
|
defined(PSA_WANT_ALG_ECB_NO_PADDING) || \
|
||||||
|
(defined(PSA_WANT_ALG_CBC_NO_PADDING) && \
|
||||||
|
!defined(MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING)) || \
|
||||||
|
(defined(PSA_WANT_ALG_CBC_PKCS7) && \
|
||||||
|
!defined(MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7))
|
||||||
|
#define PSA_HAVE_SOFT_BLOCK_MODE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_KEY_TYPE_AES)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_AES)
|
||||||
|
#define PSA_HAVE_SOFT_KEY_TYPE_AES 1
|
||||||
|
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_AES */
|
||||||
|
#if defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
|
||||||
|
defined(PSA_HAVE_SOFT_BLOCK_MODE)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES 1
|
||||||
|
#define MBEDTLS_AES_C
|
||||||
|
#endif /* PSA_HAVE_SOFT_KEY_TYPE_AES || PSA_HAVE_SOFT_BLOCK_MODE */
|
||||||
|
#endif /* PSA_WANT_KEY_TYPE_AES */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_KEY_TYPE_ARC4)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ARC4)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARC4 1
|
||||||
|
#define MBEDTLS_ARC4_C
|
||||||
|
#endif /*!MBEDTLS_PSA_ACCEL_KEY_TYPE_ARC4 */
|
||||||
|
#endif /* PSA_WANT_KEY_TYPE_ARC4 */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_KEY_TYPE_CAMELLIA)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA)
|
||||||
|
#define PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA 1
|
||||||
|
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA */
|
||||||
|
#if defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA) || \
|
||||||
|
defined(PSA_HAVE_SOFT_BLOCK_MODE)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA 1
|
||||||
|
#define MBEDTLS_CAMELLIA_C
|
||||||
|
#endif /* PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA || PSA_HAVE_SOFT_BLOCK_MODE */
|
||||||
|
#endif /* PSA_WANT_KEY_TYPE_CAMELLIA */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_KEY_TYPE_DES)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DES)
|
||||||
|
#define PSA_HAVE_SOFT_KEY_TYPE_DES 1
|
||||||
|
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DES */
|
||||||
|
#if defined(PSA_HAVE_SOFT_KEY_TYPE_DES) || \
|
||||||
|
defined(PSA_HAVE_SOFT_BLOCK_MODE)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES 1
|
||||||
|
#define MBEDTLS_DES_C
|
||||||
|
#endif /*PSA_HAVE_SOFT_KEY_TYPE_DES || PSA_HAVE_SOFT_BLOCK_MODE */
|
||||||
|
#endif /* PSA_WANT_KEY_TYPE_DES */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_KEY_TYPE_CHACHA20)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CHACHA20)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20 1
|
||||||
|
#define MBEDTLS_CHACHA20_C
|
||||||
|
#endif /*!MBEDTLS_PSA_ACCEL_KEY_TYPE_CHACHA20 */
|
||||||
|
#endif /* PSA_WANT_KEY_TYPE_CHACHA20 */
|
||||||
|
|
||||||
|
/* If any of the software block ciphers are selected, define
|
||||||
|
* PSA_HAVE_SOFT_BLOCK_CIPHER, which can be used in any of these
|
||||||
|
* situations. */
|
||||||
|
#if defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
|
||||||
|
defined(PSA_HAVE_SOFT_KEY_TYPE_DES) || \
|
||||||
|
defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA)
|
||||||
|
#define PSA_HAVE_SOFT_BLOCK_CIPHER 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_STREAM_CIPHER)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER 1
|
||||||
|
#endif /* PSA_WANT_ALG_STREAM_CIPHER */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_CTR)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CTR) || \
|
||||||
|
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_CTR 1
|
||||||
|
#define MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
#endif
|
||||||
|
#endif /* PSA_WANT_ALG_CTR */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_CFB)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CFB) || \
|
||||||
|
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_CFB 1
|
||||||
|
#define MBEDTLS_CIPHER_MODE_CFB
|
||||||
|
#endif
|
||||||
|
#endif /* PSA_WANT_ALG_CFB */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_OFB)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_ALG_OFB) || \
|
||||||
|
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_OFB 1
|
||||||
|
#define MBEDTLS_CIPHER_MODE_OFB
|
||||||
|
#endif
|
||||||
|
#endif /* PSA_WANT_ALG_OFB */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_XTS)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_ALG_XTS) || \
|
||||||
|
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_XTS 1
|
||||||
|
#define MBEDTLS_CIPHER_MODE_XTS
|
||||||
|
#endif
|
||||||
|
#endif /* PSA_WANT_ALG_XTS */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_ECB_NO_PADDING)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING) || \
|
||||||
|
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
|
||||||
|
#define MBEDTLS_CIPHER_MODE_CBC
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING 1
|
||||||
|
#endif
|
||||||
|
#endif /* PSA_WANT_ALG_CBC_NO_PADDING */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_CBC_PKCS7)
|
||||||
|
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7) || \
|
||||||
|
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
|
||||||
|
#define MBEDTLS_CIPHER_MODE_CBC
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 1
|
||||||
|
#define MBEDTLS_CIPHER_PADDING_PKCS7
|
||||||
|
#endif
|
||||||
|
#endif /* PSA_WANT_ALG_CBC_PKCS7 */
|
||||||
|
|
||||||
|
#if defined(PSA_WANT_ALG_CHACHA20_POLY1305)
|
||||||
|
#if defined(PSA_WANT_KEY_TYPE_CHACHA20)
|
||||||
|
#define MBEDTLS_CHACHAPOLY_C
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 1
|
||||||
|
#endif /* PSA_WANT_KEY_TYPE_CHACHA20 */
|
||||||
|
#endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */
|
||||||
|
|
||||||
|
#else /* MBEDTLS_PSA_CRYPTO_CONFIG */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure PSA_WANT_* defines are setup properly if MBEDTLS_PSA_CRYPTO_CONFIG
|
||||||
|
* is not defined
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDH_C)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_ECDH 1
|
||||||
|
#define PSA_WANT_ALG_ECDH 1
|
||||||
|
#endif /* MBEDTLS_ECDH_C */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDSA_C)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_ECDSA 1
|
||||||
|
#define PSA_WANT_ALG_ECDSA 1
|
||||||
|
|
||||||
|
// Only add in DETERMINISTIC support if ECDSA is also enabled
|
||||||
|
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA 1
|
||||||
|
#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1
|
||||||
|
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_ECDSA_C */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_C)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR 1
|
||||||
|
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR 1
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1
|
||||||
|
#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1
|
||||||
|
#endif /* MBEDTLS_ECP_C */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_HKDF_C)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
|
||||||
|
#define PSA_WANT_ALG_HMAC 1
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF 1
|
||||||
|
#define PSA_WANT_ALG_HKDF 1
|
||||||
|
#endif /* MBEDTLS_HKDF_C */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_MD_C)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
|
||||||
|
#define PSA_WANT_ALG_HMAC 1
|
||||||
|
#define PSA_WANT_KEY_TYPE_HMAC
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF 1
|
||||||
|
#define PSA_WANT_ALG_TLS12_PRF 1
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS 1
|
||||||
|
#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1
|
||||||
|
#endif /* MBEDTLS_MD_C */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_MD2_C)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_MD2 1
|
||||||
|
#define PSA_WANT_ALG_MD2 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_MD4_C)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_MD4 1
|
||||||
|
#define PSA_WANT_ALG_MD4 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_MD5_C)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_MD5 1
|
||||||
|
#define PSA_WANT_ALG_MD5 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_RIPEMD160_C)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160 1
|
||||||
|
#define PSA_WANT_ALG_RIPEMD160 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_RSA_C)
|
||||||
|
#if defined(MBEDTLS_PKCS1_V15)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT 1
|
||||||
|
#define PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN 1
|
||||||
|
#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1
|
||||||
|
#endif /* MBEDTLSS_PKCS1_V15 */
|
||||||
|
#if defined(MBEDTLS_PKCS1_V21)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP 1
|
||||||
|
#define PSA_WANT_ALG_RSA_OAEP 1
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS 1
|
||||||
|
#define PSA_WANT_ALG_RSA_PSS 1
|
||||||
|
#endif /* MBEDTLS_PKCS1_V21 */
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR 1
|
||||||
|
#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR 1
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY 1
|
||||||
|
#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1
|
||||||
|
#endif /* MBEDTLS_RSA_C */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SHA1_C)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_1 1
|
||||||
|
#define PSA_WANT_ALG_SHA_1 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SHA256_C)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_224 1
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_256 1
|
||||||
|
#define PSA_WANT_ALG_SHA_224 1
|
||||||
|
#define PSA_WANT_ALG_SHA_256 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SHA512_C)
|
||||||
|
#if !defined(MBEDTLS_SHA512_NO_SHA384)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_384 1
|
||||||
|
#define PSA_WANT_ALG_SHA_384 1
|
||||||
|
#endif
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_512 1
|
||||||
|
#define PSA_WANT_ALG_SHA_512 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_AES_C)
|
||||||
|
#define PSA_WANT_KEY_TYPE_AES 1
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ARC4_C)
|
||||||
|
#define PSA_WANT_KEY_TYPE_ARC4 1
|
||||||
|
#define PSA_WANT_ALG_STREAM_CIPHER 1
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARC4 1
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_CAMELLIA_C)
|
||||||
|
#define PSA_WANT_KEY_TYPE_CAMELLIA 1
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_DES_C)
|
||||||
|
#define PSA_WANT_KEY_TYPE_DES 1
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_CHACHA20_C)
|
||||||
|
#define PSA_WANT_KEY_TYPE_CHACHA20 1
|
||||||
|
#define PSA_WANT_ALG_STREAM_CIPHER 1
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20 1
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER 1
|
||||||
|
#if defined(MBEDTLS_CHACHAPOLY_C)
|
||||||
|
#define PSA_WANT_ALG_CHACHA20_POLY1305 1
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING 1
|
||||||
|
#define PSA_WANT_ALG_CBC_NO_PADDING 1
|
||||||
|
#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 1
|
||||||
|
#define PSA_WANT_ALG_CBC_PKCS7 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) || \
|
||||||
|
defined(MBEDTLS_CAMELLIA_C)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING 1
|
||||||
|
#define PSA_WANT_ALG_ECB_NO_PADDING 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_CFB 1
|
||||||
|
#define PSA_WANT_ALG_CFB 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_CTR 1
|
||||||
|
#define PSA_WANT_ALG_CTR 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_CIPHER_MODE_OFB)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_OFB 1
|
||||||
|
#define PSA_WANT_ALG_OFB 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||||
|
#define MBEDTLS_PSA_BUILTIN_ALG_XTS 1
|
||||||
|
#define PSA_WANT_ALG_XTS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_PSA_CRYPTO_CONFIG */
|
||||||
|
|
||||||
|
/* These features are always enabled. */
|
||||||
|
#define PSA_WANT_KEY_TYPE_DERIVE 1
|
||||||
|
#define PSA_WANT_KEY_TYPE_RAW_DATA 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_CONFIG_PSA_H */
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,44 +1,56 @@
|
|||||||
/**
|
/**
|
||||||
* \file ctr_drbg.h
|
* \file ctr_drbg.h
|
||||||
*
|
*
|
||||||
* \brief This file contains CTR_DRBG definitions and functions.
|
* \brief This file contains definitions and functions for the
|
||||||
|
* CTR_DRBG pseudorandom generator.
|
||||||
*
|
*
|
||||||
* CTR_DRBG is a standardized way of building a PRNG from a block-cipher
|
* 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:
|
* in counter mode operation, as defined in <em>NIST SP 800-90A:
|
||||||
* Recommendation for Random Number Generation Using Deterministic Random
|
* Recommendation for Random Number Generation Using Deterministic Random
|
||||||
* Bit Generators</em>.
|
* Bit Generators</em>.
|
||||||
*
|
*
|
||||||
* The Mbed TLS implementation of CTR_DRBG uses AES-256 as the underlying
|
* The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128
|
||||||
* block cipher.
|
* (if \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled at compile time)
|
||||||
|
* as the underlying block cipher, with a derivation function.
|
||||||
|
*
|
||||||
|
* The security strength as defined in NIST SP 800-90A is
|
||||||
|
* 128 bits when AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled)
|
||||||
|
* and 256 bits otherwise, provided that #MBEDTLS_CTR_DRBG_ENTROPY_LEN is
|
||||||
|
* kept at its default value (and not overridden in config.h) and that the
|
||||||
|
* DRBG instance is set up with default parameters.
|
||||||
|
* See the documentation of mbedtls_ctr_drbg_seed() for more
|
||||||
|
* information.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of Mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MBEDTLS_CTR_DRBG_H
|
#ifndef MBEDTLS_CTR_DRBG_H
|
||||||
#define MBEDTLS_CTR_DRBG_H
|
#define MBEDTLS_CTR_DRBG_H
|
||||||
|
|
||||||
#include "aes.h"
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mbedtls/aes.h"
|
||||||
|
|
||||||
#if defined(MBEDTLS_THREADING_C)
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
#include "threading.h"
|
#include "mbedtls/threading.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */
|
#define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */
|
||||||
@@ -47,7 +59,23 @@
|
|||||||
#define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A /**< Read or write error in file. */
|
#define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A /**< Read or write error in file. */
|
||||||
|
|
||||||
#define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< The block size used by the cipher. */
|
#define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< The block size used by the cipher. */
|
||||||
#define MBEDTLS_CTR_DRBG_KEYSIZE 32 /**< The key 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
|
||||||
|
|
||||||
#define MBEDTLS_CTR_DRBG_KEYBITS ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 ) /**< The key size for the DRBG operation, in bits. */
|
#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). */
|
#define MBEDTLS_CTR_DRBG_SEEDLEN ( MBEDTLS_CTR_DRBG_KEYSIZE + MBEDTLS_CTR_DRBG_BLOCKSIZE ) /**< The seed length, calculated as (counter + AES key). */
|
||||||
|
|
||||||
@@ -60,21 +88,31 @@
|
|||||||
* \{
|
* \{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/** \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_CTR_DRBG_ENTROPY_LEN)
|
||||||
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
|
#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
|
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48
|
||||||
/**< The amount of entropy used per seed by default:
|
|
||||||
* <ul><li>48 with SHA-512.</li>
|
#else /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */
|
||||||
* <li>32 with SHA-256.</li></ul>
|
|
||||||
|
/** This is 32 bytes because the entropy module uses SHA-256
|
||||||
|
* (the SHA512 module is disabled or
|
||||||
|
* \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled).
|
||||||
*/
|
*/
|
||||||
#else
|
#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) */
|
||||||
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32
|
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32
|
||||||
/**< Amount of entropy used per seed by default:
|
#endif /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */
|
||||||
* <ul><li>48 with SHA-512.</li>
|
#endif /* !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) */
|
||||||
* <li>32 with SHA-256.</li></ul>
|
|
||||||
*/
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL)
|
#if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL)
|
||||||
#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000
|
#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000
|
||||||
@@ -93,7 +131,7 @@
|
|||||||
|
|
||||||
#if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT)
|
#if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT)
|
||||||
#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384
|
#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384
|
||||||
/**< The maximum size of seed or reseed buffer. */
|
/**< The maximum size of seed or reseed buffer in bytes. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* \} name SECTION: Module settings */
|
/* \} name SECTION: Module settings */
|
||||||
@@ -107,19 +145,49 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MBEDTLS_CTR_DRBG_ENTROPY_LEN >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
|
||||||
|
/** The default length of the nonce read from the entropy source.
|
||||||
|
*
|
||||||
|
* This is \c 0 because a single read from the entropy source is sufficient
|
||||||
|
* to include a nonce.
|
||||||
|
* See the documentation of mbedtls_ctr_drbg_seed() for more information.
|
||||||
|
*/
|
||||||
|
#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN 0
|
||||||
|
#else
|
||||||
|
/** The default length of the nonce read from the entropy source.
|
||||||
|
*
|
||||||
|
* This is half of the default entropy length because a single read from
|
||||||
|
* the entropy source does not provide enough material to form a nonce.
|
||||||
|
* See the documentation of mbedtls_ctr_drbg_seed() for more information.
|
||||||
|
*/
|
||||||
|
#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN ( MBEDTLS_CTR_DRBG_ENTROPY_LEN + 1 ) / 2
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief The CTR_DRBG context structure.
|
* \brief The CTR_DRBG context structure.
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_ctr_drbg_context {
|
typedef struct mbedtls_ctr_drbg_context
|
||||||
|
{
|
||||||
unsigned char counter[16]; /*!< The counter (V). */
|
unsigned char counter[16]; /*!< The counter (V). */
|
||||||
int reseed_counter; /*!< The reseed counter. */
|
int reseed_counter; /*!< The reseed counter.
|
||||||
|
* This is the number of requests that have
|
||||||
|
* been made since the last (re)seeding,
|
||||||
|
* minus one.
|
||||||
|
* Before the initial seeding, this field
|
||||||
|
* contains the amount of entropy in bytes
|
||||||
|
* to use as a nonce for the initial seeding,
|
||||||
|
* or -1 if no nonce length has been explicitly
|
||||||
|
* set (see mbedtls_ctr_drbg_set_nonce_len()).
|
||||||
|
*/
|
||||||
int prediction_resistance; /*!< This determines whether prediction
|
int prediction_resistance; /*!< This determines whether prediction
|
||||||
resistance is enabled, that is
|
resistance is enabled, that is
|
||||||
whether to systematically reseed before
|
whether to systematically reseed before
|
||||||
each random generation. */
|
each random generation. */
|
||||||
size_t entropy_len; /*!< The amount of entropy grabbed on each
|
size_t entropy_len; /*!< The amount of entropy grabbed on each
|
||||||
seed or reseed operation. */
|
seed or reseed operation, in bytes. */
|
||||||
int reseed_interval; /*!< The reseed interval. */
|
int reseed_interval; /*!< The reseed interval.
|
||||||
|
* This is the maximum number of requests
|
||||||
|
* that can be made between reseedings. */
|
||||||
|
|
||||||
mbedtls_aes_context aes_ctx; /*!< The AES context. */
|
mbedtls_aes_context aes_ctx; /*!< The AES context. */
|
||||||
|
|
||||||
@@ -127,11 +195,18 @@ typedef struct mbedtls_ctr_drbg_context {
|
|||||||
* Callbacks (Entropy)
|
* Callbacks (Entropy)
|
||||||
*/
|
*/
|
||||||
int (*f_entropy)(void *, unsigned char *, size_t);
|
int (*f_entropy)(void *, unsigned char *, size_t);
|
||||||
/*!< The entropy callback function. */
|
/*!< The entropy callback function. */
|
||||||
|
|
||||||
void *p_entropy; /*!< The context for the entropy function. */
|
void *p_entropy; /*!< The context for the entropy function. */
|
||||||
|
|
||||||
#if defined(MBEDTLS_THREADING_C)
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
/* Invariant: the mutex is initialized if and only if f_entropy != NULL.
|
||||||
|
* This means that the mutex is initialized during the initial seeding
|
||||||
|
* in mbedtls_ctr_drbg_seed() and freed in mbedtls_ctr_drbg_free().
|
||||||
|
*
|
||||||
|
* Note that this invariant may change without notice. Do not rely on it
|
||||||
|
* and do not access the mutex directly in application code.
|
||||||
|
*/
|
||||||
mbedtls_threading_mutex_t mutex;
|
mbedtls_threading_mutex_t mutex;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -142,95 +217,330 @@ mbedtls_ctr_drbg_context;
|
|||||||
* and prepares it for mbedtls_ctr_drbg_seed()
|
* and prepares it for mbedtls_ctr_drbg_seed()
|
||||||
* or mbedtls_ctr_drbg_free().
|
* or mbedtls_ctr_drbg_free().
|
||||||
*
|
*
|
||||||
|
* \note The reseed interval is
|
||||||
|
* #MBEDTLS_CTR_DRBG_RESEED_INTERVAL by default.
|
||||||
|
* You can override it by calling
|
||||||
|
* mbedtls_ctr_drbg_set_reseed_interval().
|
||||||
|
*
|
||||||
* \param ctx The CTR_DRBG context to initialize.
|
* \param ctx The CTR_DRBG context to initialize.
|
||||||
*/
|
*/
|
||||||
void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx);
|
void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function seeds and sets up the CTR_DRBG
|
* \brief This function seeds and sets up the CTR_DRBG
|
||||||
* entropy source for future reseeds.
|
* entropy source for future reseeds.
|
||||||
*
|
*
|
||||||
* \note Personalization data can be provided in addition to the more generic
|
* A typical choice for the \p f_entropy and \p p_entropy parameters is
|
||||||
* entropy source, to make this instantiation as unique as possible.
|
* 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).
|
||||||
|
*
|
||||||
|
* The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default.
|
||||||
|
* You can override it by calling mbedtls_ctr_drbg_set_entropy_len().
|
||||||
|
*
|
||||||
|
* The entropy nonce length is:
|
||||||
|
* - \c 0 if the entropy length is at least 3/2 times the entropy length,
|
||||||
|
* which guarantees that the security strength is the maximum permitted
|
||||||
|
* by the key size and entropy length according to NIST SP 800-90A §10.2.1;
|
||||||
|
* - Half the entropy length otherwise.
|
||||||
|
* You can override it by calling mbedtls_ctr_drbg_set_nonce_len().
|
||||||
|
* With the default entropy length, the entropy nonce length is
|
||||||
|
* #MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN.
|
||||||
|
*
|
||||||
|
* You can provide a nonce and personalization string in addition to the
|
||||||
|
* entropy source, to make this instantiation as unique as possible.
|
||||||
|
* See SP 800-90A §8.6.7 for more details about nonces.
|
||||||
|
*
|
||||||
|
* 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 following strings:
|
||||||
|
* - A string obtained by calling \p f_entropy function for the entropy
|
||||||
|
* length.
|
||||||
|
*/
|
||||||
|
#if MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN == 0
|
||||||
|
/**
|
||||||
|
* - If mbedtls_ctr_drbg_set_nonce_len() has been called, a string
|
||||||
|
* obtained by calling \p f_entropy function for the specified length.
|
||||||
|
*/
|
||||||
|
#else
|
||||||
|
/**
|
||||||
|
* - A string obtained by calling \p f_entropy function for the entropy nonce
|
||||||
|
* length. If the entropy nonce length is \c 0, this function does not
|
||||||
|
* make a second call to \p f_entropy.
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
/**
|
||||||
|
* \note When Mbed TLS is built with threading support,
|
||||||
|
* after this function returns successfully,
|
||||||
|
* it is safe to call mbedtls_ctr_drbg_random()
|
||||||
|
* from multiple threads. Other operations, including
|
||||||
|
* reseeding, are not thread-safe.
|
||||||
|
*/
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
/**
|
||||||
|
* - The \p custom string.
|
||||||
|
*
|
||||||
|
* \note To achieve the nominal security strength permitted
|
||||||
|
* by CTR_DRBG, the entropy length must be:
|
||||||
|
* - at least 16 bytes for a 128-bit strength
|
||||||
|
* (maximum achievable strength when using AES-128);
|
||||||
|
* - at least 32 bytes for a 256-bit strength
|
||||||
|
* (maximum achievable strength when using AES-256).
|
||||||
|
*
|
||||||
|
* In addition, if you do not pass a nonce in \p custom,
|
||||||
|
* the sum of the entropy length
|
||||||
|
* and the entropy nonce length must be:
|
||||||
|
* - at least 24 bytes for a 128-bit strength
|
||||||
|
* (maximum achievable strength when using AES-128);
|
||||||
|
* - at least 48 bytes for a 256-bit strength
|
||||||
|
* (maximum achievable strength when using AES-256).
|
||||||
*
|
*
|
||||||
* \param ctx The CTR_DRBG context to seed.
|
* \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.
|
||||||
|
* After a failed call to mbedtls_ctr_drbg_seed(),
|
||||||
|
* you must call mbedtls_ctr_drbg_free().
|
||||||
* \param f_entropy The entropy callback, taking as arguments the
|
* \param f_entropy The entropy callback, taking as arguments the
|
||||||
* \p p_entropy context, the buffer to fill, and the
|
* \p p_entropy context, the buffer to fill, and the
|
||||||
length of the buffer.
|
* length of the buffer.
|
||||||
* \param p_entropy The entropy context.
|
* \p f_entropy is always called with a buffer size
|
||||||
* \param custom Personalization data, that is device-specific
|
* less than or equal to the entropy length.
|
||||||
identifiers. Can be NULL.
|
* \param p_entropy The entropy context to pass to \p f_entropy.
|
||||||
* \param len The length of the personalization data.
|
* \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.
|
||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
|
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context *ctx,
|
int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
|
||||||
int (*f_entropy)(void *, unsigned char *, size_t),
|
int (*f_entropy)(void *, unsigned char *, size_t),
|
||||||
void *p_entropy,
|
void *p_entropy,
|
||||||
const unsigned char *custom,
|
const unsigned char *custom,
|
||||||
size_t len);
|
size_t len );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function clears CTR_CRBG context data.
|
* \brief This function resets CTR_DRBG context to the state immediately
|
||||||
|
* after initial call of mbedtls_ctr_drbg_init().
|
||||||
*
|
*
|
||||||
* \param ctx The CTR_DRBG context to clear.
|
* \param ctx The CTR_DRBG context to clear.
|
||||||
*/
|
*/
|
||||||
void mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context *ctx);
|
void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function turns prediction resistance on or off.
|
* \brief This function turns prediction resistance on or off.
|
||||||
* The default value is off.
|
* The default value is off.
|
||||||
*
|
*
|
||||||
* \note If enabled, entropy is gathered at the beginning of
|
* \note If enabled, entropy is gathered at the beginning of
|
||||||
* every call to mbedtls_ctr_drbg_random_with_add().
|
* every call to mbedtls_ctr_drbg_random_with_add()
|
||||||
|
* or mbedtls_ctr_drbg_random().
|
||||||
* Only use this if your entropy source has sufficient
|
* Only use this if your entropy source has sufficient
|
||||||
* throughput.
|
* throughput.
|
||||||
*
|
*
|
||||||
* \param ctx The CTR_DRBG context.
|
* \param ctx The CTR_DRBG context.
|
||||||
* \param resistance #MBEDTLS_CTR_DRBG_PR_ON or #MBEDTLS_CTR_DRBG_PR_OFF.
|
* \param resistance #MBEDTLS_CTR_DRBG_PR_ON or #MBEDTLS_CTR_DRBG_PR_OFF.
|
||||||
*/
|
*/
|
||||||
void mbedtls_ctr_drbg_set_prediction_resistance(mbedtls_ctr_drbg_context *ctx,
|
void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
|
||||||
int resistance);
|
int resistance );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function sets the amount of entropy grabbed on each
|
* \brief This function sets the amount of entropy grabbed on each
|
||||||
* seed or reseed. The default value is
|
* seed or reseed.
|
||||||
* #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
|
*
|
||||||
|
* 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.
|
||||||
*
|
*
|
||||||
* \param ctx The CTR_DRBG context.
|
* \param ctx The CTR_DRBG context.
|
||||||
* \param len The amount of entropy to grab.
|
* \param len The amount of entropy to grab, in bytes.
|
||||||
|
* This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
|
||||||
|
* and at most the maximum length accepted by the
|
||||||
|
* entropy function that is set in the context.
|
||||||
*/
|
*/
|
||||||
void mbedtls_ctr_drbg_set_entropy_len(mbedtls_ctr_drbg_context *ctx,
|
void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
|
||||||
size_t len);
|
size_t len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function sets the amount of entropy grabbed
|
||||||
|
* as a nonce for the initial seeding.
|
||||||
|
*
|
||||||
|
* Call this function before calling mbedtls_ctr_drbg_seed() to read
|
||||||
|
* a nonce from the entropy source during the initial seeding.
|
||||||
|
*
|
||||||
|
* \param ctx The CTR_DRBG context.
|
||||||
|
* \param len The amount of entropy to grab for the nonce, in bytes.
|
||||||
|
* This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
|
||||||
|
* and at most the maximum length accepted by the
|
||||||
|
* entropy function that is set in the context.
|
||||||
|
*
|
||||||
|
* \return \c 0 on success.
|
||||||
|
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if \p len is
|
||||||
|
* more than #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
|
||||||
|
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
|
||||||
|
* if the initial seeding has already taken place.
|
||||||
|
*/
|
||||||
|
int mbedtls_ctr_drbg_set_nonce_len( mbedtls_ctr_drbg_context *ctx,
|
||||||
|
size_t len );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function sets the reseed interval.
|
* \brief This function sets the reseed interval.
|
||||||
* The default value is #MBEDTLS_CTR_DRBG_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.
|
||||||
*
|
*
|
||||||
* \param ctx The CTR_DRBG context.
|
* \param ctx The CTR_DRBG context.
|
||||||
* \param interval The reseed interval.
|
* \param interval The reseed interval.
|
||||||
*/
|
*/
|
||||||
void mbedtls_ctr_drbg_set_reseed_interval(mbedtls_ctr_drbg_context *ctx,
|
void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
|
||||||
int interval);
|
int interval );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function reseeds the CTR_DRBG context, that is
|
* \brief This function reseeds the CTR_DRBG context, that is
|
||||||
* extracts data from the entropy source.
|
* extracts data from the entropy source.
|
||||||
*
|
*
|
||||||
|
* \note This function is not thread-safe. It is not safe
|
||||||
|
* to call this function if another thread might be
|
||||||
|
* concurrently obtaining random numbers from the same
|
||||||
|
* context or updating or reseeding the same context.
|
||||||
|
*
|
||||||
* \param ctx The CTR_DRBG context.
|
* \param ctx The CTR_DRBG context.
|
||||||
* \param additional Additional data to add to the state. Can be NULL.
|
* \param additional Additional data to add to the state. Can be \c NULL.
|
||||||
* \param len The length of the additional data.
|
* \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 \c 0 on success.
|
||||||
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
|
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_ctr_drbg_reseed(mbedtls_ctr_drbg_context *ctx,
|
int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
|
||||||
const unsigned char *additional, size_t len);
|
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.
|
||||||
*
|
*
|
||||||
|
* \note This function is not thread-safe. It is not safe
|
||||||
|
* to call this function if another thread might be
|
||||||
|
* concurrently obtaining random numbers from the same
|
||||||
|
* context or updating or reseeding the same 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.
|
||||||
|
*
|
||||||
|
* \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 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 This function is not thread-safe. It is not safe
|
||||||
|
* to call this function if another thread might be
|
||||||
|
* concurrently obtaining random numbers from the same
|
||||||
|
* context or updating or reseeding the same context.
|
||||||
|
*
|
||||||
|
* \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.
|
||||||
|
*
|
||||||
|
* \return \c 0 on success.
|
||||||
|
* \return #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,
|
||||||
|
unsigned char *output, size_t output_len,
|
||||||
|
const unsigned char *additional, size_t add_len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function uses CTR_DRBG to generate random data.
|
||||||
|
*
|
||||||
|
* This function automatically reseeds if the reseed counter is exceeded
|
||||||
|
* or prediction resistance is enabled.
|
||||||
|
*/
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
/**
|
||||||
|
* \note When Mbed TLS is built with threading support,
|
||||||
|
* it is safe to call mbedtls_ctr_drbg_random()
|
||||||
|
* from multiple threads. Other operations, including
|
||||||
|
* reseeding, are not thread-safe.
|
||||||
|
*/
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
/**
|
||||||
|
* \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.
|
||||||
|
*
|
||||||
|
* \return \c 0 on success.
|
||||||
|
* \return #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
|
* \note If \p add_len is greater than
|
||||||
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, only the first
|
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, only the first
|
||||||
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used.
|
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used.
|
||||||
@@ -239,48 +549,13 @@ int mbedtls_ctr_drbg_reseed(mbedtls_ctr_drbg_context *ctx,
|
|||||||
* \param ctx The CTR_DRBG context.
|
* \param ctx The CTR_DRBG context.
|
||||||
* \param additional The data to update the state with.
|
* \param additional The data to update the state with.
|
||||||
* \param add_len Length of \p additional data.
|
* \param add_len Length of \p additional data.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
void mbedtls_ctr_drbg_update(mbedtls_ctr_drbg_context *ctx,
|
MBEDTLS_DEPRECATED void mbedtls_ctr_drbg_update(
|
||||||
const unsigned char *additional, size_t add_len);
|
mbedtls_ctr_drbg_context *ctx,
|
||||||
|
const unsigned char *additional,
|
||||||
/**
|
size_t add_len );
|
||||||
* \brief This function updates a CTR_DRBG instance with additional
|
#undef MBEDTLS_DEPRECATED
|
||||||
* data and uses it to generate random data.
|
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||||
*
|
|
||||||
* \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.
|
|
||||||
* \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
|
|
||||||
* #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief This function uses CTR_DRBG to generate random data.
|
|
||||||
*
|
|
||||||
* \note The function automatically reseeds if the reseed counter is exceeded.
|
|
||||||
*
|
|
||||||
* \param p_rng The CTR_DRBG context. This must be a pointer to a
|
|
||||||
* #mbedtls_ctr_drbg_context structure.
|
|
||||||
* \param output The buffer to fill.
|
|
||||||
* \param output_len The length of the buffer.
|
|
||||||
*
|
|
||||||
* \return \c 0 on success.
|
|
||||||
* \return #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_FS_IO)
|
#if defined(MBEDTLS_FS_IO)
|
||||||
/**
|
/**
|
||||||
@@ -291,10 +566,10 @@ int mbedtls_ctr_drbg_random(void *p_rng,
|
|||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
|
* \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
|
||||||
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on
|
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on reseed
|
||||||
* failure.
|
* failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_ctr_drbg_write_seed_file(mbedtls_ctr_drbg_context *ctx, const char *path);
|
int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function reads and updates a seed file. The seed
|
* \brief This function reads and updates a seed file. The seed
|
||||||
@@ -305,24 +580,25 @@ int mbedtls_ctr_drbg_write_seed_file(mbedtls_ctr_drbg_context *ctx, const char *
|
|||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
|
* \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
|
||||||
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
|
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on
|
||||||
* #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG on failure.
|
* reseed failure.
|
||||||
|
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if the existing
|
||||||
|
* seed file is too large.
|
||||||
*/
|
*/
|
||||||
int mbedtls_ctr_drbg_update_seed_file(mbedtls_ctr_drbg_context *ctx, const char *path);
|
int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
|
||||||
#endif /* MBEDTLS_FS_IO */
|
#endif /* MBEDTLS_FS_IO */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief The CTR_DRBG checkup routine.
|
* \brief The CTR_DRBG checkup routine.
|
||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return \c 1 on failure.
|
* \return \c 1 on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_ctr_drbg_self_test(int verbose);
|
int mbedtls_ctr_drbg_self_test( int verbose );
|
||||||
|
|
||||||
/* Internal functions (do not call directly) */
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
int mbedtls_ctr_drbg_seed_entropy_len(mbedtls_ctr_drbg_context *,
|
|
||||||
int (*)(void *, unsigned char *, size_t), void *,
|
|
||||||
const unsigned char *, size_t, size_t);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
434
common/mbedtls/debug.c
Normal file
434
common/mbedtls/debug.c
Normal file
@@ -0,0 +1,434 @@
|
|||||||
|
/*
|
||||||
|
* Debugging routines
|
||||||
|
*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_DEBUG_C)
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PLATFORM_C)
|
||||||
|
#include "mbedtls/platform.h"
|
||||||
|
#else
|
||||||
|
#include <stdlib.h>
|
||||||
|
#define mbedtls_calloc calloc
|
||||||
|
#define mbedtls_free free
|
||||||
|
#define mbedtls_time_t time_t
|
||||||
|
#define mbedtls_snprintf snprintf
|
||||||
|
#define mbedtls_vsnprintf vsnprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mbedtls/debug.h"
|
||||||
|
#include "mbedtls/error.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
|
||||||
|
}
|
||||||
|
|
||||||
|
MBEDTLS_PRINTF_ATTRIBUTE(5, 6)
|
||||||
|
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 = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
|
if( NULL == ssl ||
|
||||||
|
NULL == ssl->conf ||
|
||||||
|
NULL == ssl->conf->f_dbg ||
|
||||||
|
level > debug_threshold )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_start( argp, format );
|
||||||
|
ret = mbedtls_vsnprintf( str, DEBUG_BUF_SIZE, format, argp );
|
||||||
|
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( NULL == ssl ||
|
||||||
|
NULL == ssl->conf ||
|
||||||
|
NULL == ssl->conf->f_dbg ||
|
||||||
|
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, (unsigned int) -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( NULL == ssl ||
|
||||||
|
NULL == ssl->conf ||
|
||||||
|
NULL == ssl->conf->f_dbg ||
|
||||||
|
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( NULL == ssl ||
|
||||||
|
NULL == ssl->conf ||
|
||||||
|
NULL == ssl->conf->f_dbg ||
|
||||||
|
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( NULL == ssl ||
|
||||||
|
NULL == ssl->conf ||
|
||||||
|
NULL == ssl->conf->f_dbg ||
|
||||||
|
NULL == X ||
|
||||||
|
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( NULL == ssl ||
|
||||||
|
NULL == ssl->conf ||
|
||||||
|
NULL == ssl->conf->f_dbg ||
|
||||||
|
NULL == crt ||
|
||||||
|
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 */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDH_C)
|
||||||
|
static void mbedtls_debug_printf_ecdh_internal( const mbedtls_ssl_context *ssl,
|
||||||
|
int level, const char *file,
|
||||||
|
int line,
|
||||||
|
const mbedtls_ecdh_context *ecdh,
|
||||||
|
mbedtls_debug_ecdh_attr attr )
|
||||||
|
{
|
||||||
|
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||||
|
const mbedtls_ecdh_context* ctx = ecdh;
|
||||||
|
#else
|
||||||
|
const mbedtls_ecdh_context_mbed* ctx = &ecdh->ctx.mbed_ecdh;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch( attr )
|
||||||
|
{
|
||||||
|
case MBEDTLS_DEBUG_ECDH_Q:
|
||||||
|
mbedtls_debug_print_ecp( ssl, level, file, line, "ECDH: Q",
|
||||||
|
&ctx->Q );
|
||||||
|
break;
|
||||||
|
case MBEDTLS_DEBUG_ECDH_QP:
|
||||||
|
mbedtls_debug_print_ecp( ssl, level, file, line, "ECDH: Qp",
|
||||||
|
&ctx->Qp );
|
||||||
|
break;
|
||||||
|
case MBEDTLS_DEBUG_ECDH_Z:
|
||||||
|
mbedtls_debug_print_mpi( ssl, level, file, line, "ECDH: z",
|
||||||
|
&ctx->z );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||||
|
mbedtls_debug_printf_ecdh_internal( ssl, level, file, line, ecdh, attr );
|
||||||
|
#else
|
||||||
|
switch( ecdh->var )
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
mbedtls_debug_printf_ecdh_internal( ssl, level, file, line, ecdh,
|
||||||
|
attr );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_ECDH_C */
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_DEBUG_C */
|
||||||
306
common/mbedtls/debug.h
Normal file
306
common/mbedtls/debug.h
Normal file
@@ -0,0 +1,306 @@
|
|||||||
|
/**
|
||||||
|
* \file debug.h
|
||||||
|
*
|
||||||
|
* \brief Functions for controlling and providing debug output from the library.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef MBEDTLS_DEBUG_H
|
||||||
|
#define MBEDTLS_DEBUG_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mbedtls/ssl.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_C)
|
||||||
|
#include "mbedtls/ecp.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_DEBUG_C)
|
||||||
|
|
||||||
|
#define MBEDTLS_DEBUG_STRIP_PARENS( ... ) __VA_ARGS__
|
||||||
|
|
||||||
|
#define MBEDTLS_SSL_DEBUG_MSG( level, args ) \
|
||||||
|
mbedtls_debug_print_msg( ssl, level, __FILE__, __LINE__, \
|
||||||
|
MBEDTLS_DEBUG_STRIP_PARENS args )
|
||||||
|
|
||||||
|
#define MBEDTLS_SSL_DEBUG_RET( level, text, ret ) \
|
||||||
|
mbedtls_debug_print_ret( ssl, level, __FILE__, __LINE__, text, ret )
|
||||||
|
|
||||||
|
#define MBEDTLS_SSL_DEBUG_BUF( level, text, buf, len ) \
|
||||||
|
mbedtls_debug_print_buf( ssl, level, __FILE__, __LINE__, text, buf, len )
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_BIGNUM_C)
|
||||||
|
#define MBEDTLS_SSL_DEBUG_MPI( level, text, X ) \
|
||||||
|
mbedtls_debug_print_mpi( ssl, level, __FILE__, __LINE__, text, X )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_C)
|
||||||
|
#define MBEDTLS_SSL_DEBUG_ECP( level, text, X ) \
|
||||||
|
mbedtls_debug_print_ecp( ssl, level, __FILE__, __LINE__, text, X )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||||
|
#define MBEDTLS_SSL_DEBUG_CRT( level, text, crt ) \
|
||||||
|
mbedtls_debug_print_crt( ssl, level, __FILE__, __LINE__, text, crt )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
|
||||||
|
#define MBEDTLS_SSL_DEBUG_MSG( level, args ) do { } while( 0 )
|
||||||
|
#define MBEDTLS_SSL_DEBUG_RET( level, text, ret ) do { } while( 0 )
|
||||||
|
#define MBEDTLS_SSL_DEBUG_BUF( level, text, buf, len ) do { } while( 0 )
|
||||||
|
#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 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def MBEDTLS_PRINTF_ATTRIBUTE
|
||||||
|
*
|
||||||
|
* Mark a function as having printf attributes, and thus enable checking
|
||||||
|
* via -wFormat and other flags. This does nothing on builds with compilers
|
||||||
|
* that do not support the format attribute
|
||||||
|
*
|
||||||
|
* Module: library/debug.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module provides debugging functions.
|
||||||
|
*/
|
||||||
|
#if defined(__has_attribute)
|
||||||
|
#if __has_attribute(format)
|
||||||
|
#define MBEDTLS_PRINTF_ATTRIBUTE(string_index, first_to_check) \
|
||||||
|
__attribute__((format (printf, string_index, first_to_check)))
|
||||||
|
#else /* __has_attribute(format) */
|
||||||
|
#define MBEDTLS_PRINTF_ATTRIBUTE(string_index, first_to_check)
|
||||||
|
#endif /* __has_attribute(format) */
|
||||||
|
#else /* defined(__has_attribute) */
|
||||||
|
#define MBEDTLS_PRINTF_ATTRIBUTE(string_index, first_to_check)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def MBEDTLS_PRINTF_SIZET
|
||||||
|
*
|
||||||
|
* MBEDTLS_PRINTF_xxx: Due to issues with older window compilers
|
||||||
|
* and MinGW we need to define the printf specifier for size_t
|
||||||
|
* and long long per platform.
|
||||||
|
*
|
||||||
|
* Module: library/debug.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module provides debugging functions.
|
||||||
|
*/
|
||||||
|
#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1800)
|
||||||
|
#include <inttypes.h>
|
||||||
|
#define MBEDTLS_PRINTF_SIZET PRIuPTR
|
||||||
|
#define MBEDTLS_PRINTF_LONGLONG "I64d"
|
||||||
|
#else /* defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1800) */
|
||||||
|
#define MBEDTLS_PRINTF_SIZET "zu"
|
||||||
|
#define MBEDTLS_PRINTF_LONGLONG "lld"
|
||||||
|
#endif /* defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1800) */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set the threshold error level to handle globally all debug output.
|
||||||
|
* Debug messages that have a level over the threshold value are
|
||||||
|
* discarded.
|
||||||
|
* (Default value: 0 = No debug )
|
||||||
|
*
|
||||||
|
* \param threshold theshold level of messages to filter on. Messages at a
|
||||||
|
* higher level will be discarded.
|
||||||
|
* - Debug levels
|
||||||
|
* - 0 No debug
|
||||||
|
* - 1 Error
|
||||||
|
* - 2 State change
|
||||||
|
* - 3 Informational
|
||||||
|
* - 4 Verbose
|
||||||
|
*/
|
||||||
|
void mbedtls_debug_set_threshold( int threshold );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Print a message to the debug output. This function is always used
|
||||||
|
* through the MBEDTLS_SSL_DEBUG_MSG() 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 message has occurred in
|
||||||
|
* \param line line number the message has occurred at
|
||||||
|
* \param format format specifier, in printf format
|
||||||
|
* \param ... variables used by the format specifier
|
||||||
|
*
|
||||||
|
* \attention This function is intended for INTERNAL usage within the
|
||||||
|
* library only.
|
||||||
|
*/
|
||||||
|
void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
|
||||||
|
const char *file, int line,
|
||||||
|
const char *format, ... ) MBEDTLS_PRINTF_ATTRIBUTE(5, 6);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Print the return value of a function to the debug output. This
|
||||||
|
* function is always used through the MBEDTLS_SSL_DEBUG_RET() 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 text the name of the function that returned the error
|
||||||
|
* \param ret the return code value
|
||||||
|
*
|
||||||
|
* \attention This function is intended for INTERNAL usage within the
|
||||||
|
* library only.
|
||||||
|
*/
|
||||||
|
void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level,
|
||||||
|
const char *file, int line,
|
||||||
|
const char *text, int ret );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Output a buffer of size len bytes to the debug output. This function
|
||||||
|
* is always used through the MBEDTLS_SSL_DEBUG_BUF() 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 text a name or label for the buffer being dumped. Normally the
|
||||||
|
* variable or buffer name
|
||||||
|
* \param buf the buffer to be outputted
|
||||||
|
* \param len length of the buffer
|
||||||
|
*
|
||||||
|
* \attention This function is intended for INTERNAL usage within the
|
||||||
|
* library only.
|
||||||
|
*/
|
||||||
|
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 );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_BIGNUM_C)
|
||||||
|
/**
|
||||||
|
* \brief Print a MPI variable to the debug output. This function is always
|
||||||
|
* used through the MBEDTLS_SSL_DEBUG_MPI() 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 text a name or label for the MPI being output. Normally the
|
||||||
|
* variable name
|
||||||
|
* \param X the MPI variable
|
||||||
|
*
|
||||||
|
* \attention This function is intended for INTERNAL usage within the
|
||||||
|
* library only.
|
||||||
|
*/
|
||||||
|
void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level,
|
||||||
|
const char *file, int line,
|
||||||
|
const char *text, const mbedtls_mpi *X );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_C)
|
||||||
|
/**
|
||||||
|
* \brief Print an ECP point to the debug output. This function is always
|
||||||
|
* used through the MBEDTLS_SSL_DEBUG_ECP() 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 text a name or label for the ECP point being output. Normally the
|
||||||
|
* variable name
|
||||||
|
* \param X the ECP point
|
||||||
|
*
|
||||||
|
* \attention This function is intended for INTERNAL usage within the
|
||||||
|
* library only.
|
||||||
|
*/
|
||||||
|
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 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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,
|
||||||
|
* 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 text a name or label for the certificate being output
|
||||||
|
* \param crt X.509 certificate structure
|
||||||
|
*
|
||||||
|
* \attention This function is intended for INTERNAL usage within the
|
||||||
|
* library only.
|
||||||
|
*/
|
||||||
|
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 );
|
||||||
|
#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
@@ -8,31 +8,27 @@
|
|||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifndef MBEDTLS_DES_H
|
#ifndef MBEDTLS_DES_H
|
||||||
#define MBEDTLS_DES_H
|
#define MBEDTLS_DES_H
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
#include "config.h"
|
#include "mbedtls/config.h"
|
||||||
#else
|
#else
|
||||||
#include MBEDTLS_CONFIG_FILE
|
#include MBEDTLS_CONFIG_FILE
|
||||||
#endif
|
#endif
|
||||||
@@ -44,6 +40,8 @@
|
|||||||
#define MBEDTLS_DES_DECRYPT 0
|
#define MBEDTLS_DES_DECRYPT 0
|
||||||
|
|
||||||
#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */
|
#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_ERR_DES_HW_ACCEL_FAILED -0x0033 /**< DES hardware accelerator failed. */
|
||||||
|
|
||||||
#define MBEDTLS_DES_KEY_SIZE 8
|
#define MBEDTLS_DES_KEY_SIZE 8
|
||||||
@@ -63,7 +61,8 @@ extern "C" {
|
|||||||
* security risk. We recommend considering stronger ciphers
|
* security risk. We recommend considering stronger ciphers
|
||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_des_context {
|
typedef struct mbedtls_des_context
|
||||||
|
{
|
||||||
uint32_t sk[32]; /*!< DES subkeys */
|
uint32_t sk[32]; /*!< DES subkeys */
|
||||||
}
|
}
|
||||||
mbedtls_des_context;
|
mbedtls_des_context;
|
||||||
@@ -71,7 +70,8 @@ mbedtls_des_context;
|
|||||||
/**
|
/**
|
||||||
* \brief Triple-DES context structure
|
* \brief Triple-DES context structure
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_des3_context {
|
typedef struct mbedtls_des3_context
|
||||||
|
{
|
||||||
uint32_t sk[96]; /*!< 3DES subkeys */
|
uint32_t sk[96]; /*!< 3DES subkeys */
|
||||||
}
|
}
|
||||||
mbedtls_des3_context;
|
mbedtls_des3_context;
|
||||||
@@ -89,7 +89,7 @@ mbedtls_des3_context;
|
|||||||
* security risk. We recommend considering stronger ciphers
|
* security risk. We recommend considering stronger ciphers
|
||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
void mbedtls_des_init(mbedtls_des_context *ctx);
|
void mbedtls_des_init( mbedtls_des_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Clear DES context
|
* \brief Clear DES context
|
||||||
@@ -100,21 +100,21 @@ void mbedtls_des_init(mbedtls_des_context *ctx);
|
|||||||
* security risk. We recommend considering stronger ciphers
|
* security risk. We recommend considering stronger ciphers
|
||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
void mbedtls_des_free(mbedtls_des_context *ctx);
|
void mbedtls_des_free( mbedtls_des_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Initialize Triple-DES context
|
* \brief Initialize Triple-DES context
|
||||||
*
|
*
|
||||||
* \param ctx DES3 context to be initialized
|
* \param ctx DES3 context to be initialized
|
||||||
*/
|
*/
|
||||||
void mbedtls_des3_init(mbedtls_des3_context *ctx);
|
void mbedtls_des3_init( mbedtls_des3_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Clear Triple-DES context
|
* \brief Clear Triple-DES context
|
||||||
*
|
*
|
||||||
* \param ctx DES3 context to be cleared
|
* \param ctx DES3 context to be cleared
|
||||||
*/
|
*/
|
||||||
void mbedtls_des3_free(mbedtls_des3_context *ctx);
|
void mbedtls_des3_free( mbedtls_des3_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Set key parity on the given key to odd.
|
* \brief Set key parity on the given key to odd.
|
||||||
@@ -128,7 +128,7 @@ void mbedtls_des3_free(mbedtls_des3_context *ctx);
|
|||||||
* security risk. We recommend considering stronger ciphers
|
* security risk. We recommend considering stronger ciphers
|
||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
void mbedtls_des_key_set_parity(unsigned char key[MBEDTLS_DES_KEY_SIZE]);
|
void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Check that key parity on the given key is odd.
|
* \brief Check that key parity on the given key is odd.
|
||||||
@@ -144,7 +144,7 @@ void mbedtls_des_key_set_parity(unsigned char key[MBEDTLS_DES_KEY_SIZE]);
|
|||||||
* security risk. We recommend considering stronger ciphers
|
* security risk. We recommend considering stronger ciphers
|
||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
int mbedtls_des_key_check_key_parity(const unsigned char key[MBEDTLS_DES_KEY_SIZE]);
|
int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Check that key is not a weak or semi-weak DES key
|
* \brief Check that key is not a weak or semi-weak DES key
|
||||||
@@ -157,7 +157,7 @@ int mbedtls_des_key_check_key_parity(const unsigned char key[MBEDTLS_DES_KEY_SIZ
|
|||||||
* security risk. We recommend considering stronger ciphers
|
* security risk. We recommend considering stronger ciphers
|
||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
int mbedtls_des_key_check_weak(const unsigned char key[MBEDTLS_DES_KEY_SIZE]);
|
int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief DES key schedule (56-bit, encryption)
|
* \brief DES key schedule (56-bit, encryption)
|
||||||
@@ -171,7 +171,7 @@ int mbedtls_des_key_check_weak(const unsigned char key[MBEDTLS_DES_KEY_SIZE]);
|
|||||||
* security risk. We recommend considering stronger ciphers
|
* security risk. We recommend considering stronger ciphers
|
||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
int mbedtls_des_setkey_enc(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]);
|
int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief DES key schedule (56-bit, decryption)
|
* \brief DES key schedule (56-bit, decryption)
|
||||||
@@ -185,7 +185,7 @@ int mbedtls_des_setkey_enc(mbedtls_des_context *ctx, const unsigned char key[MBE
|
|||||||
* security risk. We recommend considering stronger ciphers
|
* security risk. We recommend considering stronger ciphers
|
||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
int mbedtls_des_setkey_dec(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]);
|
int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Triple-DES key schedule (112-bit, encryption)
|
* \brief Triple-DES key schedule (112-bit, encryption)
|
||||||
@@ -195,8 +195,8 @@ int mbedtls_des_setkey_dec(mbedtls_des_context *ctx, const unsigned char key[MBE
|
|||||||
*
|
*
|
||||||
* \return 0
|
* \return 0
|
||||||
*/
|
*/
|
||||||
int mbedtls_des3_set2key_enc(mbedtls_des3_context *ctx,
|
int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
|
||||||
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2]);
|
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Triple-DES key schedule (112-bit, decryption)
|
* \brief Triple-DES key schedule (112-bit, decryption)
|
||||||
@@ -206,8 +206,8 @@ int mbedtls_des3_set2key_enc(mbedtls_des3_context *ctx,
|
|||||||
*
|
*
|
||||||
* \return 0
|
* \return 0
|
||||||
*/
|
*/
|
||||||
int mbedtls_des3_set2key_dec(mbedtls_des3_context *ctx,
|
int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
|
||||||
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2]);
|
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Triple-DES key schedule (168-bit, encryption)
|
* \brief Triple-DES key schedule (168-bit, encryption)
|
||||||
@@ -217,8 +217,8 @@ int mbedtls_des3_set2key_dec(mbedtls_des3_context *ctx,
|
|||||||
*
|
*
|
||||||
* \return 0
|
* \return 0
|
||||||
*/
|
*/
|
||||||
int mbedtls_des3_set3key_enc(mbedtls_des3_context *ctx,
|
int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
|
||||||
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3]);
|
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Triple-DES key schedule (168-bit, decryption)
|
* \brief Triple-DES key schedule (168-bit, decryption)
|
||||||
@@ -228,8 +228,8 @@ int mbedtls_des3_set3key_enc(mbedtls_des3_context *ctx,
|
|||||||
*
|
*
|
||||||
* \return 0
|
* \return 0
|
||||||
*/
|
*/
|
||||||
int mbedtls_des3_set3key_dec(mbedtls_des3_context *ctx,
|
int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
|
||||||
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3]);
|
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief DES-ECB block encryption/decryption
|
* \brief DES-ECB block encryption/decryption
|
||||||
@@ -244,9 +244,9 @@ int mbedtls_des3_set3key_dec(mbedtls_des3_context *ctx,
|
|||||||
* security risk. We recommend considering stronger ciphers
|
* security risk. We recommend considering stronger ciphers
|
||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
int mbedtls_des_crypt_ecb(mbedtls_des_context *ctx,
|
int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
|
||||||
const unsigned char input[8],
|
const unsigned char input[8],
|
||||||
unsigned char output[8]);
|
unsigned char output[8] );
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||||
/**
|
/**
|
||||||
@@ -271,12 +271,12 @@ int mbedtls_des_crypt_ecb(mbedtls_des_context *ctx,
|
|||||||
* security risk. We recommend considering stronger ciphers
|
* security risk. We recommend considering stronger ciphers
|
||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
int mbedtls_des_crypt_cbc(mbedtls_des_context *ctx,
|
int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
|
||||||
int mode,
|
int mode,
|
||||||
size_t length,
|
size_t length,
|
||||||
unsigned char iv[8],
|
unsigned char iv[8],
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -288,9 +288,9 @@ int mbedtls_des_crypt_cbc(mbedtls_des_context *ctx,
|
|||||||
*
|
*
|
||||||
* \return 0 if successful
|
* \return 0 if successful
|
||||||
*/
|
*/
|
||||||
int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx,
|
int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
|
||||||
const unsigned char input[8],
|
const unsigned char input[8],
|
||||||
unsigned char output[8]);
|
unsigned char output[8] );
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||||
/**
|
/**
|
||||||
@@ -313,12 +313,12 @@ int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx,
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH
|
* \return 0 if successful, or MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH
|
||||||
*/
|
*/
|
||||||
int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx,
|
int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
|
||||||
int mode,
|
int mode,
|
||||||
size_t length,
|
size_t length,
|
||||||
unsigned char iv[8],
|
unsigned char iv[8],
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -333,15 +333,19 @@ int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx,
|
|||||||
* security risk. We recommend considering stronger ciphers
|
* security risk. We recommend considering stronger ciphers
|
||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
void mbedtls_des_setkey(uint32_t SK[32],
|
void mbedtls_des_setkey( uint32_t SK[32],
|
||||||
const unsigned char key[MBEDTLS_DES_KEY_SIZE]);
|
const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Checkup routine
|
* \brief Checkup routine
|
||||||
*
|
*
|
||||||
* \return 0 if successful, or 1 if the test failed
|
* \return 0 if successful, or 1 if the test failed
|
||||||
*/
|
*/
|
||||||
int mbedtls_des_self_test(int verbose);
|
int mbedtls_des_self_test( int verbose );
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
735
common/mbedtls/dhm.c
Normal file
735
common/mbedtls/dhm.c
Normal file
@@ -0,0 +1,735 @@
|
|||||||
|
/*
|
||||||
|
* Diffie-Hellman-Merkle key exchange
|
||||||
|
*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* The following sources were referenced in the design of this implementation
|
||||||
|
* of the Diffie-Hellman-Merkle algorithm:
|
||||||
|
*
|
||||||
|
* [1] Handbook of Applied Cryptography - 1997, Chapter 12
|
||||||
|
* Menezes, van Oorschot and Vanstone
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_DHM_C)
|
||||||
|
|
||||||
|
#include "mbedtls/dhm.h"
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||||
|
#include "mbedtls/pem.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ASN1_PARSE_C)
|
||||||
|
#include "mbedtls/asn1.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PLATFORM_C)
|
||||||
|
#include "mbedtls/platform.h"
|
||||||
|
#else
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#define mbedtls_printf printf
|
||||||
|
#define mbedtls_calloc calloc
|
||||||
|
#define mbedtls_free free
|
||||||
|
#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 )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* helper to validate the mbedtls_mpi size and import it
|
||||||
|
*/
|
||||||
|
static int dhm_read_bignum( mbedtls_mpi *X,
|
||||||
|
unsigned char **p,
|
||||||
|
const unsigned char *end )
|
||||||
|
{
|
||||||
|
int ret, n;
|
||||||
|
|
||||||
|
if( end - *p < 2 )
|
||||||
|
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
n = ( (*p)[0] << 8 ) | (*p)[1];
|
||||||
|
(*p) += 2;
|
||||||
|
|
||||||
|
if( (int)( end - *p ) < n )
|
||||||
|
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 )
|
||||||
|
return( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED + ret );
|
||||||
|
|
||||||
|
(*p) += n;
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify sanity of parameter with regards to P
|
||||||
|
*
|
||||||
|
* Parameter should be: 2 <= public_param <= P - 2
|
||||||
|
*
|
||||||
|
* This means that we need to return an error if
|
||||||
|
* public_param < 2 or public_param > P-2
|
||||||
|
*
|
||||||
|
* For more information on the attack, see:
|
||||||
|
* http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
|
||||||
|
* http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
|
||||||
|
*/
|
||||||
|
static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P )
|
||||||
|
{
|
||||||
|
mbedtls_mpi L, U;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U );
|
||||||
|
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) );
|
||||||
|
|
||||||
|
if( mbedtls_mpi_cmp_mpi( param, &L ) < 0 ||
|
||||||
|
mbedtls_mpi_cmp_mpi( param, &U ) > 0 )
|
||||||
|
{
|
||||||
|
ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
mbedtls_mpi_free( &L ); mbedtls_mpi_free( &U );
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
void mbedtls_dhm_init( mbedtls_dhm_context *ctx )
|
||||||
|
{
|
||||||
|
DHM_VALIDATE( ctx != NULL );
|
||||||
|
memset( ctx, 0, sizeof( mbedtls_dhm_context ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse the ServerKeyExchange parameters
|
||||||
|
*/
|
||||||
|
int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
|
||||||
|
unsigned char **p,
|
||||||
|
const unsigned char *end )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
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 ||
|
||||||
|
( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
ctx->len = mbedtls_mpi_size( &ctx->P );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup and write the ServerKeyExchange parameters
|
||||||
|
*/
|
||||||
|
int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
|
||||||
|
unsigned char *output, size_t *olen,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
|
void *p_rng )
|
||||||
|
{
|
||||||
|
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 );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate X as large as possible ( < P )
|
||||||
|
*/
|
||||||
|
do
|
||||||
|
{
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
|
||||||
|
|
||||||
|
while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
|
||||||
|
|
||||||
|
if( count++ > 10 )
|
||||||
|
return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED );
|
||||||
|
}
|
||||||
|
while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate GX = G^X mod P
|
||||||
|
*/
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
|
||||||
|
&ctx->P , &ctx->RP ) );
|
||||||
|
|
||||||
|
if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* export P, G, GX
|
||||||
|
*/
|
||||||
|
#define DHM_MPI_EXPORT( X, n ) \
|
||||||
|
do { \
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ), \
|
||||||
|
p + 2, \
|
||||||
|
( n ) ) ); \
|
||||||
|
*p++ = (unsigned char)( ( n ) >> 8 ); \
|
||||||
|
*p++ = (unsigned char)( ( n ) ); \
|
||||||
|
p += ( n ); \
|
||||||
|
} while( 0 )
|
||||||
|
|
||||||
|
n1 = mbedtls_mpi_size( &ctx->P );
|
||||||
|
n2 = mbedtls_mpi_size( &ctx->G );
|
||||||
|
n3 = mbedtls_mpi_size( &ctx->GX );
|
||||||
|
|
||||||
|
p = output;
|
||||||
|
DHM_MPI_EXPORT( &ctx->P , n1 );
|
||||||
|
DHM_MPI_EXPORT( &ctx->G , n2 );
|
||||||
|
DHM_MPI_EXPORT( &ctx->GX, n3 );
|
||||||
|
|
||||||
|
*olen = p - output;
|
||||||
|
|
||||||
|
ctx->len = n1;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED + ret );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set prime modulus and generator
|
||||||
|
*/
|
||||||
|
int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
|
||||||
|
const mbedtls_mpi *P,
|
||||||
|
const mbedtls_mpi *G )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
DHM_VALIDATE_RET( ctx != NULL );
|
||||||
|
DHM_VALIDATE_RET( P != NULL );
|
||||||
|
DHM_VALIDATE_RET( G != NULL );
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
|
||||||
|
( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_DHM_SET_GROUP_FAILED + ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->len = mbedtls_mpi_size( &ctx->P );
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Import the peer's public value G^Y
|
||||||
|
*/
|
||||||
|
int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
|
||||||
|
const unsigned char *input, size_t ilen )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
DHM_VALIDATE_RET( ctx != NULL );
|
||||||
|
DHM_VALIDATE_RET( input != NULL );
|
||||||
|
|
||||||
|
if( ilen < 1 || ilen > ctx->len )
|
||||||
|
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
|
||||||
|
return( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED + ret );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create own private value X and export G^X
|
||||||
|
*/
|
||||||
|
int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
|
||||||
|
unsigned char *output, size_t olen,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
|
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 )
|
||||||
|
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
|
||||||
|
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* generate X and calculate GX = G^X mod P
|
||||||
|
*/
|
||||||
|
do
|
||||||
|
{
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
|
||||||
|
|
||||||
|
while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
|
||||||
|
|
||||||
|
if( count++ > 10 )
|
||||||
|
return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED );
|
||||||
|
}
|
||||||
|
while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
|
||||||
|
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
|
||||||
|
&ctx->P , &ctx->RP ) );
|
||||||
|
|
||||||
|
if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) );
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED + ret );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pick a random R in the range [2, M) for blinding purposes
|
||||||
|
*/
|
||||||
|
static int dhm_random_below( mbedtls_mpi *R, const mbedtls_mpi *M,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||||
|
{
|
||||||
|
int ret, count;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( R, mbedtls_mpi_size( M ), f_rng, p_rng ) );
|
||||||
|
|
||||||
|
while( mbedtls_mpi_cmp_mpi( R, M ) >= 0 )
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( R, 1 ) );
|
||||||
|
|
||||||
|
if( count++ > 10 )
|
||||||
|
return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
|
||||||
|
}
|
||||||
|
while( mbedtls_mpi_cmp_int( R, 1 ) <= 0 );
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use the blinding method and optimisation suggested in section 10 of:
|
||||||
|
* KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
|
||||||
|
* DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
|
||||||
|
* Berlin Heidelberg, 1996. p. 104-113.
|
||||||
|
*/
|
||||||
|
static int dhm_update_blinding( mbedtls_dhm_context *ctx,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
mbedtls_mpi R;
|
||||||
|
|
||||||
|
mbedtls_mpi_init( &R );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't use any blinding the first time a particular X is used,
|
||||||
|
* but remember it to use blinding next time.
|
||||||
|
*/
|
||||||
|
if( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 )
|
||||||
|
{
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &ctx->pX, &ctx->X ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vi, 1 ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vf, 1 ) );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ok, we need blinding. Can we re-use existing values?
|
||||||
|
* If yes, just update them by squaring them.
|
||||||
|
*/
|
||||||
|
if( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 )
|
||||||
|
{
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) );
|
||||||
|
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to generate blinding values from scratch
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Vi = random( 2, P-1 ) */
|
||||||
|
MBEDTLS_MPI_CHK( dhm_random_below( &ctx->Vi, &ctx->P, f_rng, p_rng ) );
|
||||||
|
|
||||||
|
/* Vf = Vi^-X mod P
|
||||||
|
* First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod),
|
||||||
|
* then elevate to the Xth power. */
|
||||||
|
MBEDTLS_MPI_CHK( dhm_random_below( &R, &ctx->P, f_rng, p_rng ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vi, &R ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vf, &ctx->P ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &R ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
|
||||||
|
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) );
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
mbedtls_mpi_free( &R );
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Derive and export the shared secret (G^Y)^X mod P
|
||||||
|
*/
|
||||||
|
int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
|
||||||
|
unsigned char *output, size_t output_size, size_t *olen,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
|
void *p_rng )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
mbedtls_mpi GYb;
|
||||||
|
DHM_VALIDATE_RET( ctx != NULL );
|
||||||
|
DHM_VALIDATE_RET( output != NULL );
|
||||||
|
DHM_VALIDATE_RET( olen != NULL );
|
||||||
|
|
||||||
|
if( output_size < ctx->len )
|
||||||
|
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
mbedtls_mpi_init( &GYb );
|
||||||
|
|
||||||
|
/* Blind peer's value */
|
||||||
|
if( f_rng != NULL )
|
||||||
|
{
|
||||||
|
MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &GYb, &ctx->GY ) );
|
||||||
|
|
||||||
|
/* Do modular exponentiation */
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X,
|
||||||
|
&ctx->P, &ctx->RP ) );
|
||||||
|
|
||||||
|
/* Unblind secret value */
|
||||||
|
if( f_rng != NULL )
|
||||||
|
{
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
*olen = mbedtls_mpi_size( &ctx->K );
|
||||||
|
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) );
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
mbedtls_mpi_free( &GYb );
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
return( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED + ret );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free the components of a DHM key
|
||||||
|
*/
|
||||||
|
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_platform_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ASN1_PARSE_C)
|
||||||
|
/*
|
||||||
|
* Parse DHM parameters
|
||||||
|
*/
|
||||||
|
int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
|
||||||
|
size_t dhminlen )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
size_t len;
|
||||||
|
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 */
|
||||||
|
if( dhminlen == 0 || dhmin[dhminlen - 1] != '\0' )
|
||||||
|
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
|
||||||
|
else
|
||||||
|
ret = mbedtls_pem_read_buffer( &pem,
|
||||||
|
"-----BEGIN DH PARAMETERS-----",
|
||||||
|
"-----END DH PARAMETERS-----",
|
||||||
|
dhmin, NULL, 0, &dhminlen );
|
||||||
|
|
||||||
|
if( ret == 0 )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Was PEM encoded
|
||||||
|
*/
|
||||||
|
dhminlen = pem.buflen;
|
||||||
|
}
|
||||||
|
else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
|
||||||
|
#else
|
||||||
|
p = (unsigned char *) dhmin;
|
||||||
|
#endif /* MBEDTLS_PEM_PARSE_C */
|
||||||
|
end = p + dhminlen;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DHParams ::= SEQUENCE {
|
||||||
|
* prime INTEGER, -- P
|
||||||
|
* generator INTEGER, -- g
|
||||||
|
* privateValueLength INTEGER OPTIONAL
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
|
||||||
|
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
||||||
|
{
|
||||||
|
ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
end = p + len;
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
|
||||||
|
( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
|
||||||
|
{
|
||||||
|
ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( p != end )
|
||||||
|
{
|
||||||
|
/* This might be the optional privateValueLength.
|
||||||
|
* If so, we can cleanly discard it */
|
||||||
|
mbedtls_mpi rec;
|
||||||
|
mbedtls_mpi_init( &rec );
|
||||||
|
ret = mbedtls_asn1_get_mpi( &p, end, &rec );
|
||||||
|
mbedtls_mpi_free( &rec );
|
||||||
|
if ( ret != 0 )
|
||||||
|
{
|
||||||
|
ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if ( p != end )
|
||||||
|
{
|
||||||
|
ret = MBEDTLS_ERR_DHM_INVALID_FORMAT +
|
||||||
|
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
dhm->len = mbedtls_mpi_size( &dhm->P );
|
||||||
|
|
||||||
|
exit:
|
||||||
|
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||||
|
mbedtls_pem_free( &pem );
|
||||||
|
#endif
|
||||||
|
if( ret != 0 )
|
||||||
|
mbedtls_dhm_free( dhm );
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_FS_IO)
|
||||||
|
/*
|
||||||
|
* Load all data from a file into a given buffer.
|
||||||
|
*
|
||||||
|
* The file is expected to contain either PEM or DER encoded data.
|
||||||
|
* A terminating null byte is always appended. It is included in the announced
|
||||||
|
* length only if the data looks like it is PEM encoded.
|
||||||
|
*/
|
||||||
|
static int load_file( const char *path, unsigned char **buf, size_t *n )
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
long size;
|
||||||
|
|
||||||
|
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||||
|
return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
|
||||||
|
|
||||||
|
fseek( f, 0, SEEK_END );
|
||||||
|
if( ( size = ftell( f ) ) == -1 )
|
||||||
|
{
|
||||||
|
fclose( f );
|
||||||
|
return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
|
||||||
|
}
|
||||||
|
fseek( f, 0, SEEK_SET );
|
||||||
|
|
||||||
|
*n = (size_t) size;
|
||||||
|
|
||||||
|
if( *n + 1 == 0 ||
|
||||||
|
( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
|
||||||
|
{
|
||||||
|
fclose( f );
|
||||||
|
return( MBEDTLS_ERR_DHM_ALLOC_FAILED );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( fread( *buf, 1, *n, f ) != *n )
|
||||||
|
{
|
||||||
|
fclose( f );
|
||||||
|
|
||||||
|
mbedtls_platform_zeroize( *buf, *n + 1 );
|
||||||
|
mbedtls_free( *buf );
|
||||||
|
|
||||||
|
return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose( f );
|
||||||
|
|
||||||
|
(*buf)[*n] = '\0';
|
||||||
|
|
||||||
|
if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL )
|
||||||
|
++*n;
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load and parse DHM parameters
|
||||||
|
*/
|
||||||
|
int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
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_free( buf );
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_FS_IO */
|
||||||
|
#endif /* MBEDTLS_ASN1_PARSE_C */
|
||||||
|
#endif /* MBEDTLS_DHM_ALT */
|
||||||
|
|
||||||
|
#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 );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checkup routine
|
||||||
|
*/
|
||||||
|
int mbedtls_dhm_self_test( int verbose )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
mbedtls_dhm_context dhm;
|
||||||
|
|
||||||
|
mbedtls_dhm_init( &dhm );
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( " DHM parameter load: " );
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_dhm_parse_dhm( &dhm,
|
||||||
|
(const unsigned char *) mbedtls_test_dhm_params,
|
||||||
|
mbedtls_test_dhm_params_len ) ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( "failed\n" );
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( "passed\n\n" );
|
||||||
|
|
||||||
|
exit:
|
||||||
|
mbedtls_dhm_free( &dhm );
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_DHM_C */
|
||||||
1092
common/mbedtls/dhm.h
Normal file
1092
common/mbedtls/dhm.h
Normal file
File diff suppressed because it is too large
Load Diff
729
common/mbedtls/ecdh.c
Normal file
729
common/mbedtls/ecdh.c
Normal file
@@ -0,0 +1,729 @@
|
|||||||
|
/*
|
||||||
|
* Elliptic curve Diffie-Hellman
|
||||||
|
*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* References:
|
||||||
|
*
|
||||||
|
* SEC1 http://www.secg.org/index.php?action=secg,docs_secg
|
||||||
|
* RFC 4492
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDH_C)
|
||||||
|
|
||||||
|
#include "mbedtls/ecdh.h"
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* Parameter validation macros based on platform_util.h */
|
||||||
|
#define ECDH_VALIDATE_RET( cond ) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
|
||||||
|
#define ECDH_VALIDATE( cond ) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||||
|
typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static mbedtls_ecp_group_id mbedtls_ecdh_grp_id(
|
||||||
|
const mbedtls_ecdh_context *ctx )
|
||||||
|
{
|
||||||
|
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||||
|
return( ctx->grp.id );
|
||||||
|
#else
|
||||||
|
return( ctx->grp_id );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_ecdh_can_do( mbedtls_ecp_group_id gid )
|
||||||
|
{
|
||||||
|
/* At this time, all groups support ECDH. */
|
||||||
|
(void) gid;
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
|
||||||
|
/*
|
||||||
|
* Generate public key (restartable version)
|
||||||
|
*
|
||||||
|
* Note: this internal function relies on its caller preserving the value of
|
||||||
|
* the output parameter 'd' across continuation calls. This would not be
|
||||||
|
* acceptable for a public function but is OK here as we control call sites.
|
||||||
|
*/
|
||||||
|
static int ecdh_gen_public_restartable( mbedtls_ecp_group *grp,
|
||||||
|
mbedtls_mpi *d, mbedtls_ecp_point *Q,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
|
void *p_rng,
|
||||||
|
mbedtls_ecp_restart_ctx *rs_ctx )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
|
/* If multiplication is in progress, we already generated a privkey */
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
if( rs_ctx == NULL || rs_ctx->rsm == NULL )
|
||||||
|
#endif
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) );
|
||||||
|
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, Q, d, &grp->G,
|
||||||
|
f_rng, p_rng, rs_ctx ) );
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate public key
|
||||||
|
*/
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
ECDH_VALIDATE_RET( grp != NULL );
|
||||||
|
ECDH_VALIDATE_RET( d != NULL );
|
||||||
|
ECDH_VALIDATE_RET( Q != NULL );
|
||||||
|
ECDH_VALIDATE_RET( f_rng != NULL );
|
||||||
|
return( ecdh_gen_public_restartable( grp, d, Q, f_rng, p_rng, NULL ) );
|
||||||
|
}
|
||||||
|
#endif /* !MBEDTLS_ECDH_GEN_PUBLIC_ALT */
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
|
||||||
|
/*
|
||||||
|
* Compute shared secret (SEC1 3.3.1)
|
||||||
|
*/
|
||||||
|
static int ecdh_compute_shared_restartable( 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,
|
||||||
|
mbedtls_ecp_restart_ctx *rs_ctx )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
mbedtls_ecp_point P;
|
||||||
|
|
||||||
|
mbedtls_ecp_point_init( &P );
|
||||||
|
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, &P, d, Q,
|
||||||
|
f_rng, p_rng, rs_ctx ) );
|
||||||
|
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 )
|
||||||
|
{
|
||||||
|
ECDH_VALIDATE_RET( grp != NULL );
|
||||||
|
ECDH_VALIDATE_RET( Q != NULL );
|
||||||
|
ECDH_VALIDATE_RET( d != NULL );
|
||||||
|
ECDH_VALIDATE_RET( z != NULL );
|
||||||
|
return( ecdh_compute_shared_restartable( grp, z, Q, d,
|
||||||
|
f_rng, p_rng, NULL ) );
|
||||||
|
}
|
||||||
|
#endif /* !MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
|
||||||
|
|
||||||
|
static void ecdh_init_internal( mbedtls_ecdh_context_mbed *ctx )
|
||||||
|
{
|
||||||
|
mbedtls_ecp_group_init( &ctx->grp );
|
||||||
|
mbedtls_mpi_init( &ctx->d );
|
||||||
|
mbedtls_ecp_point_init( &ctx->Q );
|
||||||
|
mbedtls_ecp_point_init( &ctx->Qp );
|
||||||
|
mbedtls_mpi_init( &ctx->z );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
mbedtls_ecp_restart_init( &ctx->rs );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize context
|
||||||
|
*/
|
||||||
|
void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx )
|
||||||
|
{
|
||||||
|
ECDH_VALIDATE( ctx != NULL );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||||
|
ecdh_init_internal( ctx );
|
||||||
|
mbedtls_ecp_point_init( &ctx->Vi );
|
||||||
|
mbedtls_ecp_point_init( &ctx->Vf );
|
||||||
|
mbedtls_mpi_init( &ctx->_d );
|
||||||
|
#else
|
||||||
|
memset( ctx, 0, sizeof( mbedtls_ecdh_context ) );
|
||||||
|
|
||||||
|
ctx->var = MBEDTLS_ECDH_VARIANT_NONE;
|
||||||
|
#endif
|
||||||
|
ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
ctx->restart_enabled = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ecdh_setup_internal( mbedtls_ecdh_context_mbed *ctx,
|
||||||
|
mbedtls_ecp_group_id grp_id )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
|
ret = mbedtls_ecp_group_load( &ctx->grp, grp_id );
|
||||||
|
if( ret != 0 )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup context
|
||||||
|
*/
|
||||||
|
int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id )
|
||||||
|
{
|
||||||
|
ECDH_VALIDATE_RET( ctx != NULL );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||||
|
return( ecdh_setup_internal( ctx, grp_id ) );
|
||||||
|
#else
|
||||||
|
switch( grp_id )
|
||||||
|
{
|
||||||
|
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||||
|
case MBEDTLS_ECP_DP_CURVE25519:
|
||||||
|
ctx->point_format = MBEDTLS_ECP_PF_COMPRESSED;
|
||||||
|
ctx->var = MBEDTLS_ECDH_VARIANT_EVEREST;
|
||||||
|
ctx->grp_id = grp_id;
|
||||||
|
return( mbedtls_everest_setup( &ctx->ctx.everest_ecdh, grp_id ) );
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
|
||||||
|
ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0;
|
||||||
|
ctx->grp_id = grp_id;
|
||||||
|
ecdh_init_internal( &ctx->ctx.mbed_ecdh );
|
||||||
|
return( ecdh_setup_internal( &ctx->ctx.mbed_ecdh, grp_id ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ecdh_free_internal( mbedtls_ecdh_context_mbed *ctx )
|
||||||
|
{
|
||||||
|
mbedtls_ecp_group_free( &ctx->grp );
|
||||||
|
mbedtls_mpi_free( &ctx->d );
|
||||||
|
mbedtls_ecp_point_free( &ctx->Q );
|
||||||
|
mbedtls_ecp_point_free( &ctx->Qp );
|
||||||
|
mbedtls_mpi_free( &ctx->z );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
mbedtls_ecp_restart_free( &ctx->rs );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
/*
|
||||||
|
* Enable restartable operations for context
|
||||||
|
*/
|
||||||
|
void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx )
|
||||||
|
{
|
||||||
|
ECDH_VALIDATE( ctx != NULL );
|
||||||
|
|
||||||
|
ctx->restart_enabled = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free context
|
||||||
|
*/
|
||||||
|
void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx )
|
||||||
|
{
|
||||||
|
if( ctx == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||||
|
mbedtls_ecp_point_free( &ctx->Vi );
|
||||||
|
mbedtls_ecp_point_free( &ctx->Vf );
|
||||||
|
mbedtls_mpi_free( &ctx->_d );
|
||||||
|
ecdh_free_internal( ctx );
|
||||||
|
#else
|
||||||
|
switch( ctx->var )
|
||||||
|
{
|
||||||
|
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||||
|
case MBEDTLS_ECDH_VARIANT_EVEREST:
|
||||||
|
mbedtls_everest_free( &ctx->ctx.everest_ecdh );
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
|
||||||
|
ecdh_free_internal( &ctx->ctx.mbed_ecdh );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
|
||||||
|
ctx->var = MBEDTLS_ECDH_VARIANT_NONE;
|
||||||
|
ctx->grp_id = MBEDTLS_ECP_DP_NONE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ecdh_make_params_internal( mbedtls_ecdh_context_mbed *ctx,
|
||||||
|
size_t *olen, int point_format,
|
||||||
|
unsigned char *buf, size_t blen,
|
||||||
|
int (*f_rng)(void *,
|
||||||
|
unsigned char *,
|
||||||
|
size_t),
|
||||||
|
void *p_rng,
|
||||||
|
int restart_enabled )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
size_t grp_len, pt_len;
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
mbedtls_ecp_restart_ctx *rs_ctx = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( ctx->grp.pbits == 0 )
|
||||||
|
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
if( restart_enabled )
|
||||||
|
rs_ctx = &ctx->rs;
|
||||||
|
#else
|
||||||
|
(void) restart_enabled;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q,
|
||||||
|
f_rng, p_rng, rs_ctx ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
#else
|
||||||
|
if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q,
|
||||||
|
f_rng, p_rng ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||||
|
|
||||||
|
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, point_format,
|
||||||
|
&pt_len, buf, blen ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
*olen = grp_len + pt_len;
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup and write the ServerKeyExchange 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 restart_enabled = 0;
|
||||||
|
ECDH_VALIDATE_RET( ctx != NULL );
|
||||||
|
ECDH_VALIDATE_RET( olen != NULL );
|
||||||
|
ECDH_VALIDATE_RET( buf != NULL );
|
||||||
|
ECDH_VALIDATE_RET( f_rng != NULL );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
restart_enabled = ctx->restart_enabled;
|
||||||
|
#else
|
||||||
|
(void) restart_enabled;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||||
|
return( ecdh_make_params_internal( ctx, olen, ctx->point_format, buf, blen,
|
||||||
|
f_rng, p_rng, restart_enabled ) );
|
||||||
|
#else
|
||||||
|
switch( ctx->var )
|
||||||
|
{
|
||||||
|
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||||
|
case MBEDTLS_ECDH_VARIANT_EVEREST:
|
||||||
|
return( mbedtls_everest_make_params( &ctx->ctx.everest_ecdh, olen,
|
||||||
|
buf, blen, f_rng, p_rng ) );
|
||||||
|
#endif
|
||||||
|
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
|
||||||
|
return( ecdh_make_params_internal( &ctx->ctx.mbed_ecdh, olen,
|
||||||
|
ctx->point_format, buf, blen,
|
||||||
|
f_rng, p_rng,
|
||||||
|
restart_enabled ) );
|
||||||
|
default:
|
||||||
|
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ecdh_read_params_internal( mbedtls_ecdh_context_mbed *ctx,
|
||||||
|
const unsigned char **buf,
|
||||||
|
const unsigned char *end )
|
||||||
|
{
|
||||||
|
return( mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf,
|
||||||
|
end - *buf ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
mbedtls_ecp_group_id grp_id;
|
||||||
|
ECDH_VALIDATE_RET( ctx != NULL );
|
||||||
|
ECDH_VALIDATE_RET( buf != NULL );
|
||||||
|
ECDH_VALIDATE_RET( *buf != NULL );
|
||||||
|
ECDH_VALIDATE_RET( end != NULL );
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, end - *buf ) )
|
||||||
|
!= 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_ecdh_setup( ctx, grp_id ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||||
|
return( ecdh_read_params_internal( ctx, buf, end ) );
|
||||||
|
#else
|
||||||
|
switch( ctx->var )
|
||||||
|
{
|
||||||
|
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||||
|
case MBEDTLS_ECDH_VARIANT_EVEREST:
|
||||||
|
return( mbedtls_everest_read_params( &ctx->ctx.everest_ecdh,
|
||||||
|
buf, end) );
|
||||||
|
#endif
|
||||||
|
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
|
||||||
|
return( ecdh_read_params_internal( &ctx->ctx.mbed_ecdh,
|
||||||
|
buf, end ) );
|
||||||
|
default:
|
||||||
|
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ecdh_get_params_internal( mbedtls_ecdh_context_mbed *ctx,
|
||||||
|
const mbedtls_ecp_keypair *key,
|
||||||
|
mbedtls_ecdh_side side )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
|
/* 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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
ECDH_VALIDATE_RET( ctx != NULL );
|
||||||
|
ECDH_VALIDATE_RET( key != NULL );
|
||||||
|
ECDH_VALIDATE_RET( side == MBEDTLS_ECDH_OURS ||
|
||||||
|
side == MBEDTLS_ECDH_THEIRS );
|
||||||
|
|
||||||
|
if( mbedtls_ecdh_grp_id( ctx ) == MBEDTLS_ECP_DP_NONE )
|
||||||
|
{
|
||||||
|
/* This is the first call to get_params(). Set up the context
|
||||||
|
* for use with the group. */
|
||||||
|
if( ( ret = mbedtls_ecdh_setup( ctx, key->grp.id ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This is not the first call to get_params(). Check that the
|
||||||
|
* current key's group is the same as the context's, which was set
|
||||||
|
* from the first key's group. */
|
||||||
|
if( mbedtls_ecdh_grp_id( ctx ) != key->grp.id )
|
||||||
|
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||||
|
return( ecdh_get_params_internal( ctx, key, side ) );
|
||||||
|
#else
|
||||||
|
switch( ctx->var )
|
||||||
|
{
|
||||||
|
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||||
|
case MBEDTLS_ECDH_VARIANT_EVEREST:
|
||||||
|
{
|
||||||
|
mbedtls_everest_ecdh_side s = side == MBEDTLS_ECDH_OURS ?
|
||||||
|
MBEDTLS_EVEREST_ECDH_OURS :
|
||||||
|
MBEDTLS_EVEREST_ECDH_THEIRS;
|
||||||
|
return( mbedtls_everest_get_params( &ctx->ctx.everest_ecdh,
|
||||||
|
key, s) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
|
||||||
|
return( ecdh_get_params_internal( &ctx->ctx.mbed_ecdh,
|
||||||
|
key, side ) );
|
||||||
|
default:
|
||||||
|
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ecdh_make_public_internal( mbedtls_ecdh_context_mbed *ctx,
|
||||||
|
size_t *olen, int point_format,
|
||||||
|
unsigned char *buf, size_t blen,
|
||||||
|
int (*f_rng)(void *,
|
||||||
|
unsigned char *,
|
||||||
|
size_t),
|
||||||
|
void *p_rng,
|
||||||
|
int restart_enabled )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
mbedtls_ecp_restart_ctx *rs_ctx = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( ctx->grp.pbits == 0 )
|
||||||
|
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
if( restart_enabled )
|
||||||
|
rs_ctx = &ctx->rs;
|
||||||
|
#else
|
||||||
|
(void) restart_enabled;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q,
|
||||||
|
f_rng, p_rng, rs_ctx ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
#else
|
||||||
|
if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q,
|
||||||
|
f_rng, p_rng ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||||
|
|
||||||
|
return mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, point_format, olen,
|
||||||
|
buf, blen );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 restart_enabled = 0;
|
||||||
|
ECDH_VALIDATE_RET( ctx != NULL );
|
||||||
|
ECDH_VALIDATE_RET( olen != NULL );
|
||||||
|
ECDH_VALIDATE_RET( buf != NULL );
|
||||||
|
ECDH_VALIDATE_RET( f_rng != NULL );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
restart_enabled = ctx->restart_enabled;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||||
|
return( ecdh_make_public_internal( ctx, olen, ctx->point_format, buf, blen,
|
||||||
|
f_rng, p_rng, restart_enabled ) );
|
||||||
|
#else
|
||||||
|
switch( ctx->var )
|
||||||
|
{
|
||||||
|
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||||
|
case MBEDTLS_ECDH_VARIANT_EVEREST:
|
||||||
|
return( mbedtls_everest_make_public( &ctx->ctx.everest_ecdh, olen,
|
||||||
|
buf, blen, f_rng, p_rng ) );
|
||||||
|
#endif
|
||||||
|
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
|
||||||
|
return( ecdh_make_public_internal( &ctx->ctx.mbed_ecdh, olen,
|
||||||
|
ctx->point_format, buf, blen,
|
||||||
|
f_rng, p_rng,
|
||||||
|
restart_enabled ) );
|
||||||
|
default:
|
||||||
|
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ecdh_read_public_internal( mbedtls_ecdh_context_mbed *ctx,
|
||||||
|
const unsigned char *buf, size_t blen )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
const unsigned char *p = buf;
|
||||||
|
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse and import the client's public value
|
||||||
|
*/
|
||||||
|
int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
|
||||||
|
const unsigned char *buf, size_t blen )
|
||||||
|
{
|
||||||
|
ECDH_VALIDATE_RET( ctx != NULL );
|
||||||
|
ECDH_VALIDATE_RET( buf != NULL );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||||
|
return( ecdh_read_public_internal( ctx, buf, blen ) );
|
||||||
|
#else
|
||||||
|
switch( ctx->var )
|
||||||
|
{
|
||||||
|
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||||
|
case MBEDTLS_ECDH_VARIANT_EVEREST:
|
||||||
|
return( mbedtls_everest_read_public( &ctx->ctx.everest_ecdh,
|
||||||
|
buf, blen ) );
|
||||||
|
#endif
|
||||||
|
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
|
||||||
|
return( ecdh_read_public_internal( &ctx->ctx.mbed_ecdh,
|
||||||
|
buf, blen ) );
|
||||||
|
default:
|
||||||
|
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ecdh_calc_secret_internal( mbedtls_ecdh_context_mbed *ctx,
|
||||||
|
size_t *olen, unsigned char *buf,
|
||||||
|
size_t blen,
|
||||||
|
int (*f_rng)(void *,
|
||||||
|
unsigned char *,
|
||||||
|
size_t),
|
||||||
|
void *p_rng,
|
||||||
|
int restart_enabled )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
mbedtls_ecp_restart_ctx *rs_ctx = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( ctx == NULL || ctx->grp.pbits == 0 )
|
||||||
|
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
if( restart_enabled )
|
||||||
|
rs_ctx = &ctx->rs;
|
||||||
|
#else
|
||||||
|
(void) restart_enabled;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
if( ( ret = ecdh_compute_shared_restartable( &ctx->grp, &ctx->z, &ctx->Qp,
|
||||||
|
&ctx->d, f_rng, p_rng,
|
||||||
|
rs_ctx ) ) != 0 )
|
||||||
|
{
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if( ( ret = mbedtls_ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp,
|
||||||
|
&ctx->d, f_rng, p_rng ) ) != 0 )
|
||||||
|
{
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||||
|
|
||||||
|
if( mbedtls_mpi_size( &ctx->z ) > blen )
|
||||||
|
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
*olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 );
|
||||||
|
|
||||||
|
if( mbedtls_ecp_get_type( &ctx->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
|
||||||
|
return mbedtls_mpi_write_binary_le( &ctx->z, buf, *olen );
|
||||||
|
|
||||||
|
return mbedtls_mpi_write_binary( &ctx->z, buf, *olen );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 restart_enabled = 0;
|
||||||
|
ECDH_VALIDATE_RET( ctx != NULL );
|
||||||
|
ECDH_VALIDATE_RET( olen != NULL );
|
||||||
|
ECDH_VALIDATE_RET( buf != NULL );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
restart_enabled = ctx->restart_enabled;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||||
|
return( ecdh_calc_secret_internal( ctx, olen, buf, blen, f_rng, p_rng,
|
||||||
|
restart_enabled ) );
|
||||||
|
#else
|
||||||
|
switch( ctx->var )
|
||||||
|
{
|
||||||
|
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||||
|
case MBEDTLS_ECDH_VARIANT_EVEREST:
|
||||||
|
return( mbedtls_everest_calc_secret( &ctx->ctx.everest_ecdh, olen,
|
||||||
|
buf, blen, f_rng, p_rng ) );
|
||||||
|
#endif
|
||||||
|
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
|
||||||
|
return( ecdh_calc_secret_internal( &ctx->ctx.mbed_ecdh, olen, buf,
|
||||||
|
blen, f_rng, p_rng,
|
||||||
|
restart_enabled ) );
|
||||||
|
default:
|
||||||
|
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_ECDH_C */
|
||||||
446
common/mbedtls/ecdh.h
Normal file
446
common/mbedtls/ecdh.h
Normal file
@@ -0,0 +1,446 @@
|
|||||||
|
/**
|
||||||
|
* \file ecdh.h
|
||||||
|
*
|
||||||
|
* \brief This file contains ECDH definitions and functions.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* For more information, see <em>NIST SP 800-56A Rev. 2: Recommendation for
|
||||||
|
* Pair-Wise Key Establishment Schemes Using Discrete Logarithm
|
||||||
|
* Cryptography</em>.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MBEDTLS_ECDH_H
|
||||||
|
#define MBEDTLS_ECDH_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mbedtls/ecp.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||||
|
#undef MBEDTLS_ECDH_LEGACY_CONTEXT
|
||||||
|
#include "everest/everest.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the source of the imported EC key.
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
MBEDTLS_ECDH_OURS, /**< Our key. */
|
||||||
|
MBEDTLS_ECDH_THEIRS, /**< The key of the peer. */
|
||||||
|
} 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 */
|
||||||
|
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||||
|
MBEDTLS_ECDH_VARIANT_EVEREST /*!< Everest implementation */
|
||||||
|
#endif
|
||||||
|
} 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
|
||||||
|
{
|
||||||
|
#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. */
|
||||||
|
mbedtls_ecp_point Qp; /*!< The value of the public key of the peer. */
|
||||||
|
mbedtls_mpi z; /*!< The shared secret. */
|
||||||
|
int point_format; /*!< The format of point export in TLS messages. */
|
||||||
|
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;
|
||||||
|
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||||
|
mbedtls_ecdh_context_everest everest_ecdh;
|
||||||
|
#endif
|
||||||
|
} 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Check whether a given group can be used for ECDH.
|
||||||
|
*
|
||||||
|
* \param gid The ECP group ID to check.
|
||||||
|
*
|
||||||
|
* \return \c 1 if the group can be used, \c 0 otherwise
|
||||||
|
*/
|
||||||
|
int mbedtls_ecdh_can_do( mbedtls_ecp_group_id gid );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function generates an ECDH keypair on an elliptic
|
||||||
|
* curve.
|
||||||
|
*
|
||||||
|
* This function performs the first of two core computations
|
||||||
|
* 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 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.
|
||||||
|
*
|
||||||
|
* \return \c 0 on success.
|
||||||
|
* \return Another \c MBEDTLS_ERR_ECP_XXX or
|
||||||
|
* \c MBEDTLS_MPI_XXX error code on failure.
|
||||||
|
*/
|
||||||
|
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 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function computes the shared secret.
|
||||||
|
*
|
||||||
|
* This function performs the second of two core computations
|
||||||
|
* implemented during the ECDH key exchange. The first core
|
||||||
|
* computation is performed by mbedtls_ecdh_gen_public().
|
||||||
|
*
|
||||||
|
* \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.
|
||||||
|
*/
|
||||||
|
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 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function initializes an ECDH context.
|
||||||
|
*
|
||||||
|
* \param ctx The ECDH context to initialize. This must not be \c NULL.
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* This is the second function used by a TLS server for ECDHE
|
||||||
|
* ciphersuites. (It is called after mbedtls_ecdh_setup().)
|
||||||
|
*
|
||||||
|
* \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,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
|
void *p_rng );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function parses the ECDHE parameters in a
|
||||||
|
* TLS ServerKeyExchange handshake message.
|
||||||
|
*
|
||||||
|
* \note In a TLS handshake, this is the how the client
|
||||||
|
* sets up its ECDHE context from the server's public
|
||||||
|
* ECDHE key material.
|
||||||
|
*
|
||||||
|
* \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 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function sets up an ECDH context from an EC key.
|
||||||
|
*
|
||||||
|
* It is used by clients and servers in place of the
|
||||||
|
* ServerKeyEchange for static ECDH, and imports ECDH
|
||||||
|
* parameters from the EC key information of a certificate.
|
||||||
|
*
|
||||||
|
* \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 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function generates a public key and exports it
|
||||||
|
* as a TLS ClientKeyExchange payload.
|
||||||
|
*
|
||||||
|
* This is the second function used by a TLS client for ECDH(E)
|
||||||
|
* ciphersuites.
|
||||||
|
*
|
||||||
|
* \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,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
|
void *p_rng );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function parses and processes the ECDHE payload of a
|
||||||
|
* TLS ClientKeyExchange message.
|
||||||
|
*
|
||||||
|
* 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().)
|
||||||
|
*
|
||||||
|
* \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 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function derives and exports the shared secret.
|
||||||
|
*
|
||||||
|
* 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().
|
||||||
|
*
|
||||||
|
* \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.
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
|
||||||
|
#endif /* ecdh.h */
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -11,66 +11,134 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of Mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MBEDTLS_ECDSA_H
|
#ifndef MBEDTLS_ECDSA_H
|
||||||
#define MBEDTLS_ECDSA_H
|
#define MBEDTLS_ECDSA_H
|
||||||
|
|
||||||
#include "ecp.h"
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
#include "md.h"
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
#include "mbedtls/ecp.h"
|
||||||
* RFC-4492 page 20:
|
#include "mbedtls/md.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Maximum ECDSA signature size for a given curve bit size
|
||||||
*
|
*
|
||||||
|
* \param bits Curve size in bits
|
||||||
|
* \return Maximum signature size in bytes
|
||||||
|
*
|
||||||
|
* \note This macro returns a compile-time constant if its argument
|
||||||
|
* is one. It may evaluate its argument multiple times.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
* Ecdsa-Sig-Value ::= SEQUENCE {
|
* Ecdsa-Sig-Value ::= SEQUENCE {
|
||||||
* r INTEGER,
|
* r INTEGER,
|
||||||
* s INTEGER
|
* s INTEGER
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* Size is at most
|
* For each of r and s, the value (V) may include an extra initial "0" bit.
|
||||||
* 1 (tag) + 1 (len) + 1 (initial 0) + ECP_MAX_BYTES for each of r and s,
|
|
||||||
* twice that + 1 (tag) + 2 (len) for the sequence
|
|
||||||
* (assuming ECP_MAX_BYTES is less than 126 for r and s,
|
|
||||||
* and less than 124 (total len <= 255) for the sequence)
|
|
||||||
*/
|
*/
|
||||||
#if MBEDTLS_ECP_MAX_BYTES > 124
|
#define MBEDTLS_ECDSA_MAX_SIG_LEN( bits ) \
|
||||||
#error "MBEDTLS_ECP_MAX_BYTES bigger than expected, please fix MBEDTLS_ECDSA_MAX_LEN"
|
( /*T,L of SEQUENCE*/ ( ( bits ) >= 61 * 8 ? 3 : 2 ) + \
|
||||||
#endif
|
/*T,L of r,s*/ 2 * ( ( ( bits ) >= 127 * 8 ? 3 : 2 ) + \
|
||||||
/** The maximal size of an ECDSA signature in Bytes. */
|
/*V of r,s*/ ( ( bits ) + 8 ) / 8 ) )
|
||||||
#define MBEDTLS_ECDSA_MAX_LEN ( 3 + 2 * ( 3 + MBEDTLS_ECP_MAX_BYTES ) )
|
|
||||||
|
|
||||||
/**
|
/** The maximal size of an ECDSA signature in Bytes. */
|
||||||
* \brief The ECDSA context structure.
|
#define MBEDTLS_ECDSA_MAX_LEN MBEDTLS_ECDSA_MAX_SIG_LEN( MBEDTLS_ECP_MAX_BITS )
|
||||||
*/
|
|
||||||
typedef mbedtls_ecp_keypair mbedtls_ecdsa_context;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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 checks whether a given group can be used
|
||||||
|
* for ECDSA.
|
||||||
|
*
|
||||||
|
* \param gid The ECP group ID to check.
|
||||||
|
*
|
||||||
|
* \return \c 1 if the group can be used, \c 0 otherwise
|
||||||
|
*/
|
||||||
|
int mbedtls_ecdsa_can_do( mbedtls_ecp_group_id gid );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function computes the ECDSA signature of a
|
* \brief This function computes the ECDSA signature of a
|
||||||
* previously-hashed message.
|
* previously-hashed message.
|
||||||
*
|
*
|
||||||
* \note The deterministic version is usually preferred.
|
* \note The deterministic version implemented in
|
||||||
|
* mbedtls_ecdsa_sign_det() is usually preferred.
|
||||||
*
|
*
|
||||||
* \note If the bitlength of the message hash is larger than the
|
* \note If the bitlength of the message hash is larger than the
|
||||||
* bitlength of the group order, then the hash is truncated
|
* bitlength of the group order, then the hash is truncated
|
||||||
@@ -80,24 +148,93 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* \see ecp.h
|
* \see ecp.h
|
||||||
*
|
*
|
||||||
* \param grp The ECP group.
|
* \param grp The context for the elliptic curve to use.
|
||||||
* \param r The first output integer.
|
* This must be initialized and have group parameters
|
||||||
* \param s The second output integer.
|
* set, for example through mbedtls_ecp_group_load().
|
||||||
* \param d The private signing key.
|
* \param r The MPI context in which to store the first part
|
||||||
* \param buf The message hash.
|
* the signature. This must be initialized.
|
||||||
* \param blen The length of \p buf.
|
* \param s The MPI context in which to store the second part
|
||||||
* \param f_rng The RNG function.
|
* the signature. This must be initialized.
|
||||||
* \param p_rng The RNG context.
|
* \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 \c 0 on success.
|
||||||
* \return An \c MBEDTLS_ERR_ECP_XXX
|
* \return An \c MBEDTLS_ERR_ECP_XXX
|
||||||
* or \c MBEDTLS_MPI_XXX error code on failure.
|
* or \c MBEDTLS_MPI_XXX error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
|
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,
|
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
|
||||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
|
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
|
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
|
||||||
|
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
|
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
||||||
|
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
|
||||||
|
#else
|
||||||
|
#define MBEDTLS_DEPRECATED
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* \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.
|
||||||
|
*
|
||||||
|
* \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.)
|
||||||
|
*
|
||||||
|
* \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 ) MBEDTLS_DEPRECATED;
|
||||||
|
#undef MBEDTLS_DEPRECATED
|
||||||
|
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function computes the ECDSA signature of a
|
* \brief This function computes the ECDSA signature of a
|
||||||
* previously-hashed message, deterministic version.
|
* previously-hashed message, deterministic version.
|
||||||
@@ -114,21 +251,35 @@ int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
|
|||||||
*
|
*
|
||||||
* \see ecp.h
|
* \see ecp.h
|
||||||
*
|
*
|
||||||
* \param grp The ECP group.
|
* \param grp The context for the elliptic curve to use.
|
||||||
* \param r The first output integer.
|
* This must be initialized and have group parameters
|
||||||
* \param s The second output integer.
|
* set, for example through mbedtls_ecp_group_load().
|
||||||
* \param d The private signing key.
|
* \param r The MPI context in which to store the first part
|
||||||
* \param buf The message hash.
|
* the signature. This must be initialized.
|
||||||
* \param blen The length of \p buf.
|
* \param s The MPI context in which to store the second part
|
||||||
* \param md_alg The MD algorithm used to hash the message.
|
* 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 \c 0 on success.
|
||||||
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
|
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
|
||||||
* error code on failure.
|
* error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_ecdsa_sign_det(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
|
int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r,
|
||||||
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
|
mbedtls_mpi *s, const mbedtls_mpi *d,
|
||||||
mbedtls_md_type_t md_alg);
|
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 );
|
||||||
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
|
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -143,12 +294,19 @@ int mbedtls_ecdsa_sign_det(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *
|
|||||||
*
|
*
|
||||||
* \see ecp.h
|
* \see ecp.h
|
||||||
*
|
*
|
||||||
* \param grp The ECP group.
|
* \param grp The ECP group to use.
|
||||||
* \param buf The message hash.
|
* This must be initialized and have group parameters
|
||||||
* \param blen The length of \p buf.
|
* set, for example through mbedtls_ecp_group_load().
|
||||||
* \param Q The public key to use for verification.
|
* \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.
|
* \param r The first integer of the signature.
|
||||||
|
* This must be initialized.
|
||||||
* \param s The second integer of the signature.
|
* \param s The second integer of the signature.
|
||||||
|
* This must be initialized.
|
||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the signature
|
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the signature
|
||||||
@@ -156,9 +314,10 @@ int mbedtls_ecdsa_sign_det(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *
|
|||||||
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
|
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
|
||||||
* error code on failure for any other reason.
|
* error code on failure for any other reason.
|
||||||
*/
|
*/
|
||||||
int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp,
|
int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
|
||||||
const unsigned char *buf, size_t blen,
|
const unsigned char *buf, size_t blen,
|
||||||
const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s);
|
const mbedtls_ecp_point *Q, const mbedtls_mpi *r,
|
||||||
|
const mbedtls_mpi *s);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function computes the ECDSA signature and writes it
|
* \brief This function computes the ECDSA signature and writes it
|
||||||
@@ -175,11 +334,6 @@ int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp,
|
|||||||
* of the Digital Signature Algorithm (DSA) and Elliptic
|
* of the Digital Signature Algorithm (DSA) and Elliptic
|
||||||
* Curve Digital Signature Algorithm (ECDSA)</em>.
|
* Curve Digital Signature Algorithm (ECDSA)</em>.
|
||||||
*
|
*
|
||||||
* \note The \p sig buffer must be at least twice as large as the
|
|
||||||
* size of the curve used, plus 9. For example, 73 Bytes if
|
|
||||||
* a 256-bit curve is used. A buffer length of
|
|
||||||
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
|
|
||||||
*
|
|
||||||
* \note If the bitlength of the message hash is larger than the
|
* \note If the bitlength of the message hash is larger than the
|
||||||
* bitlength of the group order, then the hash is truncated as
|
* bitlength of the group order, then the hash is truncated as
|
||||||
* defined in <em>Standards for Efficient Cryptography Group
|
* defined in <em>Standards for Efficient Cryptography Group
|
||||||
@@ -188,24 +342,84 @@ int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp,
|
|||||||
*
|
*
|
||||||
* \see ecp.h
|
* \see ecp.h
|
||||||
*
|
*
|
||||||
* \param ctx The ECDSA context.
|
* \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 md_alg The message digest that was used to hash the message.
|
||||||
* \param hash The message hash.
|
* \param hash The message hash to be signed. This must be a readable
|
||||||
* \param hlen The length of the hash.
|
* buffer of length \p blen Bytes.
|
||||||
* \param sig The buffer that holds the signature.
|
* \param hlen The length of the hash \p hash in Bytes.
|
||||||
* \param slen The length of the signature written.
|
* \param sig The buffer to which to write the signature. This must be a
|
||||||
* \param f_rng The RNG function.
|
* writable buffer of length at least twice as large as the
|
||||||
* \param p_rng The RNG context.
|
* 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 used only for blinding and may be set to \c NULL, but
|
||||||
|
* doing so is DEPRECATED.
|
||||||
|
* \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 \c 0 on success.
|
||||||
* \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
|
* \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
|
||||||
* \c MBEDTLS_ERR_ASN1_XXX error code on failure.
|
* \c MBEDTLS_ERR_ASN1_XXX error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg,
|
int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx,
|
||||||
const unsigned char *hash, size_t hlen,
|
mbedtls_md_type_t md_alg,
|
||||||
unsigned char *sig, size_t *slen,
|
const unsigned char *hash, size_t hlen,
|
||||||
int (*f_rng)(void *, unsigned char *, size_t),
|
unsigned char *sig, size_t *slen,
|
||||||
void *p_rng);
|
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_ECDSA_DETERMINISTIC)
|
||||||
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
|
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
@@ -227,11 +441,6 @@ int mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx, mbedtls_md_type_t
|
|||||||
* \warning It is not thread-safe to use the same context in
|
* \warning It is not thread-safe to use the same context in
|
||||||
* multiple threads.
|
* multiple threads.
|
||||||
*
|
*
|
||||||
* \note The \p sig buffer must be at least twice as large as the
|
|
||||||
* size of the curve used, plus 9. For example, 73 Bytes if a
|
|
||||||
* 256-bit curve is used. A buffer length of
|
|
||||||
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
|
|
||||||
*
|
|
||||||
* \note If the bitlength of the message hash is larger than the
|
* \note If the bitlength of the message hash is larger than the
|
||||||
* bitlength of the group order, then the hash is truncated as
|
* bitlength of the group order, then the hash is truncated as
|
||||||
* defined in <em>Standards for Efficient Cryptography Group
|
* defined in <em>Standards for Efficient Cryptography Group
|
||||||
@@ -243,21 +452,29 @@ int mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx, mbedtls_md_type_t
|
|||||||
* \deprecated Superseded by mbedtls_ecdsa_write_signature() in
|
* \deprecated Superseded by mbedtls_ecdsa_write_signature() in
|
||||||
* Mbed TLS version 2.0 and later.
|
* Mbed TLS version 2.0 and later.
|
||||||
*
|
*
|
||||||
* \param ctx The ECDSA context.
|
* \param ctx The ECDSA context to use. This must be initialized
|
||||||
* \param hash The message hash.
|
* and have a group and private key bound to it, for example
|
||||||
* \param hlen The length of the hash.
|
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
|
||||||
* \param sig The buffer that holds the signature.
|
* \param hash The message hash to be signed. This must be a readable
|
||||||
* \param slen The length of the signature written.
|
* buffer of length \p blen Bytes.
|
||||||
* \param md_alg The MD algorithm used to hash the message.
|
* \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 \c 0 on success.
|
||||||
* \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
|
* \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
|
||||||
* \c MBEDTLS_ERR_ASN1_XXX error code on failure.
|
* \c MBEDTLS_ERR_ASN1_XXX error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_ecdsa_write_signature_det(mbedtls_ecdsa_context *ctx,
|
int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
|
||||||
const unsigned char *hash, size_t hlen,
|
const unsigned char *hash, size_t hlen,
|
||||||
unsigned char *sig, size_t *slen,
|
unsigned char *sig, size_t *slen,
|
||||||
mbedtls_md_type_t md_alg) MBEDTLS_DEPRECATED;
|
mbedtls_md_type_t md_alg ) MBEDTLS_DEPRECATED;
|
||||||
#undef MBEDTLS_DEPRECATED
|
#undef MBEDTLS_DEPRECATED
|
||||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||||
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
|
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
|
||||||
@@ -273,11 +490,14 @@ int mbedtls_ecdsa_write_signature_det(mbedtls_ecdsa_context *ctx,
|
|||||||
*
|
*
|
||||||
* \see ecp.h
|
* \see ecp.h
|
||||||
*
|
*
|
||||||
* \param ctx The ECDSA context.
|
* \param ctx The ECDSA context to use. This must be initialized
|
||||||
* \param hash The message hash.
|
* and have a group and public key bound to it.
|
||||||
* \param hlen The size of the hash.
|
* \param hash The message hash that was signed. This must be a readable
|
||||||
* \param sig The signature to read and verify.
|
* buffer of length \p size Bytes.
|
||||||
* \param slen The size of \p sig.
|
* \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 \c 0 on success.
|
||||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
|
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
|
||||||
@@ -286,9 +506,45 @@ int mbedtls_ecdsa_write_signature_det(mbedtls_ecdsa_context *ctx,
|
|||||||
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
|
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
|
||||||
* error code on failure for any other reason.
|
* error code on failure for any other reason.
|
||||||
*/
|
*/
|
||||||
int mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context *ctx,
|
int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
|
||||||
const unsigned char *hash, size_t hlen,
|
const unsigned char *hash, size_t hlen,
|
||||||
const unsigned char *sig, size_t slen);
|
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.
|
* \brief This function generates an ECDSA keypair on the given curve.
|
||||||
@@ -296,45 +552,72 @@ int mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context *ctx,
|
|||||||
* \see ecp.h
|
* \see ecp.h
|
||||||
*
|
*
|
||||||
* \param ctx The ECDSA context to store the keypair in.
|
* \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
|
* \param gid The elliptic curve to use. One of the various
|
||||||
* \c MBEDTLS_ECP_DP_XXX macros depending on configuration.
|
* \c MBEDTLS_ECP_DP_XXX macros depending on configuration.
|
||||||
* \param f_rng The RNG function.
|
* \param f_rng The RNG function to use. This must not be \c NULL.
|
||||||
* \param p_rng The RNG context.
|
* \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.
|
||||||
*
|
*
|
||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return An \c MBEDTLS_ERR_ECP_XXX code on failure.
|
* \return An \c MBEDTLS_ERR_ECP_XXX code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_ecdsa_genkey(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
|
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 (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function sets an ECDSA context from an EC key pair.
|
* \brief This function sets up an ECDSA context from an EC key pair.
|
||||||
*
|
*
|
||||||
* \see ecp.h
|
* \see ecp.h
|
||||||
*
|
*
|
||||||
* \param ctx The ECDSA context to set.
|
* \param ctx The ECDSA context to setup. This must be initialized.
|
||||||
* \param key The EC key to use.
|
* \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 \c 0 on success.
|
||||||
* \return An \c MBEDTLS_ERR_ECP_XXX code on failure.
|
* \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.
|
* \brief This function initializes an ECDSA context.
|
||||||
*
|
*
|
||||||
* \param ctx The ECDSA context to initialize.
|
* \param ctx The ECDSA context to initialize.
|
||||||
|
* This must not be \c NULL.
|
||||||
*/
|
*/
|
||||||
void mbedtls_ecdsa_init(mbedtls_ecdsa_context *ctx);
|
void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function frees an ECDSA context.
|
* \brief This function frees an ECDSA context.
|
||||||
*
|
*
|
||||||
* \param ctx The ECDSA context to free.
|
* \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.
|
||||||
*/
|
*/
|
||||||
void mbedtls_ecdsa_free(mbedtls_ecdsa_context *ctx);
|
void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx );
|
||||||
|
|
||||||
int ecdsa_signature_to_asn1(const mbedtls_mpi *r, const mbedtls_mpi *s, unsigned char *sig, size_t *slen);
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
1146
common/mbedtls/ecjpake.c
Normal file
1146
common/mbedtls/ecjpake.c
Normal file
File diff suppressed because it is too large
Load Diff
275
common/mbedtls/ecjpake.h
Normal file
275
common/mbedtls/ecjpake.h
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
/**
|
||||||
|
* \file ecjpake.h
|
||||||
|
*
|
||||||
|
* \brief Elliptic curve J-PAKE
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef MBEDTLS_ECJPAKE_H
|
||||||
|
#define MBEDTLS_ECJPAKE_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* J-PAKE is a password-authenticated key exchange that allows deriving a
|
||||||
|
* strong shared secret from a (potentially low entropy) pre-shared
|
||||||
|
* passphrase, with forward secrecy and mutual authentication.
|
||||||
|
* https://en.wikipedia.org/wiki/Password_Authenticated_Key_Exchange_by_Juggling
|
||||||
|
*
|
||||||
|
* This file implements the Elliptic Curve variant of J-PAKE,
|
||||||
|
* as defined in Chapter 7.4 of the Thread v1.0 Specification,
|
||||||
|
* available to members of the Thread Group http://threadgroup.org/
|
||||||
|
*
|
||||||
|
* As the J-PAKE algorithm is inherently symmetric, so is our API.
|
||||||
|
* Each party needs to send its first round message, in any order, to the
|
||||||
|
* other party, then each sends its second round message, in any order.
|
||||||
|
* The payloads are serialized in a way suitable for use in TLS, but could
|
||||||
|
* also be use outside TLS.
|
||||||
|
*/
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mbedtls/ecp.h"
|
||||||
|
#include "mbedtls/md.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Roles in the EC J-PAKE exchange
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
MBEDTLS_ECJPAKE_CLIENT = 0, /**< Client */
|
||||||
|
MBEDTLS_ECJPAKE_SERVER, /**< Server */
|
||||||
|
} mbedtls_ecjpake_role;
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_ECJPAKE_ALT)
|
||||||
|
/**
|
||||||
|
* EC J-PAKE context structure.
|
||||||
|
*
|
||||||
|
* J-PAKE is a symmetric protocol, except for the identifiers used in
|
||||||
|
* Zero-Knowledge Proofs, and the serialization of the second message
|
||||||
|
* (KeyExchange) as defined by the Thread spec.
|
||||||
|
*
|
||||||
|
* In order to benefit from this symmetry, we choose a different naming
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
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 */
|
||||||
|
|
||||||
|
mbedtls_ecp_point Xm1; /**< My public key 1 C: X1, S: X3 */
|
||||||
|
mbedtls_ecp_point Xm2; /**< My public key 2 C: X2, S: X4 */
|
||||||
|
mbedtls_ecp_point Xp1; /**< Peer public key 1 C: X3, S: X1 */
|
||||||
|
mbedtls_ecp_point Xp2; /**< Peer public key 2 C: X4, S: X2 */
|
||||||
|
mbedtls_ecp_point Xp; /**< Peer public key C: Xs, S: Xc */
|
||||||
|
|
||||||
|
mbedtls_mpi xm1; /**< My private key 1 C: x1, S: x3 */
|
||||||
|
mbedtls_mpi xm2; /**< My private key 2 C: x2, S: x4 */
|
||||||
|
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* \param ctx The ECJPAKE context to initialize.
|
||||||
|
* This must not be \c NULL.
|
||||||
|
*/
|
||||||
|
void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set up an ECJPAKE context for use.
|
||||||
|
*
|
||||||
|
* \note Currently the only values for hash/curve allowed by the
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* \return \c 0 if successful.
|
||||||
|
* \return A negative error code on failure.
|
||||||
|
*/
|
||||||
|
int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
|
||||||
|
mbedtls_ecjpake_role role,
|
||||||
|
mbedtls_md_type_t hash,
|
||||||
|
mbedtls_ecp_group_id curve,
|
||||||
|
const unsigned char *secret,
|
||||||
|
size_t len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Check if an ECJPAKE context is ready for use.
|
||||||
|
*
|
||||||
|
* \param ctx The ECJPAKE context to check. This must be
|
||||||
|
* initialized.
|
||||||
|
*
|
||||||
|
* \return \c 0 if the context is ready for use.
|
||||||
|
* \return #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).
|
||||||
|
*
|
||||||
|
* \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.
|
||||||
|
*
|
||||||
|
* \return \c 0 if successful.
|
||||||
|
* \return A negative error code on failure.
|
||||||
|
*/
|
||||||
|
int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
|
||||||
|
unsigned char *buf, size_t len, size_t *olen,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
|
void *p_rng );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Read and process the first round message
|
||||||
|
* (TLS: contents of the Client/ServerHello extension,
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* \return \c 0 if successful.
|
||||||
|
* \return A negative error code on failure.
|
||||||
|
*/
|
||||||
|
int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
|
||||||
|
const unsigned char *buf,
|
||||||
|
size_t len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Generate and write the second round message
|
||||||
|
* (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.
|
||||||
|
*
|
||||||
|
* \return \c 0 if successful.
|
||||||
|
* \return A negative error code on failure.
|
||||||
|
*/
|
||||||
|
int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
|
||||||
|
unsigned char *buf, size_t len, size_t *olen,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
|
void *p_rng );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Read and process the second round message
|
||||||
|
* (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.
|
||||||
|
*
|
||||||
|
* \return \c 0 if successful.
|
||||||
|
* \return A negative error code on failure.
|
||||||
|
*/
|
||||||
|
int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
|
||||||
|
const unsigned char *buf,
|
||||||
|
size_t len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Derive the shared 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.
|
||||||
|
*
|
||||||
|
* \return \c 0 if successful.
|
||||||
|
* \return A negative error code on failure.
|
||||||
|
*/
|
||||||
|
int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
|
||||||
|
unsigned char *buf, size_t len, size_t *olen,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
|
void *p_rng );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This clears an ECJPAKE context and frees any
|
||||||
|
* embedded data structure.
|
||||||
|
*
|
||||||
|
* \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.
|
||||||
|
*/
|
||||||
|
void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Checkup routine
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or 1 if a test failed
|
||||||
|
*/
|
||||||
|
int mbedtls_ecjpake_self_test( int verbose );
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ecjpake.h */
|
||||||
3594
common/mbedtls/ecp.c
3594
common/mbedtls/ecp.c
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
@@ -5,24 +5,20 @@
|
|||||||
* point arithmetic.
|
* point arithmetic.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -63,6 +59,12 @@
|
|||||||
#ifndef MBEDTLS_ECP_INTERNAL_H
|
#ifndef MBEDTLS_ECP_INTERNAL_H
|
||||||
#define MBEDTLS_ECP_INTERNAL_H
|
#define MBEDTLS_ECP_INTERNAL_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
|
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,7 +76,7 @@
|
|||||||
*
|
*
|
||||||
* \return Non-zero if successful.
|
* \return Non-zero if successful.
|
||||||
*/
|
*/
|
||||||
unsigned char mbedtls_internal_ecp_grp_capable(const mbedtls_ecp_group *grp);
|
unsigned char mbedtls_internal_ecp_grp_capable( const mbedtls_ecp_group *grp );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Initialise the Elliptic Curve Point module extension.
|
* \brief Initialise the Elliptic Curve Point module extension.
|
||||||
@@ -91,7 +93,7 @@ unsigned char mbedtls_internal_ecp_grp_capable(const mbedtls_ecp_group *grp);
|
|||||||
*
|
*
|
||||||
* \return 0 if successful.
|
* \return 0 if successful.
|
||||||
*/
|
*/
|
||||||
int mbedtls_internal_ecp_init(const mbedtls_ecp_group *grp);
|
int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Frees and deallocates the Elliptic Curve Point module
|
* \brief Frees and deallocates the Elliptic Curve Point module
|
||||||
@@ -99,9 +101,9 @@ int mbedtls_internal_ecp_init(const mbedtls_ecp_group *grp);
|
|||||||
*
|
*
|
||||||
* \param grp The pointer to the group the module was initialised for.
|
* \param grp The pointer to the group the module was initialised for.
|
||||||
*/
|
*/
|
||||||
void mbedtls_internal_ecp_free(const mbedtls_ecp_group *grp);
|
void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp );
|
||||||
|
|
||||||
#if defined(ECP_SHORTWEIERSTRASS)
|
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
|
#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
|
||||||
/**
|
/**
|
||||||
@@ -119,9 +121,9 @@ void mbedtls_internal_ecp_free(const mbedtls_ecp_group *grp);
|
|||||||
*
|
*
|
||||||
* \return 0 if successful.
|
* \return 0 if successful.
|
||||||
*/
|
*/
|
||||||
int mbedtls_internal_ecp_randomize_jac(const mbedtls_ecp_group *grp,
|
int mbedtls_internal_ecp_randomize_jac( const mbedtls_ecp_group *grp,
|
||||||
mbedtls_ecp_point *pt, int (*f_rng)(void *, unsigned char *, size_t),
|
mbedtls_ecp_point *pt, int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
void *p_rng);
|
void *p_rng );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECP_ADD_MIXED_ALT)
|
#if defined(MBEDTLS_ECP_ADD_MIXED_ALT)
|
||||||
@@ -164,9 +166,9 @@ int mbedtls_internal_ecp_randomize_jac(const mbedtls_ecp_group *grp,
|
|||||||
*
|
*
|
||||||
* \return 0 if successful.
|
* \return 0 if successful.
|
||||||
*/
|
*/
|
||||||
int mbedtls_internal_ecp_add_mixed(const mbedtls_ecp_group *grp,
|
int mbedtls_internal_ecp_add_mixed( const mbedtls_ecp_group *grp,
|
||||||
mbedtls_ecp_point *R, const mbedtls_ecp_point *P,
|
mbedtls_ecp_point *R, const mbedtls_ecp_point *P,
|
||||||
const mbedtls_ecp_point *Q);
|
const mbedtls_ecp_point *Q );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -189,8 +191,8 @@ int mbedtls_internal_ecp_add_mixed(const mbedtls_ecp_group *grp,
|
|||||||
* \return 0 if successful.
|
* \return 0 if successful.
|
||||||
*/
|
*/
|
||||||
#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT)
|
#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT)
|
||||||
int mbedtls_internal_ecp_double_jac(const mbedtls_ecp_group *grp,
|
int mbedtls_internal_ecp_double_jac( const mbedtls_ecp_group *grp,
|
||||||
mbedtls_ecp_point *R, const mbedtls_ecp_point *P);
|
mbedtls_ecp_point *R, const mbedtls_ecp_point *P );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -219,8 +221,8 @@ int mbedtls_internal_ecp_double_jac(const mbedtls_ecp_group *grp,
|
|||||||
* an error if one of the points is zero.
|
* an error if one of the points is zero.
|
||||||
*/
|
*/
|
||||||
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT)
|
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT)
|
||||||
int mbedtls_internal_ecp_normalize_jac_many(const mbedtls_ecp_group *grp,
|
int mbedtls_internal_ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
|
||||||
mbedtls_ecp_point *T[], size_t t_len);
|
mbedtls_ecp_point *T[], size_t t_len );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -237,18 +239,18 @@ int mbedtls_internal_ecp_normalize_jac_many(const mbedtls_ecp_group *grp,
|
|||||||
* \return 0 if successful.
|
* \return 0 if successful.
|
||||||
*/
|
*/
|
||||||
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT)
|
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT)
|
||||||
int mbedtls_internal_ecp_normalize_jac(const mbedtls_ecp_group *grp,
|
int mbedtls_internal_ecp_normalize_jac( const mbedtls_ecp_group *grp,
|
||||||
mbedtls_ecp_point *pt);
|
mbedtls_ecp_point *pt );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* ECP_SHORTWEIERSTRASS */
|
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
|
||||||
|
|
||||||
#if defined(ECP_MONTGOMERY)
|
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
|
#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
|
||||||
int mbedtls_internal_ecp_double_add_mxz(const mbedtls_ecp_group *grp,
|
int mbedtls_internal_ecp_double_add_mxz( const mbedtls_ecp_group *grp,
|
||||||
mbedtls_ecp_point *R, mbedtls_ecp_point *S, const mbedtls_ecp_point *P,
|
mbedtls_ecp_point *R, mbedtls_ecp_point *S, const mbedtls_ecp_point *P,
|
||||||
const mbedtls_ecp_point *Q, const mbedtls_mpi *d);
|
const mbedtls_ecp_point *Q, const mbedtls_mpi *d );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -267,9 +269,9 @@ int mbedtls_internal_ecp_double_add_mxz(const mbedtls_ecp_group *grp,
|
|||||||
* \return 0 if successful
|
* \return 0 if successful
|
||||||
*/
|
*/
|
||||||
#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT)
|
#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT)
|
||||||
int mbedtls_internal_ecp_randomize_mxz(const mbedtls_ecp_group *grp,
|
int mbedtls_internal_ecp_randomize_mxz( const mbedtls_ecp_group *grp,
|
||||||
mbedtls_ecp_point *P, int (*f_rng)(void *, unsigned char *, size_t),
|
mbedtls_ecp_point *P, int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
void *p_rng);
|
void *p_rng );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -283,11 +285,11 @@ int mbedtls_internal_ecp_randomize_mxz(const mbedtls_ecp_group *grp,
|
|||||||
* \return 0 if successful
|
* \return 0 if successful
|
||||||
*/
|
*/
|
||||||
#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
|
#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
|
||||||
int mbedtls_internal_ecp_normalize_mxz(const mbedtls_ecp_group *grp,
|
int mbedtls_internal_ecp_normalize_mxz( const mbedtls_ecp_group *grp,
|
||||||
mbedtls_ecp_point *P);
|
mbedtls_ecp_point *P );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* ECP_MONTGOMERY */
|
#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
|
||||||
|
|
||||||
#endif /* MBEDTLS_ECP_INTERNAL_ALT */
|
#endif /* MBEDTLS_ECP_INTERNAL_ALT */
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* Entropy accumulator implementation
|
* Entropy accumulator implementation
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#include "common.h"
|
||||||
#include "mbedtls/config.h"
|
|
||||||
#else
|
|
||||||
#include MBEDTLS_CONFIG_FILE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_ENTROPY_C)
|
#if defined(MBEDTLS_ENTROPY_C)
|
||||||
|
|
||||||
@@ -38,6 +30,7 @@
|
|||||||
#include "mbedtls/entropy.h"
|
#include "mbedtls/entropy.h"
|
||||||
#include "mbedtls/entropy_poll.h"
|
#include "mbedtls/entropy_poll.h"
|
||||||
#include "mbedtls/platform_util.h"
|
#include "mbedtls/platform_util.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -64,94 +57,103 @@
|
|||||||
|
|
||||||
#define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */
|
#define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */
|
||||||
|
|
||||||
void mbedtls_entropy_init(mbedtls_entropy_context *ctx) {
|
void mbedtls_entropy_init( mbedtls_entropy_context *ctx )
|
||||||
|
{
|
||||||
ctx->source_count = 0;
|
ctx->source_count = 0;
|
||||||
memset(ctx->source, 0, sizeof(ctx->source));
|
memset( ctx->source, 0, sizeof( ctx->source ) );
|
||||||
|
|
||||||
#if defined(MBEDTLS_THREADING_C)
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
mbedtls_mutex_init(&ctx->mutex);
|
mbedtls_mutex_init( &ctx->mutex );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ctx->accumulator_started = 0;
|
ctx->accumulator_started = 0;
|
||||||
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
|
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
|
||||||
mbedtls_sha512_init(&ctx->accumulator);
|
mbedtls_sha512_init( &ctx->accumulator );
|
||||||
#else
|
#else
|
||||||
mbedtls_sha256_init(&ctx->accumulator);
|
mbedtls_sha256_init( &ctx->accumulator );
|
||||||
#endif
|
#endif
|
||||||
#if defined(MBEDTLS_HAVEGE_C)
|
#if defined(MBEDTLS_HAVEGE_C)
|
||||||
mbedtls_havege_init(&ctx->havege_data);
|
mbedtls_havege_init( &ctx->havege_data );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Reminder: Update ENTROPY_HAVE_STRONG in the test files
|
/* Reminder: Update ENTROPY_HAVE_STRONG in the test files
|
||||||
* when adding more strong entropy sources here. */
|
* when adding more strong entropy sources here. */
|
||||||
|
|
||||||
#if defined(MBEDTLS_TEST_NULL_ENTROPY)
|
#if defined(MBEDTLS_TEST_NULL_ENTROPY)
|
||||||
mbedtls_entropy_add_source(ctx, mbedtls_null_entropy_poll, NULL,
|
mbedtls_entropy_add_source( ctx, mbedtls_null_entropy_poll, NULL,
|
||||||
1, MBEDTLS_ENTROPY_SOURCE_STRONG);
|
1, MBEDTLS_ENTROPY_SOURCE_STRONG );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
|
#if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
|
||||||
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
|
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
|
||||||
mbedtls_entropy_add_source(ctx, mbedtls_platform_entropy_poll, NULL,
|
mbedtls_entropy_add_source( ctx, mbedtls_platform_entropy_poll, NULL,
|
||||||
MBEDTLS_ENTROPY_MIN_PLATFORM,
|
MBEDTLS_ENTROPY_MIN_PLATFORM,
|
||||||
MBEDTLS_ENTROPY_SOURCE_STRONG);
|
MBEDTLS_ENTROPY_SOURCE_STRONG );
|
||||||
#endif
|
#endif
|
||||||
#if defined(MBEDTLS_TIMING_C)
|
#if defined(MBEDTLS_TIMING_C)
|
||||||
mbedtls_entropy_add_source(ctx, mbedtls_hardclock_poll, NULL,
|
mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL,
|
||||||
MBEDTLS_ENTROPY_MIN_HARDCLOCK,
|
MBEDTLS_ENTROPY_MIN_HARDCLOCK,
|
||||||
MBEDTLS_ENTROPY_SOURCE_WEAK);
|
MBEDTLS_ENTROPY_SOURCE_WEAK );
|
||||||
#endif
|
#endif
|
||||||
#if defined(MBEDTLS_HAVEGE_C)
|
#if defined(MBEDTLS_HAVEGE_C)
|
||||||
mbedtls_entropy_add_source(ctx, mbedtls_havege_poll, &ctx->havege_data,
|
mbedtls_entropy_add_source( ctx, mbedtls_havege_poll, &ctx->havege_data,
|
||||||
MBEDTLS_ENTROPY_MIN_HAVEGE,
|
MBEDTLS_ENTROPY_MIN_HAVEGE,
|
||||||
MBEDTLS_ENTROPY_SOURCE_STRONG);
|
MBEDTLS_ENTROPY_SOURCE_STRONG );
|
||||||
#endif
|
#endif
|
||||||
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
||||||
mbedtls_entropy_add_source(ctx, mbedtls_hardware_poll, NULL,
|
mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL,
|
||||||
MBEDTLS_ENTROPY_MIN_HARDWARE,
|
MBEDTLS_ENTROPY_MIN_HARDWARE,
|
||||||
MBEDTLS_ENTROPY_SOURCE_STRONG);
|
MBEDTLS_ENTROPY_SOURCE_STRONG );
|
||||||
#endif
|
#endif
|
||||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||||
mbedtls_entropy_add_source(ctx, mbedtls_nv_seed_poll, NULL,
|
mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL,
|
||||||
MBEDTLS_ENTROPY_BLOCK_SIZE,
|
MBEDTLS_ENTROPY_BLOCK_SIZE,
|
||||||
MBEDTLS_ENTROPY_SOURCE_STRONG);
|
MBEDTLS_ENTROPY_SOURCE_STRONG );
|
||||||
ctx->initial_entropy_run = 0;
|
ctx->initial_entropy_run = 0;
|
||||||
#endif
|
#endif
|
||||||
#endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */
|
#endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */
|
||||||
}
|
}
|
||||||
|
|
||||||
void mbedtls_entropy_free(mbedtls_entropy_context *ctx) {
|
void mbedtls_entropy_free( mbedtls_entropy_context *ctx )
|
||||||
|
{
|
||||||
|
/* If the context was already free, don't call free() again.
|
||||||
|
* This is important for mutexes which don't allow double-free. */
|
||||||
|
if( ctx->accumulator_started == -1 )
|
||||||
|
return;
|
||||||
|
|
||||||
#if defined(MBEDTLS_HAVEGE_C)
|
#if defined(MBEDTLS_HAVEGE_C)
|
||||||
mbedtls_havege_free(&ctx->havege_data);
|
mbedtls_havege_free( &ctx->havege_data );
|
||||||
#endif
|
#endif
|
||||||
#if defined(MBEDTLS_THREADING_C)
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
mbedtls_mutex_free(&ctx->mutex);
|
mbedtls_mutex_free( &ctx->mutex );
|
||||||
#endif
|
#endif
|
||||||
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
|
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
|
||||||
mbedtls_sha512_free(&ctx->accumulator);
|
mbedtls_sha512_free( &ctx->accumulator );
|
||||||
#else
|
#else
|
||||||
mbedtls_sha256_free(&ctx->accumulator);
|
mbedtls_sha256_free( &ctx->accumulator );
|
||||||
#endif
|
#endif
|
||||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||||
ctx->initial_entropy_run = 0;
|
ctx->initial_entropy_run = 0;
|
||||||
#endif
|
#endif
|
||||||
ctx->source_count = 0;
|
ctx->source_count = 0;
|
||||||
mbedtls_platform_zeroize(ctx->source, sizeof(ctx->source));
|
mbedtls_platform_zeroize( ctx->source, sizeof( ctx->source ) );
|
||||||
ctx->accumulator_started = 0;
|
ctx->accumulator_started = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_entropy_add_source(mbedtls_entropy_context *ctx,
|
int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
|
||||||
mbedtls_entropy_f_source_ptr f_source, void *p_source,
|
mbedtls_entropy_f_source_ptr f_source, void *p_source,
|
||||||
size_t threshold, int strong) {
|
size_t threshold, int strong )
|
||||||
|
{
|
||||||
int idx, ret = 0;
|
int idx, ret = 0;
|
||||||
|
|
||||||
#if defined(MBEDTLS_THREADING_C)
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0)
|
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
idx = ctx->source_count;
|
idx = ctx->source_count;
|
||||||
if (idx >= MBEDTLS_ENTROPY_MAX_SOURCES) {
|
if( idx >= MBEDTLS_ENTROPY_MAX_SOURCES )
|
||||||
|
{
|
||||||
ret = MBEDTLS_ERR_ENTROPY_MAX_SOURCES;
|
ret = MBEDTLS_ERR_ENTROPY_MAX_SOURCES;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
@@ -165,30 +167,32 @@ int mbedtls_entropy_add_source(mbedtls_entropy_context *ctx,
|
|||||||
|
|
||||||
exit:
|
exit:
|
||||||
#if defined(MBEDTLS_THREADING_C)
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
if (mbedtls_mutex_unlock(&ctx->mutex) != 0)
|
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
|
||||||
return (MBEDTLS_ERR_THREADING_MUTEX_ERROR);
|
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Entropy accumulator update
|
* Entropy accumulator update
|
||||||
*/
|
*/
|
||||||
static int entropy_update(mbedtls_entropy_context *ctx, unsigned char source_id,
|
static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id,
|
||||||
const unsigned char *data, size_t len) {
|
const unsigned char *data, size_t len )
|
||||||
|
{
|
||||||
unsigned char header[2];
|
unsigned char header[2];
|
||||||
unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||||
size_t use_len = len;
|
size_t use_len = len;
|
||||||
const unsigned char *p = data;
|
const unsigned char *p = data;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (use_len > MBEDTLS_ENTROPY_BLOCK_SIZE) {
|
if( use_len > MBEDTLS_ENTROPY_BLOCK_SIZE )
|
||||||
|
{
|
||||||
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
|
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
|
||||||
if ((ret = mbedtls_sha512_ret(data, len, tmp, 0)) != 0)
|
if( ( ret = mbedtls_sha512_ret( data, len, tmp, 0 ) ) != 0 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
#else
|
#else
|
||||||
if ((ret = mbedtls_sha256_ret(data, len, tmp, 0)) != 0)
|
if( ( ret = mbedtls_sha256_ret( data, len, tmp, 0 ) ) != 0 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
#endif
|
#endif
|
||||||
p = tmp;
|
p = tmp;
|
||||||
@@ -204,158 +208,177 @@ static int entropy_update(mbedtls_entropy_context *ctx, unsigned char source_id,
|
|||||||
* gather entropy eventually execute this code.
|
* gather entropy eventually execute this code.
|
||||||
*/
|
*/
|
||||||
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
|
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
|
||||||
if (ctx->accumulator_started == 0 &&
|
if( ctx->accumulator_started == 0 &&
|
||||||
(ret = mbedtls_sha512_starts_ret(&ctx->accumulator, 0)) != 0)
|
( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
else
|
else
|
||||||
ctx->accumulator_started = 1;
|
ctx->accumulator_started = 1;
|
||||||
if ((ret = mbedtls_sha512_update_ret(&ctx->accumulator, header, 2)) != 0)
|
if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, header, 2 ) ) != 0 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
ret = mbedtls_sha512_update_ret(&ctx->accumulator, p, use_len);
|
ret = mbedtls_sha512_update_ret( &ctx->accumulator, p, use_len );
|
||||||
#else
|
#else
|
||||||
if (ctx->accumulator_started == 0 &&
|
if( ctx->accumulator_started == 0 &&
|
||||||
(ret = mbedtls_sha256_starts_ret(&ctx->accumulator, 0)) != 0)
|
( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
else
|
else
|
||||||
ctx->accumulator_started = 1;
|
ctx->accumulator_started = 1;
|
||||||
if ((ret = mbedtls_sha256_update_ret(&ctx->accumulator, header, 2)) != 0)
|
if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, header, 2 ) ) != 0 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
ret = mbedtls_sha256_update_ret(&ctx->accumulator, p, use_len);
|
ret = mbedtls_sha256_update_ret( &ctx->accumulator, p, use_len );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
mbedtls_platform_zeroize(tmp, sizeof(tmp));
|
mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
|
||||||
|
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_entropy_update_manual(mbedtls_entropy_context *ctx,
|
int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
|
||||||
const unsigned char *data, size_t len) {
|
const unsigned char *data, size_t len )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
#if defined(MBEDTLS_THREADING_C)
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0)
|
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = entropy_update(ctx, MBEDTLS_ENTROPY_SOURCE_MANUAL, data, len);
|
ret = entropy_update( ctx, MBEDTLS_ENTROPY_SOURCE_MANUAL, data, len );
|
||||||
|
|
||||||
#if defined(MBEDTLS_THREADING_C)
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
if (mbedtls_mutex_unlock(&ctx->mutex) != 0)
|
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
|
||||||
return (MBEDTLS_ERR_THREADING_MUTEX_ERROR);
|
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run through the different sources to add entropy to our accumulator
|
* Run through the different sources to add entropy to our accumulator
|
||||||
*/
|
*/
|
||||||
static int entropy_gather_internal(mbedtls_entropy_context *ctx) {
|
static int entropy_gather_internal( mbedtls_entropy_context *ctx )
|
||||||
int ret, i, have_one_strong = 0;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||||
|
int i;
|
||||||
|
int have_one_strong = 0;
|
||||||
unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER];
|
unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER];
|
||||||
size_t olen;
|
size_t olen;
|
||||||
|
|
||||||
if (ctx->source_count == 0)
|
if( ctx->source_count == 0 )
|
||||||
return (MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED);
|
return( MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run through our entropy sources
|
* Run through our entropy sources
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < ctx->source_count; i++) {
|
for( i = 0; i < ctx->source_count; i++ )
|
||||||
if (ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG)
|
{
|
||||||
|
if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG )
|
||||||
have_one_strong = 1;
|
have_one_strong = 1;
|
||||||
|
|
||||||
olen = 0;
|
olen = 0;
|
||||||
if ((ret = ctx->source[i].f_source(ctx->source[i].p_source,
|
if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source,
|
||||||
buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen)) != 0) {
|
buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen ) ) != 0 )
|
||||||
|
{
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add if we actually gathered something
|
* Add if we actually gathered something
|
||||||
*/
|
*/
|
||||||
if (olen > 0) {
|
if( olen > 0 )
|
||||||
if ((ret = entropy_update(ctx, (unsigned char) i,
|
{
|
||||||
buf, olen)) != 0)
|
if( ( ret = entropy_update( ctx, (unsigned char) i,
|
||||||
return (ret);
|
buf, olen ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
ctx->source[i].size += olen;
|
ctx->source[i].size += olen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (have_one_strong == 0)
|
if( have_one_strong == 0 )
|
||||||
ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE;
|
ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
mbedtls_platform_zeroize(buf, sizeof(buf));
|
mbedtls_platform_zeroize( buf, sizeof( buf ) );
|
||||||
|
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Thread-safe wrapper for entropy_gather_internal()
|
* Thread-safe wrapper for entropy_gather_internal()
|
||||||
*/
|
*/
|
||||||
int mbedtls_entropy_gather(mbedtls_entropy_context *ctx) {
|
int mbedtls_entropy_gather( mbedtls_entropy_context *ctx )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
#if defined(MBEDTLS_THREADING_C)
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0)
|
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = entropy_gather_internal(ctx);
|
ret = entropy_gather_internal( ctx );
|
||||||
|
|
||||||
#if defined(MBEDTLS_THREADING_C)
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
if (mbedtls_mutex_unlock(&ctx->mutex) != 0)
|
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
|
||||||
return (MBEDTLS_ERR_THREADING_MUTEX_ERROR);
|
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_entropy_func(void *data, unsigned char *output, size_t len) {
|
int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
|
||||||
int ret, count = 0, i, done;
|
{
|
||||||
|
int ret, count = 0, i, thresholds_reached;
|
||||||
|
size_t strong_size;
|
||||||
mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data;
|
mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data;
|
||||||
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||||
|
|
||||||
if (len > MBEDTLS_ENTROPY_BLOCK_SIZE)
|
if( len > MBEDTLS_ENTROPY_BLOCK_SIZE )
|
||||||
return (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
|
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
|
||||||
|
|
||||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||||
/* Update the NV entropy seed before generating any entropy for outside
|
/* Update the NV entropy seed before generating any entropy for outside
|
||||||
* use.
|
* use.
|
||||||
*/
|
*/
|
||||||
if (ctx->initial_entropy_run == 0) {
|
if( ctx->initial_entropy_run == 0 )
|
||||||
|
{
|
||||||
ctx->initial_entropy_run = 1;
|
ctx->initial_entropy_run = 1;
|
||||||
if ((ret = mbedtls_entropy_update_nv_seed(ctx)) != 0)
|
if( ( ret = mbedtls_entropy_update_nv_seed( ctx ) ) != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_THREADING_C)
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0)
|
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Always gather extra entropy before a call
|
* Always gather extra entropy before a call
|
||||||
*/
|
*/
|
||||||
do {
|
do
|
||||||
if (count++ > ENTROPY_MAX_LOOP) {
|
{
|
||||||
|
if( count++ > ENTROPY_MAX_LOOP )
|
||||||
|
{
|
||||||
ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = entropy_gather_internal(ctx)) != 0)
|
if( ( ret = entropy_gather_internal( ctx ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
done = 1;
|
thresholds_reached = 1;
|
||||||
for (i = 0; i < ctx->source_count; i++)
|
strong_size = 0;
|
||||||
if (ctx->source[i].size < ctx->source[i].threshold)
|
for( i = 0; i < ctx->source_count; i++ )
|
||||||
done = 0;
|
{
|
||||||
} while (! done);
|
if( ctx->source[i].size < ctx->source[i].threshold )
|
||||||
|
thresholds_reached = 0;
|
||||||
|
if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG )
|
||||||
|
strong_size += ctx->source[i].size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while( ! thresholds_reached || strong_size < MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||||
|
|
||||||
memset(buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE);
|
memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||||
|
|
||||||
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
|
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
|
||||||
/*
|
/*
|
||||||
@@ -363,100 +386,103 @@ int mbedtls_entropy_func(void *data, unsigned char *output, size_t len) {
|
|||||||
* in a previous call to entropy_update(). If this is not guaranteed, the
|
* in a previous call to entropy_update(). If this is not guaranteed, the
|
||||||
* code below will fail.
|
* code below will fail.
|
||||||
*/
|
*/
|
||||||
if ((ret = mbedtls_sha512_finish_ret(&ctx->accumulator, buf)) != 0)
|
if( ( ret = mbedtls_sha512_finish_ret( &ctx->accumulator, buf ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset accumulator and counters and recycle existing entropy
|
* Reset accumulator and counters and recycle existing entropy
|
||||||
*/
|
*/
|
||||||
mbedtls_sha512_free(&ctx->accumulator);
|
mbedtls_sha512_free( &ctx->accumulator );
|
||||||
mbedtls_sha512_init(&ctx->accumulator);
|
mbedtls_sha512_init( &ctx->accumulator );
|
||||||
if ((ret = mbedtls_sha512_starts_ret(&ctx->accumulator, 0)) != 0)
|
if( ( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
if ((ret = mbedtls_sha512_update_ret(&ctx->accumulator, buf,
|
if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, buf,
|
||||||
MBEDTLS_ENTROPY_BLOCK_SIZE)) != 0)
|
MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perform second SHA-512 on entropy
|
* Perform second SHA-512 on entropy
|
||||||
*/
|
*/
|
||||||
if ((ret = mbedtls_sha512_ret(buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
|
if( ( ret = mbedtls_sha512_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
|
||||||
buf, 0)) != 0)
|
buf, 0 ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
#else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
|
#else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
|
||||||
if ((ret = mbedtls_sha256_finish_ret(&ctx->accumulator, buf)) != 0)
|
if( ( ret = mbedtls_sha256_finish_ret( &ctx->accumulator, buf ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset accumulator and counters and recycle existing entropy
|
* Reset accumulator and counters and recycle existing entropy
|
||||||
*/
|
*/
|
||||||
mbedtls_sha256_free(&ctx->accumulator);
|
mbedtls_sha256_free( &ctx->accumulator );
|
||||||
mbedtls_sha256_init(&ctx->accumulator);
|
mbedtls_sha256_init( &ctx->accumulator );
|
||||||
if ((ret = mbedtls_sha256_starts_ret(&ctx->accumulator, 0)) != 0)
|
if( ( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
if ((ret = mbedtls_sha256_update_ret(&ctx->accumulator, buf,
|
if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, buf,
|
||||||
MBEDTLS_ENTROPY_BLOCK_SIZE)) != 0)
|
MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perform second SHA-256 on entropy
|
* Perform second SHA-256 on entropy
|
||||||
*/
|
*/
|
||||||
if ((ret = mbedtls_sha256_ret(buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
|
if( ( ret = mbedtls_sha256_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
|
||||||
buf, 0)) != 0)
|
buf, 0 ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
#endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
|
#endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
|
||||||
|
|
||||||
for (i = 0; i < ctx->source_count; i++)
|
for( i = 0; i < ctx->source_count; i++ )
|
||||||
ctx->source[i].size = 0;
|
ctx->source[i].size = 0;
|
||||||
|
|
||||||
memcpy(output, buf, len);
|
memcpy( output, buf, len );
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
mbedtls_platform_zeroize(buf, sizeof(buf));
|
mbedtls_platform_zeroize( buf, sizeof( buf ) );
|
||||||
|
|
||||||
#if defined(MBEDTLS_THREADING_C)
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
if (mbedtls_mutex_unlock(&ctx->mutex) != 0)
|
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
|
||||||
return (MBEDTLS_ERR_THREADING_MUTEX_ERROR);
|
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||||
int mbedtls_entropy_update_nv_seed(mbedtls_entropy_context *ctx) {
|
int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx )
|
||||||
|
{
|
||||||
int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
|
int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
|
||||||
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||||
|
|
||||||
/* Read new seed and write it to NV */
|
/* Read new seed and write it to NV */
|
||||||
if ((ret = mbedtls_entropy_func(ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE)) != 0)
|
if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
|
|
||||||
if (mbedtls_nv_seed_write(buf, MBEDTLS_ENTROPY_BLOCK_SIZE) < 0)
|
if( mbedtls_nv_seed_write( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 )
|
||||||
return (MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR);
|
return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
|
||||||
|
|
||||||
/* Manually update the remaining stream with a separator value to diverge */
|
/* Manually update the remaining stream with a separator value to diverge */
|
||||||
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);
|
ret = mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||||
|
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_ENTROPY_NV_SEED */
|
#endif /* MBEDTLS_ENTROPY_NV_SEED */
|
||||||
|
|
||||||
#if defined(MBEDTLS_FS_IO)
|
#if defined(MBEDTLS_FS_IO)
|
||||||
int mbedtls_entropy_write_seed_file(mbedtls_entropy_context *ctx, const char *path) {
|
int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path )
|
||||||
|
{
|
||||||
int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
|
int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||||
|
|
||||||
if ((f = fopen(path, "wb")) == NULL)
|
if( ( f = fopen( path, "wb" ) ) == NULL )
|
||||||
return (MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR);
|
return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
|
||||||
|
|
||||||
if ((ret = mbedtls_entropy_func(ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE)) != 0)
|
if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (fwrite(buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f) != MBEDTLS_ENTROPY_BLOCK_SIZE) {
|
if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) != MBEDTLS_ENTROPY_BLOCK_SIZE )
|
||||||
|
{
|
||||||
ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
|
ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
@@ -464,41 +490,42 @@ int mbedtls_entropy_write_seed_file(mbedtls_entropy_context *ctx, const char *pa
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
mbedtls_platform_zeroize(buf, sizeof(buf));
|
mbedtls_platform_zeroize( buf, sizeof( buf ) );
|
||||||
|
|
||||||
fclose(f);
|
fclose( f );
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_entropy_update_seed_file(mbedtls_entropy_context *ctx, const char *path) {
|
int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path )
|
||||||
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
size_t n;
|
size_t n;
|
||||||
unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ];
|
unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ];
|
||||||
|
|
||||||
if ((f = fopen(path, "rb")) == NULL)
|
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||||
return (MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR);
|
return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
|
||||||
|
|
||||||
fseek(f, 0, SEEK_END);
|
fseek( f, 0, SEEK_END );
|
||||||
n = (size_t) ftell(f);
|
n = (size_t) ftell( f );
|
||||||
fseek(f, 0, SEEK_SET);
|
fseek( f, 0, SEEK_SET );
|
||||||
|
|
||||||
if (n > MBEDTLS_ENTROPY_MAX_SEED_SIZE)
|
if( n > MBEDTLS_ENTROPY_MAX_SEED_SIZE )
|
||||||
n = MBEDTLS_ENTROPY_MAX_SEED_SIZE;
|
n = MBEDTLS_ENTROPY_MAX_SEED_SIZE;
|
||||||
|
|
||||||
if (fread(buf, 1, n, f) != n)
|
if( fread( buf, 1, n, f ) != n )
|
||||||
ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
|
ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
|
||||||
else
|
else
|
||||||
ret = mbedtls_entropy_update_manual(ctx, buf, n);
|
ret = mbedtls_entropy_update_manual( ctx, buf, n );
|
||||||
|
|
||||||
fclose(f);
|
fclose( f );
|
||||||
|
|
||||||
mbedtls_platform_zeroize(buf, sizeof(buf));
|
mbedtls_platform_zeroize( buf, sizeof( buf ) );
|
||||||
|
|
||||||
if (ret != 0)
|
if( ret != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
|
|
||||||
return (mbedtls_entropy_write_seed_file(ctx, path));
|
return( mbedtls_entropy_write_seed_file( ctx, path ) );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_FS_IO */
|
#endif /* MBEDTLS_FS_IO */
|
||||||
|
|
||||||
@@ -507,54 +534,60 @@ int mbedtls_entropy_update_seed_file(mbedtls_entropy_context *ctx, const char *p
|
|||||||
/*
|
/*
|
||||||
* Dummy source function
|
* Dummy source function
|
||||||
*/
|
*/
|
||||||
static int entropy_dummy_source(void *data, unsigned char *output,
|
static int entropy_dummy_source( void *data, unsigned char *output,
|
||||||
size_t len, size_t *olen) {
|
size_t len, size_t *olen )
|
||||||
|
{
|
||||||
((void) data);
|
((void) data);
|
||||||
|
|
||||||
memset(output, 0x2a, len);
|
memset( output, 0x2a, len );
|
||||||
*olen = len;
|
*olen = len;
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
#endif /* !MBEDTLS_TEST_NULL_ENTROPY */
|
#endif /* !MBEDTLS_TEST_NULL_ENTROPY */
|
||||||
|
|
||||||
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
||||||
|
|
||||||
static int mbedtls_entropy_source_self_test_gather(unsigned char *buf, size_t buf_len) {
|
static int mbedtls_entropy_source_self_test_gather( unsigned char *buf, size_t buf_len )
|
||||||
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
size_t entropy_len = 0;
|
size_t entropy_len = 0;
|
||||||
size_t olen = 0;
|
size_t olen = 0;
|
||||||
size_t attempts = buf_len;
|
size_t attempts = buf_len;
|
||||||
|
|
||||||
while (attempts > 0 && entropy_len < buf_len) {
|
while( attempts > 0 && entropy_len < buf_len )
|
||||||
if ((ret = mbedtls_hardware_poll(NULL, buf + entropy_len,
|
{
|
||||||
buf_len - entropy_len, &olen)) != 0)
|
if( ( ret = mbedtls_hardware_poll( NULL, buf + entropy_len,
|
||||||
return (ret);
|
buf_len - entropy_len, &olen ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
entropy_len += olen;
|
entropy_len += olen;
|
||||||
attempts--;
|
attempts--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entropy_len < buf_len) {
|
if( entropy_len < buf_len )
|
||||||
|
{
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int mbedtls_entropy_source_self_test_check_bits(const unsigned char *buf,
|
static int mbedtls_entropy_source_self_test_check_bits( const unsigned char *buf,
|
||||||
size_t buf_len) {
|
size_t buf_len )
|
||||||
unsigned char set = 0xFF;
|
{
|
||||||
|
unsigned char set= 0xFF;
|
||||||
unsigned char unset = 0x00;
|
unsigned char unset = 0x00;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < buf_len; i++) {
|
for( i = 0; i < buf_len; i++ )
|
||||||
|
{
|
||||||
set &= buf[i];
|
set &= buf[i];
|
||||||
unset |= buf[i];
|
unset |= buf[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return (set == 0xFF || unset == 0x00);
|
return( set == 0xFF || unset == 0x00 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -568,43 +601,45 @@ static int mbedtls_entropy_source_self_test_check_bits(const unsigned char *buf,
|
|||||||
* are not equal.
|
* are not equal.
|
||||||
* - The error code returned by the entropy source is not an error.
|
* - The error code returned by the entropy source is not an error.
|
||||||
*/
|
*/
|
||||||
int mbedtls_entropy_source_self_test(int verbose) {
|
int mbedtls_entropy_source_self_test( int verbose )
|
||||||
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
unsigned char buf0[2 * sizeof(unsigned long long int)];
|
unsigned char buf0[2 * sizeof( unsigned long long int )];
|
||||||
unsigned char buf1[2 * sizeof(unsigned long long int)];
|
unsigned char buf1[2 * sizeof( unsigned long long int )];
|
||||||
|
|
||||||
if (verbose != 0)
|
if( verbose != 0 )
|
||||||
mbedtls_printf(" ENTROPY_BIAS test: ");
|
mbedtls_printf( " ENTROPY_BIAS test: " );
|
||||||
|
|
||||||
memset(buf0, 0x00, sizeof(buf0));
|
memset( buf0, 0x00, sizeof( buf0 ) );
|
||||||
memset(buf1, 0x00, sizeof(buf1));
|
memset( buf1, 0x00, sizeof( buf1 ) );
|
||||||
|
|
||||||
if ((ret = mbedtls_entropy_source_self_test_gather(buf0, sizeof(buf0))) != 0)
|
if( ( ret = mbedtls_entropy_source_self_test_gather( buf0, sizeof( buf0 ) ) ) != 0 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if ((ret = mbedtls_entropy_source_self_test_gather(buf1, sizeof(buf1))) != 0)
|
if( ( ret = mbedtls_entropy_source_self_test_gather( buf1, sizeof( buf1 ) ) ) != 0 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* Make sure that the returned values are not all 0 or 1 */
|
/* Make sure that the returned values are not all 0 or 1 */
|
||||||
if ((ret = mbedtls_entropy_source_self_test_check_bits(buf0, sizeof(buf0))) != 0)
|
if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf0, sizeof( buf0 ) ) ) != 0 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if ((ret = mbedtls_entropy_source_self_test_check_bits(buf1, sizeof(buf1))) != 0)
|
if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf1, sizeof( buf1 ) ) ) != 0 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* Make sure that the entropy source is not returning values in a
|
/* Make sure that the entropy source is not returning values in a
|
||||||
* pattern */
|
* pattern */
|
||||||
ret = memcmp(buf0, buf1, sizeof(buf0)) == 0;
|
ret = memcmp( buf0, buf1, sizeof( buf0 ) ) == 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (verbose != 0) {
|
if( verbose != 0 )
|
||||||
if (ret != 0)
|
{
|
||||||
mbedtls_printf("failed\n");
|
if( ret != 0 )
|
||||||
|
mbedtls_printf( "failed\n" );
|
||||||
else
|
else
|
||||||
mbedtls_printf("passed\n");
|
mbedtls_printf( "passed\n" );
|
||||||
|
|
||||||
mbedtls_printf("\n");
|
mbedtls_printf( "\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ret != 0);
|
return( ret != 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
|
#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
|
||||||
@@ -614,7 +649,8 @@ cleanup:
|
|||||||
* test that the functions don't cause errors and write the correct
|
* test that the functions don't cause errors and write the correct
|
||||||
* amount of data to buffers.
|
* amount of data to buffers.
|
||||||
*/
|
*/
|
||||||
int mbedtls_entropy_self_test(int verbose) {
|
int mbedtls_entropy_self_test( int verbose )
|
||||||
|
{
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
#if !defined(MBEDTLS_TEST_NULL_ENTROPY)
|
#if !defined(MBEDTLS_TEST_NULL_ENTROPY)
|
||||||
mbedtls_entropy_context ctx;
|
mbedtls_entropy_context ctx;
|
||||||
@@ -623,22 +659,22 @@ int mbedtls_entropy_self_test(int verbose) {
|
|||||||
size_t i, j;
|
size_t i, j;
|
||||||
#endif /* !MBEDTLS_TEST_NULL_ENTROPY */
|
#endif /* !MBEDTLS_TEST_NULL_ENTROPY */
|
||||||
|
|
||||||
if (verbose != 0)
|
if( verbose != 0 )
|
||||||
mbedtls_printf(" ENTROPY test: ");
|
mbedtls_printf( " ENTROPY test: " );
|
||||||
|
|
||||||
#if !defined(MBEDTLS_TEST_NULL_ENTROPY)
|
#if !defined(MBEDTLS_TEST_NULL_ENTROPY)
|
||||||
mbedtls_entropy_init(&ctx);
|
mbedtls_entropy_init( &ctx );
|
||||||
|
|
||||||
/* First do a gather to make sure we have default sources */
|
/* First do a gather to make sure we have default sources */
|
||||||
if ((ret = mbedtls_entropy_gather(&ctx)) != 0)
|
if( ( ret = mbedtls_entropy_gather( &ctx ) ) != 0 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
ret = mbedtls_entropy_add_source(&ctx, entropy_dummy_source, NULL, 16,
|
ret = mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL, 16,
|
||||||
MBEDTLS_ENTROPY_SOURCE_WEAK);
|
MBEDTLS_ENTROPY_SOURCE_WEAK );
|
||||||
if (ret != 0)
|
if( ret != 0 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if ((ret = mbedtls_entropy_update_manual(&ctx, buf, sizeof buf)) != 0)
|
if( ( ret = mbedtls_entropy_update_manual( &ctx, buf, sizeof buf ) ) != 0 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -649,40 +685,44 @@ int mbedtls_entropy_self_test(int verbose) {
|
|||||||
* each of the 32 or 64 bytes to be non-zero has a false failure rate
|
* each of the 32 or 64 bytes to be non-zero has a false failure rate
|
||||||
* of at most 2^(-58) which is acceptable.
|
* of at most 2^(-58) which is acceptable.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < 8; i++) {
|
for( i = 0; i < 8; i++ )
|
||||||
if ((ret = mbedtls_entropy_func(&ctx, buf, sizeof(buf))) != 0)
|
{
|
||||||
|
if( ( ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) ) ) != 0 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
for (j = 0; j < sizeof(buf); j++)
|
for( j = 0; j < sizeof( buf ); j++ )
|
||||||
acc[j] |= buf[j];
|
acc[j] |= buf[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j < sizeof(buf); j++) {
|
for( j = 0; j < sizeof( buf ); j++ )
|
||||||
if (acc[j] == 0) {
|
{
|
||||||
|
if( acc[j] == 0 )
|
||||||
|
{
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
||||||
if ((ret = mbedtls_entropy_source_self_test(0)) != 0)
|
if( ( ret = mbedtls_entropy_source_self_test( 0 ) ) != 0 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
mbedtls_entropy_free(&ctx);
|
mbedtls_entropy_free( &ctx );
|
||||||
#endif /* !MBEDTLS_TEST_NULL_ENTROPY */
|
#endif /* !MBEDTLS_TEST_NULL_ENTROPY */
|
||||||
|
|
||||||
if (verbose != 0) {
|
if( verbose != 0 )
|
||||||
if (ret != 0)
|
{
|
||||||
mbedtls_printf("failed\n");
|
if( ret != 0 )
|
||||||
|
mbedtls_printf( "failed\n" );
|
||||||
else
|
else
|
||||||
mbedtls_printf("passed\n");
|
mbedtls_printf( "passed\n" );
|
||||||
|
|
||||||
mbedtls_printf("\n");
|
mbedtls_printf( "\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ret != 0);
|
return( ret != 0 );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_SELF_TEST */
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
|
|||||||
@@ -4,30 +4,26 @@
|
|||||||
* \brief Entropy accumulator implementation
|
* \brief Entropy accumulator implementation
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef MBEDTLS_ENTROPY_H
|
#ifndef MBEDTLS_ENTROPY_H
|
||||||
#define MBEDTLS_ENTROPY_H
|
#define MBEDTLS_ENTROPY_H
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
#include "config.h"
|
#include "mbedtls/config.h"
|
||||||
#else
|
#else
|
||||||
#include MBEDTLS_CONFIG_FILE
|
#include MBEDTLS_CONFIG_FILE
|
||||||
#endif
|
#endif
|
||||||
@@ -35,21 +31,21 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
|
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
|
||||||
#include "sha512.h"
|
#include "mbedtls/sha512.h"
|
||||||
#define MBEDTLS_ENTROPY_SHA512_ACCUMULATOR
|
#define MBEDTLS_ENTROPY_SHA512_ACCUMULATOR
|
||||||
#else
|
#else
|
||||||
#if defined(MBEDTLS_SHA256_C)
|
#if defined(MBEDTLS_SHA256_C)
|
||||||
#define MBEDTLS_ENTROPY_SHA256_ACCUMULATOR
|
#define MBEDTLS_ENTROPY_SHA256_ACCUMULATOR
|
||||||
#include "sha256.h"
|
#include "mbedtls/sha256.h"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_THREADING_C)
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
#include "threading.h"
|
#include "mbedtls/threading.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_HAVEGE_C)
|
#if defined(MBEDTLS_HAVEGE_C)
|
||||||
#include "havege.h"
|
#include "mbedtls/havege.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED -0x003C /**< Critical entropy source failure. */
|
#define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED -0x003C /**< Critical entropy source failure. */
|
||||||
@@ -104,14 +100,15 @@ extern "C" {
|
|||||||
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED otherwise
|
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED otherwise
|
||||||
*/
|
*/
|
||||||
typedef int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output, size_t len,
|
typedef int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output, size_t len,
|
||||||
size_t *olen);
|
size_t *olen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Entropy source state
|
* \brief Entropy source state
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_entropy_source_state {
|
typedef struct mbedtls_entropy_source_state
|
||||||
|
{
|
||||||
mbedtls_entropy_f_source_ptr f_source; /**< The entropy source callback */
|
mbedtls_entropy_f_source_ptr f_source; /**< The entropy source callback */
|
||||||
void *p_source; /**< The callback data pointer */
|
void * p_source; /**< The callback data pointer */
|
||||||
size_t size; /**< Amount received in bytes */
|
size_t size; /**< Amount received in bytes */
|
||||||
size_t threshold; /**< Minimum bytes required before release */
|
size_t threshold; /**< Minimum bytes required before release */
|
||||||
int strong; /**< Is the source strong? */
|
int strong; /**< Is the source strong? */
|
||||||
@@ -121,14 +118,17 @@ mbedtls_entropy_source_state;
|
|||||||
/**
|
/**
|
||||||
* \brief Entropy context structure
|
* \brief Entropy context structure
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_entropy_context {
|
typedef struct mbedtls_entropy_context
|
||||||
int accumulator_started;
|
{
|
||||||
|
int accumulator_started; /* 0 after init.
|
||||||
|
* 1 after the first update.
|
||||||
|
* -1 after free. */
|
||||||
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
|
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
|
||||||
mbedtls_sha512_context accumulator;
|
mbedtls_sha512_context accumulator;
|
||||||
#else
|
#else
|
||||||
mbedtls_sha256_context accumulator;
|
mbedtls_sha256_context accumulator;
|
||||||
#endif
|
#endif
|
||||||
int source_count;
|
int source_count; /* Number of entries used in source. */
|
||||||
mbedtls_entropy_source_state source[MBEDTLS_ENTROPY_MAX_SOURCES];
|
mbedtls_entropy_source_state source[MBEDTLS_ENTROPY_MAX_SOURCES];
|
||||||
#if defined(MBEDTLS_HAVEGE_C)
|
#if defined(MBEDTLS_HAVEGE_C)
|
||||||
mbedtls_havege_state havege_data;
|
mbedtls_havege_state havege_data;
|
||||||
@@ -147,14 +147,14 @@ mbedtls_entropy_context;
|
|||||||
*
|
*
|
||||||
* \param ctx Entropy context to initialize
|
* \param ctx Entropy context to initialize
|
||||||
*/
|
*/
|
||||||
void mbedtls_entropy_init(mbedtls_entropy_context *ctx);
|
void mbedtls_entropy_init( mbedtls_entropy_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Free the data in the context
|
* \brief Free the data in the context
|
||||||
*
|
*
|
||||||
* \param ctx Entropy context to free
|
* \param ctx Entropy context to free
|
||||||
*/
|
*/
|
||||||
void mbedtls_entropy_free(mbedtls_entropy_context *ctx);
|
void mbedtls_entropy_free( mbedtls_entropy_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Adds an entropy source to poll
|
* \brief Adds an entropy source to poll
|
||||||
@@ -173,9 +173,9 @@ void mbedtls_entropy_free(mbedtls_entropy_context *ctx);
|
|||||||
*
|
*
|
||||||
* \return 0 if successful or MBEDTLS_ERR_ENTROPY_MAX_SOURCES
|
* \return 0 if successful or MBEDTLS_ERR_ENTROPY_MAX_SOURCES
|
||||||
*/
|
*/
|
||||||
int mbedtls_entropy_add_source(mbedtls_entropy_context *ctx,
|
int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
|
||||||
mbedtls_entropy_f_source_ptr f_source, void *p_source,
|
mbedtls_entropy_f_source_ptr f_source, void *p_source,
|
||||||
size_t threshold, int strong);
|
size_t threshold, int strong );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Trigger an extra gather poll for the accumulator
|
* \brief Trigger an extra gather poll for the accumulator
|
||||||
@@ -185,7 +185,7 @@ int mbedtls_entropy_add_source(mbedtls_entropy_context *ctx,
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
|
* \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
|
||||||
*/
|
*/
|
||||||
int mbedtls_entropy_gather(mbedtls_entropy_context *ctx);
|
int mbedtls_entropy_gather( mbedtls_entropy_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Retrieve entropy from the accumulator
|
* \brief Retrieve entropy from the accumulator
|
||||||
@@ -198,7 +198,7 @@ int mbedtls_entropy_gather(mbedtls_entropy_context *ctx);
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
|
* \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
|
||||||
*/
|
*/
|
||||||
int mbedtls_entropy_func(void *data, unsigned char *output, size_t len);
|
int mbedtls_entropy_func( void *data, unsigned char *output, size_t len );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Add data to the accumulator manually
|
* \brief Add data to the accumulator manually
|
||||||
@@ -210,8 +210,8 @@ int mbedtls_entropy_func(void *data, unsigned char *output, size_t len);
|
|||||||
*
|
*
|
||||||
* \return 0 if successful
|
* \return 0 if successful
|
||||||
*/
|
*/
|
||||||
int mbedtls_entropy_update_manual(mbedtls_entropy_context *ctx,
|
int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
|
||||||
const unsigned char *data, size_t len);
|
const unsigned char *data, size_t len );
|
||||||
|
|
||||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||||
/**
|
/**
|
||||||
@@ -222,7 +222,7 @@ int mbedtls_entropy_update_manual(mbedtls_entropy_context *ctx,
|
|||||||
*
|
*
|
||||||
* \return 0 if successful
|
* \return 0 if successful
|
||||||
*/
|
*/
|
||||||
int mbedtls_entropy_update_nv_seed(mbedtls_entropy_context *ctx);
|
int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx );
|
||||||
#endif /* MBEDTLS_ENTROPY_NV_SEED */
|
#endif /* MBEDTLS_ENTROPY_NV_SEED */
|
||||||
|
|
||||||
#if defined(MBEDTLS_FS_IO)
|
#if defined(MBEDTLS_FS_IO)
|
||||||
@@ -236,7 +236,7 @@ int mbedtls_entropy_update_nv_seed(mbedtls_entropy_context *ctx);
|
|||||||
* MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error, or
|
* MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error, or
|
||||||
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
|
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
|
||||||
*/
|
*/
|
||||||
int mbedtls_entropy_write_seed_file(mbedtls_entropy_context *ctx, const char *path);
|
int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Read and update a seed file. Seed is added to this
|
* \brief Read and update a seed file. Seed is added to this
|
||||||
@@ -250,7 +250,7 @@ int mbedtls_entropy_write_seed_file(mbedtls_entropy_context *ctx, const char *pa
|
|||||||
* MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error,
|
* MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error,
|
||||||
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
|
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
|
||||||
*/
|
*/
|
||||||
int mbedtls_entropy_update_seed_file(mbedtls_entropy_context *ctx, const char *path);
|
int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path );
|
||||||
#endif /* MBEDTLS_FS_IO */
|
#endif /* MBEDTLS_FS_IO */
|
||||||
|
|
||||||
#if defined(MBEDTLS_SELF_TEST)
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
@@ -262,7 +262,7 @@ int mbedtls_entropy_update_seed_file(mbedtls_entropy_context *ctx, const char *p
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or 1 if a test failed
|
* \return 0 if successful, or 1 if a test failed
|
||||||
*/
|
*/
|
||||||
int mbedtls_entropy_self_test(int verbose);
|
int mbedtls_entropy_self_test( int verbose );
|
||||||
|
|
||||||
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
||||||
/**
|
/**
|
||||||
@@ -278,7 +278,7 @@ int mbedtls_entropy_self_test(int verbose);
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or 1 if a test failed
|
* \return 0 if successful, or 1 if a test failed
|
||||||
*/
|
*/
|
||||||
int mbedtls_entropy_source_self_test(int verbose);
|
int mbedtls_entropy_source_self_test( int verbose );
|
||||||
#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
|
#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
|
||||||
#endif /* MBEDTLS_SELF_TEST */
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
|
|||||||
@@ -1,36 +1,28 @@
|
|||||||
/*
|
/*
|
||||||
* Platform-specific and custom entropy polling functions
|
* Platform-specific and custom entropy polling functions
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__) && !defined(_GNU_SOURCE)
|
||||||
/* Ensure that syscall() is available even when compiling with -std=c99 */
|
/* Ensure that syscall() is available even when compiling with -std=c99 */
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#include "common.h"
|
||||||
#include "mbedtls/config.h"
|
|
||||||
#else
|
|
||||||
#include MBEDTLS_CONFIG_FILE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -38,6 +30,7 @@
|
|||||||
|
|
||||||
#include "mbedtls/entropy.h"
|
#include "mbedtls/entropy.h"
|
||||||
#include "mbedtls/entropy_poll.h"
|
#include "mbedtls/entropy_poll.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
#if defined(MBEDTLS_TIMING_C)
|
#if defined(MBEDTLS_TIMING_C)
|
||||||
#include "mbedtls/timing.h"
|
#include "mbedtls/timing.h"
|
||||||
@@ -53,7 +46,7 @@
|
|||||||
|
|
||||||
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
|
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
|
||||||
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
|
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
|
||||||
!defined(__HAIKU__)
|
!defined(__HAIKU__) && !defined(__midipix__)
|
||||||
#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h"
|
#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -65,26 +58,29 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <wincrypt.h>
|
#include <wincrypt.h>
|
||||||
|
|
||||||
int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len,
|
int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len,
|
||||||
size_t *olen) {
|
size_t *olen )
|
||||||
|
{
|
||||||
HCRYPTPROV provider;
|
HCRYPTPROV provider;
|
||||||
((void) data);
|
((void) data);
|
||||||
*olen = 0;
|
*olen = 0;
|
||||||
|
|
||||||
if (CryptAcquireContext(&provider, NULL, NULL,
|
if( CryptAcquireContext( &provider, NULL, NULL,
|
||||||
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) == FALSE) {
|
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE )
|
||||||
return (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
|
{
|
||||||
|
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CryptGenRandom(provider, (DWORD) len, output) == FALSE) {
|
if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE )
|
||||||
CryptReleaseContext(provider, 0);
|
{
|
||||||
return (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
|
CryptReleaseContext( provider, 0 );
|
||||||
|
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
|
||||||
}
|
}
|
||||||
|
|
||||||
CryptReleaseContext(provider, 0);
|
CryptReleaseContext( provider, 0 );
|
||||||
*olen = len;
|
*olen = len;
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
#else /* _WIN32 && !EFIX64 && !EFI32 */
|
#else /* _WIN32 && !EFIX64 && !EFI32 */
|
||||||
|
|
||||||
@@ -93,172 +89,202 @@ int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len,
|
|||||||
* Since there is no wrapper in the libc yet, use the generic syscall wrapper
|
* Since there is no wrapper in the libc yet, use the generic syscall wrapper
|
||||||
* available in GNU libc and compatible libc's (eg uClibc).
|
* available in GNU libc and compatible libc's (eg uClibc).
|
||||||
*/
|
*/
|
||||||
#if defined(__linux__) && defined(__GLIBC__)
|
#if ((defined(__linux__) && defined(__GLIBC__)) || defined(__midipix__))
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#if defined(SYS_getrandom)
|
#if defined(SYS_getrandom)
|
||||||
#define HAVE_GETRANDOM
|
#define HAVE_GETRANDOM
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
static int getrandom_wrapper(void *buf, size_t buflen, unsigned int flags) {
|
static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
|
||||||
|
{
|
||||||
/* MemSan cannot understand that the syscall writes to the buffer */
|
/* MemSan cannot understand that the syscall writes to the buffer */
|
||||||
#if defined(__has_feature)
|
#if defined(__has_feature)
|
||||||
#if __has_feature(memory_sanitizer)
|
#if __has_feature(memory_sanitizer)
|
||||||
memset(buf, 0, buflen);
|
memset( buf, 0, buflen );
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
return( syscall( SYS_getrandom, buf, buflen, flags ) );
|
||||||
return (syscall(SYS_getrandom, buf, buflen, flags));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <sys/utsname.h>
|
|
||||||
/* Check if version is at least 3.17.0 */
|
|
||||||
static int check_version_3_17_plus(void) {
|
|
||||||
int minor;
|
|
||||||
struct utsname un;
|
|
||||||
const char *ver;
|
|
||||||
|
|
||||||
/* Get version information */
|
|
||||||
uname(&un);
|
|
||||||
ver = un.release;
|
|
||||||
|
|
||||||
/* Check major version; assume a single digit */
|
|
||||||
if (ver[0] < '3' || ver[0] > '9' || ver [1] != '.')
|
|
||||||
return (-1);
|
|
||||||
|
|
||||||
if (ver[0] - '0' > 3)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
/* Ok, so now we know major == 3, check minor.
|
|
||||||
* Assume 1 or 2 digits. */
|
|
||||||
if (ver[2] < '0' || ver[2] > '9')
|
|
||||||
return (-1);
|
|
||||||
|
|
||||||
minor = ver[2] - '0';
|
|
||||||
|
|
||||||
if (ver[3] >= '0' && ver[3] <= '9')
|
|
||||||
minor = 10 * minor + ver[3] - '0';
|
|
||||||
else if (ver [3] != '.')
|
|
||||||
return (-1);
|
|
||||||
|
|
||||||
if (minor < 17)
|
|
||||||
return (-1);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
static int has_getrandom = -1;
|
|
||||||
#endif /* SYS_getrandom */
|
#endif /* SYS_getrandom */
|
||||||
#endif /* __linux__ */
|
#endif /* __linux__ || __midipix__ */
|
||||||
|
|
||||||
|
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||||
|
#include <sys/param.h>
|
||||||
|
#if (defined(__FreeBSD__) && __FreeBSD_version >= 1200000) || \
|
||||||
|
(defined(__DragonFly__) && __DragonFly_version >= 500700)
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/random.h>
|
||||||
|
#define HAVE_GETRANDOM
|
||||||
|
static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
|
||||||
|
{
|
||||||
|
return getrandom( buf, buflen, flags );
|
||||||
|
}
|
||||||
|
#endif /* (__FreeBSD__ && __FreeBSD_version >= 1200000) ||
|
||||||
|
(__DragonFly__ && __DragonFly_version >= 500700) */
|
||||||
|
#endif /* __FreeBSD__ || __DragonFly__ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some BSD systems provide KERN_ARND.
|
||||||
|
* This is equivalent to reading from /dev/urandom, only it doesn't require an
|
||||||
|
* open file descriptor, and provides up to 256 bytes per call (basically the
|
||||||
|
* same as getentropy(), but with a longer history).
|
||||||
|
*
|
||||||
|
* Documentation: https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+7
|
||||||
|
*/
|
||||||
|
#if (defined(__FreeBSD__) || defined(__NetBSD__)) && !defined(HAVE_GETRANDOM)
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#if defined(KERN_ARND)
|
||||||
|
#define HAVE_SYSCTL_ARND
|
||||||
|
|
||||||
|
static int sysctl_arnd_wrapper( unsigned char *buf, size_t buflen )
|
||||||
|
{
|
||||||
|
int name[2];
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
name[0] = CTL_KERN;
|
||||||
|
name[1] = KERN_ARND;
|
||||||
|
|
||||||
|
while( buflen > 0 )
|
||||||
|
{
|
||||||
|
len = buflen > 256 ? 256 : buflen;
|
||||||
|
if( sysctl(name, 2, buf, &len, NULL, 0) == -1 )
|
||||||
|
return( -1 );
|
||||||
|
buflen -= len;
|
||||||
|
buf += len;
|
||||||
|
}
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
#endif /* KERN_ARND */
|
||||||
|
#endif /* __FreeBSD__ || __NetBSD__ */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int mbedtls_platform_entropy_poll(void *data,
|
int mbedtls_platform_entropy_poll( void *data,
|
||||||
unsigned char *output, size_t len, size_t *olen) {
|
unsigned char *output, size_t len, size_t *olen )
|
||||||
|
{
|
||||||
FILE *file;
|
FILE *file;
|
||||||
size_t read_len;
|
size_t read_len;
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
((void) data);
|
((void) data);
|
||||||
|
|
||||||
#if defined(HAVE_GETRANDOM)
|
#if defined(HAVE_GETRANDOM)
|
||||||
if (has_getrandom == -1)
|
ret = getrandom_wrapper( output, len, 0 );
|
||||||
has_getrandom = (check_version_3_17_plus() == 0);
|
if( ret >= 0 )
|
||||||
|
{
|
||||||
if (has_getrandom) {
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if ((ret = getrandom_wrapper(output, len, 0)) < 0)
|
|
||||||
return (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
|
|
||||||
|
|
||||||
*olen = ret;
|
*olen = ret;
|
||||||
return (0);
|
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 */
|
#endif /* HAVE_GETRANDOM */
|
||||||
|
|
||||||
|
#if defined(HAVE_SYSCTL_ARND)
|
||||||
|
((void) file);
|
||||||
|
((void) read_len);
|
||||||
|
if( sysctl_arnd_wrapper( output, len ) == -1 )
|
||||||
|
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
|
||||||
|
*olen = len;
|
||||||
|
return( 0 );
|
||||||
|
#else
|
||||||
|
|
||||||
*olen = 0;
|
*olen = 0;
|
||||||
|
|
||||||
file = fopen("/dev/urandom", "rb");
|
file = fopen( "/dev/urandom", "rb" );
|
||||||
if (file == NULL)
|
if( file == NULL )
|
||||||
return (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
|
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
|
||||||
|
|
||||||
read_len = fread(output, 1, len, file);
|
read_len = fread( output, 1, len, file );
|
||||||
if (read_len != len) {
|
if( read_len != len )
|
||||||
fclose(file);
|
{
|
||||||
return (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
|
fclose( file );
|
||||||
|
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(file);
|
fclose( file );
|
||||||
*olen = len;
|
*olen = len;
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
|
#endif /* HAVE_SYSCTL_ARND */
|
||||||
}
|
}
|
||||||
#endif /* _WIN32 && !EFIX64 && !EFI32 */
|
#endif /* _WIN32 && !EFIX64 && !EFI32 */
|
||||||
#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
|
#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
|
||||||
|
|
||||||
#if defined(MBEDTLS_TEST_NULL_ENTROPY)
|
#if defined(MBEDTLS_TEST_NULL_ENTROPY)
|
||||||
int mbedtls_null_entropy_poll(void *data,
|
int mbedtls_null_entropy_poll( void *data,
|
||||||
unsigned char *output, size_t len, size_t *olen) {
|
unsigned char *output, size_t len, size_t *olen )
|
||||||
|
{
|
||||||
((void) data);
|
((void) data);
|
||||||
((void) output);
|
((void) output);
|
||||||
|
|
||||||
*olen = 0;
|
*olen = 0;
|
||||||
|
if( len < sizeof(unsigned char) )
|
||||||
|
return( 0 );
|
||||||
|
|
||||||
if (len < sizeof(unsigned char))
|
output[0] = 0;
|
||||||
return (0);
|
|
||||||
|
|
||||||
*olen = sizeof(unsigned char);
|
*olen = sizeof(unsigned char);
|
||||||
|
return( 0 );
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_TIMING_C)
|
#if defined(MBEDTLS_TIMING_C)
|
||||||
int mbedtls_hardclock_poll(void *data,
|
int mbedtls_hardclock_poll( void *data,
|
||||||
unsigned char *output, size_t len, size_t *olen) {
|
unsigned char *output, size_t len, size_t *olen )
|
||||||
|
{
|
||||||
unsigned long timer = mbedtls_timing_hardclock();
|
unsigned long timer = mbedtls_timing_hardclock();
|
||||||
((void) data);
|
((void) data);
|
||||||
*olen = 0;
|
*olen = 0;
|
||||||
|
|
||||||
if (len < sizeof(unsigned long))
|
if( len < sizeof(unsigned long) )
|
||||||
return (0);
|
return( 0 );
|
||||||
|
|
||||||
memcpy(output, &timer, sizeof(unsigned long));
|
memcpy( output, &timer, sizeof(unsigned long) );
|
||||||
*olen = sizeof(unsigned long);
|
*olen = sizeof(unsigned long);
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_TIMING_C */
|
#endif /* MBEDTLS_TIMING_C */
|
||||||
|
|
||||||
#if defined(MBEDTLS_HAVEGE_C)
|
#if defined(MBEDTLS_HAVEGE_C)
|
||||||
int mbedtls_havege_poll(void *data,
|
int mbedtls_havege_poll( void *data,
|
||||||
unsigned char *output, size_t len, size_t *olen) {
|
unsigned char *output, size_t len, size_t *olen )
|
||||||
|
{
|
||||||
mbedtls_havege_state *hs = (mbedtls_havege_state *) data;
|
mbedtls_havege_state *hs = (mbedtls_havege_state *) data;
|
||||||
*olen = 0;
|
*olen = 0;
|
||||||
|
|
||||||
if (mbedtls_havege_random(hs, output, len) != 0)
|
if( mbedtls_havege_random( hs, output, len ) != 0 )
|
||||||
return (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
|
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
|
||||||
|
|
||||||
*olen = len;
|
*olen = len;
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_HAVEGE_C */
|
#endif /* MBEDTLS_HAVEGE_C */
|
||||||
|
|
||||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||||
int mbedtls_nv_seed_poll(void *data,
|
int mbedtls_nv_seed_poll( void *data,
|
||||||
unsigned char *output, size_t len, size_t *olen) {
|
unsigned char *output, size_t len, size_t *olen )
|
||||||
|
{
|
||||||
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||||
size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
|
size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
|
||||||
((void) data);
|
((void) data);
|
||||||
|
|
||||||
memset(buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE);
|
memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||||
|
|
||||||
if (mbedtls_nv_seed_read(buf, MBEDTLS_ENTROPY_BLOCK_SIZE) < 0)
|
if( mbedtls_nv_seed_read( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 )
|
||||||
return (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
|
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
|
||||||
|
|
||||||
if (len < use_len)
|
if( len < use_len )
|
||||||
use_len = len;
|
use_len = len;
|
||||||
|
|
||||||
memcpy(output, buf, use_len);
|
memcpy( output, buf, use_len );
|
||||||
*olen = use_len;
|
*olen = use_len;
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_ENTROPY_NV_SEED */
|
#endif /* MBEDTLS_ENTROPY_NV_SEED */
|
||||||
|
|
||||||
|
|||||||
@@ -4,30 +4,26 @@
|
|||||||
* \brief Platform-specific and custom entropy polling functions
|
* \brief Platform-specific and custom entropy polling functions
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef MBEDTLS_ENTROPY_POLL_H
|
#ifndef MBEDTLS_ENTROPY_POLL_H
|
||||||
#define MBEDTLS_ENTROPY_POLL_H
|
#define MBEDTLS_ENTROPY_POLL_H
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
#include "config.h"
|
#include "mbedtls/config.h"
|
||||||
#else
|
#else
|
||||||
#include MBEDTLS_CONFIG_FILE
|
#include MBEDTLS_CONFIG_FILE
|
||||||
#endif
|
#endif
|
||||||
@@ -52,16 +48,16 @@ extern "C" {
|
|||||||
* \brief Entropy poll callback that provides 0 entropy.
|
* \brief Entropy poll callback that provides 0 entropy.
|
||||||
*/
|
*/
|
||||||
#if defined(MBEDTLS_TEST_NULL_ENTROPY)
|
#if defined(MBEDTLS_TEST_NULL_ENTROPY)
|
||||||
int mbedtls_null_entropy_poll(void *data,
|
int mbedtls_null_entropy_poll( void *data,
|
||||||
unsigned char *output, size_t len, size_t *olen);
|
unsigned char *output, size_t len, size_t *olen );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
|
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
|
||||||
/**
|
/**
|
||||||
* \brief Platform-specific entropy poll callback
|
* \brief Platform-specific entropy poll callback
|
||||||
*/
|
*/
|
||||||
int mbedtls_platform_entropy_poll(void *data,
|
int mbedtls_platform_entropy_poll( void *data,
|
||||||
unsigned char *output, size_t len, size_t *olen);
|
unsigned char *output, size_t len, size_t *olen );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_HAVEGE_C)
|
#if defined(MBEDTLS_HAVEGE_C)
|
||||||
@@ -70,16 +66,16 @@ int mbedtls_platform_entropy_poll(void *data,
|
|||||||
*
|
*
|
||||||
* Requires an HAVEGE state as its data pointer.
|
* Requires an HAVEGE state as its data pointer.
|
||||||
*/
|
*/
|
||||||
int mbedtls_havege_poll(void *data,
|
int mbedtls_havege_poll( void *data,
|
||||||
unsigned char *output, size_t len, size_t *olen);
|
unsigned char *output, size_t len, size_t *olen );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_TIMING_C)
|
#if defined(MBEDTLS_TIMING_C)
|
||||||
/**
|
/**
|
||||||
* \brief mbedtls_timing_hardclock-based entropy poll callback
|
* \brief mbedtls_timing_hardclock-based entropy poll callback
|
||||||
*/
|
*/
|
||||||
int mbedtls_hardclock_poll(void *data,
|
int mbedtls_hardclock_poll( void *data,
|
||||||
unsigned char *output, size_t len, size_t *olen);
|
unsigned char *output, size_t len, size_t *olen );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
||||||
@@ -91,8 +87,8 @@ int mbedtls_hardclock_poll(void *data,
|
|||||||
*
|
*
|
||||||
* \note This must accept NULL as its first argument.
|
* \note This must accept NULL as its first argument.
|
||||||
*/
|
*/
|
||||||
int mbedtls_hardware_poll(void *data,
|
int mbedtls_hardware_poll( void *data,
|
||||||
unsigned char *output, size_t len, size_t *olen);
|
unsigned char *output, size_t len, size_t *olen );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||||
@@ -101,8 +97,8 @@ int mbedtls_hardware_poll(void *data,
|
|||||||
*
|
*
|
||||||
* \note This must accept NULL as its first argument.
|
* \note This must accept NULL as its first argument.
|
||||||
*/
|
*/
|
||||||
int mbedtls_nv_seed_poll(void *data,
|
int mbedtls_nv_seed_poll( void *data,
|
||||||
unsigned char *output, size_t len, size_t *olen);
|
unsigned char *output, size_t len, size_t *olen );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,28 +4,30 @@
|
|||||||
* \brief Error to string translation
|
* \brief Error to string translation
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef MBEDTLS_ERROR_H
|
#ifndef MBEDTLS_ERROR_H
|
||||||
#define MBEDTLS_ERROR_H
|
#define MBEDTLS_ERROR_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,9 +50,10 @@
|
|||||||
* For historical reasons, low-level error codes are divided in even and odd,
|
* For historical reasons, low-level error codes are divided in even and odd,
|
||||||
* even codes were assigned first, and -1 is reserved for other errors.
|
* even codes were assigned first, and -1 is reserved for other errors.
|
||||||
*
|
*
|
||||||
* Low-level module errors (0x0002-0x007E, 0x0003-0x007F)
|
* Low-level module errors (0x0002-0x007E, 0x0001-0x007F)
|
||||||
*
|
*
|
||||||
* Module Nr Codes assigned
|
* Module Nr Codes assigned
|
||||||
|
* ERROR 2 0x006E 0x0001
|
||||||
* MPI 7 0x0002-0x0010
|
* MPI 7 0x0002-0x0010
|
||||||
* GCM 3 0x0012-0x0014 0x0013-0x0013
|
* GCM 3 0x0012-0x0014 0x0013-0x0013
|
||||||
* BLOWFISH 3 0x0016-0x0018 0x0017-0x0017
|
* BLOWFISH 3 0x0016-0x0018 0x0017-0x0017
|
||||||
@@ -76,12 +79,13 @@
|
|||||||
* MD4 1 0x002D-0x002D
|
* MD4 1 0x002D-0x002D
|
||||||
* MD5 1 0x002F-0x002F
|
* MD5 1 0x002F-0x002F
|
||||||
* RIPEMD160 1 0x0031-0x0031
|
* RIPEMD160 1 0x0031-0x0031
|
||||||
* SHA1 1 0x0035-0x0035
|
* SHA1 1 0x0035-0x0035 0x0073-0x0073
|
||||||
* SHA256 1 0x0037-0x0037
|
* SHA256 1 0x0037-0x0037 0x0074-0x0074
|
||||||
* SHA512 1 0x0039-0x0039
|
* SHA512 1 0x0039-0x0039 0x0075-0x0075
|
||||||
* CHACHA20 3 0x0051-0x0055
|
* CHACHA20 3 0x0051-0x0055
|
||||||
* POLY1305 3 0x0057-0x005B
|
* POLY1305 3 0x0057-0x005B
|
||||||
* CHACHAPOLY 2 0x0054-0x0056
|
* CHACHAPOLY 2 0x0054-0x0056
|
||||||
|
* PLATFORM 2 0x0070-0x0072
|
||||||
*
|
*
|
||||||
* High-level module nr (3 bits - 0x0...-0x7...)
|
* High-level module nr (3 bits - 0x0...-0x7...)
|
||||||
* Name ID Nr of Errors
|
* Name ID Nr of Errors
|
||||||
@@ -92,12 +96,13 @@
|
|||||||
* DHM 3 11
|
* DHM 3 11
|
||||||
* PK 3 15 (Started from top)
|
* PK 3 15 (Started from top)
|
||||||
* RSA 4 11
|
* RSA 4 11
|
||||||
* ECP 4 9 (Started from top)
|
* ECP 4 10 (Started from top)
|
||||||
* MD 5 5
|
* MD 5 5
|
||||||
* HKDF 5 1 (Started from top)
|
* HKDF 5 1 (Started from top)
|
||||||
* CIPHER 6 8
|
* SSL 5 2 (Started from 0x5F00)
|
||||||
* SSL 6 22 (Started from top)
|
* CIPHER 6 8 (Started from 0x6080)
|
||||||
* SSL 7 31
|
* SSL 6 24 (Started from top, plus 0x6000)
|
||||||
|
* SSL 7 32
|
||||||
*
|
*
|
||||||
* Module dependent error code (5 bits 0x.00.-0x.F8.)
|
* Module dependent error code (5 bits 0x.00.-0x.F8.)
|
||||||
*/
|
*/
|
||||||
@@ -106,6 +111,9 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MBEDTLS_ERR_ERROR_GENERIC_ERROR -0x0001 /**< Generic error */
|
||||||
|
#define MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED -0x006E /**< This is a bug in the library */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Translate a mbed TLS error code into a string representation,
|
* \brief Translate a mbed TLS error code into a string representation,
|
||||||
* Result is truncated if necessary and always includes a terminating
|
* Result is truncated if necessary and always includes a terminating
|
||||||
@@ -115,7 +123,37 @@ extern "C" {
|
|||||||
* \param buffer buffer to place representation in
|
* \param buffer buffer to place representation in
|
||||||
* \param buflen length of the buffer
|
* \param buflen length of the buffer
|
||||||
*/
|
*/
|
||||||
void mbedtls_strerror(int errnum, char *buffer, size_t buflen);
|
void mbedtls_strerror( int errnum, char *buffer, size_t buflen );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Translate the high-level part of an Mbed TLS error code into a string
|
||||||
|
* representation.
|
||||||
|
*
|
||||||
|
* This function returns a const pointer to an un-modifiable string. The caller
|
||||||
|
* must not try to modify the string. It is intended to be used mostly for
|
||||||
|
* logging purposes.
|
||||||
|
*
|
||||||
|
* \param error_code error code
|
||||||
|
*
|
||||||
|
* \return The string representation of the error code, or \c NULL if the error
|
||||||
|
* code is unknown.
|
||||||
|
*/
|
||||||
|
const char * mbedtls_high_level_strerr( int error_code );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Translate the low-level part of an Mbed TLS error code into a string
|
||||||
|
* representation.
|
||||||
|
*
|
||||||
|
* This function returns a const pointer to an un-modifiable string. The caller
|
||||||
|
* must not try to modify the string. It is intended to be used mostly for
|
||||||
|
* logging purposes.
|
||||||
|
*
|
||||||
|
* \param error_code error code
|
||||||
|
*
|
||||||
|
* \return The string representation of the error code, or \c NULL if the error
|
||||||
|
* code is unknown.
|
||||||
|
*/
|
||||||
|
const char * mbedtls_low_level_strerr( int error_code );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
1024
common/mbedtls/gcm.c
Normal file
1024
common/mbedtls/gcm.c
Normal file
File diff suppressed because it is too large
Load Diff
324
common/mbedtls/gcm.h
Normal file
324
common/mbedtls/gcm.h
Normal file
@@ -0,0 +1,324 @@
|
|||||||
|
/**
|
||||||
|
* \file gcm.h
|
||||||
|
*
|
||||||
|
* \brief This file contains GCM definitions and functions.
|
||||||
|
*
|
||||||
|
* The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined
|
||||||
|
* in <em>D. McGrew, J. Viega, The Galois/Counter Mode of Operation
|
||||||
|
* (GCM), Natl. Inst. Stand. Technol.</em>
|
||||||
|
*
|
||||||
|
* For more information on GCM, see <em>NIST SP 800-38D: Recommendation for
|
||||||
|
* Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC</em>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MBEDTLS_GCM_H
|
||||||
|
#define MBEDTLS_GCM_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mbedtls/cipher.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define MBEDTLS_GCM_ENCRYPT 1
|
||||||
|
#define MBEDTLS_GCM_DECRYPT 0
|
||||||
|
|
||||||
|
#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */
|
||||||
|
|
||||||
|
/* MBEDTLS_ERR_GCM_HW_ACCEL_FAILED is deprecated and should not be used. */
|
||||||
|
#define MBEDTLS_ERR_GCM_HW_ACCEL_FAILED -0x0013 /**< GCM hardware accelerator failed. */
|
||||||
|
|
||||||
|
#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_GCM_ALT)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief The GCM context structure.
|
||||||
|
*/
|
||||||
|
typedef struct mbedtls_gcm_context
|
||||||
|
{
|
||||||
|
mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */
|
||||||
|
uint64_t HL[16]; /*!< Precalculated HTable low. */
|
||||||
|
uint64_t HH[16]; /*!< Precalculated HTable high. */
|
||||||
|
uint64_t len; /*!< The total length of the encrypted data. */
|
||||||
|
uint64_t add_len; /*!< The total length of the additional data. */
|
||||||
|
unsigned char base_ectr[16]; /*!< The first ECTR for tag. */
|
||||||
|
unsigned char y[16]; /*!< The Y working value. */
|
||||||
|
unsigned char buf[16]; /*!< The buf working value. */
|
||||||
|
int mode; /*!< The operation to perform:
|
||||||
|
#MBEDTLS_GCM_ENCRYPT or
|
||||||
|
#MBEDTLS_GCM_DECRYPT. */
|
||||||
|
}
|
||||||
|
mbedtls_gcm_context;
|
||||||
|
|
||||||
|
#else /* !MBEDTLS_GCM_ALT */
|
||||||
|
#include "gcm_alt.h"
|
||||||
|
#endif /* !MBEDTLS_GCM_ALT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function initializes the specified GCM context,
|
||||||
|
* to make references valid, and prepares the context
|
||||||
|
* for mbedtls_gcm_setkey() or mbedtls_gcm_free().
|
||||||
|
*
|
||||||
|
* The function does not bind the GCM context to a particular
|
||||||
|
* cipher, nor set the key. For this purpose, use
|
||||||
|
* mbedtls_gcm_setkey().
|
||||||
|
*
|
||||||
|
* \param ctx The GCM context to initialize. This must not be \c NULL.
|
||||||
|
*/
|
||||||
|
void mbedtls_gcm_init( mbedtls_gcm_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function associates a GCM context with a
|
||||||
|
* cipher algorithm and a key.
|
||||||
|
*
|
||||||
|
* \param ctx The GCM context. This must be initialized.
|
||||||
|
* \param cipher The 128-bit block cipher to use.
|
||||||
|
* \param key The encryption key. This must be a readable buffer of at
|
||||||
|
* least \p keybits bits.
|
||||||
|
* \param keybits The key size in bits. Valid options are:
|
||||||
|
* <ul><li>128 bits</li>
|
||||||
|
* <li>192 bits</li>
|
||||||
|
* <li>256 bits</li></ul>
|
||||||
|
*
|
||||||
|
* \return \c 0 on success.
|
||||||
|
* \return A cipher-specific error code on failure.
|
||||||
|
*/
|
||||||
|
int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
|
||||||
|
mbedtls_cipher_id_t cipher,
|
||||||
|
const unsigned char *key,
|
||||||
|
unsigned int keybits );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function performs GCM encryption or decryption of a buffer.
|
||||||
|
*
|
||||||
|
* \note For encryption, the output buffer can be the same as the
|
||||||
|
* input buffer. For decryption, the output buffer cannot be
|
||||||
|
* the same as input buffer. If the buffers overlap, the output
|
||||||
|
* buffer must trail at least 8 Bytes behind the input buffer.
|
||||||
|
*
|
||||||
|
* \warning When this function performs a decryption, it outputs the
|
||||||
|
* authentication tag and does not verify that the data is
|
||||||
|
* authentic. You should use this function to perform encryption
|
||||||
|
* only. For decryption, use mbedtls_gcm_auth_decrypt() instead.
|
||||||
|
*
|
||||||
|
* \param ctx The GCM context to use for encryption or decryption. This
|
||||||
|
* must be initialized.
|
||||||
|
* \param mode The operation to perform:
|
||||||
|
* - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption.
|
||||||
|
* The ciphertext is written to \p output and the
|
||||||
|
* authentication tag is written to \p tag.
|
||||||
|
* - #MBEDTLS_GCM_DECRYPT to perform decryption.
|
||||||
|
* The plaintext is written to \p output and the
|
||||||
|
* authentication tag is written to \p tag.
|
||||||
|
* Note that this mode is not recommended, because it does
|
||||||
|
* not verify the authenticity of the data. For this reason,
|
||||||
|
* you should use mbedtls_gcm_auth_decrypt() instead of
|
||||||
|
* calling this function in decryption mode.
|
||||||
|
* \param length The length of the input data, which is equal to the length
|
||||||
|
* of the output data.
|
||||||
|
* \param iv The initialization vector. This must be a readable buffer of
|
||||||
|
* at least \p iv_len Bytes.
|
||||||
|
* \param iv_len The length of the IV.
|
||||||
|
* \param add The buffer holding the additional data. This must be of at
|
||||||
|
* least that size in Bytes.
|
||||||
|
* \param add_len The length of the additional data.
|
||||||
|
* \param input The buffer holding the input data. If \p length is greater
|
||||||
|
* than zero, this must be a readable buffer of at least that
|
||||||
|
* size in Bytes.
|
||||||
|
* \param output The buffer for holding the output data. If \p length is greater
|
||||||
|
* than zero, this must be a writable buffer of at least that
|
||||||
|
* size in Bytes.
|
||||||
|
* \param tag_len The length of the tag to generate.
|
||||||
|
* \param tag The buffer for holding the tag. This must be a writable
|
||||||
|
* buffer of at least \p tag_len Bytes.
|
||||||
|
*
|
||||||
|
* \return \c 0 if the encryption or decryption was performed
|
||||||
|
* successfully. Note that in #MBEDTLS_GCM_DECRYPT mode,
|
||||||
|
* this does not indicate that the data is authentic.
|
||||||
|
* \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are
|
||||||
|
* not valid or a cipher-specific error code if the encryption
|
||||||
|
* or decryption failed.
|
||||||
|
*/
|
||||||
|
int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
|
||||||
|
int mode,
|
||||||
|
size_t length,
|
||||||
|
const unsigned char *iv,
|
||||||
|
size_t iv_len,
|
||||||
|
const unsigned char *add,
|
||||||
|
size_t add_len,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output,
|
||||||
|
size_t tag_len,
|
||||||
|
unsigned char *tag );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function performs a GCM authenticated decryption of a
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* \note For decryption, the output buffer cannot be the same as
|
||||||
|
* input buffer. If the buffers overlap, the output buffer
|
||||||
|
* must trail at least 8 Bytes behind the input buffer.
|
||||||
|
*
|
||||||
|
* \param ctx The GCM context. This must be initialized.
|
||||||
|
* \param length The length of the ciphertext to decrypt, which is also
|
||||||
|
* the length of the decrypted plaintext.
|
||||||
|
* \param iv The initialization vector. This must be a readable buffer
|
||||||
|
* of at least \p iv_len Bytes.
|
||||||
|
* \param iv_len The length of the IV.
|
||||||
|
* \param add The buffer holding the additional data. This must be of at
|
||||||
|
* least that size in Bytes.
|
||||||
|
* \param add_len The length of the additional data.
|
||||||
|
* \param tag The buffer holding the tag to verify. This must be a
|
||||||
|
* readable buffer of at least \p tag_len Bytes.
|
||||||
|
* \param tag_len The length of the tag to verify.
|
||||||
|
* \param input The buffer holding the ciphertext. If \p length is greater
|
||||||
|
* than zero, this must be a readable buffer of at least that
|
||||||
|
* size.
|
||||||
|
* \param output The buffer for holding the decrypted plaintext. If \p length
|
||||||
|
* is greater than zero, this must be a writable buffer of at
|
||||||
|
* least that size.
|
||||||
|
*
|
||||||
|
* \return \c 0 if successful and authenticated.
|
||||||
|
* \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match.
|
||||||
|
* \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are
|
||||||
|
* not valid or a cipher-specific error code if the decryption
|
||||||
|
* failed.
|
||||||
|
*/
|
||||||
|
int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
|
||||||
|
size_t length,
|
||||||
|
const unsigned char *iv,
|
||||||
|
size_t iv_len,
|
||||||
|
const unsigned char *add,
|
||||||
|
size_t add_len,
|
||||||
|
const unsigned char *tag,
|
||||||
|
size_t tag_len,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function starts a GCM encryption or decryption
|
||||||
|
* operation.
|
||||||
|
*
|
||||||
|
* \param ctx The GCM context. This must be initialized.
|
||||||
|
* \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or
|
||||||
|
* #MBEDTLS_GCM_DECRYPT.
|
||||||
|
* \param iv The initialization vector. This must be a readable buffer of
|
||||||
|
* at least \p iv_len Bytes.
|
||||||
|
* \param iv_len The length of the IV.
|
||||||
|
* \param add The buffer holding the additional data, or \c NULL
|
||||||
|
* if \p add_len is \c 0.
|
||||||
|
* \param add_len The length of the additional data. If \c 0,
|
||||||
|
* \p add may be \c NULL.
|
||||||
|
*
|
||||||
|
* \return \c 0 on success.
|
||||||
|
*/
|
||||||
|
int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
|
||||||
|
int mode,
|
||||||
|
const unsigned char *iv,
|
||||||
|
size_t iv_len,
|
||||||
|
const unsigned char *add,
|
||||||
|
size_t add_len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function feeds an input buffer into an ongoing GCM
|
||||||
|
* encryption or decryption operation.
|
||||||
|
*
|
||||||
|
* ` The function expects input to be a multiple of 16
|
||||||
|
* Bytes. Only the last call before calling
|
||||||
|
* mbedtls_gcm_finish() can be less than 16 Bytes.
|
||||||
|
*
|
||||||
|
* \note For decryption, the output buffer cannot be the same as
|
||||||
|
* input buffer. If the buffers overlap, the output buffer
|
||||||
|
* must trail at least 8 Bytes behind the input buffer.
|
||||||
|
*
|
||||||
|
* \param ctx The GCM context. This must be initialized.
|
||||||
|
* \param length The length of the input data. This must be a multiple of
|
||||||
|
* 16 except in the last call before mbedtls_gcm_finish().
|
||||||
|
* \param input The buffer holding the input data. If \p length is greater
|
||||||
|
* than zero, this must be a readable buffer of at least that
|
||||||
|
* size in Bytes.
|
||||||
|
* \param output The buffer for holding the output data. If \p length is
|
||||||
|
* greater than zero, this must be a writable buffer of at
|
||||||
|
* least that size in Bytes.
|
||||||
|
*
|
||||||
|
* \return \c 0 on success.
|
||||||
|
* \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
|
||||||
|
*/
|
||||||
|
int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
|
||||||
|
size_t length,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function finishes the GCM operation and generates
|
||||||
|
* the authentication tag.
|
||||||
|
*
|
||||||
|
* It wraps up the GCM stream, and generates the
|
||||||
|
* tag. The tag can have a maximum length of 16 Bytes.
|
||||||
|
*
|
||||||
|
* \param ctx The GCM context. This must be initialized.
|
||||||
|
* \param tag The buffer for holding the tag. This must be a writable
|
||||||
|
* buffer of at least \p tag_len Bytes.
|
||||||
|
* \param tag_len The length of the tag to generate. This must be at least
|
||||||
|
* four.
|
||||||
|
*
|
||||||
|
* \return \c 0 on success.
|
||||||
|
* \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
|
||||||
|
*/
|
||||||
|
int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
|
||||||
|
unsigned char *tag,
|
||||||
|
size_t tag_len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function clears a GCM context and the underlying
|
||||||
|
* cipher sub-context.
|
||||||
|
*
|
||||||
|
* \param ctx The GCM context to clear. If this is \c NULL, the call has
|
||||||
|
* no effect. Otherwise, this must be initialized.
|
||||||
|
*/
|
||||||
|
void mbedtls_gcm_free( mbedtls_gcm_context *ctx );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief The GCM checkup routine.
|
||||||
|
*
|
||||||
|
* \return \c 0 on success.
|
||||||
|
* \return \c 1 on failure.
|
||||||
|
*/
|
||||||
|
int mbedtls_gcm_self_test( int verbose );
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* gcm.h */
|
||||||
237
common/mbedtls/havege.c
Normal file
237
common/mbedtls/havege.c
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
/**
|
||||||
|
* \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
|
||||||
|
*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_HAVEGE_C)
|
||||||
|
|
||||||
|
#include "mbedtls/havege.h"
|
||||||
|
#include "mbedtls/timing.h"
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------
|
||||||
|
* 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) { uint32_t *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 = (uint32_t) 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 = (uint32_t) 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 )
|
||||||
|
{
|
||||||
|
size_t n = 0;
|
||||||
|
size_t i;
|
||||||
|
uint32_t U1, U2, *A, *B, *C, *D;
|
||||||
|
uint32_t PT1, PT2, *WALK, RES[16];
|
||||||
|
uint32_t 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_platform_zeroize( hs, sizeof( mbedtls_havege_state ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HAVEGE rand function
|
||||||
|
*/
|
||||||
|
int mbedtls_havege_random( void *p_rng, unsigned char *buf, size_t len )
|
||||||
|
{
|
||||||
|
uint32_t 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( val ) )
|
||||||
|
use_len = sizeof( val );
|
||||||
|
|
||||||
|
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 */
|
||||||
80
common/mbedtls/havege.h
Normal file
80
common/mbedtls/havege.h
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/**
|
||||||
|
* \file havege.h
|
||||||
|
*
|
||||||
|
* \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef MBEDTLS_HAVEGE_H
|
||||||
|
#define MBEDTLS_HAVEGE_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define MBEDTLS_HAVEGE_COLLECT_SIZE 1024
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief HAVEGE state structure
|
||||||
|
*/
|
||||||
|
typedef struct mbedtls_havege_state
|
||||||
|
{
|
||||||
|
uint32_t PT1, PT2, offset[2];
|
||||||
|
uint32_t pool[MBEDTLS_HAVEGE_COLLECT_SIZE];
|
||||||
|
uint32_t WALK[8192];
|
||||||
|
}
|
||||||
|
mbedtls_havege_state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief HAVEGE initialization
|
||||||
|
*
|
||||||
|
* \param hs HAVEGE state to be initialized
|
||||||
|
*/
|
||||||
|
void mbedtls_havege_init( mbedtls_havege_state *hs );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Clear HAVEGE state
|
||||||
|
*
|
||||||
|
* \param hs HAVEGE state to be cleared
|
||||||
|
*/
|
||||||
|
void mbedtls_havege_free( mbedtls_havege_state *hs );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief HAVEGE rand function
|
||||||
|
*
|
||||||
|
* \param p_rng A HAVEGE state
|
||||||
|
* \param output Buffer to fill
|
||||||
|
* \param len Length of buffer
|
||||||
|
*
|
||||||
|
* \return 0
|
||||||
|
*/
|
||||||
|
int mbedtls_havege_random( void *p_rng, unsigned char *output, size_t len );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* havege.h */
|
||||||
189
common/mbedtls/hkdf.c
Normal file
189
common/mbedtls/hkdf.c
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
* HKDF implementation -- RFC 5869
|
||||||
|
*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_HKDF_C)
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "mbedtls/hkdf.h"
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
|
int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt,
|
||||||
|
size_t salt_len, const unsigned char *ikm, size_t ikm_len,
|
||||||
|
const unsigned char *info, size_t info_len,
|
||||||
|
unsigned char *okm, size_t okm_len )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
unsigned char prk[MBEDTLS_MD_MAX_SIZE];
|
||||||
|
|
||||||
|
ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, prk );
|
||||||
|
|
||||||
|
if( ret == 0 )
|
||||||
|
{
|
||||||
|
ret = mbedtls_hkdf_expand( md, prk, mbedtls_md_get_size( md ),
|
||||||
|
info, info_len, okm, okm_len );
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_platform_zeroize( prk, sizeof( prk ) );
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_hkdf_extract( const mbedtls_md_info_t *md,
|
||||||
|
const unsigned char *salt, size_t salt_len,
|
||||||
|
const unsigned char *ikm, size_t ikm_len,
|
||||||
|
unsigned char *prk )
|
||||||
|
{
|
||||||
|
unsigned char null_salt[MBEDTLS_MD_MAX_SIZE] = { '\0' };
|
||||||
|
|
||||||
|
if( salt == NULL )
|
||||||
|
{
|
||||||
|
size_t hash_len;
|
||||||
|
|
||||||
|
if( salt_len != 0 )
|
||||||
|
{
|
||||||
|
return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
hash_len = mbedtls_md_get_size( md );
|
||||||
|
|
||||||
|
if( hash_len == 0 )
|
||||||
|
{
|
||||||
|
return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
salt = null_salt;
|
||||||
|
salt_len = hash_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return( mbedtls_md_hmac( md, salt, salt_len, ikm, ikm_len, prk ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk,
|
||||||
|
size_t prk_len, const unsigned char *info,
|
||||||
|
size_t info_len, unsigned char *okm, size_t okm_len )
|
||||||
|
{
|
||||||
|
size_t hash_len;
|
||||||
|
size_t where = 0;
|
||||||
|
size_t n;
|
||||||
|
size_t t_len = 0;
|
||||||
|
size_t i;
|
||||||
|
int ret = 0;
|
||||||
|
mbedtls_md_context_t ctx;
|
||||||
|
unsigned char t[MBEDTLS_MD_MAX_SIZE];
|
||||||
|
|
||||||
|
if( okm == NULL )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
hash_len = mbedtls_md_get_size( md );
|
||||||
|
|
||||||
|
if( prk_len < hash_len || hash_len == 0 )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( info == NULL )
|
||||||
|
{
|
||||||
|
info = (const unsigned char *) "";
|
||||||
|
info_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = okm_len / hash_len;
|
||||||
|
|
||||||
|
if( okm_len % hash_len != 0 )
|
||||||
|
{
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Per RFC 5869 Section 2.3, okm_len must not exceed
|
||||||
|
* 255 times the hash length
|
||||||
|
*/
|
||||||
|
if( n > 255 )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_md_init( &ctx );
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_md_setup( &ctx, md, 1 ) ) != 0 )
|
||||||
|
{
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset( t, 0, hash_len );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute T = T(1) | T(2) | T(3) | ... | T(N)
|
||||||
|
* Where T(N) is defined in RFC 5869 Section 2.3
|
||||||
|
*/
|
||||||
|
for( i = 1; i <= n; i++ )
|
||||||
|
{
|
||||||
|
size_t num_to_copy;
|
||||||
|
unsigned char c = i & 0xff;
|
||||||
|
|
||||||
|
ret = mbedtls_md_hmac_starts( &ctx, prk, prk_len );
|
||||||
|
if( ret != 0 )
|
||||||
|
{
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mbedtls_md_hmac_update( &ctx, t, t_len );
|
||||||
|
if( ret != 0 )
|
||||||
|
{
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mbedtls_md_hmac_update( &ctx, info, info_len );
|
||||||
|
if( ret != 0 )
|
||||||
|
{
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The constant concatenated to the end of each T(n) is a single octet.
|
||||||
|
* */
|
||||||
|
ret = mbedtls_md_hmac_update( &ctx, &c, 1 );
|
||||||
|
if( ret != 0 )
|
||||||
|
{
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mbedtls_md_hmac_finish( &ctx, t );
|
||||||
|
if( ret != 0 )
|
||||||
|
{
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_to_copy = i != n ? hash_len : okm_len - where;
|
||||||
|
memcpy( okm + where, t, num_to_copy );
|
||||||
|
where += hash_len;
|
||||||
|
t_len = hash_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
mbedtls_md_free( &ctx );
|
||||||
|
mbedtls_platform_zeroize( t, sizeof( t ) );
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_HKDF_C */
|
||||||
139
common/mbedtls/hkdf.h
Normal file
139
common/mbedtls/hkdf.h
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
/**
|
||||||
|
* \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 The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef MBEDTLS_HKDF_H
|
||||||
|
#define MBEDTLS_HKDF_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mbedtls/md.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name HKDF Error codes
|
||||||
|
* \{
|
||||||
|
*/
|
||||||
|
#define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA -0x5F80 /**< Bad input parameters to function. */
|
||||||
|
/* \} name */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This is the HMAC-based Extract-and-Expand Key Derivation Function
|
||||||
|
* (HKDF).
|
||||||
|
*
|
||||||
|
* \param md A hash function; md.size denotes the length of the hash
|
||||||
|
* function output in bytes.
|
||||||
|
* \param salt An optional salt value (a non-secret random value);
|
||||||
|
* if the salt is not provided, a string of all zeros of
|
||||||
|
* md.size length is used as the salt.
|
||||||
|
* \param salt_len The length in bytes of the optional \p salt.
|
||||||
|
* \param ikm The input keying material.
|
||||||
|
* \param ikm_len The length in bytes of \p ikm.
|
||||||
|
* \param info An optional context and application specific information
|
||||||
|
* string. This can be a zero-length string.
|
||||||
|
* \param info_len The length of \p info in bytes.
|
||||||
|
* \param okm The output keying material of \p okm_len bytes.
|
||||||
|
* \param okm_len The length of the output keying material in bytes. This
|
||||||
|
* must be less than or equal to 255 * md.size bytes.
|
||||||
|
*
|
||||||
|
* \return 0 on success.
|
||||||
|
* \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
|
||||||
|
* \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
|
||||||
|
* MD layer.
|
||||||
|
*/
|
||||||
|
int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt,
|
||||||
|
size_t salt_len, const unsigned char *ikm, size_t ikm_len,
|
||||||
|
const unsigned char *info, size_t info_len,
|
||||||
|
unsigned char *okm, size_t okm_len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Take the input keying material \p ikm and extract from it a
|
||||||
|
* fixed-length pseudorandom key \p prk.
|
||||||
|
*
|
||||||
|
* \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( const mbedtls_md_info_t *md,
|
||||||
|
const unsigned char *salt, size_t salt_len,
|
||||||
|
const unsigned char *ikm, size_t ikm_len,
|
||||||
|
unsigned char *prk );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Expand the supplied \p prk into several additional pseudorandom
|
||||||
|
* keys, which is the output of the HKDF.
|
||||||
|
*
|
||||||
|
* \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( const mbedtls_md_info_t *md, const unsigned char *prk,
|
||||||
|
size_t prk_len, const unsigned char *info,
|
||||||
|
size_t info_len, unsigned char *okm, size_t okm_len );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* hkdf.h */
|
||||||
629
common/mbedtls/hmac_drbg.c
Normal file
629
common/mbedtls/hmac_drbg.c
Normal file
@@ -0,0 +1,629 @@
|
|||||||
|
/*
|
||||||
|
* HMAC_DRBG implementation (NIST SP 800-90)
|
||||||
|
*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_HMAC_DRBG_C)
|
||||||
|
|
||||||
|
#include "mbedtls/hmac_drbg.h"
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_FS_IO)
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
#if defined(MBEDTLS_PLATFORM_C)
|
||||||
|
#include "mbedtls/platform.h"
|
||||||
|
#else
|
||||||
|
#include <stdio.h>
|
||||||
|
#define mbedtls_printf printf
|
||||||
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
#endif /* MBEDTLS_PLATFORM_C */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HMAC_DRBG context initialization
|
||||||
|
*/
|
||||||
|
void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
|
||||||
|
{
|
||||||
|
memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
|
||||||
|
|
||||||
|
ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
|
||||||
|
|
||||||
|
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_platform_zeroize( K, sizeof( K ) );
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
mbedtls_mutex_init( &ctx->mutex );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internal function used both for seeding and reseeding the DRBG.
|
||||||
|
* Comments starting with arabic numbers refer to section 10.1.2.4
|
||||||
|
* of SP800-90A, while roman numbers refer to section 9.2.
|
||||||
|
*/
|
||||||
|
static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
|
||||||
|
const unsigned char *additional, size_t len,
|
||||||
|
int use_nonce )
|
||||||
|
{
|
||||||
|
unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
|
||||||
|
size_t seedlen = 0;
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
|
{
|
||||||
|
size_t total_entropy_len;
|
||||||
|
|
||||||
|
if( use_nonce == 0 )
|
||||||
|
total_entropy_len = ctx->entropy_len;
|
||||||
|
else
|
||||||
|
total_entropy_len = ctx->entropy_len * 3 / 2;
|
||||||
|
|
||||||
|
/* III. Check input length */
|
||||||
|
if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
|
||||||
|
total_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;
|
||||||
|
|
||||||
|
/* For initial seeding, allow adding of nonce generated
|
||||||
|
* from the entropy source. See Sect 8.6.7 in SP800-90A. */
|
||||||
|
if( use_nonce )
|
||||||
|
{
|
||||||
|
/* Note: We don't merge the two calls to f_entropy() in order
|
||||||
|
* to avoid requesting too much entropy from f_entropy()
|
||||||
|
* at once. Specifically, if the underlying digest is not
|
||||||
|
* SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
|
||||||
|
* is larger than the maximum of 32 Bytes that our own
|
||||||
|
* entropy source implementation can emit in a single
|
||||||
|
* call in configurations disabling SHA-512. */
|
||||||
|
if( ( ret = ctx->f_entropy( ctx->p_entropy,
|
||||||
|
seed + seedlen,
|
||||||
|
ctx->entropy_len / 2 ) ) != 0 )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
|
||||||
|
}
|
||||||
|
|
||||||
|
seedlen += ctx->entropy_len / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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_platform_zeroize( seed, seedlen );
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HMAC_DRBG reseeding: 10.1.2.4 + 9.2
|
||||||
|
*/
|
||||||
|
int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
|
||||||
|
const unsigned char *additional, size_t len )
|
||||||
|
{
|
||||||
|
return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HMAC_DRBG initialisation (10.1.2.3 + 9.1)
|
||||||
|
*
|
||||||
|
* The nonce is not passed as a separate parameter but extracted
|
||||||
|
* from the entropy source as suggested in 8.6.7.
|
||||||
|
*/
|
||||||
|
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 = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
size_t md_size;
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
/* The mutex is initialized iff the md context is set up. */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
mbedtls_mutex_init( &ctx->mutex );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if( ctx->entropy_len == 0 )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* 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.)
|
||||||
|
*/
|
||||||
|
ctx->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 */
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
|
||||||
|
1 /* add nonce */ ) ) != 0 )
|
||||||
|
{
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
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 seeding
|
||||||
|
*/
|
||||||
|
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_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
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_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function resets HMAC_DRBG context to the state immediately
|
||||||
|
* after initial call of mbedtls_hmac_drbg_init().
|
||||||
|
*/
|
||||||
|
void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
|
||||||
|
{
|
||||||
|
if( ctx == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
/* The mutex is initialized iff the md context is set up. */
|
||||||
|
if( ctx->md_ctx.md_info != NULL )
|
||||||
|
mbedtls_mutex_free( &ctx->mutex );
|
||||||
|
#endif
|
||||||
|
mbedtls_md_free( &ctx->md_ctx );
|
||||||
|
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
|
||||||
|
ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_FS_IO)
|
||||||
|
int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
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_platform_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 = NULL;
|
||||||
|
size_t n;
|
||||||
|
unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
|
||||||
|
unsigned char c;
|
||||||
|
|
||||||
|
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||||
|
return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
|
||||||
|
|
||||||
|
n = fread( buf, 1, sizeof( buf ), f );
|
||||||
|
if( fread( &c, 1, 1, f ) != 0 )
|
||||||
|
{
|
||||||
|
ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if( n == 0 || ferror( f ) )
|
||||||
|
{
|
||||||
|
ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
fclose( f );
|
||||||
|
f = NULL;
|
||||||
|
|
||||||
|
ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
|
||||||
|
|
||||||
|
exit:
|
||||||
|
mbedtls_platform_zeroize( buf, sizeof( buf ) );
|
||||||
|
if( f != NULL )
|
||||||
|
fclose( f );
|
||||||
|
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 */
|
||||||
470
common/mbedtls/hmac_drbg.h
Normal file
470
common/mbedtls/hmac_drbg.h
Normal file
@@ -0,0 +1,470 @@
|
|||||||
|
/**
|
||||||
|
* \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>.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef MBEDTLS_HMAC_DRBG_H
|
||||||
|
#define MBEDTLS_HMAC_DRBG_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mbedtls/md.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
#include "mbedtls/threading.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Error codes
|
||||||
|
*/
|
||||||
|
#define MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG -0x0003 /**< Too many random requested in single call. */
|
||||||
|
#define MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG -0x0005 /**< Input too large (Entropy + additional). */
|
||||||
|
#define MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR -0x0007 /**< Read/write error in file. */
|
||||||
|
#define MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED -0x0009 /**< The entropy source failed. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name SECTION: Module settings
|
||||||
|
*
|
||||||
|
* The configuration options you can set for this module are in this section.
|
||||||
|
* Either change them in config.h or define them on the compiler command line.
|
||||||
|
* \{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_HMAC_DRBG_RESEED_INTERVAL)
|
||||||
|
#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_HMAC_DRBG_MAX_INPUT)
|
||||||
|
#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_HMAC_DRBG_MAX_REQUEST)
|
||||||
|
#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT)
|
||||||
|
#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* \} name SECTION: Module settings */
|
||||||
|
|
||||||
|
#define MBEDTLS_HMAC_DRBG_PR_OFF 0 /**< No prediction resistance */
|
||||||
|
#define MBEDTLS_HMAC_DRBG_PR_ON 1 /**< Prediction resistance enabled */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HMAC_DRBG context.
|
||||||
|
*/
|
||||||
|
typedef struct mbedtls_hmac_drbg_context
|
||||||
|
{
|
||||||
|
/* Working state: the key K is not stored explicitly,
|
||||||
|
* 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 */
|
||||||
|
|
||||||
|
/* Administrative state */
|
||||||
|
size_t entropy_len; /*!< entropy bytes grabbed on each (re)seed */
|
||||||
|
int prediction_resistance; /*!< enable prediction resistance (Automatic
|
||||||
|
reseed before every random generation) */
|
||||||
|
int reseed_interval; /*!< reseed interval */
|
||||||
|
|
||||||
|
/* Callbacks */
|
||||||
|
int (*f_entropy)(void *, unsigned char *, size_t); /*!< entropy function */
|
||||||
|
void *p_entropy; /*!< context for the entropy function */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
/* Invariant: the mutex is initialized if and only if
|
||||||
|
* md_ctx->md_info != NULL. This means that the mutex is initialized
|
||||||
|
* during the initial seeding in mbedtls_hmac_drbg_seed() or
|
||||||
|
* mbedtls_hmac_drbg_seed_buf() and freed in mbedtls_ctr_drbg_free().
|
||||||
|
*
|
||||||
|
* Note that this invariant may change without notice. Do not rely on it
|
||||||
|
* and do not access the mutex directly in application code.
|
||||||
|
*/
|
||||||
|
mbedtls_threading_mutex_t mutex;
|
||||||
|
#endif
|
||||||
|
} mbedtls_hmac_drbg_context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief HMAC_DRBG context initialization.
|
||||||
|
*
|
||||||
|
* This function makes the context ready for mbedtls_hmac_drbg_seed(),
|
||||||
|
* mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free().
|
||||||
|
*
|
||||||
|
* \note The reseed interval is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL
|
||||||
|
* by default. Override this value by calling
|
||||||
|
* mbedtls_hmac_drbg_set_reseed_interval().
|
||||||
|
*
|
||||||
|
* \param ctx HMAC_DRBG context to be initialized.
|
||||||
|
*/
|
||||||
|
void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief HMAC_DRBG initial seeding.
|
||||||
|
*
|
||||||
|
* Set the initial seed and set up the 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).
|
||||||
|
*
|
||||||
|
* 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 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.
|
||||||
|
*/
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
/**
|
||||||
|
* \note When Mbed TLS is built with threading support,
|
||||||
|
* after this function returns successfully,
|
||||||
|
* it is safe to call mbedtls_hmac_drbg_random()
|
||||||
|
* from multiple threads. Other operations, including
|
||||||
|
* reseeding, are not thread-safe.
|
||||||
|
*/
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
/**
|
||||||
|
* \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.
|
||||||
|
*/
|
||||||
|
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 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initilisation of simpified HMAC_DRBG (never reseeds).
|
||||||
|
*
|
||||||
|
* This function is meant for use in algorithms that need a pseudorandom
|
||||||
|
* input such as deterministic ECDSA.
|
||||||
|
*/
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
/**
|
||||||
|
* \note When Mbed TLS is built with threading support,
|
||||||
|
* after this function returns successfully,
|
||||||
|
* it is safe to call mbedtls_hmac_drbg_random()
|
||||||
|
* from multiple threads. Other operations, including
|
||||||
|
* reseeding, are not thread-safe.
|
||||||
|
*/
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
/**
|
||||||
|
* \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.
|
||||||
|
*/
|
||||||
|
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 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function turns prediction resistance on or off.
|
||||||
|
* The default value is off.
|
||||||
|
*
|
||||||
|
* \note If enabled, entropy is gathered at the beginning of
|
||||||
|
* every call to mbedtls_hmac_drbg_random_with_add()
|
||||||
|
* or mbedtls_hmac_drbg_random().
|
||||||
|
* Only use this if your entropy source has sufficient
|
||||||
|
* throughput.
|
||||||
|
*
|
||||||
|
* \param ctx The 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 sets the amount of entropy grabbed on each
|
||||||
|
* seed or reseed.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
void 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.
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* \note This function is not thread-safe. It is not safe
|
||||||
|
* to call this function if another thread might be
|
||||||
|
* concurrently obtaining random numbers from the same
|
||||||
|
* context or updating or reseeding the same context.
|
||||||
|
*
|
||||||
|
* \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.
|
||||||
|
*
|
||||||
|
* \return \c 0 on success, or an error from the underlying
|
||||||
|
* hash calculation.
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* \note This function is not thread-safe. It is not safe
|
||||||
|
* to call this function if another thread might be
|
||||||
|
* concurrently obtaining random numbers from the same
|
||||||
|
* context or updating or reseeding the same context.
|
||||||
|
*
|
||||||
|
* \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()).
|
||||||
|
*
|
||||||
|
* \return \c 0 if successful.
|
||||||
|
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
|
||||||
|
* if a call to the entropy function 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.
|
||||||
|
*
|
||||||
|
* This function automatically reseeds if the reseed counter is exceeded
|
||||||
|
* or prediction resistance is enabled.
|
||||||
|
*
|
||||||
|
* \note This function is not thread-safe. It is not safe
|
||||||
|
* to call this function if another thread might be
|
||||||
|
* concurrently obtaining random numbers from the same
|
||||||
|
* context or updating or reseeding the same context.
|
||||||
|
*
|
||||||
|
* \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.
|
||||||
|
*
|
||||||
|
* \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.
|
||||||
|
*/
|
||||||
|
int mbedtls_hmac_drbg_random_with_add( void *p_rng,
|
||||||
|
unsigned char *output, size_t output_len,
|
||||||
|
const unsigned char *additional,
|
||||||
|
size_t add_len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function uses HMAC_DRBG to generate random data.
|
||||||
|
*
|
||||||
|
* This function automatically reseeds if the reseed counter is exceeded
|
||||||
|
* or prediction resistance is enabled.
|
||||||
|
*/
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
/**
|
||||||
|
* \note When Mbed TLS is built with threading support,
|
||||||
|
* it is safe to call mbedtls_ctr_drbg_random()
|
||||||
|
* from multiple threads. Other operations, including
|
||||||
|
* reseeding, are not thread-safe.
|
||||||
|
*/
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
/**
|
||||||
|
* \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.
|
||||||
|
*
|
||||||
|
* \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.
|
||||||
|
*/
|
||||||
|
int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function resets HMAC_DRBG context to the state immediately
|
||||||
|
* after initial call of mbedtls_hmac_drbg_init().
|
||||||
|
*
|
||||||
|
* \param ctx The 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.
|
||||||
|
*
|
||||||
|
* \param ctx The HMAC_DRBG context.
|
||||||
|
* \param path The 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.
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* \param ctx The HMAC_DRBG context.
|
||||||
|
* \param path The 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.
|
||||||
|
*/
|
||||||
|
int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path );
|
||||||
|
#endif /* MBEDTLS_FS_IO */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
/**
|
||||||
|
* \brief The HMAC_DRBG Checkup routine.
|
||||||
|
*
|
||||||
|
* \return \c 0 if successful.
|
||||||
|
* \return \c 1 if the test failed.
|
||||||
|
*/
|
||||||
|
int mbedtls_hmac_drbg_self_test( int verbose );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* hmac_drbg.h */
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,29 +1,25 @@
|
|||||||
/**
|
/**
|
||||||
* \file md.h
|
* \file md.h
|
||||||
*
|
*
|
||||||
* \brief This file contains the generic message-digest wrapper.
|
* \brief This file contains the generic message-digest wrapper.
|
||||||
*
|
*
|
||||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of Mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MBEDTLS_MD_H
|
#ifndef MBEDTLS_MD_H
|
||||||
@@ -32,7 +28,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
#include "config.h"
|
#include "mbedtls/config.h"
|
||||||
#else
|
#else
|
||||||
#include MBEDTLS_CONFIG_FILE
|
#include MBEDTLS_CONFIG_FILE
|
||||||
#endif
|
#endif
|
||||||
@@ -41,6 +37,8 @@
|
|||||||
#define MBEDTLS_ERR_MD_BAD_INPUT_DATA -0x5100 /**< Bad input parameters to function. */
|
#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_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */
|
||||||
#define MBEDTLS_ERR_MD_FILE_IO_ERROR -0x5200 /**< Opening or reading of file failed. */
|
#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. */
|
#define MBEDTLS_ERR_MD_HW_ACCEL_FAILED -0x5280 /**< MD hardware accelerator failed. */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -56,7 +54,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
MBEDTLS_MD_NONE = 0, /**< None. */
|
MBEDTLS_MD_NONE=0, /**< None. */
|
||||||
MBEDTLS_MD_MD2, /**< The MD2 message digest. */
|
MBEDTLS_MD_MD2, /**< The MD2 message digest. */
|
||||||
MBEDTLS_MD_MD4, /**< The MD4 message digest. */
|
MBEDTLS_MD_MD4, /**< The MD4 message digest. */
|
||||||
MBEDTLS_MD_MD5, /**< The MD5 message digest. */
|
MBEDTLS_MD_MD5, /**< The MD5 message digest. */
|
||||||
@@ -74,6 +72,12 @@ typedef enum {
|
|||||||
#define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 or less */
|
#define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 or less */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SHA512_C)
|
||||||
|
#define MBEDTLS_MD_MAX_BLOCK_SIZE 128
|
||||||
|
#else
|
||||||
|
#define MBEDTLS_MD_MAX_BLOCK_SIZE 64
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opaque struct defined in md_internal.h.
|
* Opaque struct defined in md_internal.h.
|
||||||
*/
|
*/
|
||||||
@@ -82,7 +86,8 @@ typedef struct mbedtls_md_info_t mbedtls_md_info_t;
|
|||||||
/**
|
/**
|
||||||
* The generic message-digest context.
|
* The generic message-digest context.
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_md_context_t {
|
typedef struct mbedtls_md_context_t
|
||||||
|
{
|
||||||
/** Information about the associated message digest. */
|
/** Information about the associated message digest. */
|
||||||
const mbedtls_md_info_t *md_info;
|
const mbedtls_md_info_t *md_info;
|
||||||
|
|
||||||
@@ -97,12 +102,14 @@ typedef struct mbedtls_md_context_t {
|
|||||||
* \brief This function returns the list of digests supported by the
|
* \brief This function returns the list of digests supported by the
|
||||||
* generic digest module.
|
* generic digest module.
|
||||||
*
|
*
|
||||||
|
* \note The list starts with the strongest available hashes.
|
||||||
|
*
|
||||||
* \return A statically allocated array of digests. Each element
|
* \return A statically allocated array of digests. Each element
|
||||||
* in the returned list is an integer belonging to the
|
* in the returned list is an integer belonging to the
|
||||||
* message-digest enumeration #mbedtls_md_type_t.
|
* message-digest enumeration #mbedtls_md_type_t.
|
||||||
* The last entry is 0.
|
* The last entry is 0.
|
||||||
*/
|
*/
|
||||||
const int *mbedtls_md_list(void);
|
const int *mbedtls_md_list( void );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function returns the message-digest information
|
* \brief This function returns the message-digest information
|
||||||
@@ -113,7 +120,7 @@ const int *mbedtls_md_list(void);
|
|||||||
* \return The message-digest information associated with \p md_name.
|
* \return The message-digest information associated with \p md_name.
|
||||||
* \return NULL if the associated message-digest information is not found.
|
* \return NULL if the associated message-digest information is not found.
|
||||||
*/
|
*/
|
||||||
const mbedtls_md_info_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
|
* \brief This function returns the message-digest information
|
||||||
@@ -124,7 +131,7 @@ const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name);
|
|||||||
* \return The message-digest information associated with \p md_type.
|
* \return The message-digest information associated with \p md_type.
|
||||||
* \return NULL if the associated message-digest information is not found.
|
* \return NULL if the associated message-digest information is not found.
|
||||||
*/
|
*/
|
||||||
const mbedtls_md_info_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
|
* \brief This function initializes a message-digest context without
|
||||||
@@ -134,7 +141,7 @@ const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type);
|
|||||||
* context for mbedtls_md_setup() for binding it to a
|
* context for mbedtls_md_setup() for binding it to a
|
||||||
* message-digest algorithm.
|
* message-digest algorithm.
|
||||||
*/
|
*/
|
||||||
void mbedtls_md_init(mbedtls_md_context_t *ctx);
|
void mbedtls_md_init( mbedtls_md_context_t *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function clears the internal structure of \p ctx and
|
* \brief This function clears the internal structure of \p ctx and
|
||||||
@@ -149,7 +156,7 @@ void mbedtls_md_init(mbedtls_md_context_t *ctx);
|
|||||||
* You must not call this function if you have not called
|
* You must not call this function if you have not called
|
||||||
* mbedtls_md_init().
|
* mbedtls_md_init().
|
||||||
*/
|
*/
|
||||||
void mbedtls_md_free(mbedtls_md_context_t *ctx);
|
void mbedtls_md_free( mbedtls_md_context_t *ctx );
|
||||||
|
|
||||||
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
|
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
||||||
@@ -175,7 +182,7 @@ void mbedtls_md_free(mbedtls_md_context_t *ctx);
|
|||||||
* failure.
|
* failure.
|
||||||
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
|
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_md_init_ctx(mbedtls_md_context_t *ctx, const mbedtls_md_info_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
|
#undef MBEDTLS_DEPRECATED
|
||||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||||
|
|
||||||
@@ -198,7 +205,7 @@ int mbedtls_md_init_ctx(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_i
|
|||||||
* failure.
|
* failure.
|
||||||
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
|
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_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
|
* \brief This function clones the state of an message-digest
|
||||||
@@ -219,8 +226,8 @@ int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info
|
|||||||
* \return \c 0 on success.
|
* \return \c 0 on success.
|
||||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure.
|
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_md_clone(mbedtls_md_context_t *dst,
|
int mbedtls_md_clone( mbedtls_md_context_t *dst,
|
||||||
const mbedtls_md_context_t *src);
|
const mbedtls_md_context_t *src );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function extracts the message-digest size from the
|
* \brief This function extracts the message-digest size from the
|
||||||
@@ -231,7 +238,7 @@ int mbedtls_md_clone(mbedtls_md_context_t *dst,
|
|||||||
*
|
*
|
||||||
* \return The size of the message-digest output in Bytes.
|
* \return The size of the message-digest output in Bytes.
|
||||||
*/
|
*/
|
||||||
unsigned char mbedtls_md_get_size(const mbedtls_md_info_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
|
* \brief This function extracts the message-digest type from the
|
||||||
@@ -242,7 +249,7 @@ unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info);
|
|||||||
*
|
*
|
||||||
* \return The type of the message digest.
|
* \return The type of the message digest.
|
||||||
*/
|
*/
|
||||||
mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_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
|
* \brief This function extracts the message-digest name from the
|
||||||
@@ -253,7 +260,7 @@ mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info);
|
|||||||
*
|
*
|
||||||
* \return The name of the message digest.
|
* \return The name of the message digest.
|
||||||
*/
|
*/
|
||||||
const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info);
|
const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function starts a message-digest computation.
|
* \brief This function starts a message-digest computation.
|
||||||
@@ -268,7 +275,7 @@ const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info);
|
|||||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||||
* failure.
|
* failure.
|
||||||
*/
|
*/
|
||||||
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
|
* \brief This function feeds an input buffer into an ongoing
|
||||||
@@ -286,7 +293,7 @@ int mbedtls_md_starts(mbedtls_md_context_t *ctx);
|
|||||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||||
* failure.
|
* failure.
|
||||||
*/
|
*/
|
||||||
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,
|
* \brief This function finishes the digest operation,
|
||||||
@@ -306,7 +313,7 @@ int mbedtls_md_update(mbedtls_md_context_t *ctx, const unsigned char *input, siz
|
|||||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||||
* failure.
|
* failure.
|
||||||
*/
|
*/
|
||||||
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,
|
* \brief This function calculates the message-digest of a buffer,
|
||||||
@@ -326,8 +333,8 @@ int mbedtls_md_finish(mbedtls_md_context_t *ctx, unsigned char *output);
|
|||||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||||
* failure.
|
* failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_md(const mbedtls_md_info_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);
|
unsigned char *output );
|
||||||
|
|
||||||
#if defined(MBEDTLS_FS_IO)
|
#if defined(MBEDTLS_FS_IO)
|
||||||
/**
|
/**
|
||||||
@@ -347,8 +354,8 @@ int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, siz
|
|||||||
* the file pointed by \p path.
|
* the file pointed by \p path.
|
||||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL.
|
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL.
|
||||||
*/
|
*/
|
||||||
int mbedtls_md_file(const mbedtls_md_info_t *md_info, const char *path,
|
int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
#endif /* MBEDTLS_FS_IO */
|
#endif /* MBEDTLS_FS_IO */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -369,8 +376,8 @@ int mbedtls_md_file(const mbedtls_md_info_t *md_info, const char *path,
|
|||||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||||
* failure.
|
* failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_md_hmac_starts(mbedtls_md_context_t *ctx, const unsigned char *key,
|
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
|
||||||
size_t keylen);
|
size_t keylen );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function feeds an input buffer into an ongoing HMAC
|
* \brief This function feeds an input buffer into an ongoing HMAC
|
||||||
@@ -391,8 +398,8 @@ int mbedtls_md_hmac_starts(mbedtls_md_context_t *ctx, const unsigned char *key,
|
|||||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||||
* failure.
|
* failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_md_hmac_update(mbedtls_md_context_t *ctx, const unsigned char *input,
|
int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input,
|
||||||
size_t ilen);
|
size_t ilen );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function finishes the HMAC operation, and writes
|
* \brief This function finishes the HMAC operation, and writes
|
||||||
@@ -412,7 +419,7 @@ int mbedtls_md_hmac_update(mbedtls_md_context_t *ctx, const unsigned char *input
|
|||||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||||
* failure.
|
* failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_md_hmac_finish(mbedtls_md_context_t *ctx, unsigned char *output);
|
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function prepares to authenticate a new message with
|
* \brief This function prepares to authenticate a new message with
|
||||||
@@ -429,7 +436,7 @@ int mbedtls_md_hmac_finish(mbedtls_md_context_t *ctx, unsigned char *output);
|
|||||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||||
* failure.
|
* failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_md_hmac_reset(mbedtls_md_context_t *ctx);
|
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function calculates the full generic HMAC
|
* \brief This function calculates the full generic HMAC
|
||||||
@@ -453,12 +460,12 @@ int mbedtls_md_hmac_reset(mbedtls_md_context_t *ctx);
|
|||||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||||
* failure.
|
* failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_md_hmac(const mbedtls_md_info_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,
|
const unsigned char *input, size_t ilen,
|
||||||
unsigned char *output);
|
unsigned char *output );
|
||||||
|
|
||||||
/* Internal use */
|
/* Internal use */
|
||||||
int mbedtls_md_process(mbedtls_md_context_t *ctx, const unsigned char *data);
|
int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
360
common/mbedtls/md2.c
Normal file
360
common/mbedtls/md2.c
Normal file
@@ -0,0 +1,360 @@
|
|||||||
|
/*
|
||||||
|
* RFC 1115/1319 compliant MD2 implementation
|
||||||
|
*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* The MD2 algorithm was designed by Ron Rivest in 1989.
|
||||||
|
*
|
||||||
|
* http://www.ietf.org/rfc/rfc1115.txt
|
||||||
|
* http://www.ietf.org/rfc/rfc1319.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_MD2_C)
|
||||||
|
|
||||||
|
#include "mbedtls/md2.h"
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
#if defined(MBEDTLS_PLATFORM_C)
|
||||||
|
#include "mbedtls/platform.h"
|
||||||
|
#else
|
||||||
|
#include <stdio.h>
|
||||||
|
#define mbedtls_printf printf
|
||||||
|
#endif /* MBEDTLS_PLATFORM_C */
|
||||||
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_MD2_ALT)
|
||||||
|
|
||||||
|
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_platform_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];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zeroise variables to clear sensitive data from memory. */
|
||||||
|
mbedtls_platform_zeroize( &t, sizeof( t ) );
|
||||||
|
|
||||||
|
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 = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
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 = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
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_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
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" },
|
||||||
|
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }
|
||||||
|
};
|
||||||
|
|
||||||
|
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 */
|
||||||
304
common/mbedtls/md2.h
Normal file
304
common/mbedtls/md2.h
Normal file
@@ -0,0 +1,304 @@
|
|||||||
|
/**
|
||||||
|
* \file md2.h
|
||||||
|
*
|
||||||
|
* \brief MD2 message digest algorithm (hash function)
|
||||||
|
*
|
||||||
|
* \warning MD2 is considered a weak message digest and its use constitutes a
|
||||||
|
* security risk. We recommend considering stronger message digests
|
||||||
|
* instead.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef MBEDTLS_MD2_H
|
||||||
|
#define MBEDTLS_MD2_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MD2 context structure
|
||||||
|
*
|
||||||
|
* \warning MD2 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct mbedtls_md2_context
|
||||||
|
{
|
||||||
|
unsigned char cksum[16]; /*!< checksum of the data block */
|
||||||
|
unsigned char state[48]; /*!< intermediate digest state */
|
||||||
|
unsigned char buffer[16]; /*!< data block being processed */
|
||||||
|
size_t left; /*!< amount of data in buffer */
|
||||||
|
}
|
||||||
|
mbedtls_md2_context;
|
||||||
|
|
||||||
|
#else /* MBEDTLS_MD2_ALT */
|
||||||
|
#include "md2_alt.h"
|
||||||
|
#endif /* MBEDTLS_MD2_ALT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initialize MD2 context
|
||||||
|
*
|
||||||
|
* \param ctx MD2 context to be initialized
|
||||||
|
*
|
||||||
|
* \warning MD2 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void mbedtls_md2_init( mbedtls_md2_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Clear MD2 context
|
||||||
|
*
|
||||||
|
* \param ctx MD2 context to be cleared
|
||||||
|
*
|
||||||
|
* \warning MD2 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void mbedtls_md2_free( mbedtls_md2_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Clone (the state of) an MD2 context
|
||||||
|
*
|
||||||
|
* \param dst The destination context
|
||||||
|
* \param src The context to be cloned
|
||||||
|
*
|
||||||
|
* \warning MD2 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void mbedtls_md2_clone( mbedtls_md2_context *dst,
|
||||||
|
const mbedtls_md2_context *src );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MD2 context setup
|
||||||
|
*
|
||||||
|
* \param ctx context to be initialized
|
||||||
|
*
|
||||||
|
* \return 0 if successful
|
||||||
|
*
|
||||||
|
* \warning MD2 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MD2 process buffer
|
||||||
|
*
|
||||||
|
* \param ctx MD2 context
|
||||||
|
* \param input buffer holding the data
|
||||||
|
* \param ilen length of the input data
|
||||||
|
*
|
||||||
|
* \return 0 if successful
|
||||||
|
*
|
||||||
|
* \warning MD2 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int mbedtls_md2_update_ret( mbedtls_md2_context *ctx,
|
||||||
|
const unsigned char *input,
|
||||||
|
size_t ilen );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MD2 final digest
|
||||||
|
*
|
||||||
|
* \param ctx MD2 context
|
||||||
|
* \param output MD2 checksum result
|
||||||
|
*
|
||||||
|
* \return 0 if successful
|
||||||
|
*
|
||||||
|
* \warning MD2 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx,
|
||||||
|
unsigned char output[16] );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MD2 process data block (internal use only)
|
||||||
|
*
|
||||||
|
* \param ctx MD2 context
|
||||||
|
*
|
||||||
|
* \return 0 if successful
|
||||||
|
*
|
||||||
|
* \warning MD2 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int mbedtls_internal_md2_process( mbedtls_md2_context *ctx );
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
|
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
||||||
|
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
|
||||||
|
#else
|
||||||
|
#define MBEDTLS_DEPRECATED
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* \brief MD2 context setup
|
||||||
|
*
|
||||||
|
* \deprecated Superseded by mbedtls_md2_starts_ret() in 2.7.0
|
||||||
|
*
|
||||||
|
* \param ctx context to be initialized
|
||||||
|
*
|
||||||
|
* \warning MD2 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MBEDTLS_DEPRECATED void mbedtls_md2_starts( mbedtls_md2_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MD2 process buffer
|
||||||
|
*
|
||||||
|
* \deprecated Superseded by mbedtls_md2_update_ret() in 2.7.0
|
||||||
|
*
|
||||||
|
* \param ctx MD2 context
|
||||||
|
* \param input buffer holding the data
|
||||||
|
* \param ilen length of the input data
|
||||||
|
*
|
||||||
|
* \warning MD2 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MBEDTLS_DEPRECATED void mbedtls_md2_update( mbedtls_md2_context *ctx,
|
||||||
|
const unsigned char *input,
|
||||||
|
size_t ilen );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MD2 final digest
|
||||||
|
*
|
||||||
|
* \deprecated Superseded by mbedtls_md2_finish_ret() in 2.7.0
|
||||||
|
*
|
||||||
|
* \param ctx MD2 context
|
||||||
|
* \param output MD2 checksum result
|
||||||
|
*
|
||||||
|
* \warning MD2 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MBEDTLS_DEPRECATED void mbedtls_md2_finish( mbedtls_md2_context *ctx,
|
||||||
|
unsigned char output[16] );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MD2 process data block (internal use only)
|
||||||
|
*
|
||||||
|
* \deprecated Superseded by mbedtls_internal_md2_process() in 2.7.0
|
||||||
|
*
|
||||||
|
* \param ctx MD2 context
|
||||||
|
*
|
||||||
|
* \warning MD2 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MBEDTLS_DEPRECATED void mbedtls_md2_process( mbedtls_md2_context *ctx );
|
||||||
|
|
||||||
|
#undef MBEDTLS_DEPRECATED
|
||||||
|
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Output = MD2( input buffer )
|
||||||
|
*
|
||||||
|
* \param input buffer holding the data
|
||||||
|
* \param ilen length of the input data
|
||||||
|
* \param output MD2 checksum result
|
||||||
|
*
|
||||||
|
* \warning MD2 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int mbedtls_md2_ret( const unsigned char *input,
|
||||||
|
size_t ilen,
|
||||||
|
unsigned char output[16] );
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
|
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
||||||
|
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
|
||||||
|
#else
|
||||||
|
#define MBEDTLS_DEPRECATED
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* \brief Output = MD2( input buffer )
|
||||||
|
*
|
||||||
|
* \deprecated Superseded by mbedtls_md2_ret() in 2.7.0
|
||||||
|
*
|
||||||
|
* \param input buffer holding the data
|
||||||
|
* \param ilen length of the input data
|
||||||
|
* \param output MD2 checksum result
|
||||||
|
*
|
||||||
|
* \warning MD2 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MBEDTLS_DEPRECATED void mbedtls_md2( const unsigned char *input,
|
||||||
|
size_t ilen,
|
||||||
|
unsigned char output[16] );
|
||||||
|
|
||||||
|
#undef MBEDTLS_DEPRECATED
|
||||||
|
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Checkup routine
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or 1 if the test failed
|
||||||
|
*
|
||||||
|
* \warning MD2 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int mbedtls_md2_self_test( int verbose );
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* mbedtls_md2.h */
|
||||||
484
common/mbedtls/md4.c
Normal file
484
common/mbedtls/md4.c
Normal file
@@ -0,0 +1,484 @@
|
|||||||
|
/*
|
||||||
|
* RFC 1186/1320 compliant MD4 implementation
|
||||||
|
*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* The MD4 algorithm was designed by Ron Rivest in 1990.
|
||||||
|
*
|
||||||
|
* http://www.ietf.org/rfc/rfc1186.txt
|
||||||
|
* http://www.ietf.org/rfc/rfc1320.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_MD4_C)
|
||||||
|
|
||||||
|
#include "mbedtls/md4.h"
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
#if defined(MBEDTLS_PLATFORM_C)
|
||||||
|
#include "mbedtls/platform.h"
|
||||||
|
#else
|
||||||
|
#include <stdio.h>
|
||||||
|
#define mbedtls_printf printf
|
||||||
|
#endif /* MBEDTLS_PLATFORM_C */
|
||||||
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_MD4_ALT)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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_platform_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] )
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t X[16], A, B, C, D;
|
||||||
|
} local;
|
||||||
|
|
||||||
|
GET_UINT32_LE( local.X[ 0], data, 0 );
|
||||||
|
GET_UINT32_LE( local.X[ 1], data, 4 );
|
||||||
|
GET_UINT32_LE( local.X[ 2], data, 8 );
|
||||||
|
GET_UINT32_LE( local.X[ 3], data, 12 );
|
||||||
|
GET_UINT32_LE( local.X[ 4], data, 16 );
|
||||||
|
GET_UINT32_LE( local.X[ 5], data, 20 );
|
||||||
|
GET_UINT32_LE( local.X[ 6], data, 24 );
|
||||||
|
GET_UINT32_LE( local.X[ 7], data, 28 );
|
||||||
|
GET_UINT32_LE( local.X[ 8], data, 32 );
|
||||||
|
GET_UINT32_LE( local.X[ 9], data, 36 );
|
||||||
|
GET_UINT32_LE( local.X[10], data, 40 );
|
||||||
|
GET_UINT32_LE( local.X[11], data, 44 );
|
||||||
|
GET_UINT32_LE( local.X[12], data, 48 );
|
||||||
|
GET_UINT32_LE( local.X[13], data, 52 );
|
||||||
|
GET_UINT32_LE( local.X[14], data, 56 );
|
||||||
|
GET_UINT32_LE( local.X[15], data, 60 );
|
||||||
|
|
||||||
|
#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
|
||||||
|
|
||||||
|
local.A = ctx->state[0];
|
||||||
|
local.B = ctx->state[1];
|
||||||
|
local.C = ctx->state[2];
|
||||||
|
local.D = ctx->state[3];
|
||||||
|
|
||||||
|
#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
|
||||||
|
#define P(a,b,c,d,x,s) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
(a) += F((b),(c),(d)) + (x); \
|
||||||
|
(a) = S((a),(s)); \
|
||||||
|
} while( 0 )
|
||||||
|
|
||||||
|
|
||||||
|
P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
|
||||||
|
P( local.D, local.A, local.B, local.C, local.X[ 1], 7 );
|
||||||
|
P( local.C, local.D, local.A, local.B, local.X[ 2], 11 );
|
||||||
|
P( local.B, local.C, local.D, local.A, local.X[ 3], 19 );
|
||||||
|
P( local.A, local.B, local.C, local.D, local.X[ 4], 3 );
|
||||||
|
P( local.D, local.A, local.B, local.C, local.X[ 5], 7 );
|
||||||
|
P( local.C, local.D, local.A, local.B, local.X[ 6], 11 );
|
||||||
|
P( local.B, local.C, local.D, local.A, local.X[ 7], 19 );
|
||||||
|
P( local.A, local.B, local.C, local.D, local.X[ 8], 3 );
|
||||||
|
P( local.D, local.A, local.B, local.C, local.X[ 9], 7 );
|
||||||
|
P( local.C, local.D, local.A, local.B, local.X[10], 11 );
|
||||||
|
P( local.B, local.C, local.D, local.A, local.X[11], 19 );
|
||||||
|
P( local.A, local.B, local.C, local.D, local.X[12], 3 );
|
||||||
|
P( local.D, local.A, local.B, local.C, local.X[13], 7 );
|
||||||
|
P( local.C, local.D, local.A, local.B, local.X[14], 11 );
|
||||||
|
P( local.B, local.C, local.D, local.A, local.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) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
(a) += F((b),(c),(d)) + (x) + 0x5A827999; \
|
||||||
|
(a) = S((a),(s)); \
|
||||||
|
} while( 0 )
|
||||||
|
|
||||||
|
P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
|
||||||
|
P( local.D, local.A, local.B, local.C, local.X[ 4], 5 );
|
||||||
|
P( local.C, local.D, local.A, local.B, local.X[ 8], 9 );
|
||||||
|
P( local.B, local.C, local.D, local.A, local.X[12], 13 );
|
||||||
|
P( local.A, local.B, local.C, local.D, local.X[ 1], 3 );
|
||||||
|
P( local.D, local.A, local.B, local.C, local.X[ 5], 5 );
|
||||||
|
P( local.C, local.D, local.A, local.B, local.X[ 9], 9 );
|
||||||
|
P( local.B, local.C, local.D, local.A, local.X[13], 13 );
|
||||||
|
P( local.A, local.B, local.C, local.D, local.X[ 2], 3 );
|
||||||
|
P( local.D, local.A, local.B, local.C, local.X[ 6], 5 );
|
||||||
|
P( local.C, local.D, local.A, local.B, local.X[10], 9 );
|
||||||
|
P( local.B, local.C, local.D, local.A, local.X[14], 13 );
|
||||||
|
P( local.A, local.B, local.C, local.D, local.X[ 3], 3 );
|
||||||
|
P( local.D, local.A, local.B, local.C, local.X[ 7], 5 );
|
||||||
|
P( local.C, local.D, local.A, local.B, local.X[11], 9 );
|
||||||
|
P( local.B, local.C, local.D, local.A, local.X[15], 13 );
|
||||||
|
|
||||||
|
#undef P
|
||||||
|
#undef F
|
||||||
|
|
||||||
|
#define F(x,y,z) ((x) ^ (y) ^ (z))
|
||||||
|
#define P(a,b,c,d,x,s) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
(a) += F((b),(c),(d)) + (x) + 0x6ED9EBA1; \
|
||||||
|
(a) = S((a),(s)); \
|
||||||
|
} while( 0 )
|
||||||
|
|
||||||
|
P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
|
||||||
|
P( local.D, local.A, local.B, local.C, local.X[ 8], 9 );
|
||||||
|
P( local.C, local.D, local.A, local.B, local.X[ 4], 11 );
|
||||||
|
P( local.B, local.C, local.D, local.A, local.X[12], 15 );
|
||||||
|
P( local.A, local.B, local.C, local.D, local.X[ 2], 3 );
|
||||||
|
P( local.D, local.A, local.B, local.C, local.X[10], 9 );
|
||||||
|
P( local.C, local.D, local.A, local.B, local.X[ 6], 11 );
|
||||||
|
P( local.B, local.C, local.D, local.A, local.X[14], 15 );
|
||||||
|
P( local.A, local.B, local.C, local.D, local.X[ 1], 3 );
|
||||||
|
P( local.D, local.A, local.B, local.C, local.X[ 9], 9 );
|
||||||
|
P( local.C, local.D, local.A, local.B, local.X[ 5], 11 );
|
||||||
|
P( local.B, local.C, local.D, local.A, local.X[13], 15 );
|
||||||
|
P( local.A, local.B, local.C, local.D, local.X[ 3], 3 );
|
||||||
|
P( local.D, local.A, local.B, local.C, local.X[11], 9 );
|
||||||
|
P( local.C, local.D, local.A, local.B, local.X[ 7], 11 );
|
||||||
|
P( local.B, local.C, local.D, local.A, local.X[15], 15 );
|
||||||
|
|
||||||
|
#undef F
|
||||||
|
#undef P
|
||||||
|
|
||||||
|
ctx->state[0] += local.A;
|
||||||
|
ctx->state[1] += local.B;
|
||||||
|
ctx->state[2] += local.C;
|
||||||
|
ctx->state[3] += local.D;
|
||||||
|
|
||||||
|
/* Zeroise variables to clear sensitive data from memory. */
|
||||||
|
mbedtls_platform_zeroize( &local, sizeof( local ) );
|
||||||
|
|
||||||
|
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 = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
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 = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
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_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
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" },
|
||||||
|
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }
|
||||||
|
};
|
||||||
|
|
||||||
|
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 */
|
||||||
309
common/mbedtls/md4.h
Normal file
309
common/mbedtls/md4.h
Normal file
@@ -0,0 +1,309 @@
|
|||||||
|
/**
|
||||||
|
* \file md4.h
|
||||||
|
*
|
||||||
|
* \brief MD4 message digest algorithm (hash function)
|
||||||
|
*
|
||||||
|
* \warning MD4 is considered a weak message digest and its use constitutes a
|
||||||
|
* security risk. We recommend considering stronger message digests
|
||||||
|
* instead.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef MBEDTLS_MD4_H
|
||||||
|
#define MBEDTLS_MD4_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MD4 context structure
|
||||||
|
*
|
||||||
|
* \warning MD4 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct mbedtls_md4_context
|
||||||
|
{
|
||||||
|
uint32_t total[2]; /*!< number of bytes processed */
|
||||||
|
uint32_t state[4]; /*!< intermediate digest state */
|
||||||
|
unsigned char buffer[64]; /*!< data block being processed */
|
||||||
|
}
|
||||||
|
mbedtls_md4_context;
|
||||||
|
|
||||||
|
#else /* MBEDTLS_MD4_ALT */
|
||||||
|
#include "md4_alt.h"
|
||||||
|
#endif /* MBEDTLS_MD4_ALT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initialize MD4 context
|
||||||
|
*
|
||||||
|
* \param ctx MD4 context to be initialized
|
||||||
|
*
|
||||||
|
* \warning MD4 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void mbedtls_md4_init( mbedtls_md4_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Clear MD4 context
|
||||||
|
*
|
||||||
|
* \param ctx MD4 context to be cleared
|
||||||
|
*
|
||||||
|
* \warning MD4 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void mbedtls_md4_free( mbedtls_md4_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Clone (the state of) an MD4 context
|
||||||
|
*
|
||||||
|
* \param dst The destination context
|
||||||
|
* \param src The context to be cloned
|
||||||
|
*
|
||||||
|
* \warning MD4 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void mbedtls_md4_clone( mbedtls_md4_context *dst,
|
||||||
|
const mbedtls_md4_context *src );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MD4 context setup
|
||||||
|
*
|
||||||
|
* \param ctx context to be initialized
|
||||||
|
*
|
||||||
|
* \return 0 if successful
|
||||||
|
*
|
||||||
|
* \warning MD4 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*/
|
||||||
|
int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MD4 process buffer
|
||||||
|
*
|
||||||
|
* \param ctx MD4 context
|
||||||
|
* \param input buffer holding the data
|
||||||
|
* \param ilen length of the input data
|
||||||
|
*
|
||||||
|
* \return 0 if successful
|
||||||
|
*
|
||||||
|
* \warning MD4 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
|
||||||
|
const unsigned char *input,
|
||||||
|
size_t ilen );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MD4 final digest
|
||||||
|
*
|
||||||
|
* \param ctx MD4 context
|
||||||
|
* \param output MD4 checksum result
|
||||||
|
*
|
||||||
|
* \return 0 if successful
|
||||||
|
*
|
||||||
|
* \warning MD4 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
|
||||||
|
unsigned char output[16] );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MD4 process data block (internal use only)
|
||||||
|
*
|
||||||
|
* \param ctx MD4 context
|
||||||
|
* \param data buffer holding one block of data
|
||||||
|
*
|
||||||
|
* \return 0 if successful
|
||||||
|
*
|
||||||
|
* \warning MD4 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
|
||||||
|
const unsigned char data[64] );
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
|
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
||||||
|
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
|
||||||
|
#else
|
||||||
|
#define MBEDTLS_DEPRECATED
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* \brief MD4 context setup
|
||||||
|
*
|
||||||
|
* \deprecated Superseded by mbedtls_md4_starts_ret() in 2.7.0
|
||||||
|
*
|
||||||
|
* \param ctx context to be initialized
|
||||||
|
*
|
||||||
|
* \warning MD4 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MBEDTLS_DEPRECATED void mbedtls_md4_starts( mbedtls_md4_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MD4 process buffer
|
||||||
|
*
|
||||||
|
* \deprecated Superseded by mbedtls_md4_update_ret() in 2.7.0
|
||||||
|
*
|
||||||
|
* \param ctx MD4 context
|
||||||
|
* \param input buffer holding the data
|
||||||
|
* \param ilen length of the input data
|
||||||
|
*
|
||||||
|
* \warning MD4 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MBEDTLS_DEPRECATED void mbedtls_md4_update( mbedtls_md4_context *ctx,
|
||||||
|
const unsigned char *input,
|
||||||
|
size_t ilen );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MD4 final digest
|
||||||
|
*
|
||||||
|
* \deprecated Superseded by mbedtls_md4_finish_ret() in 2.7.0
|
||||||
|
*
|
||||||
|
* \param ctx MD4 context
|
||||||
|
* \param output MD4 checksum result
|
||||||
|
*
|
||||||
|
* \warning MD4 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MBEDTLS_DEPRECATED void mbedtls_md4_finish( mbedtls_md4_context *ctx,
|
||||||
|
unsigned char output[16] );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MD4 process data block (internal use only)
|
||||||
|
*
|
||||||
|
* \deprecated Superseded by mbedtls_internal_md4_process() in 2.7.0
|
||||||
|
*
|
||||||
|
* \param ctx MD4 context
|
||||||
|
* \param data buffer holding one block of data
|
||||||
|
*
|
||||||
|
* \warning MD4 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MBEDTLS_DEPRECATED void mbedtls_md4_process( mbedtls_md4_context *ctx,
|
||||||
|
const unsigned char data[64] );
|
||||||
|
|
||||||
|
#undef MBEDTLS_DEPRECATED
|
||||||
|
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Output = MD4( input buffer )
|
||||||
|
*
|
||||||
|
* \param input buffer holding the data
|
||||||
|
* \param ilen length of the input data
|
||||||
|
* \param output MD4 checksum result
|
||||||
|
*
|
||||||
|
* \return 0 if successful
|
||||||
|
*
|
||||||
|
* \warning MD4 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int mbedtls_md4_ret( const unsigned char *input,
|
||||||
|
size_t ilen,
|
||||||
|
unsigned char output[16] );
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
|
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
||||||
|
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
|
||||||
|
#else
|
||||||
|
#define MBEDTLS_DEPRECATED
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* \brief Output = MD4( input buffer )
|
||||||
|
*
|
||||||
|
* \deprecated Superseded by mbedtls_md4_ret() in 2.7.0
|
||||||
|
*
|
||||||
|
* \param input buffer holding the data
|
||||||
|
* \param ilen length of the input data
|
||||||
|
* \param output MD4 checksum result
|
||||||
|
*
|
||||||
|
* \warning MD4 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MBEDTLS_DEPRECATED void mbedtls_md4( const unsigned char *input,
|
||||||
|
size_t ilen,
|
||||||
|
unsigned char output[16] );
|
||||||
|
|
||||||
|
#undef MBEDTLS_DEPRECATED
|
||||||
|
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Checkup routine
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or 1 if the test failed
|
||||||
|
*
|
||||||
|
* \warning MD4 is considered a weak message digest and its use
|
||||||
|
* constitutes a security risk. We recommend considering
|
||||||
|
* stronger message digests instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int mbedtls_md4_self_test( int verbose );
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* mbedtls_md4.h */
|
||||||
@@ -1,24 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
* RFC 1321 compliant MD5 implementation
|
* RFC 1321 compliant MD5 implementation
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* The MD5 algorithm was designed by Ron Rivest in 1991.
|
* The MD5 algorithm was designed by Ron Rivest in 1991.
|
||||||
@@ -26,16 +22,13 @@
|
|||||||
* http://www.ietf.org/rfc/rfc1321.txt
|
* http://www.ietf.org/rfc/rfc1321.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#include "common.h"
|
||||||
#include "mbedtls/config.h"
|
|
||||||
#else
|
|
||||||
#include MBEDTLS_CONFIG_FILE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_MD5_C)
|
#if defined(MBEDTLS_MD5_C)
|
||||||
|
|
||||||
#include "mbedtls/md5.h"
|
#include "mbedtls/md5.h"
|
||||||
#include "mbedtls/platform_util.h"
|
#include "mbedtls/platform_util.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -55,44 +48,48 @@
|
|||||||
*/
|
*/
|
||||||
#ifndef GET_UINT32_LE
|
#ifndef GET_UINT32_LE
|
||||||
#define GET_UINT32_LE(n,b,i) \
|
#define GET_UINT32_LE(n,b,i) \
|
||||||
{ \
|
{ \
|
||||||
(n) = ( (uint32_t) (b)[(i) ] ) \
|
(n) = ( (uint32_t) (b)[(i) ] ) \
|
||||||
| ( (uint32_t) (b)[(i) + 1] << 8 ) \
|
| ( (uint32_t) (b)[(i) + 1] << 8 ) \
|
||||||
| ( (uint32_t) (b)[(i) + 2] << 16 ) \
|
| ( (uint32_t) (b)[(i) + 2] << 16 ) \
|
||||||
| ( (uint32_t) (b)[(i) + 3] << 24 ); \
|
| ( (uint32_t) (b)[(i) + 3] << 24 ); \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PUT_UINT32_LE
|
#ifndef PUT_UINT32_LE
|
||||||
#define PUT_UINT32_LE(n,b,i) \
|
#define PUT_UINT32_LE(n,b,i) \
|
||||||
{ \
|
{ \
|
||||||
(b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
|
(b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
|
||||||
(b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
|
(b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
|
||||||
(b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
|
(b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
|
||||||
(b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
|
(b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void mbedtls_md5_init(mbedtls_md5_context *ctx) {
|
void mbedtls_md5_init( mbedtls_md5_context *ctx )
|
||||||
memset(ctx, 0, sizeof(mbedtls_md5_context));
|
{
|
||||||
|
memset( ctx, 0, sizeof( mbedtls_md5_context ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void mbedtls_md5_free(mbedtls_md5_context *ctx) {
|
void mbedtls_md5_free( mbedtls_md5_context *ctx )
|
||||||
if (ctx == NULL)
|
{
|
||||||
|
if( ctx == NULL )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_md5_context));
|
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md5_context ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void mbedtls_md5_clone(mbedtls_md5_context *dst,
|
void mbedtls_md5_clone( mbedtls_md5_context *dst,
|
||||||
const mbedtls_md5_context *src) {
|
const mbedtls_md5_context *src )
|
||||||
|
{
|
||||||
*dst = *src;
|
*dst = *src;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MD5 context setup
|
* MD5 context setup
|
||||||
*/
|
*/
|
||||||
int mbedtls_md5_starts_ret(mbedtls_md5_context *ctx) {
|
int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx )
|
||||||
|
{
|
||||||
ctx->total[0] = 0;
|
ctx->total[0] = 0;
|
||||||
ctx->total[1] = 0;
|
ctx->total[1] = 0;
|
||||||
|
|
||||||
@@ -101,145 +98,157 @@ int mbedtls_md5_starts_ret(mbedtls_md5_context *ctx) {
|
|||||||
ctx->state[2] = 0x98BADCFE;
|
ctx->state[2] = 0x98BADCFE;
|
||||||
ctx->state[3] = 0x10325476;
|
ctx->state[3] = 0x10325476;
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
void mbedtls_md5_starts(mbedtls_md5_context *ctx) {
|
void mbedtls_md5_starts( mbedtls_md5_context *ctx )
|
||||||
mbedtls_md5_starts_ret(ctx);
|
{
|
||||||
|
mbedtls_md5_starts_ret( ctx );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(MBEDTLS_MD5_PROCESS_ALT)
|
#if !defined(MBEDTLS_MD5_PROCESS_ALT)
|
||||||
int mbedtls_internal_md5_process(mbedtls_md5_context *ctx,
|
int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
|
||||||
const unsigned char data[64]) {
|
const unsigned char data[64] )
|
||||||
uint32_t X[16], A, B, C, D;
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t X[16], A, B, C, D;
|
||||||
|
} local;
|
||||||
|
|
||||||
GET_UINT32_LE(X[ 0], data, 0);
|
GET_UINT32_LE( local.X[ 0], data, 0 );
|
||||||
GET_UINT32_LE(X[ 1], data, 4);
|
GET_UINT32_LE( local.X[ 1], data, 4 );
|
||||||
GET_UINT32_LE(X[ 2], data, 8);
|
GET_UINT32_LE( local.X[ 2], data, 8 );
|
||||||
GET_UINT32_LE(X[ 3], data, 12);
|
GET_UINT32_LE( local.X[ 3], data, 12 );
|
||||||
GET_UINT32_LE(X[ 4], data, 16);
|
GET_UINT32_LE( local.X[ 4], data, 16 );
|
||||||
GET_UINT32_LE(X[ 5], data, 20);
|
GET_UINT32_LE( local.X[ 5], data, 20 );
|
||||||
GET_UINT32_LE(X[ 6], data, 24);
|
GET_UINT32_LE( local.X[ 6], data, 24 );
|
||||||
GET_UINT32_LE(X[ 7], data, 28);
|
GET_UINT32_LE( local.X[ 7], data, 28 );
|
||||||
GET_UINT32_LE(X[ 8], data, 32);
|
GET_UINT32_LE( local.X[ 8], data, 32 );
|
||||||
GET_UINT32_LE(X[ 9], data, 36);
|
GET_UINT32_LE( local.X[ 9], data, 36 );
|
||||||
GET_UINT32_LE(X[10], data, 40);
|
GET_UINT32_LE( local.X[10], data, 40 );
|
||||||
GET_UINT32_LE(X[11], data, 44);
|
GET_UINT32_LE( local.X[11], data, 44 );
|
||||||
GET_UINT32_LE(X[12], data, 48);
|
GET_UINT32_LE( local.X[12], data, 48 );
|
||||||
GET_UINT32_LE(X[13], data, 52);
|
GET_UINT32_LE( local.X[13], data, 52 );
|
||||||
GET_UINT32_LE(X[14], data, 56);
|
GET_UINT32_LE( local.X[14], data, 56 );
|
||||||
GET_UINT32_LE(X[15], data, 60);
|
GET_UINT32_LE( local.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) \
|
#define P(a,b,c,d,k,s,t) \
|
||||||
{ \
|
do \
|
||||||
a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
|
{ \
|
||||||
}
|
(a) += F((b),(c),(d)) + local.X[(k)] + (t); \
|
||||||
|
(a) = S((a),(s)) + (b); \
|
||||||
|
} while( 0 )
|
||||||
|
|
||||||
A = ctx->state[0];
|
local.A = ctx->state[0];
|
||||||
B = ctx->state[1];
|
local.B = ctx->state[1];
|
||||||
C = ctx->state[2];
|
local.C = ctx->state[2];
|
||||||
D = ctx->state[3];
|
local.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( local.A, local.B, local.C, local.D, 0, 7, 0xD76AA478 );
|
||||||
P(D, A, B, C, 1, 12, 0xE8C7B756);
|
P( local.D, local.A, local.B, local.C, 1, 12, 0xE8C7B756 );
|
||||||
P(C, D, A, B, 2, 17, 0x242070DB);
|
P( local.C, local.D, local.A, local.B, 2, 17, 0x242070DB );
|
||||||
P(B, C, D, A, 3, 22, 0xC1BDCEEE);
|
P( local.B, local.C, local.D, local.A, 3, 22, 0xC1BDCEEE );
|
||||||
P(A, B, C, D, 4, 7, 0xF57C0FAF);
|
P( local.A, local.B, local.C, local.D, 4, 7, 0xF57C0FAF );
|
||||||
P(D, A, B, C, 5, 12, 0x4787C62A);
|
P( local.D, local.A, local.B, local.C, 5, 12, 0x4787C62A );
|
||||||
P(C, D, A, B, 6, 17, 0xA8304613);
|
P( local.C, local.D, local.A, local.B, 6, 17, 0xA8304613 );
|
||||||
P(B, C, D, A, 7, 22, 0xFD469501);
|
P( local.B, local.C, local.D, local.A, 7, 22, 0xFD469501 );
|
||||||
P(A, B, C, D, 8, 7, 0x698098D8);
|
P( local.A, local.B, local.C, local.D, 8, 7, 0x698098D8 );
|
||||||
P(D, A, B, C, 9, 12, 0x8B44F7AF);
|
P( local.D, local.A, local.B, local.C, 9, 12, 0x8B44F7AF );
|
||||||
P(C, D, A, B, 10, 17, 0xFFFF5BB1);
|
P( local.C, local.D, local.A, local.B, 10, 17, 0xFFFF5BB1 );
|
||||||
P(B, C, D, A, 11, 22, 0x895CD7BE);
|
P( local.B, local.C, local.D, local.A, 11, 22, 0x895CD7BE );
|
||||||
P(A, B, C, D, 12, 7, 0x6B901122);
|
P( local.A, local.B, local.C, local.D, 12, 7, 0x6B901122 );
|
||||||
P(D, A, B, C, 13, 12, 0xFD987193);
|
P( local.D, local.A, local.B, local.C, 13, 12, 0xFD987193 );
|
||||||
P(C, D, A, B, 14, 17, 0xA679438E);
|
P( local.C, local.D, local.A, local.B, 14, 17, 0xA679438E );
|
||||||
P(B, C, D, A, 15, 22, 0x49B40821);
|
P( local.B, local.C, local.D, local.A, 15, 22, 0x49B40821 );
|
||||||
|
|
||||||
#undef F
|
#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( local.A, local.B, local.C, local.D, 1, 5, 0xF61E2562 );
|
||||||
P(D, A, B, C, 6, 9, 0xC040B340);
|
P( local.D, local.A, local.B, local.C, 6, 9, 0xC040B340 );
|
||||||
P(C, D, A, B, 11, 14, 0x265E5A51);
|
P( local.C, local.D, local.A, local.B, 11, 14, 0x265E5A51 );
|
||||||
P(B, C, D, A, 0, 20, 0xE9B6C7AA);
|
P( local.B, local.C, local.D, local.A, 0, 20, 0xE9B6C7AA );
|
||||||
P(A, B, C, D, 5, 5, 0xD62F105D);
|
P( local.A, local.B, local.C, local.D, 5, 5, 0xD62F105D );
|
||||||
P(D, A, B, C, 10, 9, 0x02441453);
|
P( local.D, local.A, local.B, local.C, 10, 9, 0x02441453 );
|
||||||
P(C, D, A, B, 15, 14, 0xD8A1E681);
|
P( local.C, local.D, local.A, local.B, 15, 14, 0xD8A1E681 );
|
||||||
P(B, C, D, A, 4, 20, 0xE7D3FBC8);
|
P( local.B, local.C, local.D, local.A, 4, 20, 0xE7D3FBC8 );
|
||||||
P(A, B, C, D, 9, 5, 0x21E1CDE6);
|
P( local.A, local.B, local.C, local.D, 9, 5, 0x21E1CDE6 );
|
||||||
P(D, A, B, C, 14, 9, 0xC33707D6);
|
P( local.D, local.A, local.B, local.C, 14, 9, 0xC33707D6 );
|
||||||
P(C, D, A, B, 3, 14, 0xF4D50D87);
|
P( local.C, local.D, local.A, local.B, 3, 14, 0xF4D50D87 );
|
||||||
P(B, C, D, A, 8, 20, 0x455A14ED);
|
P( local.B, local.C, local.D, local.A, 8, 20, 0x455A14ED );
|
||||||
P(A, B, C, D, 13, 5, 0xA9E3E905);
|
P( local.A, local.B, local.C, local.D, 13, 5, 0xA9E3E905 );
|
||||||
P(D, A, B, C, 2, 9, 0xFCEFA3F8);
|
P( local.D, local.A, local.B, local.C, 2, 9, 0xFCEFA3F8 );
|
||||||
P(C, D, A, B, 7, 14, 0x676F02D9);
|
P( local.C, local.D, local.A, local.B, 7, 14, 0x676F02D9 );
|
||||||
P(B, C, D, A, 12, 20, 0x8D2A4C8A);
|
P( local.B, local.C, local.D, local.A, 12, 20, 0x8D2A4C8A );
|
||||||
|
|
||||||
#undef F
|
#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( local.A, local.B, local.C, local.D, 5, 4, 0xFFFA3942 );
|
||||||
P(D, A, B, C, 8, 11, 0x8771F681);
|
P( local.D, local.A, local.B, local.C, 8, 11, 0x8771F681 );
|
||||||
P(C, D, A, B, 11, 16, 0x6D9D6122);
|
P( local.C, local.D, local.A, local.B, 11, 16, 0x6D9D6122 );
|
||||||
P(B, C, D, A, 14, 23, 0xFDE5380C);
|
P( local.B, local.C, local.D, local.A, 14, 23, 0xFDE5380C );
|
||||||
P(A, B, C, D, 1, 4, 0xA4BEEA44);
|
P( local.A, local.B, local.C, local.D, 1, 4, 0xA4BEEA44 );
|
||||||
P(D, A, B, C, 4, 11, 0x4BDECFA9);
|
P( local.D, local.A, local.B, local.C, 4, 11, 0x4BDECFA9 );
|
||||||
P(C, D, A, B, 7, 16, 0xF6BB4B60);
|
P( local.C, local.D, local.A, local.B, 7, 16, 0xF6BB4B60 );
|
||||||
P(B, C, D, A, 10, 23, 0xBEBFBC70);
|
P( local.B, local.C, local.D, local.A, 10, 23, 0xBEBFBC70 );
|
||||||
P(A, B, C, D, 13, 4, 0x289B7EC6);
|
P( local.A, local.B, local.C, local.D, 13, 4, 0x289B7EC6 );
|
||||||
P(D, A, B, C, 0, 11, 0xEAA127FA);
|
P( local.D, local.A, local.B, local.C, 0, 11, 0xEAA127FA );
|
||||||
P(C, D, A, B, 3, 16, 0xD4EF3085);
|
P( local.C, local.D, local.A, local.B, 3, 16, 0xD4EF3085 );
|
||||||
P(B, C, D, A, 6, 23, 0x04881D05);
|
P( local.B, local.C, local.D, local.A, 6, 23, 0x04881D05 );
|
||||||
P(A, B, C, D, 9, 4, 0xD9D4D039);
|
P( local.A, local.B, local.C, local.D, 9, 4, 0xD9D4D039 );
|
||||||
P(D, A, B, C, 12, 11, 0xE6DB99E5);
|
P( local.D, local.A, local.B, local.C, 12, 11, 0xE6DB99E5 );
|
||||||
P(C, D, A, B, 15, 16, 0x1FA27CF8);
|
P( local.C, local.D, local.A, local.B, 15, 16, 0x1FA27CF8 );
|
||||||
P(B, C, D, A, 2, 23, 0xC4AC5665);
|
P( local.B, local.C, local.D, local.A, 2, 23, 0xC4AC5665 );
|
||||||
|
|
||||||
#undef F
|
#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( local.A, local.B, local.C, local.D, 0, 6, 0xF4292244 );
|
||||||
P(D, A, B, C, 7, 10, 0x432AFF97);
|
P( local.D, local.A, local.B, local.C, 7, 10, 0x432AFF97 );
|
||||||
P(C, D, A, B, 14, 15, 0xAB9423A7);
|
P( local.C, local.D, local.A, local.B, 14, 15, 0xAB9423A7 );
|
||||||
P(B, C, D, A, 5, 21, 0xFC93A039);
|
P( local.B, local.C, local.D, local.A, 5, 21, 0xFC93A039 );
|
||||||
P(A, B, C, D, 12, 6, 0x655B59C3);
|
P( local.A, local.B, local.C, local.D, 12, 6, 0x655B59C3 );
|
||||||
P(D, A, B, C, 3, 10, 0x8F0CCC92);
|
P( local.D, local.A, local.B, local.C, 3, 10, 0x8F0CCC92 );
|
||||||
P(C, D, A, B, 10, 15, 0xFFEFF47D);
|
P( local.C, local.D, local.A, local.B, 10, 15, 0xFFEFF47D );
|
||||||
P(B, C, D, A, 1, 21, 0x85845DD1);
|
P( local.B, local.C, local.D, local.A, 1, 21, 0x85845DD1 );
|
||||||
P(A, B, C, D, 8, 6, 0x6FA87E4F);
|
P( local.A, local.B, local.C, local.D, 8, 6, 0x6FA87E4F );
|
||||||
P(D, A, B, C, 15, 10, 0xFE2CE6E0);
|
P( local.D, local.A, local.B, local.C, 15, 10, 0xFE2CE6E0 );
|
||||||
P(C, D, A, B, 6, 15, 0xA3014314);
|
P( local.C, local.D, local.A, local.B, 6, 15, 0xA3014314 );
|
||||||
P(B, C, D, A, 13, 21, 0x4E0811A1);
|
P( local.B, local.C, local.D, local.A, 13, 21, 0x4E0811A1 );
|
||||||
P(A, B, C, D, 4, 6, 0xF7537E82);
|
P( local.A, local.B, local.C, local.D, 4, 6, 0xF7537E82 );
|
||||||
P(D, A, B, C, 11, 10, 0xBD3AF235);
|
P( local.D, local.A, local.B, local.C, 11, 10, 0xBD3AF235 );
|
||||||
P(C, D, A, B, 2, 15, 0x2AD7D2BB);
|
P( local.C, local.D, local.A, local.B, 2, 15, 0x2AD7D2BB );
|
||||||
P(B, C, D, A, 9, 21, 0xEB86D391);
|
P( local.B, local.C, local.D, local.A, 9, 21, 0xEB86D391 );
|
||||||
|
|
||||||
#undef F
|
#undef F
|
||||||
|
|
||||||
ctx->state[0] += A;
|
ctx->state[0] += local.A;
|
||||||
ctx->state[1] += B;
|
ctx->state[1] += local.B;
|
||||||
ctx->state[2] += C;
|
ctx->state[2] += local.C;
|
||||||
ctx->state[3] += D;
|
ctx->state[3] += local.D;
|
||||||
|
|
||||||
return (0);
|
/* Zeroise variables to clear sensitive data from memory. */
|
||||||
|
mbedtls_platform_zeroize( &local, sizeof( local ) );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
void mbedtls_md5_process(mbedtls_md5_context *ctx,
|
void mbedtls_md5_process( mbedtls_md5_context *ctx,
|
||||||
const unsigned char data[64]) {
|
const unsigned char data[64] )
|
||||||
mbedtls_internal_md5_process(ctx, data);
|
{
|
||||||
|
mbedtls_internal_md5_process( ctx, data );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* !MBEDTLS_MD5_PROCESS_ALT */
|
#endif /* !MBEDTLS_MD5_PROCESS_ALT */
|
||||||
@@ -247,15 +256,16 @@ void mbedtls_md5_process(mbedtls_md5_context *ctx,
|
|||||||
/*
|
/*
|
||||||
* MD5 process buffer
|
* MD5 process buffer
|
||||||
*/
|
*/
|
||||||
int mbedtls_md5_update_ret(mbedtls_md5_context *ctx,
|
int mbedtls_md5_update_ret( mbedtls_md5_context *ctx,
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
size_t ilen) {
|
size_t ilen )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
size_t fill;
|
size_t fill;
|
||||||
uint32_t left;
|
uint32_t left;
|
||||||
|
|
||||||
if (ilen == 0)
|
if( ilen == 0 )
|
||||||
return (0);
|
return( 0 );
|
||||||
|
|
||||||
left = ctx->total[0] & 0x3F;
|
left = ctx->total[0] & 0x3F;
|
||||||
fill = 64 - left;
|
fill = 64 - left;
|
||||||
@@ -263,48 +273,53 @@ int mbedtls_md5_update_ret(mbedtls_md5_context *ctx,
|
|||||||
ctx->total[0] += (uint32_t) ilen;
|
ctx->total[0] += (uint32_t) ilen;
|
||||||
ctx->total[0] &= 0xFFFFFFFF;
|
ctx->total[0] &= 0xFFFFFFFF;
|
||||||
|
|
||||||
if (ctx->total[0] < (uint32_t) ilen)
|
if( ctx->total[0] < (uint32_t) ilen )
|
||||||
ctx->total[1]++;
|
ctx->total[1]++;
|
||||||
|
|
||||||
if (left && ilen >= fill) {
|
if( left && ilen >= fill )
|
||||||
memcpy((void *)(ctx->buffer + left), input, fill);
|
{
|
||||||
if ((ret = mbedtls_internal_md5_process(ctx, ctx->buffer)) != 0)
|
memcpy( (void *) (ctx->buffer + left), input, fill );
|
||||||
return (ret);
|
if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
input += fill;
|
input += fill;
|
||||||
ilen -= fill;
|
ilen -= fill;
|
||||||
left = 0;
|
left = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (ilen >= 64) {
|
while( ilen >= 64 )
|
||||||
if ((ret = mbedtls_internal_md5_process(ctx, input)) != 0)
|
{
|
||||||
return (ret);
|
if( ( ret = mbedtls_internal_md5_process( ctx, input ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
input += 64;
|
input += 64;
|
||||||
ilen -= 64;
|
ilen -= 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ilen > 0) {
|
if( ilen > 0 )
|
||||||
memcpy((void *)(ctx->buffer + left), input, ilen);
|
{
|
||||||
|
memcpy( (void *) (ctx->buffer + left), input, ilen );
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
void mbedtls_md5_update(mbedtls_md5_context *ctx,
|
void mbedtls_md5_update( mbedtls_md5_context *ctx,
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
size_t ilen) {
|
size_t ilen )
|
||||||
mbedtls_md5_update_ret(ctx, input, ilen);
|
{
|
||||||
|
mbedtls_md5_update_ret( ctx, input, ilen );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MD5 final digest
|
* MD5 final digest
|
||||||
*/
|
*/
|
||||||
int mbedtls_md5_finish_ret(mbedtls_md5_context *ctx,
|
int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
|
||||||
unsigned char output[16]) {
|
unsigned char output[16] )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
uint32_t used;
|
uint32_t used;
|
||||||
uint32_t high, low;
|
uint32_t high, low;
|
||||||
|
|
||||||
@@ -315,47 +330,51 @@ int mbedtls_md5_finish_ret(mbedtls_md5_context *ctx,
|
|||||||
|
|
||||||
ctx->buffer[used++] = 0x80;
|
ctx->buffer[used++] = 0x80;
|
||||||
|
|
||||||
if (used <= 56) {
|
if( used <= 56 )
|
||||||
|
{
|
||||||
/* Enough room for padding + length in current block */
|
/* Enough room for padding + length in current block */
|
||||||
memset(ctx->buffer + used, 0, 56 - used);
|
memset( ctx->buffer + used, 0, 56 - used );
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* We'll need an extra block */
|
/* We'll need an extra block */
|
||||||
memset(ctx->buffer + used, 0, 64 - used);
|
memset( ctx->buffer + used, 0, 64 - used );
|
||||||
|
|
||||||
if ((ret = mbedtls_internal_md5_process(ctx, ctx->buffer)) != 0)
|
if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
|
|
||||||
memset(ctx->buffer, 0, 56);
|
memset( ctx->buffer, 0, 56 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add message length
|
* Add message length
|
||||||
*/
|
*/
|
||||||
high = (ctx->total[0] >> 29)
|
high = ( ctx->total[0] >> 29 )
|
||||||
| (ctx->total[1] << 3);
|
| ( ctx->total[1] << 3 );
|
||||||
low = (ctx->total[0] << 3);
|
low = ( ctx->total[0] << 3 );
|
||||||
|
|
||||||
PUT_UINT32_LE(low, ctx->buffer, 56);
|
PUT_UINT32_LE( low, ctx->buffer, 56 );
|
||||||
PUT_UINT32_LE(high, ctx->buffer, 60);
|
PUT_UINT32_LE( high, ctx->buffer, 60 );
|
||||||
|
|
||||||
if ((ret = mbedtls_internal_md5_process(ctx, ctx->buffer)) != 0)
|
if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Output final state
|
* Output final state
|
||||||
*/
|
*/
|
||||||
PUT_UINT32_LE(ctx->state[0], output, 0);
|
PUT_UINT32_LE( ctx->state[0], output, 0 );
|
||||||
PUT_UINT32_LE(ctx->state[1], output, 4);
|
PUT_UINT32_LE( ctx->state[1], output, 4 );
|
||||||
PUT_UINT32_LE(ctx->state[2], output, 8);
|
PUT_UINT32_LE( ctx->state[2], output, 8 );
|
||||||
PUT_UINT32_LE(ctx->state[3], output, 12);
|
PUT_UINT32_LE( ctx->state[3], output, 12 );
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
void mbedtls_md5_finish(mbedtls_md5_context *ctx,
|
void mbedtls_md5_finish( mbedtls_md5_context *ctx,
|
||||||
unsigned char output[16]) {
|
unsigned char output[16] )
|
||||||
mbedtls_md5_finish_ret(ctx, output);
|
{
|
||||||
|
mbedtls_md5_finish_ret( ctx, output );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -364,34 +383,36 @@ void mbedtls_md5_finish(mbedtls_md5_context *ctx,
|
|||||||
/*
|
/*
|
||||||
* output = MD5( input buffer )
|
* output = MD5( input buffer )
|
||||||
*/
|
*/
|
||||||
int mbedtls_md5_ret(const unsigned char *input,
|
int mbedtls_md5_ret( const unsigned char *input,
|
||||||
size_t ilen,
|
size_t ilen,
|
||||||
unsigned char output[16]) {
|
unsigned char output[16] )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
mbedtls_md5_context ctx;
|
mbedtls_md5_context ctx;
|
||||||
|
|
||||||
mbedtls_md5_init(&ctx);
|
mbedtls_md5_init( &ctx );
|
||||||
|
|
||||||
if ((ret = mbedtls_md5_starts_ret(&ctx)) != 0)
|
if( ( ret = mbedtls_md5_starts_ret( &ctx ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if ((ret = mbedtls_md5_update_ret(&ctx, input, ilen)) != 0)
|
if( ( ret = mbedtls_md5_update_ret( &ctx, input, ilen ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if ((ret = mbedtls_md5_finish_ret(&ctx, output)) != 0)
|
if( ( ret = mbedtls_md5_finish_ret( &ctx, output ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
mbedtls_md5_free(&ctx);
|
mbedtls_md5_free( &ctx );
|
||||||
|
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
void mbedtls_md5(const unsigned char *input,
|
void mbedtls_md5( const unsigned char *input,
|
||||||
size_t ilen,
|
size_t ilen,
|
||||||
unsigned char output[16]) {
|
unsigned char output[16] )
|
||||||
mbedtls_md5_ret(input, ilen, output);
|
{
|
||||||
|
mbedtls_md5_ret( input, ilen, output );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -399,88 +420,77 @@ void mbedtls_md5(const unsigned char *input,
|
|||||||
/*
|
/*
|
||||||
* RFC 1321 test vectors
|
* RFC 1321 test vectors
|
||||||
*/
|
*/
|
||||||
static const unsigned char md5_test_buf[7][81] = {
|
static const unsigned char md5_test_buf[7][81] =
|
||||||
|
{
|
||||||
{ "" },
|
{ "" },
|
||||||
{ "a" },
|
{ "a" },
|
||||||
{ "abc" },
|
{ "abc" },
|
||||||
{ "message digest" },
|
{ "message digest" },
|
||||||
{ "abcdefghijklmnopqrstuvwxyz" },
|
{ "abcdefghijklmnopqrstuvwxyz" },
|
||||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
|
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
|
||||||
{
|
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }
|
||||||
"12345678901234567890123456789012345678901234567890123456789012"
|
|
||||||
"345678901234567890"
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const size_t md5_test_buflen[7] = {
|
static const size_t md5_test_buflen[7] =
|
||||||
|
{
|
||||||
0, 1, 3, 14, 26, 62, 80
|
0, 1, 3, 14, 26, 62, 80
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned char md5_test_sum[7][16] = {
|
static const unsigned char md5_test_sum[7][16] =
|
||||||
{
|
{
|
||||||
0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
|
{ 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
|
||||||
0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E
|
0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
|
||||||
},
|
{ 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
|
||||||
{
|
0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
|
||||||
0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
|
{ 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
|
||||||
0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61
|
0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
|
||||||
},
|
{ 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
|
||||||
{
|
0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
|
||||||
0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
|
{ 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
|
||||||
0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72
|
0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
|
||||||
},
|
{ 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
|
||||||
{
|
0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
|
||||||
0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
|
{ 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
|
||||||
0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0
|
0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
|
||||||
},
|
|
||||||
{
|
|
||||||
0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
|
|
||||||
0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
|
|
||||||
0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
|
|
||||||
0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Checkup routine
|
* Checkup routine
|
||||||
*/
|
*/
|
||||||
int mbedtls_md5_self_test(int verbose) {
|
int mbedtls_md5_self_test( int verbose )
|
||||||
|
{
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
unsigned char md5sum[16];
|
unsigned char md5sum[16];
|
||||||
|
|
||||||
for (i = 0; i < 7; i++) {
|
for( i = 0; i < 7; i++ )
|
||||||
if (verbose != 0)
|
{
|
||||||
mbedtls_printf(" MD5 test #%d: ", i + 1);
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( " MD5 test #%d: ", i + 1 );
|
||||||
|
|
||||||
ret = mbedtls_md5_ret(md5_test_buf[i], md5_test_buflen[i], md5sum);
|
ret = mbedtls_md5_ret( md5_test_buf[i], md5_test_buflen[i], md5sum );
|
||||||
if (ret != 0)
|
if( ret != 0 )
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (memcmp(md5sum, md5_test_sum[i], 16) != 0) {
|
if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
|
||||||
|
{
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose != 0)
|
if( verbose != 0 )
|
||||||
mbedtls_printf("passed\n");
|
mbedtls_printf( "passed\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose != 0)
|
if( verbose != 0 )
|
||||||
mbedtls_printf("\n");
|
mbedtls_printf( "\n" );
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (verbose != 0)
|
if( verbose != 0 )
|
||||||
mbedtls_printf("failed\n");
|
mbedtls_printf( "failed\n" );
|
||||||
|
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MBEDTLS_SELF_TEST */
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|||||||
@@ -8,30 +8,26 @@
|
|||||||
* digests instead.
|
* digests instead.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef MBEDTLS_MD5_H
|
#ifndef MBEDTLS_MD5_H
|
||||||
#define MBEDTLS_MD5_H
|
#define MBEDTLS_MD5_H
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
#include "config.h"
|
#include "mbedtls/config.h"
|
||||||
#else
|
#else
|
||||||
#include MBEDTLS_CONFIG_FILE
|
#include MBEDTLS_CONFIG_FILE
|
||||||
#endif
|
#endif
|
||||||
@@ -39,6 +35,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.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 */
|
#define MBEDTLS_ERR_MD5_HW_ACCEL_FAILED -0x002F /**< MD5 hardware accelerator failed */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -57,7 +54,8 @@ extern "C" {
|
|||||||
* stronger message digests instead.
|
* stronger message digests instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_md5_context {
|
typedef struct mbedtls_md5_context
|
||||||
|
{
|
||||||
uint32_t total[2]; /*!< number of bytes processed */
|
uint32_t total[2]; /*!< number of bytes processed */
|
||||||
uint32_t state[4]; /*!< intermediate digest state */
|
uint32_t state[4]; /*!< intermediate digest state */
|
||||||
unsigned char buffer[64]; /*!< data block being processed */
|
unsigned char buffer[64]; /*!< data block being processed */
|
||||||
@@ -78,7 +76,7 @@ mbedtls_md5_context;
|
|||||||
* stronger message digests instead.
|
* stronger message digests instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void mbedtls_md5_init(mbedtls_md5_context *ctx);
|
void mbedtls_md5_init( mbedtls_md5_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Clear MD5 context
|
* \brief Clear MD5 context
|
||||||
@@ -90,7 +88,7 @@ void mbedtls_md5_init(mbedtls_md5_context *ctx);
|
|||||||
* stronger message digests instead.
|
* stronger message digests instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void mbedtls_md5_free(mbedtls_md5_context *ctx);
|
void mbedtls_md5_free( mbedtls_md5_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Clone (the state of) an MD5 context
|
* \brief Clone (the state of) an MD5 context
|
||||||
@@ -103,8 +101,8 @@ void mbedtls_md5_free(mbedtls_md5_context *ctx);
|
|||||||
* stronger message digests instead.
|
* stronger message digests instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void mbedtls_md5_clone(mbedtls_md5_context *dst,
|
void mbedtls_md5_clone( mbedtls_md5_context *dst,
|
||||||
const mbedtls_md5_context *src);
|
const mbedtls_md5_context *src );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief MD5 context setup
|
* \brief MD5 context setup
|
||||||
@@ -118,7 +116,7 @@ void mbedtls_md5_clone(mbedtls_md5_context *dst,
|
|||||||
* stronger message digests instead.
|
* stronger message digests instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int mbedtls_md5_starts_ret(mbedtls_md5_context *ctx);
|
int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief MD5 process buffer
|
* \brief MD5 process buffer
|
||||||
@@ -134,9 +132,9 @@ int mbedtls_md5_starts_ret(mbedtls_md5_context *ctx);
|
|||||||
* stronger message digests instead.
|
* stronger message digests instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int mbedtls_md5_update_ret(mbedtls_md5_context *ctx,
|
int mbedtls_md5_update_ret( mbedtls_md5_context *ctx,
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
size_t ilen);
|
size_t ilen );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief MD5 final digest
|
* \brief MD5 final digest
|
||||||
@@ -151,8 +149,8 @@ int mbedtls_md5_update_ret(mbedtls_md5_context *ctx,
|
|||||||
* stronger message digests instead.
|
* stronger message digests instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int mbedtls_md5_finish_ret(mbedtls_md5_context *ctx,
|
int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
|
||||||
unsigned char output[16]);
|
unsigned char output[16] );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief MD5 process data block (internal use only)
|
* \brief MD5 process data block (internal use only)
|
||||||
@@ -167,8 +165,8 @@ int mbedtls_md5_finish_ret(mbedtls_md5_context *ctx,
|
|||||||
* stronger message digests instead.
|
* stronger message digests instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int mbedtls_internal_md5_process(mbedtls_md5_context *ctx,
|
int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
|
||||||
const unsigned char data[64]);
|
const unsigned char data[64] );
|
||||||
|
|
||||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
||||||
@@ -188,7 +186,7 @@ int mbedtls_internal_md5_process(mbedtls_md5_context *ctx,
|
|||||||
* stronger message digests instead.
|
* stronger message digests instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
MBEDTLS_DEPRECATED void mbedtls_md5_starts(mbedtls_md5_context *ctx);
|
MBEDTLS_DEPRECATED void mbedtls_md5_starts( mbedtls_md5_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief MD5 process buffer
|
* \brief MD5 process buffer
|
||||||
@@ -204,9 +202,9 @@ MBEDTLS_DEPRECATED void mbedtls_md5_starts(mbedtls_md5_context *ctx);
|
|||||||
* stronger message digests instead.
|
* stronger message digests instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
MBEDTLS_DEPRECATED void mbedtls_md5_update(mbedtls_md5_context *ctx,
|
MBEDTLS_DEPRECATED void mbedtls_md5_update( mbedtls_md5_context *ctx,
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
size_t ilen);
|
size_t ilen );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief MD5 final digest
|
* \brief MD5 final digest
|
||||||
@@ -221,8 +219,8 @@ MBEDTLS_DEPRECATED void mbedtls_md5_update(mbedtls_md5_context *ctx,
|
|||||||
* stronger message digests instead.
|
* stronger message digests instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
MBEDTLS_DEPRECATED void mbedtls_md5_finish(mbedtls_md5_context *ctx,
|
MBEDTLS_DEPRECATED void mbedtls_md5_finish( mbedtls_md5_context *ctx,
|
||||||
unsigned char output[16]);
|
unsigned char output[16] );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief MD5 process data block (internal use only)
|
* \brief MD5 process data block (internal use only)
|
||||||
@@ -237,8 +235,8 @@ MBEDTLS_DEPRECATED void mbedtls_md5_finish(mbedtls_md5_context *ctx,
|
|||||||
* stronger message digests instead.
|
* stronger message digests instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
MBEDTLS_DEPRECATED void mbedtls_md5_process(mbedtls_md5_context *ctx,
|
MBEDTLS_DEPRECATED void mbedtls_md5_process( mbedtls_md5_context *ctx,
|
||||||
const unsigned char data[64]);
|
const unsigned char data[64] );
|
||||||
|
|
||||||
#undef MBEDTLS_DEPRECATED
|
#undef MBEDTLS_DEPRECATED
|
||||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||||
@@ -257,9 +255,9 @@ MBEDTLS_DEPRECATED void mbedtls_md5_process(mbedtls_md5_context *ctx,
|
|||||||
* stronger message digests instead.
|
* stronger message digests instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int mbedtls_md5_ret(const unsigned char *input,
|
int mbedtls_md5_ret( const unsigned char *input,
|
||||||
size_t ilen,
|
size_t ilen,
|
||||||
unsigned char output[16]);
|
unsigned char output[16] );
|
||||||
|
|
||||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
||||||
@@ -281,13 +279,15 @@ int mbedtls_md5_ret(const unsigned char *input,
|
|||||||
* stronger message digests instead.
|
* stronger message digests instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
MBEDTLS_DEPRECATED void mbedtls_md5(const unsigned char *input,
|
MBEDTLS_DEPRECATED void mbedtls_md5( const unsigned char *input,
|
||||||
size_t ilen,
|
size_t ilen,
|
||||||
unsigned char output[16]);
|
unsigned char output[16] );
|
||||||
|
|
||||||
#undef MBEDTLS_DEPRECATED
|
#undef MBEDTLS_DEPRECATED
|
||||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Checkup routine
|
* \brief Checkup routine
|
||||||
*
|
*
|
||||||
@@ -298,7 +298,9 @@ MBEDTLS_DEPRECATED void mbedtls_md5(const unsigned char *input,
|
|||||||
* stronger message digests instead.
|
* stronger message digests instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int mbedtls_md5_self_test(int verbose);
|
int mbedtls_md5_self_test( int verbose );
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,35 +8,31 @@
|
|||||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef MBEDTLS_MD_WRAP_H
|
#ifndef MBEDTLS_MD_WRAP_H
|
||||||
#define MBEDTLS_MD_WRAP_H
|
#define MBEDTLS_MD_WRAP_H
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
#include "config.h"
|
#include "mbedtls/config.h"
|
||||||
#else
|
#else
|
||||||
#include MBEDTLS_CONFIG_FILE
|
#include MBEDTLS_CONFIG_FILE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "md.h"
|
#include "mbedtls/md.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -46,43 +42,19 @@ extern "C" {
|
|||||||
* Message digest information.
|
* Message digest information.
|
||||||
* Allows message digest functions to be called in a generic way.
|
* Allows message digest functions to be called in a generic way.
|
||||||
*/
|
*/
|
||||||
struct mbedtls_md_info_t {
|
struct mbedtls_md_info_t
|
||||||
|
{
|
||||||
|
/** Name of the message digest */
|
||||||
|
const char * name;
|
||||||
|
|
||||||
/** Digest identifier */
|
/** Digest identifier */
|
||||||
mbedtls_md_type_t type;
|
mbedtls_md_type_t type;
|
||||||
|
|
||||||
/** Name of the message digest */
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
/** Output length of the digest function in bytes */
|
/** Output length of the digest function in bytes */
|
||||||
int size;
|
unsigned char size;
|
||||||
|
|
||||||
/** Block length of the digest function in bytes */
|
/** Block length of the digest function in bytes */
|
||||||
int block_size;
|
unsigned char block_size;
|
||||||
|
|
||||||
/** Digest initialisation function */
|
|
||||||
int (*starts_func)(void *ctx);
|
|
||||||
|
|
||||||
/** Digest update function */
|
|
||||||
int (*update_func)(void *ctx, const unsigned char *input, size_t ilen);
|
|
||||||
|
|
||||||
/** Digest finalisation function */
|
|
||||||
int (*finish_func)(void *ctx, unsigned char *output);
|
|
||||||
|
|
||||||
/** Generic digest function */
|
|
||||||
int (*digest_func)(const unsigned char *input, size_t ilen,
|
|
||||||
unsigned char *output);
|
|
||||||
|
|
||||||
/** Allocate a new context */
|
|
||||||
void *(*ctx_alloc_func)(void);
|
|
||||||
|
|
||||||
/** Free the given context */
|
|
||||||
void (*ctx_free_func)(void *ctx);
|
|
||||||
|
|
||||||
/** Clone state from a context */
|
|
||||||
void (*clone_func)(void *dst, const void *src);
|
|
||||||
|
|
||||||
/** Internal use only */
|
|
||||||
int (*process_func)(void *ctx, const unsigned char *input);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(MBEDTLS_MD2_C)
|
#if defined(MBEDTLS_MD2_C)
|
||||||
@@ -105,7 +77,9 @@ extern const mbedtls_md_info_t mbedtls_sha224_info;
|
|||||||
extern const mbedtls_md_info_t mbedtls_sha256_info;
|
extern const mbedtls_md_info_t mbedtls_sha256_info;
|
||||||
#endif
|
#endif
|
||||||
#if defined(MBEDTLS_SHA512_C)
|
#if defined(MBEDTLS_SHA512_C)
|
||||||
|
#if !defined(MBEDTLS_SHA512_NO_SHA384)
|
||||||
extern const mbedtls_md_info_t mbedtls_sha384_info;
|
extern const mbedtls_md_info_t mbedtls_sha384_info;
|
||||||
|
#endif
|
||||||
extern const mbedtls_md_info_t mbedtls_sha512_info;
|
extern const mbedtls_md_info_t mbedtls_sha512_info;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,533 +0,0 @@
|
|||||||
/**
|
|
||||||
* \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: GPL-2.0
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
|
||||||
#include "mbedtls/config.h"
|
|
||||||
#else
|
|
||||||
#include MBEDTLS_CONFIG_FILE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_MD_C)
|
|
||||||
|
|
||||||
#include "mbedtls/md_internal.h"
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_MD2_C)
|
|
||||||
#include "mbedtls/md2.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_MD4_C)
|
|
||||||
#include "mbedtls/md4.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_MD5_C)
|
|
||||||
#include "mbedtls/md5.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_RIPEMD160_C)
|
|
||||||
#include "mbedtls/ripemd160.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_SHA1_C)
|
|
||||||
#include "mbedtls/sha1.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_SHA256_C)
|
|
||||||
#include "mbedtls/sha256.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_SHA512_C)
|
|
||||||
#include "mbedtls/sha512.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_PLATFORM_C)
|
|
||||||
#include "mbedtls/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 */
|
|
||||||
744
common/mbedtls/memory_buffer_alloc.c
Normal file
744
common/mbedtls/memory_buffer_alloc.c
Normal file
@@ -0,0 +1,744 @@
|
|||||||
|
/*
|
||||||
|
* Buffer-based memory allocator
|
||||||
|
*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
|
||||||
|
#include "mbedtls/memory_buffer_alloc.h"
|
||||||
|
|
||||||
|
/* No need for the header guard as MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
||||||
|
is dependent upon MBEDTLS_PLATFORM_C */
|
||||||
|
#include "mbedtls/platform.h"
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_MEMORY_BACKTRACE)
|
||||||
|
#include <execinfo.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
#include "mbedtls/threading.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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( void )
|
||||||
|
{
|
||||||
|
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( void )
|
||||||
|
{
|
||||||
|
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( void )
|
||||||
|
{
|
||||||
|
return verify_chain();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_MEMORY_DEBUG)
|
||||||
|
void mbedtls_memory_buffer_alloc_status( void )
|
||||||
|
{
|
||||||
|
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( void )
|
||||||
|
{
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
mbedtls_mutex_free( &heap.mutex );
|
||||||
|
#endif
|
||||||
|
mbedtls_platform_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( void )
|
||||||
|
{
|
||||||
|
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 */
|
||||||
149
common/mbedtls/memory_buffer_alloc.h
Normal file
149
common/mbedtls/memory_buffer_alloc.h
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
/**
|
||||||
|
* \file memory_buffer_alloc.h
|
||||||
|
*
|
||||||
|
* \brief Buffer-based memory allocator
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef MBEDTLS_MEMORY_BUFFER_ALLOC_H
|
||||||
|
#define MBEDTLS_MEMORY_BUFFER_ALLOC_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name SECTION: Module settings
|
||||||
|
*
|
||||||
|
* The configuration options you can set for this module are in this section.
|
||||||
|
* Either change them in config.h or define them on the compiler command line.
|
||||||
|
* \{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_MEMORY_ALIGN_MULTIPLE)
|
||||||
|
#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* \} name SECTION: Module settings */
|
||||||
|
|
||||||
|
#define MBEDTLS_MEMORY_VERIFY_NONE 0
|
||||||
|
#define MBEDTLS_MEMORY_VERIFY_ALLOC (1 << 0)
|
||||||
|
#define MBEDTLS_MEMORY_VERIFY_FREE (1 << 1)
|
||||||
|
#define MBEDTLS_MEMORY_VERIFY_ALWAYS (MBEDTLS_MEMORY_VERIFY_ALLOC | MBEDTLS_MEMORY_VERIFY_FREE)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initialize use of stack-based memory allocator.
|
||||||
|
* The stack-based allocator does memory management inside the
|
||||||
|
* presented buffer and does not call calloc() and free().
|
||||||
|
* It sets the global mbedtls_calloc() and mbedtls_free() pointers
|
||||||
|
* to its own functions.
|
||||||
|
* (Provided mbedtls_calloc() and mbedtls_free() are thread-safe if
|
||||||
|
* MBEDTLS_THREADING_C is defined)
|
||||||
|
*
|
||||||
|
* \note This code is not optimized and provides a straight-forward
|
||||||
|
* implementation of a stack-based memory allocator.
|
||||||
|
*
|
||||||
|
* \param buf buffer to use as heap
|
||||||
|
* \param len size of the buffer
|
||||||
|
*/
|
||||||
|
void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Free the mutex for thread-safety and clear remaining memory
|
||||||
|
*/
|
||||||
|
void mbedtls_memory_buffer_alloc_free( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Determine when the allocator should automatically verify the state
|
||||||
|
* of the entire chain of headers / meta-data.
|
||||||
|
* (Default: MBEDTLS_MEMORY_VERIFY_NONE)
|
||||||
|
*
|
||||||
|
* \param verify One of MBEDTLS_MEMORY_VERIFY_NONE, MBEDTLS_MEMORY_VERIFY_ALLOC,
|
||||||
|
* MBEDTLS_MEMORY_VERIFY_FREE or MBEDTLS_MEMORY_VERIFY_ALWAYS
|
||||||
|
*/
|
||||||
|
void mbedtls_memory_buffer_set_verify( int verify );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_MEMORY_DEBUG)
|
||||||
|
/**
|
||||||
|
* \brief Print out the status of the allocated memory (primarily for use
|
||||||
|
* after a program should have de-allocated all memory)
|
||||||
|
* Prints out a list of 'still allocated' blocks and their stack
|
||||||
|
* trace if MBEDTLS_MEMORY_BACKTRACE is defined.
|
||||||
|
*/
|
||||||
|
void mbedtls_memory_buffer_alloc_status( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Get the peak heap usage so far
|
||||||
|
*
|
||||||
|
* \param max_used Peak number of bytes in use or committed. This
|
||||||
|
* includes bytes in allocated blocks too small to split
|
||||||
|
* into smaller blocks but larger than the requested size.
|
||||||
|
* \param max_blocks Peak number of blocks in use, including free and used
|
||||||
|
*/
|
||||||
|
void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Reset peak statistics
|
||||||
|
*/
|
||||||
|
void mbedtls_memory_buffer_alloc_max_reset( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Get the current heap usage
|
||||||
|
*
|
||||||
|
* \param cur_used Current number of bytes in use or committed. This
|
||||||
|
* includes bytes in allocated blocks too small to split
|
||||||
|
* into smaller blocks but larger than the requested size.
|
||||||
|
* \param cur_blocks Current number of blocks in use, including free and used
|
||||||
|
*/
|
||||||
|
void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks );
|
||||||
|
#endif /* MBEDTLS_MEMORY_DEBUG */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Verifies that all headers in the memory buffer are correct
|
||||||
|
* and contain sane values. Helps debug buffer-overflow errors.
|
||||||
|
*
|
||||||
|
* Prints out first failure if MBEDTLS_MEMORY_DEBUG is defined.
|
||||||
|
* Prints out full header information if MBEDTLS_MEMORY_DEBUG
|
||||||
|
* is defined. (Includes stack trace information for each block if
|
||||||
|
* MBEDTLS_MEMORY_BACKTRACE is defined as well).
|
||||||
|
*
|
||||||
|
* \return 0 if verified, 1 otherwise
|
||||||
|
*/
|
||||||
|
int mbedtls_memory_buffer_alloc_verify( void );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
|
/**
|
||||||
|
* \brief Checkup routine
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or 1 if a test failed
|
||||||
|
*/
|
||||||
|
int mbedtls_memory_buffer_alloc_self_test( int verbose );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* memory_buffer_alloc.h */
|
||||||
35
common/mbedtls/net.h
Normal file
35
common/mbedtls/net.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* \file net.h
|
||||||
|
*
|
||||||
|
* \brief Deprecated header file that includes net_sockets.h
|
||||||
|
*
|
||||||
|
* \deprecated Superseded by mbedtls/net_sockets.h
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
|
#include "mbedtls/net_sockets.h"
|
||||||
|
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
||||||
|
#warning "Deprecated header file: Superseded by mbedtls/net_sockets.h"
|
||||||
|
#endif /* MBEDTLS_DEPRECATED_WARNING */
|
||||||
|
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||||
694
common/mbedtls/net_sockets.c
Normal file
694
common/mbedtls/net_sockets.c
Normal file
@@ -0,0 +1,694 @@
|
|||||||
|
/*
|
||||||
|
* TCP/IP or UDP/IP networking functions
|
||||||
|
*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Enable definition of getaddrinfo() even when compiling with -std=c99. Must
|
||||||
|
* be set before config.h, which pulls in glibc's features.h indirectly.
|
||||||
|
* Harmless on other platforms. */
|
||||||
|
#define _POSIX_C_SOURCE 200112L
|
||||||
|
#define _XOPEN_SOURCE 600 /* sockaddr_storage */
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_NET_C)
|
||||||
|
|
||||||
|
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
|
||||||
|
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
|
||||||
|
!defined(__HAIKU__) && !defined(__midipix__)
|
||||||
|
#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PLATFORM_C)
|
||||||
|
#include "mbedtls/platform.h"
|
||||||
|
#else
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mbedtls/net_sockets.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
|
||||||
|
!defined(EFI32)
|
||||||
|
|
||||||
|
#define IS_EINTR( ret ) ( ( ret ) == WSAEINTR )
|
||||||
|
|
||||||
|
#if !defined(_WIN32_WINNT)
|
||||||
|
/* Enables getaddrinfo() & Co */
|
||||||
|
#define _WIN32_WINNT 0x0501
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#if (_WIN32_WINNT < 0x0501)
|
||||||
|
#include <wspiapi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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>
|
||||||
|
|
||||||
|
#define IS_EINTR( ret ) ( ( ret ) == EINTR )
|
||||||
|
|
||||||
|
#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 = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
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 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 = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
int type;
|
||||||
|
|
||||||
|
struct sockaddr_storage client_addr;
|
||||||
|
|
||||||
|
#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \
|
||||||
|
defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t) || \
|
||||||
|
defined(socklen_t) || (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if data is available on the socket
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
fd_set read_fds;
|
||||||
|
fd_set write_fds;
|
||||||
|
|
||||||
|
int fd = ctx->fd;
|
||||||
|
|
||||||
|
if( fd < 0 )
|
||||||
|
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
|
||||||
|
|
||||||
|
/* A limitation of select() is that it only works with file descriptors
|
||||||
|
* that are strictly less than FD_SETSIZE. This is a limitation of the
|
||||||
|
* fd_set type. Error out early, because attempting to call FD_SET on a
|
||||||
|
* large file descriptor is a buffer overflow on typical platforms. */
|
||||||
|
if( fd >= FD_SETSIZE )
|
||||||
|
return( MBEDTLS_ERR_NET_POLL_FAILED );
|
||||||
|
|
||||||
|
#if defined(__has_feature)
|
||||||
|
#if __has_feature(memory_sanitizer)
|
||||||
|
/* Ensure that memory sanitizers consider read_fds and write_fds as
|
||||||
|
* initialized even on platforms such as Glibc/x86_64 where FD_ZERO
|
||||||
|
* is implemented in assembly. */
|
||||||
|
memset( &read_fds, 0, sizeof( read_fds ) );
|
||||||
|
memset( &write_fds, 0, sizeof( write_fds ) );
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FD_ZERO( &read_fds );
|
||||||
|
if( rw & MBEDTLS_NET_POLL_READ )
|
||||||
|
{
|
||||||
|
rw &= ~MBEDTLS_NET_POLL_READ;
|
||||||
|
FD_SET( fd, &read_fds );
|
||||||
|
}
|
||||||
|
|
||||||
|
FD_ZERO( &write_fds );
|
||||||
|
if( rw & MBEDTLS_NET_POLL_WRITE )
|
||||||
|
{
|
||||||
|
rw &= ~MBEDTLS_NET_POLL_WRITE;
|
||||||
|
FD_SET( fd, &write_fds );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( rw != 0 )
|
||||||
|
return( MBEDTLS_ERR_NET_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
tv.tv_sec = timeout / 1000;
|
||||||
|
tv.tv_usec = ( timeout % 1000 ) * 1000;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ret = select( fd + 1, &read_fds, &write_fds, NULL,
|
||||||
|
timeout == (uint32_t) -1 ? NULL : &tv );
|
||||||
|
}
|
||||||
|
while( IS_EINTR( ret ) );
|
||||||
|
|
||||||
|
if( ret < 0 )
|
||||||
|
return( MBEDTLS_ERR_NET_POLL_FAILED );
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
if( FD_ISSET( fd, &read_fds ) )
|
||||||
|
ret |= MBEDTLS_NET_POLL_READ;
|
||||||
|
if( FD_ISSET( fd, &write_fds ) )
|
||||||
|
ret |= MBEDTLS_NET_POLL_WRITE;
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
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 = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
struct timeval tv;
|
||||||
|
fd_set read_fds;
|
||||||
|
int fd = ((mbedtls_net_context *) ctx)->fd;
|
||||||
|
|
||||||
|
if( fd < 0 )
|
||||||
|
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
|
||||||
|
|
||||||
|
/* A limitation of select() is that it only works with file descriptors
|
||||||
|
* that are strictly less than FD_SETSIZE. This is a limitation of the
|
||||||
|
* fd_set type. Error out early, because attempting to call FD_SET on a
|
||||||
|
* large file descriptor is a buffer overflow on typical platforms. */
|
||||||
|
if( fd >= FD_SETSIZE )
|
||||||
|
return( MBEDTLS_ERR_NET_POLL_FAILED );
|
||||||
|
|
||||||
|
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 = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Close the connection
|
||||||
|
*/
|
||||||
|
void mbedtls_net_close( mbedtls_net_context *ctx )
|
||||||
|
{
|
||||||
|
if( ctx->fd == -1 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
close( ctx->fd );
|
||||||
|
|
||||||
|
ctx->fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 */
|
||||||
288
common/mbedtls/net_sockets.h
Normal file
288
common/mbedtls/net_sockets.h
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
/**
|
||||||
|
* \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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef MBEDTLS_NET_SOCKETS_H
|
||||||
|
#define MBEDTLS_NET_SOCKETS_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mbedtls/ssl.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define MBEDTLS_ERR_NET_SOCKET_FAILED -0x0042 /**< Failed to open a socket. */
|
||||||
|
#define MBEDTLS_ERR_NET_CONNECT_FAILED -0x0044 /**< The connection to the given server / port failed. */
|
||||||
|
#define MBEDTLS_ERR_NET_BIND_FAILED -0x0046 /**< Binding of the socket failed. */
|
||||||
|
#define MBEDTLS_ERR_NET_LISTEN_FAILED -0x0048 /**< Could not listen on the socket. */
|
||||||
|
#define MBEDTLS_ERR_NET_ACCEPT_FAILED -0x004A /**< Could not accept the incoming connection. */
|
||||||
|
#define MBEDTLS_ERR_NET_RECV_FAILED -0x004C /**< Reading information from the socket failed. */
|
||||||
|
#define MBEDTLS_ERR_NET_SEND_FAILED -0x004E /**< Sending information through the socket failed. */
|
||||||
|
#define MBEDTLS_ERR_NET_CONN_RESET -0x0050 /**< Connection was reset by peer. */
|
||||||
|
#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
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper type for sockets.
|
||||||
|
*
|
||||||
|
* Currently backed by just a file descriptor, but might be more in the future
|
||||||
|
* (eg two file descriptors for combined IPv4 + IPv6 support, or additional
|
||||||
|
* structures for hand-made UDP demultiplexing).
|
||||||
|
*/
|
||||||
|
typedef struct mbedtls_net_context
|
||||||
|
{
|
||||||
|
int fd; /**< The underlying file descriptor */
|
||||||
|
}
|
||||||
|
mbedtls_net_context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initialize a context
|
||||||
|
* Just makes the context ready to be used or freed safely.
|
||||||
|
*
|
||||||
|
* \param ctx Context to initialize
|
||||||
|
*/
|
||||||
|
void mbedtls_net_init( mbedtls_net_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initiate a connection with host:port in the given protocol
|
||||||
|
*
|
||||||
|
* \param ctx Socket to use
|
||||||
|
* \param host Host to connect to
|
||||||
|
* \param port Port to connect to
|
||||||
|
* \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or one of:
|
||||||
|
* MBEDTLS_ERR_NET_SOCKET_FAILED,
|
||||||
|
* MBEDTLS_ERR_NET_UNKNOWN_HOST,
|
||||||
|
* MBEDTLS_ERR_NET_CONNECT_FAILED
|
||||||
|
*
|
||||||
|
* \note Sets the socket in connected mode even with UDP.
|
||||||
|
*/
|
||||||
|
int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Create a receiving socket on bind_ip:port in the chosen
|
||||||
|
* protocol. If bind_ip == NULL, all interfaces are bound.
|
||||||
|
*
|
||||||
|
* \param ctx Socket to use
|
||||||
|
* \param bind_ip IP to bind to, can be NULL
|
||||||
|
* \param port Port number to use
|
||||||
|
* \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or one of:
|
||||||
|
* MBEDTLS_ERR_NET_SOCKET_FAILED,
|
||||||
|
* MBEDTLS_ERR_NET_UNKNOWN_HOST,
|
||||||
|
* MBEDTLS_ERR_NET_BIND_FAILED,
|
||||||
|
* MBEDTLS_ERR_NET_LISTEN_FAILED
|
||||||
|
*
|
||||||
|
* \note Regardless of the protocol, opens the sockets and binds it.
|
||||||
|
* In addition, make the socket listening if protocol is TCP.
|
||||||
|
*/
|
||||||
|
int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Accept a connection from a remote client
|
||||||
|
*
|
||||||
|
* \param bind_ctx Relevant socket
|
||||||
|
* \param client_ctx Will contain the connected client socket
|
||||||
|
* \param client_ip Will contain the client IP address, can be NULL
|
||||||
|
* \param buf_size Size of the client_ip buffer
|
||||||
|
* \param ip_len Will receive the size of the client IP written,
|
||||||
|
* can be NULL if client_ip is null
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or
|
||||||
|
* MBEDTLS_ERR_NET_SOCKET_FAILED,
|
||||||
|
* MBEDTLS_ERR_NET_BIND_FAILED,
|
||||||
|
* MBEDTLS_ERR_NET_ACCEPT_FAILED, or
|
||||||
|
* MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small,
|
||||||
|
* MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to
|
||||||
|
* non-blocking and accept() would block.
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
*
|
||||||
|
* \note The current implementation of this function uses
|
||||||
|
* select() and returns an error if the file descriptor
|
||||||
|
* is \c FD_SETSIZE or greater.
|
||||||
|
*
|
||||||
|
* \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
|
||||||
|
*
|
||||||
|
* \param ctx Socket to set
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or a non-zero error code
|
||||||
|
*/
|
||||||
|
int mbedtls_net_set_block( mbedtls_net_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set the socket non-blocking
|
||||||
|
*
|
||||||
|
* \param ctx Socket to set
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or a non-zero error code
|
||||||
|
*/
|
||||||
|
int mbedtls_net_set_nonblock( mbedtls_net_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Portable usleep helper
|
||||||
|
*
|
||||||
|
* \param usec Amount of microseconds to sleep
|
||||||
|
*
|
||||||
|
* \note Real amount of time slept will not be less than
|
||||||
|
* select()'s timeout granularity (typically, 10ms).
|
||||||
|
*/
|
||||||
|
void mbedtls_net_usleep( unsigned long usec );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Read at most 'len' characters. If no error occurs,
|
||||||
|
* the actual amount read is returned.
|
||||||
|
*
|
||||||
|
* \param ctx Socket
|
||||||
|
* \param buf The buffer to write to
|
||||||
|
* \param len Maximum length of the buffer
|
||||||
|
*
|
||||||
|
* \return the number of bytes received,
|
||||||
|
* or a non-zero error code; with a non-blocking socket,
|
||||||
|
* MBEDTLS_ERR_SSL_WANT_READ indicates read() would block.
|
||||||
|
*/
|
||||||
|
int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Write at most 'len' characters. If no error occurs,
|
||||||
|
* the actual amount read is returned.
|
||||||
|
*
|
||||||
|
* \param ctx Socket
|
||||||
|
* \param buf The buffer to read from
|
||||||
|
* \param len The length of the buffer
|
||||||
|
*
|
||||||
|
* \return the number of bytes sent,
|
||||||
|
* or a non-zero error code; with a non-blocking socket,
|
||||||
|
* MBEDTLS_ERR_SSL_WANT_WRITE indicates write() would block.
|
||||||
|
*/
|
||||||
|
int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Read at most 'len' characters, blocking for at most
|
||||||
|
* 'timeout' seconds. If no error occurs, the actual amount
|
||||||
|
* read is returned.
|
||||||
|
*
|
||||||
|
* \note The current implementation of this function uses
|
||||||
|
* select() and returns an error if the file descriptor
|
||||||
|
* is \c FD_SETSIZE or greater.
|
||||||
|
*
|
||||||
|
* \param ctx Socket
|
||||||
|
* \param buf The buffer to write to
|
||||||
|
* \param len Maximum length of the buffer
|
||||||
|
* \param timeout Maximum number of milliseconds to wait for data
|
||||||
|
* 0 means no timeout (wait forever)
|
||||||
|
*
|
||||||
|
* \return The number of bytes received if successful.
|
||||||
|
* MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out.
|
||||||
|
* MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal.
|
||||||
|
* Another negative error code (MBEDTLS_ERR_NET_xxx)
|
||||||
|
* for other failures.
|
||||||
|
*
|
||||||
|
* \note This function will block (until data becomes available or
|
||||||
|
* timeout is reached) even if the socket is set to
|
||||||
|
* non-blocking. Handling timeouts with non-blocking reads
|
||||||
|
* requires a different strategy.
|
||||||
|
*/
|
||||||
|
int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
|
||||||
|
uint32_t timeout );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Closes down the connection and free associated data
|
||||||
|
*
|
||||||
|
* \param ctx The context to close
|
||||||
|
*/
|
||||||
|
void mbedtls_net_close( mbedtls_net_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Gracefully shutdown the connection and free associated data
|
||||||
|
*
|
||||||
|
* \param ctx The context to free
|
||||||
|
*/
|
||||||
|
void mbedtls_net_free( mbedtls_net_context *ctx );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* net_sockets.h */
|
||||||
750
common/mbedtls/nist_kw.c
Normal file
750
common/mbedtls/nist_kw.c
Normal file
@@ -0,0 +1,750 @@
|
|||||||
|
/*
|
||||||
|
* Implementation of NIST SP 800-38F key wrapping, supporting KW and KWP modes
|
||||||
|
* only
|
||||||
|
*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Definition of Key Wrapping:
|
||||||
|
* https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf
|
||||||
|
* RFC 3394 "Advanced Encryption Standard (AES) Key Wrap Algorithm"
|
||||||
|
* RFC 5649 "Advanced Encryption Standard (AES) Key Wrap with Padding Algorithm"
|
||||||
|
*
|
||||||
|
* Note: RFC 3394 defines different methodology for intermediate operations for
|
||||||
|
* the wrapping and unwrapping operation than the definition in NIST SP 800-38F.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_NIST_KW_C)
|
||||||
|
|
||||||
|
#include "mbedtls/nist_kw.h"
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
|
||||||
|
#if defined(MBEDTLS_PLATFORM_C)
|
||||||
|
#include "mbedtls/platform.h"
|
||||||
|
#else
|
||||||
|
#include <stdio.h>
|
||||||
|
#define mbedtls_printf printf
|
||||||
|
#endif /* MBEDTLS_PLATFORM_C */
|
||||||
|
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_NIST_KW_ALT)
|
||||||
|
|
||||||
|
#define KW_SEMIBLOCK_LENGTH 8
|
||||||
|
#define MIN_SEMIBLOCKS_COUNT 3
|
||||||
|
|
||||||
|
/* constant-time buffer comparison */
|
||||||
|
static inline unsigned char mbedtls_nist_kw_safer_memcmp( const void *a, const void *b, size_t n )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
volatile const unsigned char *A = (volatile const unsigned char *) a;
|
||||||
|
volatile const unsigned char *B = (volatile const unsigned char *) b;
|
||||||
|
volatile unsigned char diff = 0;
|
||||||
|
|
||||||
|
for( i = 0; i < n; i++ )
|
||||||
|
{
|
||||||
|
/* Read volatile data in order before computing diff.
|
||||||
|
* This avoids IAR compiler warning:
|
||||||
|
* 'the order of volatile accesses is undefined ..' */
|
||||||
|
unsigned char x = A[i], y = B[i];
|
||||||
|
diff |= x ^ y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return( diff );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! The 64-bit default integrity check value (ICV) for KW mode. */
|
||||||
|
static const unsigned char NIST_KW_ICV1[] = {0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6};
|
||||||
|
/*! The 32-bit default integrity check value (ICV) for KWP mode. */
|
||||||
|
static const unsigned char NIST_KW_ICV2[] = {0xA6, 0x59, 0x59, 0xA6};
|
||||||
|
|
||||||
|
#ifndef GET_UINT32_BE
|
||||||
|
#define GET_UINT32_BE(n,b,i) \
|
||||||
|
do { \
|
||||||
|
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
|
||||||
|
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
|
||||||
|
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
|
||||||
|
| ( (uint32_t) (b)[(i) + 3] ); \
|
||||||
|
} while( 0 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PUT_UINT32_BE
|
||||||
|
#define PUT_UINT32_BE(n,b,i) \
|
||||||
|
do { \
|
||||||
|
(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) ); \
|
||||||
|
} while( 0 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize context
|
||||||
|
*/
|
||||||
|
void mbedtls_nist_kw_init( mbedtls_nist_kw_context *ctx )
|
||||||
|
{
|
||||||
|
memset( ctx, 0, sizeof( mbedtls_nist_kw_context ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
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_CIPHER_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
if( cipher_info->block_size != 16 )
|
||||||
|
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SP 800-38F currently defines AES cipher as the only block cipher allowed:
|
||||||
|
* "For KW and KWP, the underlying block cipher shall be approved, and the
|
||||||
|
* block size shall be 128 bits. Currently, the AES block cipher, with key
|
||||||
|
* lengths of 128, 192, or 256 bits, is the only block cipher that fits
|
||||||
|
* this profile."
|
||||||
|
* Currently we don't support other 128 bit block ciphers for key wrapping,
|
||||||
|
* such as Camellia and Aria.
|
||||||
|
*/
|
||||||
|
if( cipher != MBEDTLS_CIPHER_ID_AES )
|
||||||
|
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
|
||||||
|
|
||||||
|
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,
|
||||||
|
is_wrap ? MBEDTLS_ENCRYPT :
|
||||||
|
MBEDTLS_DECRYPT )
|
||||||
|
) != 0 )
|
||||||
|
{
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free context
|
||||||
|
*/
|
||||||
|
void mbedtls_nist_kw_free( mbedtls_nist_kw_context *ctx )
|
||||||
|
{
|
||||||
|
mbedtls_cipher_free( &ctx->cipher_ctx );
|
||||||
|
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_nist_kw_context ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper function for Xoring the uint64_t "t" with the encrypted A.
|
||||||
|
* Defined in NIST SP 800-38F section 6.1
|
||||||
|
*/
|
||||||
|
static void calc_a_xor_t( unsigned char A[KW_SEMIBLOCK_LENGTH], uint64_t t )
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
for( i = 0; i < sizeof( t ); i++ )
|
||||||
|
{
|
||||||
|
A[i] ^= ( t >> ( ( sizeof( t ) - 1 - i ) * 8 ) ) & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* KW-AE as defined in SP 800-38F section 6.2
|
||||||
|
* KWP-AE as defined in SP 800-38F section 6.3
|
||||||
|
*/
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
size_t semiblocks = 0;
|
||||||
|
size_t s;
|
||||||
|
size_t olen, padlen = 0;
|
||||||
|
uint64_t t = 0;
|
||||||
|
unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
|
||||||
|
unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2];
|
||||||
|
unsigned char *R2 = output + KW_SEMIBLOCK_LENGTH;
|
||||||
|
unsigned char *A = output;
|
||||||
|
|
||||||
|
*out_len = 0;
|
||||||
|
/*
|
||||||
|
* Generate the String to work on
|
||||||
|
*/
|
||||||
|
if( mode == MBEDTLS_KW_MODE_KW )
|
||||||
|
{
|
||||||
|
if( out_size < in_len + KW_SEMIBLOCK_LENGTH )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* According to SP 800-38F Table 1, the plaintext length for KW
|
||||||
|
* must be between 2 to 2^54-1 semiblocks inclusive.
|
||||||
|
*/
|
||||||
|
if( in_len < 16 ||
|
||||||
|
#if SIZE_MAX > 0x1FFFFFFFFFFFFF8
|
||||||
|
in_len > 0x1FFFFFFFFFFFFF8 ||
|
||||||
|
#endif
|
||||||
|
in_len % KW_SEMIBLOCK_LENGTH != 0 )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy( output, NIST_KW_ICV1, KW_SEMIBLOCK_LENGTH );
|
||||||
|
memmove( output + KW_SEMIBLOCK_LENGTH, input, in_len );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( in_len % 8 != 0 )
|
||||||
|
{
|
||||||
|
padlen = ( 8 - ( in_len % 8 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( out_size < in_len + KW_SEMIBLOCK_LENGTH + padlen )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* According to SP 800-38F Table 1, the plaintext length for KWP
|
||||||
|
* must be between 1 and 2^32-1 octets inclusive.
|
||||||
|
*/
|
||||||
|
if( in_len < 1
|
||||||
|
#if SIZE_MAX > 0xFFFFFFFF
|
||||||
|
|| in_len > 0xFFFFFFFF
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy( output, NIST_KW_ICV2, KW_SEMIBLOCK_LENGTH / 2 );
|
||||||
|
PUT_UINT32_BE( ( in_len & 0xffffffff ), output,
|
||||||
|
KW_SEMIBLOCK_LENGTH / 2 );
|
||||||
|
|
||||||
|
memcpy( output + KW_SEMIBLOCK_LENGTH, input, in_len );
|
||||||
|
memset( output + KW_SEMIBLOCK_LENGTH + in_len, 0, padlen );
|
||||||
|
}
|
||||||
|
semiblocks = ( ( in_len + padlen ) / KW_SEMIBLOCK_LENGTH ) + 1;
|
||||||
|
|
||||||
|
s = 6 * ( semiblocks - 1 );
|
||||||
|
|
||||||
|
if( mode == MBEDTLS_KW_MODE_KWP
|
||||||
|
&& in_len <= KW_SEMIBLOCK_LENGTH )
|
||||||
|
{
|
||||||
|
memcpy( inbuff, output, 16 );
|
||||||
|
ret = mbedtls_cipher_update( &ctx->cipher_ctx,
|
||||||
|
inbuff, 16, output, &olen );
|
||||||
|
if( ret != 0 )
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Do the wrapping function W, as defined in RFC 3394 section 2.2.1
|
||||||
|
*/
|
||||||
|
if( semiblocks < MIN_SEMIBLOCKS_COUNT )
|
||||||
|
{
|
||||||
|
ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate intermediate values */
|
||||||
|
for( t = 1; t <= s; t++ )
|
||||||
|
{
|
||||||
|
memcpy( inbuff, A, KW_SEMIBLOCK_LENGTH );
|
||||||
|
memcpy( inbuff + KW_SEMIBLOCK_LENGTH, R2, KW_SEMIBLOCK_LENGTH );
|
||||||
|
|
||||||
|
ret = mbedtls_cipher_update( &ctx->cipher_ctx,
|
||||||
|
inbuff, 16, outbuff, &olen );
|
||||||
|
if( ret != 0 )
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH );
|
||||||
|
calc_a_xor_t( A, t );
|
||||||
|
|
||||||
|
memcpy( R2, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH );
|
||||||
|
R2 += KW_SEMIBLOCK_LENGTH;
|
||||||
|
if( R2 >= output + ( semiblocks * KW_SEMIBLOCK_LENGTH ) )
|
||||||
|
R2 = output + KW_SEMIBLOCK_LENGTH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_len = semiblocks * KW_SEMIBLOCK_LENGTH;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
if( ret != 0)
|
||||||
|
{
|
||||||
|
memset( output, 0, semiblocks * KW_SEMIBLOCK_LENGTH );
|
||||||
|
}
|
||||||
|
mbedtls_platform_zeroize( inbuff, KW_SEMIBLOCK_LENGTH * 2 );
|
||||||
|
mbedtls_platform_zeroize( outbuff, KW_SEMIBLOCK_LENGTH * 2 );
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* W-1 function as defined in RFC 3394 section 2.2.2
|
||||||
|
* This function assumes the following:
|
||||||
|
* 1. Output buffer is at least of size ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH.
|
||||||
|
* 2. The input buffer is of size semiblocks * KW_SEMIBLOCK_LENGTH.
|
||||||
|
* 3. Minimal number of semiblocks is 3.
|
||||||
|
* 4. A is a buffer to hold the first semiblock of the input buffer.
|
||||||
|
*/
|
||||||
|
static int unwrap( mbedtls_nist_kw_context *ctx,
|
||||||
|
const unsigned char *input, size_t semiblocks,
|
||||||
|
unsigned char A[KW_SEMIBLOCK_LENGTH],
|
||||||
|
unsigned char *output, size_t* out_len )
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
const size_t s = 6 * ( semiblocks - 1 );
|
||||||
|
size_t olen;
|
||||||
|
uint64_t t = 0;
|
||||||
|
unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
|
||||||
|
unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2];
|
||||||
|
unsigned char *R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH;
|
||||||
|
*out_len = 0;
|
||||||
|
|
||||||
|
if( semiblocks < MIN_SEMIBLOCKS_COUNT )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy( A, input, KW_SEMIBLOCK_LENGTH );
|
||||||
|
memmove( output, input + KW_SEMIBLOCK_LENGTH, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH );
|
||||||
|
|
||||||
|
/* Calculate intermediate values */
|
||||||
|
for( t = s; t >= 1; t-- )
|
||||||
|
{
|
||||||
|
calc_a_xor_t( A, t );
|
||||||
|
|
||||||
|
memcpy( inbuff, A, KW_SEMIBLOCK_LENGTH );
|
||||||
|
memcpy( inbuff + KW_SEMIBLOCK_LENGTH, R, KW_SEMIBLOCK_LENGTH );
|
||||||
|
|
||||||
|
ret = mbedtls_cipher_update( &ctx->cipher_ctx,
|
||||||
|
inbuff, 16, outbuff, &olen );
|
||||||
|
if( ret != 0 )
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH );
|
||||||
|
|
||||||
|
/* Set R as LSB64 of outbuff */
|
||||||
|
memcpy( R, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH );
|
||||||
|
|
||||||
|
if( R == output )
|
||||||
|
R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH;
|
||||||
|
else
|
||||||
|
R -= KW_SEMIBLOCK_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_len = ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if( ret != 0)
|
||||||
|
memset( output, 0, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH );
|
||||||
|
mbedtls_platform_zeroize( inbuff, sizeof( inbuff ) );
|
||||||
|
mbedtls_platform_zeroize( outbuff, sizeof( outbuff ) );
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* KW-AD as defined in SP 800-38F section 6.2
|
||||||
|
* KWP-AD as defined in SP 800-38F section 6.3
|
||||||
|
*/
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
size_t i, olen;
|
||||||
|
unsigned char A[KW_SEMIBLOCK_LENGTH];
|
||||||
|
unsigned char diff, bad_padding = 0;
|
||||||
|
|
||||||
|
*out_len = 0;
|
||||||
|
if( out_size < in_len - KW_SEMIBLOCK_LENGTH )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( mode == MBEDTLS_KW_MODE_KW )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* According to SP 800-38F Table 1, the ciphertext length for KW
|
||||||
|
* must be between 3 to 2^54 semiblocks inclusive.
|
||||||
|
*/
|
||||||
|
if( in_len < 24 ||
|
||||||
|
#if SIZE_MAX > 0x200000000000000
|
||||||
|
in_len > 0x200000000000000 ||
|
||||||
|
#endif
|
||||||
|
in_len % KW_SEMIBLOCK_LENGTH != 0 )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = unwrap( ctx, input, in_len / KW_SEMIBLOCK_LENGTH,
|
||||||
|
A, output, out_len );
|
||||||
|
if( ret != 0 )
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
/* Check ICV in "constant-time" */
|
||||||
|
diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV1, A, KW_SEMIBLOCK_LENGTH );
|
||||||
|
|
||||||
|
if( diff != 0 )
|
||||||
|
{
|
||||||
|
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if( mode == MBEDTLS_KW_MODE_KWP )
|
||||||
|
{
|
||||||
|
size_t padlen = 0;
|
||||||
|
uint32_t Plen;
|
||||||
|
/*
|
||||||
|
* According to SP 800-38F Table 1, the ciphertext length for KWP
|
||||||
|
* must be between 2 to 2^29 semiblocks inclusive.
|
||||||
|
*/
|
||||||
|
if( in_len < KW_SEMIBLOCK_LENGTH * 2 ||
|
||||||
|
#if SIZE_MAX > 0x100000000
|
||||||
|
in_len > 0x100000000 ||
|
||||||
|
#endif
|
||||||
|
in_len % KW_SEMIBLOCK_LENGTH != 0 )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( in_len == KW_SEMIBLOCK_LENGTH * 2 )
|
||||||
|
{
|
||||||
|
unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
|
||||||
|
ret = mbedtls_cipher_update( &ctx->cipher_ctx,
|
||||||
|
input, 16, outbuff, &olen );
|
||||||
|
if( ret != 0 )
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH );
|
||||||
|
memcpy( output, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH );
|
||||||
|
mbedtls_platform_zeroize( outbuff, sizeof( outbuff ) );
|
||||||
|
*out_len = KW_SEMIBLOCK_LENGTH;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* in_len >= KW_SEMIBLOCK_LENGTH * 3 */
|
||||||
|
ret = unwrap( ctx, input, in_len / KW_SEMIBLOCK_LENGTH,
|
||||||
|
A, output, out_len );
|
||||||
|
if( ret != 0 )
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check ICV in "constant-time" */
|
||||||
|
diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV2, A, KW_SEMIBLOCK_LENGTH / 2 );
|
||||||
|
|
||||||
|
if( diff != 0 )
|
||||||
|
{
|
||||||
|
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
GET_UINT32_BE( Plen, A, KW_SEMIBLOCK_LENGTH / 2 );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Plen is the length of the plaintext, when the input is valid.
|
||||||
|
* If Plen is larger than the plaintext and padding, padlen will be
|
||||||
|
* larger than 8, because of the type wrap around.
|
||||||
|
*/
|
||||||
|
padlen = in_len - KW_SEMIBLOCK_LENGTH - Plen;
|
||||||
|
if ( padlen > 7 )
|
||||||
|
{
|
||||||
|
padlen &= 7;
|
||||||
|
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check padding in "constant-time" */
|
||||||
|
for( diff = 0, i = 0; i < KW_SEMIBLOCK_LENGTH; i++ )
|
||||||
|
{
|
||||||
|
if( i >= KW_SEMIBLOCK_LENGTH - padlen )
|
||||||
|
diff |= output[*out_len - KW_SEMIBLOCK_LENGTH + i];
|
||||||
|
else
|
||||||
|
bad_padding |= output[*out_len - KW_SEMIBLOCK_LENGTH + i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if( diff != 0 )
|
||||||
|
{
|
||||||
|
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
{
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
memset( output + Plen, 0, padlen );
|
||||||
|
*out_len = Plen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if( ret != 0 )
|
||||||
|
{
|
||||||
|
memset( output, 0, *out_len );
|
||||||
|
*out_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_platform_zeroize( &bad_padding, sizeof( bad_padding) );
|
||||||
|
mbedtls_platform_zeroize( &diff, sizeof( diff ) );
|
||||||
|
mbedtls_platform_zeroize( A, sizeof( A ) );
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !MBEDTLS_NIST_KW_ALT */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
|
||||||
|
|
||||||
|
#define KW_TESTS 3
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test vectors taken from NIST
|
||||||
|
* https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES#KW
|
||||||
|
*/
|
||||||
|
static const unsigned int key_len[KW_TESTS] = { 16, 24, 32 };
|
||||||
|
|
||||||
|
static const unsigned char kw_key[KW_TESTS][32] = {
|
||||||
|
{ 0x75, 0x75, 0xda, 0x3a, 0x93, 0x60, 0x7c, 0xc2,
|
||||||
|
0xbf, 0xd8, 0xce, 0xc7, 0xaa, 0xdf, 0xd9, 0xa6 },
|
||||||
|
{ 0x2d, 0x85, 0x26, 0x08, 0x1d, 0x02, 0xfb, 0x5b,
|
||||||
|
0x85, 0xf6, 0x9a, 0xc2, 0x86, 0xec, 0xd5, 0x7d,
|
||||||
|
0x40, 0xdf, 0x5d, 0xf3, 0x49, 0x47, 0x44, 0xd3 },
|
||||||
|
{ 0x11, 0x2a, 0xd4, 0x1b, 0x48, 0x56, 0xc7, 0x25,
|
||||||
|
0x4a, 0x98, 0x48, 0xd3, 0x0f, 0xdd, 0x78, 0x33,
|
||||||
|
0x5b, 0x03, 0x9a, 0x48, 0xa8, 0x96, 0x2c, 0x4d,
|
||||||
|
0x1c, 0xb7, 0x8e, 0xab, 0xd5, 0xda, 0xd7, 0x88 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char kw_msg[KW_TESTS][40] = {
|
||||||
|
{ 0x42, 0x13, 0x6d, 0x3c, 0x38, 0x4a, 0x3e, 0xea,
|
||||||
|
0xc9, 0x5a, 0x06, 0x6f, 0xd2, 0x8f, 0xed, 0x3f },
|
||||||
|
{ 0x95, 0xc1, 0x1b, 0xf5, 0x35, 0x3a, 0xfe, 0xdb,
|
||||||
|
0x98, 0xfd, 0xd6, 0xc8, 0xca, 0x6f, 0xdb, 0x6d,
|
||||||
|
0xa5, 0x4b, 0x74, 0xb4, 0x99, 0x0f, 0xdc, 0x45,
|
||||||
|
0xc0, 0x9d, 0x15, 0x8f, 0x51, 0xce, 0x62, 0x9d,
|
||||||
|
0xe2, 0xaf, 0x26, 0xe3, 0x25, 0x0e, 0x6b, 0x4c },
|
||||||
|
{ 0x1b, 0x20, 0xbf, 0x19, 0x90, 0xb0, 0x65, 0xd7,
|
||||||
|
0x98, 0xe1, 0xb3, 0x22, 0x64, 0xad, 0x50, 0xa8,
|
||||||
|
0x74, 0x74, 0x92, 0xba, 0x09, 0xa0, 0x4d, 0xd1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const size_t kw_msg_len[KW_TESTS] = { 16, 40, 24 };
|
||||||
|
static const size_t kw_out_len[KW_TESTS] = { 24, 48, 32 };
|
||||||
|
static const unsigned char kw_res[KW_TESTS][48] = {
|
||||||
|
{ 0x03, 0x1f, 0x6b, 0xd7, 0xe6, 0x1e, 0x64, 0x3d,
|
||||||
|
0xf6, 0x85, 0x94, 0x81, 0x6f, 0x64, 0xca, 0xa3,
|
||||||
|
0xf5, 0x6f, 0xab, 0xea, 0x25, 0x48, 0xf5, 0xfb },
|
||||||
|
{ 0x44, 0x3c, 0x6f, 0x15, 0x09, 0x83, 0x71, 0x91,
|
||||||
|
0x3e, 0x5c, 0x81, 0x4c, 0xa1, 0xa0, 0x42, 0xec,
|
||||||
|
0x68, 0x2f, 0x7b, 0x13, 0x6d, 0x24, 0x3a, 0x4d,
|
||||||
|
0x6c, 0x42, 0x6f, 0xc6, 0x97, 0x15, 0x63, 0xe8,
|
||||||
|
0xa1, 0x4a, 0x55, 0x8e, 0x09, 0x64, 0x16, 0x19,
|
||||||
|
0xbf, 0x03, 0xfc, 0xaf, 0x90, 0xb1, 0xfc, 0x2d },
|
||||||
|
{ 0xba, 0x8a, 0x25, 0x9a, 0x47, 0x1b, 0x78, 0x7d,
|
||||||
|
0xd5, 0xd5, 0x40, 0xec, 0x25, 0xd4, 0x3d, 0x87,
|
||||||
|
0x20, 0x0f, 0xda, 0xdc, 0x6d, 0x1f, 0x05, 0xd9,
|
||||||
|
0x16, 0x58, 0x4f, 0xa9, 0xf6, 0xcb, 0xf5, 0x12 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char kwp_key[KW_TESTS][32] = {
|
||||||
|
{ 0x78, 0x65, 0xe2, 0x0f, 0x3c, 0x21, 0x65, 0x9a,
|
||||||
|
0xb4, 0x69, 0x0b, 0x62, 0x9c, 0xdf, 0x3c, 0xc4 },
|
||||||
|
{ 0xf5, 0xf8, 0x96, 0xa3, 0xbd, 0x2f, 0x4a, 0x98,
|
||||||
|
0x23, 0xef, 0x16, 0x2b, 0x00, 0xb8, 0x05, 0xd7,
|
||||||
|
0xde, 0x1e, 0xa4, 0x66, 0x26, 0x96, 0xa2, 0x58 },
|
||||||
|
{ 0x95, 0xda, 0x27, 0x00, 0xca, 0x6f, 0xd9, 0xa5,
|
||||||
|
0x25, 0x54, 0xee, 0x2a, 0x8d, 0xf1, 0x38, 0x6f,
|
||||||
|
0x5b, 0x94, 0xa1, 0xa6, 0x0e, 0xd8, 0xa4, 0xae,
|
||||||
|
0xf6, 0x0a, 0x8d, 0x61, 0xab, 0x5f, 0x22, 0x5a }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char kwp_msg[KW_TESTS][31] = {
|
||||||
|
{ 0xbd, 0x68, 0x43, 0xd4, 0x20, 0x37, 0x8d, 0xc8,
|
||||||
|
0x96 },
|
||||||
|
{ 0x6c, 0xcd, 0xd5, 0x85, 0x18, 0x40, 0x97, 0xeb,
|
||||||
|
0xd5, 0xc3, 0xaf, 0x3e, 0x47, 0xd0, 0x2c, 0x19,
|
||||||
|
0x14, 0x7b, 0x4d, 0x99, 0x5f, 0x96, 0x43, 0x66,
|
||||||
|
0x91, 0x56, 0x75, 0x8c, 0x13, 0x16, 0x8f },
|
||||||
|
{ 0xd1 }
|
||||||
|
};
|
||||||
|
static const size_t kwp_msg_len[KW_TESTS] = { 9, 31, 1 };
|
||||||
|
|
||||||
|
static const unsigned char kwp_res[KW_TESTS][48] = {
|
||||||
|
{ 0x41, 0xec, 0xa9, 0x56, 0xd4, 0xaa, 0x04, 0x7e,
|
||||||
|
0xb5, 0xcf, 0x4e, 0xfe, 0x65, 0x96, 0x61, 0xe7,
|
||||||
|
0x4d, 0xb6, 0xf8, 0xc5, 0x64, 0xe2, 0x35, 0x00 },
|
||||||
|
{ 0x4e, 0x9b, 0xc2, 0xbc, 0xbc, 0x6c, 0x1e, 0x13,
|
||||||
|
0xd3, 0x35, 0xbc, 0xc0, 0xf7, 0x73, 0x6a, 0x88,
|
||||||
|
0xfa, 0x87, 0x53, 0x66, 0x15, 0xbb, 0x8e, 0x63,
|
||||||
|
0x8b, 0xcc, 0x81, 0x66, 0x84, 0x68, 0x17, 0x90,
|
||||||
|
0x67, 0xcf, 0xa9, 0x8a, 0x9d, 0x0e, 0x33, 0x26 },
|
||||||
|
{ 0x06, 0xba, 0x7a, 0xe6, 0xf3, 0x24, 0x8c, 0xfd,
|
||||||
|
0xcf, 0x26, 0x75, 0x07, 0xfa, 0x00, 0x1b, 0xc4 }
|
||||||
|
};
|
||||||
|
static const size_t kwp_out_len[KW_TESTS] = { 24, 40, 16 };
|
||||||
|
|
||||||
|
int mbedtls_nist_kw_self_test( int verbose )
|
||||||
|
{
|
||||||
|
mbedtls_nist_kw_context ctx;
|
||||||
|
unsigned char out[48];
|
||||||
|
size_t olen;
|
||||||
|
int i;
|
||||||
|
int ret = 0;
|
||||||
|
mbedtls_nist_kw_init( &ctx );
|
||||||
|
|
||||||
|
for( i = 0; i < KW_TESTS; i++ )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( " KW-AES-%u ", (unsigned int) key_len[i] * 8 );
|
||||||
|
|
||||||
|
ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
|
||||||
|
kw_key[i], key_len[i] * 8, 1 );
|
||||||
|
if( ret != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( " KW: setup failed " );
|
||||||
|
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mbedtls_nist_kw_wrap( &ctx, MBEDTLS_KW_MODE_KW, kw_msg[i],
|
||||||
|
kw_msg_len[i], out, &olen, sizeof( out ) );
|
||||||
|
if( ret != 0 || kw_out_len[i] != olen ||
|
||||||
|
memcmp( out, kw_res[i], kw_out_len[i] ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( "failed. ");
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
|
||||||
|
kw_key[i], key_len[i] * 8, 0 ) )
|
||||||
|
!= 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( " KW: setup failed ");
|
||||||
|
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mbedtls_nist_kw_unwrap( &ctx, MBEDTLS_KW_MODE_KW,
|
||||||
|
out, olen, out, &olen, sizeof( out ) );
|
||||||
|
|
||||||
|
if( ret != 0 || olen != kw_msg_len[i] ||
|
||||||
|
memcmp( out, kw_msg[i], kw_msg_len[i] ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( "failed\n" );
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( " passed\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( i = 0; i < KW_TESTS; i++ )
|
||||||
|
{
|
||||||
|
olen = sizeof( out );
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( " KWP-AES-%u ", (unsigned int) key_len[i] * 8 );
|
||||||
|
|
||||||
|
ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, kwp_key[i],
|
||||||
|
key_len[i] * 8, 1 );
|
||||||
|
if( ret != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( " KWP: setup failed " );
|
||||||
|
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
ret = mbedtls_nist_kw_wrap( &ctx, MBEDTLS_KW_MODE_KWP, kwp_msg[i],
|
||||||
|
kwp_msg_len[i], out, &olen, sizeof( out ) );
|
||||||
|
|
||||||
|
if( ret != 0 || kwp_out_len[i] != olen ||
|
||||||
|
memcmp( out, kwp_res[i], kwp_out_len[i] ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( "failed. ");
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
|
||||||
|
kwp_key[i], key_len[i] * 8, 0 ) )
|
||||||
|
!= 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( " KWP: setup failed ");
|
||||||
|
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mbedtls_nist_kw_unwrap( &ctx, MBEDTLS_KW_MODE_KWP, out,
|
||||||
|
olen, out, &olen, sizeof( out ) );
|
||||||
|
|
||||||
|
if( ret != 0 || olen != kwp_msg_len[i] ||
|
||||||
|
memcmp( out, kwp_msg[i], kwp_msg_len[i] ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( "failed. ");
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( " passed\n" );
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
mbedtls_nist_kw_free( &ctx );
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
mbedtls_printf( "\n" );
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_NIST_KW_C */
|
||||||
182
common/mbedtls/nist_kw.h
Normal file
182
common/mbedtls/nist_kw.h
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
/**
|
||||||
|
* \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 The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MBEDTLS_NIST_KW_H
|
||||||
|
#define MBEDTLS_NIST_KW_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mbedtls/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 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 */
|
||||||
@@ -3,36 +3,29 @@
|
|||||||
*
|
*
|
||||||
* \brief Object Identifier (OID) database
|
* \brief Object Identifier (OID) database
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#include "common.h"
|
||||||
#include "mbedtls/config.h"
|
|
||||||
#else
|
|
||||||
#include MBEDTLS_CONFIG_FILE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_OID_C)
|
#if defined(MBEDTLS_OID_C)
|
||||||
|
|
||||||
#include "mbedtls/oid.h"
|
#include "mbedtls/oid.h"
|
||||||
#include "mbedtls/rsa.h"
|
#include "mbedtls/rsa.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -43,10 +36,6 @@
|
|||||||
#define mbedtls_snprintf snprintf
|
#define mbedtls_snprintf snprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
|
|
||||||
#include "mbedtls/x509.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macro to automatically add the size of #define'd OIDs
|
* Macro to automatically add the size of #define'd OIDs
|
||||||
*/
|
*/
|
||||||
@@ -56,21 +45,23 @@
|
|||||||
* Macro to generate an internal function for oid_XXX_from_asn1() (used by
|
* Macro to generate an internal function for oid_XXX_from_asn1() (used by
|
||||||
* the other functions)
|
* the other functions)
|
||||||
*/
|
*/
|
||||||
#define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST ) \
|
#define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST ) \
|
||||||
static const TYPE_T * oid_ ## NAME ## _from_asn1( const mbedtls_asn1_buf *oid ) \
|
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; \
|
const TYPE_T *p = (LIST); \
|
||||||
if( p == NULL || oid == NULL ) return( NULL ); \
|
const mbedtls_oid_descriptor_t *cur = \
|
||||||
while( cur->asn1 != NULL ) { \
|
(const mbedtls_oid_descriptor_t *) p; \
|
||||||
if( cur->asn1_len == oid->len && \
|
if( p == NULL || oid == NULL ) return( NULL ); \
|
||||||
memcmp( cur->asn1, oid->p, oid->len ) == 0 ) { \
|
while( cur->asn1 != NULL ) { \
|
||||||
return( p ); \
|
if( cur->asn1_len == oid->len && \
|
||||||
} \
|
memcmp( cur->asn1, oid->p, oid->len ) == 0 ) { \
|
||||||
p++; \
|
return( p ); \
|
||||||
cur = (const mbedtls_oid_descriptor_t *) p; \
|
} \
|
||||||
} \
|
p++; \
|
||||||
return( NULL ); \
|
cur = (const mbedtls_oid_descriptor_t *) p; \
|
||||||
|
} \
|
||||||
|
return( NULL ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -78,26 +69,26 @@
|
|||||||
* descriptor of an mbedtls_oid_descriptor_t wrapper.
|
* descriptor of an mbedtls_oid_descriptor_t wrapper.
|
||||||
*/
|
*/
|
||||||
#define FN_OID_GET_DESCRIPTOR_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \
|
#define FN_OID_GET_DESCRIPTOR_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \
|
||||||
int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \
|
int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \
|
||||||
{ \
|
{ \
|
||||||
const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \
|
const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \
|
||||||
if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \
|
if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \
|
||||||
*ATTR1 = data->descriptor.ATTR1; \
|
*ATTR1 = data->descriptor.ATTR1; \
|
||||||
return( 0 ); \
|
return( 0 ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macro to generate a function for retrieving a single attribute from an
|
* Macro to generate a function for retrieving a single attribute from an
|
||||||
* mbedtls_oid_descriptor_t wrapper.
|
* mbedtls_oid_descriptor_t wrapper.
|
||||||
*/
|
*/
|
||||||
#define FN_OID_GET_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \
|
#define FN_OID_GET_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \
|
||||||
int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \
|
int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \
|
||||||
{ \
|
{ \
|
||||||
const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \
|
const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \
|
||||||
if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \
|
if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \
|
||||||
*ATTR1 = data->ATTR1; \
|
*ATTR1 = data->ATTR1; \
|
||||||
return( 0 ); \
|
return( 0 ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macro to generate a function for retrieving two attributes from an
|
* Macro to generate a function for retrieving two attributes from an
|
||||||
@@ -105,12 +96,13 @@
|
|||||||
*/
|
*/
|
||||||
#define FN_OID_GET_ATTR2(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1, \
|
#define FN_OID_GET_ATTR2(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1, \
|
||||||
ATTR2_TYPE, ATTR2) \
|
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 ); \
|
const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \
|
||||||
if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \
|
if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \
|
||||||
*ATTR1 = data->ATTR1; \
|
*(ATTR1) = data->ATTR1; \
|
||||||
*ATTR2 = data->ATTR2; \
|
*(ATTR2) = data->ATTR2; \
|
||||||
return( 0 ); \
|
return( 0 ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,19 +111,19 @@ int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, ATTR2_TYPE * ATTR2
|
|||||||
* attribute from a mbedtls_oid_descriptor_t wrapper.
|
* attribute from a mbedtls_oid_descriptor_t wrapper.
|
||||||
*/
|
*/
|
||||||
#define FN_OID_GET_OID_BY_ATTR1(FN_NAME, TYPE_T, LIST, 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 ) \
|
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 ) { \
|
while( cur->descriptor.asn1 != NULL ) { \
|
||||||
if( cur->ATTR1 == ATTR1 ) { \
|
if( cur->ATTR1 == (ATTR1) ) { \
|
||||||
*oid = cur->descriptor.asn1; \
|
*oid = cur->descriptor.asn1; \
|
||||||
*olen = cur->descriptor.asn1_len; \
|
*olen = cur->descriptor.asn1_len; \
|
||||||
return( 0 ); \
|
return( 0 ); \
|
||||||
} \
|
} \
|
||||||
cur++; \
|
cur++; \
|
||||||
} \
|
} \
|
||||||
return( MBEDTLS_ERR_OID_NOT_FOUND ); \
|
return( MBEDTLS_ERR_OID_NOT_FOUND ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macro to generate a function for retrieving the OID based on two
|
* Macro to generate a function for retrieving the OID based on two
|
||||||
@@ -142,9 +134,9 @@ int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, ATTR2_TYPE * ATTR2
|
|||||||
int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \
|
int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \
|
||||||
size_t *olen ) \
|
size_t *olen ) \
|
||||||
{ \
|
{ \
|
||||||
const TYPE_T *cur = LIST; \
|
const TYPE_T *cur = (LIST); \
|
||||||
while( cur->descriptor.asn1 != NULL ) { \
|
while( cur->descriptor.asn1 != NULL ) { \
|
||||||
if( cur->ATTR1 == ATTR1 && cur->ATTR2 == ATTR2 ) { \
|
if( cur->ATTR1 == (ATTR1) && cur->ATTR2 == (ATTR2) ) { \
|
||||||
*oid = cur->descriptor.asn1; \
|
*oid = cur->descriptor.asn1; \
|
||||||
*olen = cur->descriptor.asn1_len; \
|
*olen = cur->descriptor.asn1_len; \
|
||||||
return( 0 ); \
|
return( 0 ); \
|
||||||
@@ -154,7 +146,6 @@ int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \
|
|||||||
return( MBEDTLS_ERR_OID_NOT_FOUND ); \
|
return( MBEDTLS_ERR_OID_NOT_FOUND ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
|
|
||||||
/*
|
/*
|
||||||
* For X520 attribute types
|
* For X520 attribute types
|
||||||
*/
|
*/
|
||||||
@@ -163,81 +154,82 @@ typedef struct {
|
|||||||
const char *short_name;
|
const char *short_name;
|
||||||
} oid_x520_attr_t;
|
} oid_x520_attr_t;
|
||||||
|
|
||||||
static const oid_x520_attr_t oid_x520_attr_type[] = {
|
static const oid_x520_attr_t oid_x520_attr_type[] =
|
||||||
|
{
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_AT_CN), "id-at-commonName", "Common Name" },
|
{ ADD_LEN( MBEDTLS_OID_AT_CN ), "id-at-commonName", "Common Name" },
|
||||||
"CN",
|
"CN",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_AT_COUNTRY), "id-at-countryName", "Country" },
|
{ ADD_LEN( MBEDTLS_OID_AT_COUNTRY ), "id-at-countryName", "Country" },
|
||||||
"C",
|
"C",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_AT_LOCALITY), "id-at-locality", "Locality" },
|
{ ADD_LEN( MBEDTLS_OID_AT_LOCALITY ), "id-at-locality", "Locality" },
|
||||||
"L",
|
"L",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_AT_STATE), "id-at-state", "State" },
|
{ ADD_LEN( MBEDTLS_OID_AT_STATE ), "id-at-state", "State" },
|
||||||
"ST",
|
"ST",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_AT_ORGANIZATION), "id-at-organizationName", "Organization" },
|
{ ADD_LEN( MBEDTLS_OID_AT_ORGANIZATION ),"id-at-organizationName", "Organization" },
|
||||||
"O",
|
"O",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_AT_ORG_UNIT), "id-at-organizationalUnitName", "Org Unit" },
|
{ ADD_LEN( MBEDTLS_OID_AT_ORG_UNIT ), "id-at-organizationalUnitName", "Org Unit" },
|
||||||
"OU",
|
"OU",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_PKCS9_EMAIL), "emailAddress", "E-mail address" },
|
{ ADD_LEN( MBEDTLS_OID_PKCS9_EMAIL ), "emailAddress", "E-mail address" },
|
||||||
"emailAddress",
|
"emailAddress",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_AT_SERIAL_NUMBER), "id-at-serialNumber", "Serial number" },
|
{ ADD_LEN( MBEDTLS_OID_AT_SERIAL_NUMBER ),"id-at-serialNumber", "Serial number" },
|
||||||
"serialNumber",
|
"serialNumber",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_AT_POSTAL_ADDRESS), "id-at-postalAddress", "Postal address" },
|
{ ADD_LEN( MBEDTLS_OID_AT_POSTAL_ADDRESS ),"id-at-postalAddress", "Postal address" },
|
||||||
"postalAddress",
|
"postalAddress",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_AT_POSTAL_CODE), "id-at-postalCode", "Postal code" },
|
{ ADD_LEN( MBEDTLS_OID_AT_POSTAL_CODE ), "id-at-postalCode", "Postal code" },
|
||||||
"postalCode",
|
"postalCode",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_AT_SUR_NAME), "id-at-surName", "Surname" },
|
{ ADD_LEN( MBEDTLS_OID_AT_SUR_NAME ), "id-at-surName", "Surname" },
|
||||||
"SN",
|
"SN",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_AT_GIVEN_NAME), "id-at-givenName", "Given name" },
|
{ ADD_LEN( MBEDTLS_OID_AT_GIVEN_NAME ), "id-at-givenName", "Given name" },
|
||||||
"GN",
|
"GN",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_AT_INITIALS), "id-at-initials", "Initials" },
|
{ ADD_LEN( MBEDTLS_OID_AT_INITIALS ), "id-at-initials", "Initials" },
|
||||||
"initials",
|
"initials",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_AT_GENERATION_QUALIFIER), "id-at-generationQualifier", "Generation qualifier" },
|
{ ADD_LEN( MBEDTLS_OID_AT_GENERATION_QUALIFIER ), "id-at-generationQualifier", "Generation qualifier" },
|
||||||
"generationQualifier",
|
"generationQualifier",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_AT_TITLE), "id-at-title", "Title" },
|
{ ADD_LEN( MBEDTLS_OID_AT_TITLE ), "id-at-title", "Title" },
|
||||||
"title",
|
"title",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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",
|
"dnQualifier",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_AT_PSEUDONYM), "id-at-pseudonym", "Pseudonym" },
|
{ ADD_LEN( MBEDTLS_OID_AT_PSEUDONYM ), "id-at-pseudonym", "Pseudonym" },
|
||||||
"pseudonym",
|
"pseudonym",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_DOMAIN_COMPONENT), "id-domainComponent", "Domain component" },
|
{ ADD_LEN( MBEDTLS_OID_DOMAIN_COMPONENT ), "id-domainComponent", "Domain component" },
|
||||||
"DC",
|
"DC",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_AT_UNIQUE_IDENTIFIER), "id-at-uniqueIdentifier", "Unique Identifier" },
|
{ ADD_LEN( MBEDTLS_OID_AT_UNIQUE_IDENTIFIER ), "id-at-uniqueIdentifier", "Unique Identifier" },
|
||||||
"uniqueIdentifier",
|
"uniqueIdentifier",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -257,26 +249,31 @@ typedef struct {
|
|||||||
int ext_type;
|
int ext_type;
|
||||||
} oid_x509_ext_t;
|
} oid_x509_ext_t;
|
||||||
|
|
||||||
static const oid_x509_ext_t oid_x509_ext[] = {
|
static const oid_x509_ext_t oid_x509_ext[] =
|
||||||
|
{
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_OID_X509_EXT_BASIC_CONSTRAINTS,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_OID_X509_EXT_KEY_USAGE,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_OID_X509_EXT_SUBJECT_ALT_NAME,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_OID_X509_EXT_NS_CERT_TYPE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ ADD_LEN( MBEDTLS_OID_CERTIFICATE_POLICIES ), "id-ce-certificatePolicies", "Certificate Policies" },
|
||||||
|
MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ NULL, 0, NULL, NULL },
|
{ NULL, 0, NULL, NULL },
|
||||||
@@ -287,19 +284,29 @@ 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_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)
|
FN_OID_GET_ATTR1(mbedtls_oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, ext_type)
|
||||||
|
|
||||||
static const mbedtls_oid_descriptor_t oid_ext_key_usage[] = {
|
static const mbedtls_oid_descriptor_t oid_ext_key_usage[] =
|
||||||
{ 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_SERVER_AUTH ), "id-kp-serverAuth", "TLS Web Server Authentication" },
|
||||||
{ ADD_LEN(MBEDTLS_OID_CODE_SIGNING), "id-kp-codeSigning", "Code Signing" },
|
{ ADD_LEN( MBEDTLS_OID_CLIENT_AUTH ), "id-kp-clientAuth", "TLS Web Client Authentication" },
|
||||||
{ ADD_LEN(MBEDTLS_OID_EMAIL_PROTECTION), "id-kp-emailProtection", "E-mail Protection" },
|
{ ADD_LEN( MBEDTLS_OID_CODE_SIGNING ), "id-kp-codeSigning", "Code Signing" },
|
||||||
{ ADD_LEN(MBEDTLS_OID_TIME_STAMPING), "id-kp-timeStamping", "Time Stamping" },
|
{ ADD_LEN( MBEDTLS_OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" },
|
||||||
{ ADD_LEN(MBEDTLS_OID_OCSP_SIGNING), "id-kp-OCSPSigning", "OCSP Signing" },
|
{ ADD_LEN( MBEDTLS_OID_TIME_STAMPING ), "id-kp-timeStamping", "Time Stamping" },
|
||||||
|
{ ADD_LEN( MBEDTLS_OID_OCSP_SIGNING ), "id-kp-OCSPSigning", "OCSP Signing" },
|
||||||
|
{ ADD_LEN( MBEDTLS_OID_WISUN_FAN ), "id-kp-wisun-fan-device", "Wi-SUN Alliance Field Area Network (FAN)" },
|
||||||
{ NULL, 0, NULL, NULL },
|
{ NULL, 0, NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, ext_key_usage, oid_ext_key_usage)
|
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)
|
FN_OID_GET_ATTR1(mbedtls_oid_get_extended_key_usage, mbedtls_oid_descriptor_t, ext_key_usage, const char *, description)
|
||||||
#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
|
|
||||||
|
static const mbedtls_oid_descriptor_t oid_certificate_policies[] =
|
||||||
|
{
|
||||||
|
{ ADD_LEN( MBEDTLS_OID_ANY_POLICY ), "anyPolicy", "Any Policy" },
|
||||||
|
{ NULL, 0, NULL, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, certificate_policies, oid_certificate_policies)
|
||||||
|
FN_OID_GET_ATTR1(mbedtls_oid_get_certificate_policies, mbedtls_oid_descriptor_t, certificate_policies, const char *, description)
|
||||||
|
|
||||||
#if defined(MBEDTLS_MD_C)
|
#if defined(MBEDTLS_MD_C)
|
||||||
/*
|
/*
|
||||||
@@ -311,55 +318,56 @@ typedef struct {
|
|||||||
mbedtls_pk_type_t pk_alg;
|
mbedtls_pk_type_t pk_alg;
|
||||||
} oid_sig_alg_t;
|
} oid_sig_alg_t;
|
||||||
|
|
||||||
static const oid_sig_alg_t oid_sig_alg[] = {
|
static const oid_sig_alg_t oid_sig_alg[] =
|
||||||
|
{
|
||||||
#if defined(MBEDTLS_RSA_C)
|
#if defined(MBEDTLS_RSA_C)
|
||||||
#if defined(MBEDTLS_MD2_C)
|
#if defined(MBEDTLS_MD2_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_PKCS1_MD2), "md2WithRSAEncryption", "RSA with MD2" },
|
{ ADD_LEN( MBEDTLS_OID_PKCS1_MD2 ), "md2WithRSAEncryption", "RSA with MD2" },
|
||||||
MBEDTLS_MD_MD2, MBEDTLS_PK_RSA,
|
MBEDTLS_MD_MD2, MBEDTLS_PK_RSA,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_MD2_C */
|
#endif /* MBEDTLS_MD2_C */
|
||||||
#if defined(MBEDTLS_MD4_C)
|
#if defined(MBEDTLS_MD4_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_PKCS1_MD4), "md4WithRSAEncryption", "RSA with MD4" },
|
{ ADD_LEN( MBEDTLS_OID_PKCS1_MD4 ), "md4WithRSAEncryption", "RSA with MD4" },
|
||||||
MBEDTLS_MD_MD4, MBEDTLS_PK_RSA,
|
MBEDTLS_MD_MD4, MBEDTLS_PK_RSA,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_MD4_C */
|
#endif /* MBEDTLS_MD4_C */
|
||||||
#if defined(MBEDTLS_MD5_C)
|
#if defined(MBEDTLS_MD5_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_PKCS1_MD5), "md5WithRSAEncryption", "RSA with MD5" },
|
{ ADD_LEN( MBEDTLS_OID_PKCS1_MD5 ), "md5WithRSAEncryption", "RSA with MD5" },
|
||||||
MBEDTLS_MD_MD5, MBEDTLS_PK_RSA,
|
MBEDTLS_MD_MD5, MBEDTLS_PK_RSA,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_MD5_C */
|
#endif /* MBEDTLS_MD5_C */
|
||||||
#if defined(MBEDTLS_SHA1_C)
|
#if defined(MBEDTLS_SHA1_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_SHA1_C */
|
#endif /* MBEDTLS_SHA1_C */
|
||||||
#if defined(MBEDTLS_SHA256_C)
|
#if defined(MBEDTLS_SHA256_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_MD_SHA224, MBEDTLS_PK_RSA,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_MD_SHA256, MBEDTLS_PK_RSA,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_SHA256_C */
|
#endif /* MBEDTLS_SHA256_C */
|
||||||
#if defined(MBEDTLS_SHA512_C)
|
#if defined(MBEDTLS_SHA512_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_MD_SHA384, MBEDTLS_PK_RSA,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_MD_SHA512, MBEDTLS_PK_RSA,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_SHA512_C */
|
#endif /* MBEDTLS_SHA512_C */
|
||||||
#if defined(MBEDTLS_SHA1_C)
|
#if defined(MBEDTLS_SHA1_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_SHA1_C */
|
#endif /* MBEDTLS_SHA1_C */
|
||||||
@@ -367,34 +375,34 @@ static const oid_sig_alg_t oid_sig_alg[] = {
|
|||||||
#if defined(MBEDTLS_ECDSA_C)
|
#if defined(MBEDTLS_ECDSA_C)
|
||||||
#if defined(MBEDTLS_SHA1_C)
|
#if defined(MBEDTLS_SHA1_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_MD_SHA1, MBEDTLS_PK_ECDSA,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_SHA1_C */
|
#endif /* MBEDTLS_SHA1_C */
|
||||||
#if defined(MBEDTLS_SHA256_C)
|
#if defined(MBEDTLS_SHA256_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_MD_SHA224, MBEDTLS_PK_ECDSA,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_MD_SHA256, MBEDTLS_PK_ECDSA,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_SHA256_C */
|
#endif /* MBEDTLS_SHA256_C */
|
||||||
#if defined(MBEDTLS_SHA512_C)
|
#if defined(MBEDTLS_SHA512_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_MD_SHA384, MBEDTLS_PK_ECDSA,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_MD_SHA512, MBEDTLS_PK_ECDSA,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_SHA512_C */
|
#endif /* MBEDTLS_SHA512_C */
|
||||||
#endif /* MBEDTLS_ECDSA_C */
|
#endif /* MBEDTLS_ECDSA_C */
|
||||||
#if defined(MBEDTLS_RSA_C)
|
#if defined(MBEDTLS_RSA_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_MD_NONE, MBEDTLS_PK_RSASSA_PSS,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_RSA_C */
|
#endif /* MBEDTLS_RSA_C */
|
||||||
@@ -418,17 +426,18 @@ typedef struct {
|
|||||||
mbedtls_pk_type_t pk_alg;
|
mbedtls_pk_type_t pk_alg;
|
||||||
} oid_pk_alg_t;
|
} oid_pk_alg_t;
|
||||||
|
|
||||||
static const oid_pk_alg_t oid_pk_alg[] = {
|
static const oid_pk_alg_t oid_pk_alg[] =
|
||||||
|
{
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_PKCS1_RSA), "rsaEncryption", "RSA" },
|
{ ADD_LEN( MBEDTLS_OID_PKCS1_RSA ), "rsaEncryption", "RSA" },
|
||||||
MBEDTLS_PK_RSA,
|
MBEDTLS_PK_RSA,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_PK_ECKEY,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_PK_ECKEY_DH,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -450,70 +459,71 @@ typedef struct {
|
|||||||
mbedtls_ecp_group_id grp_id;
|
mbedtls_ecp_group_id grp_id;
|
||||||
} oid_ecp_grp_t;
|
} oid_ecp_grp_t;
|
||||||
|
|
||||||
static const oid_ecp_grp_t oid_ecp_grp[] = {
|
static const oid_ecp_grp_t oid_ecp_grp[] =
|
||||||
|
{
|
||||||
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
|
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_EC_GRP_SECP192R1), "secp192r1", "secp192r1" },
|
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192R1 ), "secp192r1", "secp192r1" },
|
||||||
MBEDTLS_ECP_DP_SECP192R1,
|
MBEDTLS_ECP_DP_SECP192R1,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
|
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
|
||||||
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
|
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_EC_GRP_SECP224R1), "secp224r1", "secp224r1" },
|
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224R1 ), "secp224r1", "secp224r1" },
|
||||||
MBEDTLS_ECP_DP_SECP224R1,
|
MBEDTLS_ECP_DP_SECP224R1,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
|
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
|
||||||
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
|
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_EC_GRP_SECP256R1), "secp256r1", "secp256r1" },
|
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256R1 ), "secp256r1", "secp256r1" },
|
||||||
MBEDTLS_ECP_DP_SECP256R1,
|
MBEDTLS_ECP_DP_SECP256R1,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
|
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
|
||||||
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
|
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_EC_GRP_SECP384R1), "secp384r1", "secp384r1" },
|
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP384R1 ), "secp384r1", "secp384r1" },
|
||||||
MBEDTLS_ECP_DP_SECP384R1,
|
MBEDTLS_ECP_DP_SECP384R1,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
|
#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
|
||||||
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
|
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_EC_GRP_SECP521R1), "secp521r1", "secp521r1" },
|
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP521R1 ), "secp521r1", "secp521r1" },
|
||||||
MBEDTLS_ECP_DP_SECP521R1,
|
MBEDTLS_ECP_DP_SECP521R1,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
|
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
|
||||||
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
|
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_EC_GRP_SECP192K1), "secp192k1", "secp192k1" },
|
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192K1 ), "secp192k1", "secp192k1" },
|
||||||
MBEDTLS_ECP_DP_SECP192K1,
|
MBEDTLS_ECP_DP_SECP192K1,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
|
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
|
||||||
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
|
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_EC_GRP_SECP224K1), "secp224k1", "secp224k1" },
|
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224K1 ), "secp224k1", "secp224k1" },
|
||||||
MBEDTLS_ECP_DP_SECP224K1,
|
MBEDTLS_ECP_DP_SECP224K1,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
|
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
|
||||||
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
|
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_EC_GRP_SECP256K1), "secp256k1", "secp256k1" },
|
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256K1 ), "secp256k1", "secp256k1" },
|
||||||
MBEDTLS_ECP_DP_SECP256K1,
|
MBEDTLS_ECP_DP_SECP256K1,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
|
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
|
||||||
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
|
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_EC_GRP_BP256R1), "brainpoolP256r1", "brainpool256r1" },
|
{ ADD_LEN( MBEDTLS_OID_EC_GRP_BP256R1 ), "brainpoolP256r1","brainpool256r1" },
|
||||||
MBEDTLS_ECP_DP_BP256R1,
|
MBEDTLS_ECP_DP_BP256R1,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
|
#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
|
||||||
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
|
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_EC_GRP_BP384R1), "brainpoolP384r1", "brainpool384r1" },
|
{ ADD_LEN( MBEDTLS_OID_EC_GRP_BP384R1 ), "brainpoolP384r1","brainpool384r1" },
|
||||||
MBEDTLS_ECP_DP_BP384R1,
|
MBEDTLS_ECP_DP_BP384R1,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
|
#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
|
||||||
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
|
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_EC_GRP_BP512R1), "brainpoolP512r1", "brainpool512r1" },
|
{ ADD_LEN( MBEDTLS_OID_EC_GRP_BP512R1 ), "brainpoolP512r1","brainpool512r1" },
|
||||||
MBEDTLS_ECP_DP_BP512R1,
|
MBEDTLS_ECP_DP_BP512R1,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
|
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
|
||||||
@@ -537,13 +547,14 @@ typedef struct {
|
|||||||
mbedtls_cipher_type_t cipher_alg;
|
mbedtls_cipher_type_t cipher_alg;
|
||||||
} oid_cipher_alg_t;
|
} oid_cipher_alg_t;
|
||||||
|
|
||||||
static const oid_cipher_alg_t oid_cipher_alg[] = {
|
static const oid_cipher_alg_t oid_cipher_alg[] =
|
||||||
|
{
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_DES_CBC), "desCBC", "DES-CBC" },
|
{ ADD_LEN( MBEDTLS_OID_DES_CBC ), "desCBC", "DES-CBC" },
|
||||||
MBEDTLS_CIPHER_DES_CBC,
|
MBEDTLS_CIPHER_DES_CBC,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_CIPHER_DES_EDE3_CBC,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -565,51 +576,58 @@ typedef struct {
|
|||||||
mbedtls_md_type_t md_alg;
|
mbedtls_md_type_t md_alg;
|
||||||
} oid_md_alg_t;
|
} oid_md_alg_t;
|
||||||
|
|
||||||
static const oid_md_alg_t oid_md_alg[] = {
|
static const oid_md_alg_t oid_md_alg[] =
|
||||||
|
{
|
||||||
#if defined(MBEDTLS_MD2_C)
|
#if defined(MBEDTLS_MD2_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_DIGEST_ALG_MD2), "id-md2", "MD2" },
|
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD2 ), "id-md2", "MD2" },
|
||||||
MBEDTLS_MD_MD2,
|
MBEDTLS_MD_MD2,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_MD2_C */
|
#endif /* MBEDTLS_MD2_C */
|
||||||
#if defined(MBEDTLS_MD4_C)
|
#if defined(MBEDTLS_MD4_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_DIGEST_ALG_MD4), "id-md4", "MD4" },
|
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD4 ), "id-md4", "MD4" },
|
||||||
MBEDTLS_MD_MD4,
|
MBEDTLS_MD_MD4,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_MD4_C */
|
#endif /* MBEDTLS_MD4_C */
|
||||||
#if defined(MBEDTLS_MD5_C)
|
#if defined(MBEDTLS_MD5_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_DIGEST_ALG_MD5), "id-md5", "MD5" },
|
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD5 ), "id-md5", "MD5" },
|
||||||
MBEDTLS_MD_MD5,
|
MBEDTLS_MD_MD5,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_MD5_C */
|
#endif /* MBEDTLS_MD5_C */
|
||||||
#if defined(MBEDTLS_SHA1_C)
|
#if defined(MBEDTLS_SHA1_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_DIGEST_ALG_SHA1), "id-sha1", "SHA-1" },
|
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA1 ), "id-sha1", "SHA-1" },
|
||||||
MBEDTLS_MD_SHA1,
|
MBEDTLS_MD_SHA1,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_SHA1_C */
|
#endif /* MBEDTLS_SHA1_C */
|
||||||
#if defined(MBEDTLS_SHA256_C)
|
#if defined(MBEDTLS_SHA256_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_DIGEST_ALG_SHA224), "id-sha224", "SHA-224" },
|
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA224 ), "id-sha224", "SHA-224" },
|
||||||
MBEDTLS_MD_SHA224,
|
MBEDTLS_MD_SHA224,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_DIGEST_ALG_SHA256), "id-sha256", "SHA-256" },
|
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA256 ), "id-sha256", "SHA-256" },
|
||||||
MBEDTLS_MD_SHA256,
|
MBEDTLS_MD_SHA256,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_SHA256_C */
|
#endif /* MBEDTLS_SHA256_C */
|
||||||
#if defined(MBEDTLS_SHA512_C)
|
#if defined(MBEDTLS_SHA512_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_DIGEST_ALG_SHA384), "id-sha384", "SHA-384" },
|
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA384 ), "id-sha384", "SHA-384" },
|
||||||
MBEDTLS_MD_SHA384,
|
MBEDTLS_MD_SHA384,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_DIGEST_ALG_SHA512), "id-sha512", "SHA-512" },
|
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA512 ), "id-sha512", "SHA-512" },
|
||||||
MBEDTLS_MD_SHA512,
|
MBEDTLS_MD_SHA512,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_SHA512_C */
|
#endif /* MBEDTLS_SHA512_C */
|
||||||
|
#if defined(MBEDTLS_RIPEMD160_C)
|
||||||
|
{
|
||||||
|
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_RIPEMD160 ), "id-ripemd160", "RIPEMD-160" },
|
||||||
|
MBEDTLS_MD_RIPEMD160,
|
||||||
|
},
|
||||||
|
#endif /* MBEDTLS_RIPEMD160_C */
|
||||||
{
|
{
|
||||||
{ NULL, 0, NULL, NULL },
|
{ NULL, 0, NULL, NULL },
|
||||||
MBEDTLS_MD_NONE,
|
MBEDTLS_MD_NONE,
|
||||||
@@ -628,30 +646,31 @@ typedef struct {
|
|||||||
mbedtls_md_type_t md_hmac;
|
mbedtls_md_type_t md_hmac;
|
||||||
} oid_md_hmac_t;
|
} oid_md_hmac_t;
|
||||||
|
|
||||||
static const oid_md_hmac_t oid_md_hmac[] = {
|
static const oid_md_hmac_t oid_md_hmac[] =
|
||||||
|
{
|
||||||
#if defined(MBEDTLS_SHA1_C)
|
#if defined(MBEDTLS_SHA1_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_HMAC_SHA1), "hmacSHA1", "HMAC-SHA-1" },
|
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA1 ), "hmacSHA1", "HMAC-SHA-1" },
|
||||||
MBEDTLS_MD_SHA1,
|
MBEDTLS_MD_SHA1,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_SHA1_C */
|
#endif /* MBEDTLS_SHA1_C */
|
||||||
#if defined(MBEDTLS_SHA256_C)
|
#if defined(MBEDTLS_SHA256_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_HMAC_SHA224), "hmacSHA224", "HMAC-SHA-224" },
|
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA224 ), "hmacSHA224", "HMAC-SHA-224" },
|
||||||
MBEDTLS_MD_SHA224,
|
MBEDTLS_MD_SHA224,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_HMAC_SHA256), "hmacSHA256", "HMAC-SHA-256" },
|
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA256 ), "hmacSHA256", "HMAC-SHA-256" },
|
||||||
MBEDTLS_MD_SHA256,
|
MBEDTLS_MD_SHA256,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_SHA256_C */
|
#endif /* MBEDTLS_SHA256_C */
|
||||||
#if defined(MBEDTLS_SHA512_C)
|
#if defined(MBEDTLS_SHA512_C)
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_HMAC_SHA384), "hmacSHA384", "HMAC-SHA-384" },
|
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA384 ), "hmacSHA384", "HMAC-SHA-384" },
|
||||||
MBEDTLS_MD_SHA384,
|
MBEDTLS_MD_SHA384,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(MBEDTLS_OID_HMAC_SHA512), "hmacSHA512", "HMAC-SHA-512" },
|
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA512 ), "hmacSHA512", "HMAC-SHA-512" },
|
||||||
MBEDTLS_MD_SHA512,
|
MBEDTLS_MD_SHA512,
|
||||||
},
|
},
|
||||||
#endif /* MBEDTLS_SHA512_C */
|
#endif /* MBEDTLS_SHA512_C */
|
||||||
@@ -675,13 +694,14 @@ typedef struct {
|
|||||||
mbedtls_cipher_type_t cipher_alg;
|
mbedtls_cipher_type_t cipher_alg;
|
||||||
} oid_pkcs12_pbe_alg_t;
|
} oid_pkcs12_pbe_alg_t;
|
||||||
|
|
||||||
static const oid_pkcs12_pbe_alg_t oid_pkcs12_pbe_alg[] = {
|
static const oid_pkcs12_pbe_alg_t oid_pkcs12_pbe_alg[] =
|
||||||
|
{
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_MD_SHA1, MBEDTLS_CIPHER_DES_EDE3_CBC,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ ADD_LEN(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,
|
MBEDTLS_MD_SHA1, MBEDTLS_CIPHER_DES_EDE_CBC,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -698,15 +718,16 @@ FN_OID_GET_ATTR2(mbedtls_oid_get_pkcs12_pbe_alg, oid_pkcs12_pbe_alg_t, pkcs12_pb
|
|||||||
do { \
|
do { \
|
||||||
if( ret < 0 || (size_t) ret >= n ) \
|
if( ret < 0 || (size_t) ret >= n ) \
|
||||||
return( MBEDTLS_ERR_OID_BUF_TOO_SMALL ); \
|
return( MBEDTLS_ERR_OID_BUF_TOO_SMALL ); \
|
||||||
\
|
\
|
||||||
n -= (size_t) ret; \
|
n -= (size_t) ret; \
|
||||||
p += (size_t) ret; \
|
p += (size_t) ret; \
|
||||||
} while( 0 )
|
} while( 0 )
|
||||||
|
|
||||||
/* Return the x.y.z.... style numeric string for the given OID */
|
/* Return the x.y.z.... style numeric string for the given OID */
|
||||||
int mbedtls_oid_get_numeric_string(char *buf, size_t size,
|
int mbedtls_oid_get_numeric_string( char *buf, size_t size,
|
||||||
const mbedtls_asn1_buf *oid) {
|
const mbedtls_asn1_buf *oid )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
size_t i, n;
|
size_t i, n;
|
||||||
unsigned int value;
|
unsigned int value;
|
||||||
char *p;
|
char *p;
|
||||||
@@ -715,29 +736,32 @@ int mbedtls_oid_get_numeric_string(char *buf, size_t size,
|
|||||||
n = size;
|
n = size;
|
||||||
|
|
||||||
/* First byte contains first two dots */
|
/* First byte contains first two dots */
|
||||||
if (oid->len > 0) {
|
if( oid->len > 0 )
|
||||||
ret = mbedtls_snprintf(p, n, "%d.%d", oid->p[0] / 40, oid->p[0] % 40);
|
{
|
||||||
|
ret = mbedtls_snprintf( p, n, "%d.%d", oid->p[0] / 40, oid->p[0] % 40 );
|
||||||
OID_SAFE_SNPRINTF;
|
OID_SAFE_SNPRINTF;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = 0;
|
value = 0;
|
||||||
for (i = 1; i < oid->len; i++) {
|
for( i = 1; i < oid->len; i++ )
|
||||||
|
{
|
||||||
/* Prevent overflow in value. */
|
/* Prevent overflow in value. */
|
||||||
if (((value << 7) >> 7) != value)
|
if( ( ( value << 7 ) >> 7 ) != value )
|
||||||
return (MBEDTLS_ERR_OID_BUF_TOO_SMALL);
|
return( MBEDTLS_ERR_OID_BUF_TOO_SMALL );
|
||||||
|
|
||||||
value <<= 7;
|
value <<= 7;
|
||||||
value += oid->p[i] & 0x7F;
|
value += oid->p[i] & 0x7F;
|
||||||
|
|
||||||
if (!(oid->p[i] & 0x80)) {
|
if( !( oid->p[i] & 0x80 ) )
|
||||||
|
{
|
||||||
/* Last byte */
|
/* Last byte */
|
||||||
ret = mbedtls_snprintf(p, n, ".%d", value);
|
ret = mbedtls_snprintf( p, n, ".%u", value );
|
||||||
OID_SAFE_SNPRINTF;
|
OID_SAFE_SNPRINTF;
|
||||||
value = 0;
|
value = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((int)(size - n));
|
return( (int) ( size - n ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MBEDTLS_OID_C */
|
#endif /* MBEDTLS_OID_C */
|
||||||
|
|||||||
@@ -4,54 +4,68 @@
|
|||||||
* \brief Object Identifier (OID) database
|
* \brief Object Identifier (OID) database
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef MBEDTLS_OID_H
|
#ifndef MBEDTLS_OID_H
|
||||||
#define MBEDTLS_OID_H
|
#define MBEDTLS_OID_H
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
#include "config.h"
|
#include "mbedtls/config.h"
|
||||||
#else
|
#else
|
||||||
#include MBEDTLS_CONFIG_FILE
|
#include MBEDTLS_CONFIG_FILE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "asn1.h"
|
#include "mbedtls/asn1.h"
|
||||||
#include "pk.h"
|
#include "mbedtls/pk.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_C)
|
#if defined(MBEDTLS_CIPHER_C)
|
||||||
#include "cipher.h"
|
#include "mbedtls/cipher.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_MD_C)
|
#if defined(MBEDTLS_MD_C)
|
||||||
#include "md.h"
|
#include "mbedtls/md.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
|
|
||||||
#include "x509.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MBEDTLS_ERR_OID_NOT_FOUND -0x002E /**< OID is not found. */
|
#define MBEDTLS_ERR_OID_NOT_FOUND -0x002E /**< OID is not found. */
|
||||||
#define MBEDTLS_ERR_OID_BUF_TOO_SMALL -0x000B /**< output buffer is too small */
|
#define MBEDTLS_ERR_OID_BUF_TOO_SMALL -0x000B /**< output buffer is too small */
|
||||||
|
|
||||||
|
/* This is for the benefit of X.509, but defined here in order to avoid
|
||||||
|
* having a "backwards" include of x.509.h here */
|
||||||
|
/*
|
||||||
|
* X.509 extension types (internal, arbitrary values for bitsets)
|
||||||
|
*/
|
||||||
|
#define MBEDTLS_OID_X509_EXT_AUTHORITY_KEY_IDENTIFIER (1 << 0)
|
||||||
|
#define MBEDTLS_OID_X509_EXT_SUBJECT_KEY_IDENTIFIER (1 << 1)
|
||||||
|
#define MBEDTLS_OID_X509_EXT_KEY_USAGE (1 << 2)
|
||||||
|
#define MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES (1 << 3)
|
||||||
|
#define MBEDTLS_OID_X509_EXT_POLICY_MAPPINGS (1 << 4)
|
||||||
|
#define MBEDTLS_OID_X509_EXT_SUBJECT_ALT_NAME (1 << 5)
|
||||||
|
#define MBEDTLS_OID_X509_EXT_ISSUER_ALT_NAME (1 << 6)
|
||||||
|
#define MBEDTLS_OID_X509_EXT_SUBJECT_DIRECTORY_ATTRS (1 << 7)
|
||||||
|
#define MBEDTLS_OID_X509_EXT_BASIC_CONSTRAINTS (1 << 8)
|
||||||
|
#define MBEDTLS_OID_X509_EXT_NAME_CONSTRAINTS (1 << 9)
|
||||||
|
#define MBEDTLS_OID_X509_EXT_POLICY_CONSTRAINTS (1 << 10)
|
||||||
|
#define MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE (1 << 11)
|
||||||
|
#define MBEDTLS_OID_X509_EXT_CRL_DISTRIBUTION_POINTS (1 << 12)
|
||||||
|
#define MBEDTLS_OID_X509_EXT_INIHIBIT_ANYPOLICY (1 << 13)
|
||||||
|
#define MBEDTLS_OID_X509_EXT_FRESHEST_CRL (1 << 14)
|
||||||
|
#define MBEDTLS_OID_X509_EXT_NS_CERT_TYPE (1 << 16)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Top level OID tuples
|
* Top level OID tuples
|
||||||
*/
|
*/
|
||||||
@@ -66,10 +80,10 @@
|
|||||||
#define MBEDTLS_OID_COUNTRY_US "\x86\x48" /* {us(840)} */
|
#define MBEDTLS_OID_COUNTRY_US "\x86\x48" /* {us(840)} */
|
||||||
#define MBEDTLS_OID_ORG_RSA_DATA_SECURITY "\x86\xf7\x0d" /* {rsadsi(113549)} */
|
#define MBEDTLS_OID_ORG_RSA_DATA_SECURITY "\x86\xf7\x0d" /* {rsadsi(113549)} */
|
||||||
#define MBEDTLS_OID_RSA_COMPANY MBEDTLS_OID_ISO_MEMBER_BODIES MBEDTLS_OID_COUNTRY_US \
|
#define MBEDTLS_OID_RSA_COMPANY MBEDTLS_OID_ISO_MEMBER_BODIES MBEDTLS_OID_COUNTRY_US \
|
||||||
MBEDTLS_OID_ORG_RSA_DATA_SECURITY /* {iso(1) member-body(2) us(840) rsadsi(113549)} */
|
MBEDTLS_OID_ORG_RSA_DATA_SECURITY /* {iso(1) member-body(2) us(840) rsadsi(113549)} */
|
||||||
#define MBEDTLS_OID_ORG_ANSI_X9_62 "\xce\x3d" /* ansi-X9-62(10045) */
|
#define MBEDTLS_OID_ORG_ANSI_X9_62 "\xce\x3d" /* ansi-X9-62(10045) */
|
||||||
#define MBEDTLS_OID_ANSI_X9_62 MBEDTLS_OID_ISO_MEMBER_BODIES MBEDTLS_OID_COUNTRY_US \
|
#define MBEDTLS_OID_ANSI_X9_62 MBEDTLS_OID_ISO_MEMBER_BODIES MBEDTLS_OID_COUNTRY_US \
|
||||||
MBEDTLS_OID_ORG_ANSI_X9_62
|
MBEDTLS_OID_ORG_ANSI_X9_62
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ISO Identified organization OID parts
|
* ISO Identified organization OID parts
|
||||||
@@ -106,7 +120,8 @@
|
|||||||
* { iso(1) identified-organization(3) dod(6) internet(1)
|
* { iso(1) identified-organization(3) dod(6) internet(1)
|
||||||
* security(5) mechanisms(5) pkix(7) }
|
* security(5) mechanisms(5) pkix(7) }
|
||||||
*/
|
*/
|
||||||
#define MBEDTLS_OID_PKIX MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD "\x01\x05\x05\x07"
|
#define MBEDTLS_OID_INTERNET MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD "\x01"
|
||||||
|
#define MBEDTLS_OID_PKIX MBEDTLS_OID_INTERNET "\x05\x05\x07"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Arc for standard naming attributes
|
* Arc for standard naming attributes
|
||||||
@@ -151,6 +166,11 @@
|
|||||||
#define MBEDTLS_OID_INIHIBIT_ANYPOLICY MBEDTLS_OID_ID_CE "\x36" /**< id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 } */
|
#define MBEDTLS_OID_INIHIBIT_ANYPOLICY MBEDTLS_OID_ID_CE "\x36" /**< id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 } */
|
||||||
#define MBEDTLS_OID_FRESHEST_CRL MBEDTLS_OID_ID_CE "\x2E" /**< id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 } */
|
#define MBEDTLS_OID_FRESHEST_CRL MBEDTLS_OID_ID_CE "\x2E" /**< id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 } */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Certificate policies
|
||||||
|
*/
|
||||||
|
#define MBEDTLS_OID_ANY_POLICY MBEDTLS_OID_CERTIFICATE_POLICIES "\x00" /**< anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 } */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Netscape certificate extensions
|
* Netscape certificate extensions
|
||||||
*/
|
*/
|
||||||
@@ -185,6 +205,16 @@
|
|||||||
#define MBEDTLS_OID_TIME_STAMPING MBEDTLS_OID_KP "\x08" /**< id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } */
|
#define MBEDTLS_OID_TIME_STAMPING MBEDTLS_OID_KP "\x08" /**< id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } */
|
||||||
#define MBEDTLS_OID_OCSP_SIGNING MBEDTLS_OID_KP "\x09" /**< id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } */
|
#define MBEDTLS_OID_OCSP_SIGNING MBEDTLS_OID_KP "\x09" /**< id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wi-SUN Alliance Field Area Network
|
||||||
|
* { iso(1) identified-organization(3) dod(6) internet(1)
|
||||||
|
* private(4) enterprise(1) WiSUN(45605) FieldAreaNetwork(1) }
|
||||||
|
*/
|
||||||
|
#define MBEDTLS_OID_WISUN_FAN MBEDTLS_OID_INTERNET "\x04\x01\x82\xe4\x25\x01"
|
||||||
|
|
||||||
|
#define MBEDTLS_OID_ON MBEDTLS_OID_PKIX "\x08" /**< id-on OBJECT IDENTIFIER ::= { id-pkix 8 } */
|
||||||
|
#define MBEDTLS_OID_ON_HW_MODULE_NAME MBEDTLS_OID_ON "\x04" /**< id-on-hardwareModuleName OBJECT IDENTIFIER ::= { id-on 4 } */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PKCS definition OIDs
|
* PKCS definition OIDs
|
||||||
*/
|
*/
|
||||||
@@ -230,6 +260,8 @@
|
|||||||
|
|
||||||
#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_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_RIPEMD160 MBEDTLS_OID_TELETRUST "\x03\x02\x01" /**< id-ripemd160 OBJECT IDENTIFIER :: { iso(1) identified-organization(3) teletrust(36) algorithm(3) hashAlgorithm(2) ripemd160(1) } */
|
||||||
|
|
||||||
#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 } */
|
#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 } */
|
||||||
|
|
||||||
#define MBEDTLS_OID_HMAC_SHA224 MBEDTLS_OID_RSA_COMPANY "\x02\x08" /**< id-hmacWithSHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 8 } */
|
#define MBEDTLS_OID_HMAC_SHA224 MBEDTLS_OID_RSA_COMPANY "\x02\x08" /**< id-hmacWithSHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 8 } */
|
||||||
@@ -405,7 +437,8 @@ extern "C" {
|
|||||||
/**
|
/**
|
||||||
* \brief Base OID descriptor structure
|
* \brief Base OID descriptor structure
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_oid_descriptor_t {
|
typedef struct mbedtls_oid_descriptor_t
|
||||||
|
{
|
||||||
const char *asn1; /*!< OID ASN.1 representation */
|
const char *asn1; /*!< OID ASN.1 representation */
|
||||||
size_t asn1_len; /*!< length of asn1 */
|
size_t asn1_len; /*!< length of asn1 */
|
||||||
const char *name; /*!< official name (e.g. from RFC) */
|
const char *name; /*!< official name (e.g. from RFC) */
|
||||||
@@ -423,9 +456,8 @@ typedef struct mbedtls_oid_descriptor_t {
|
|||||||
* \return Length of the string written (excluding final NULL) or
|
* \return Length of the string written (excluding final NULL) or
|
||||||
* MBEDTLS_ERR_OID_BUF_TOO_SMALL in case of error
|
* MBEDTLS_ERR_OID_BUF_TOO_SMALL in case of error
|
||||||
*/
|
*/
|
||||||
int mbedtls_oid_get_numeric_string(char *buf, size_t size, const mbedtls_asn1_buf *oid);
|
int mbedtls_oid_get_numeric_string( char *buf, size_t size, const mbedtls_asn1_buf *oid );
|
||||||
|
|
||||||
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
|
|
||||||
/**
|
/**
|
||||||
* \brief Translate an X.509 extension OID into local values
|
* \brief Translate an X.509 extension OID into local values
|
||||||
*
|
*
|
||||||
@@ -434,8 +466,7 @@ int mbedtls_oid_get_numeric_string(char *buf, size_t size, const mbedtls_asn1_bu
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||||
*/
|
*/
|
||||||
int mbedtls_oid_get_x509_ext_type(const mbedtls_asn1_buf *oid, int *ext_type);
|
int mbedtls_oid_get_x509_ext_type( const mbedtls_asn1_buf *oid, int *ext_type );
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Translate an X.509 attribute type OID into the short name
|
* \brief Translate an X.509 attribute type OID into the short name
|
||||||
@@ -446,7 +477,7 @@ int mbedtls_oid_get_x509_ext_type(const mbedtls_asn1_buf *oid, int *ext_type);
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||||
*/
|
*/
|
||||||
int mbedtls_oid_get_attr_short_name(const mbedtls_asn1_buf *oid, const char **short_name);
|
int mbedtls_oid_get_attr_short_name( const mbedtls_asn1_buf *oid, const char **short_name );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Translate PublicKeyAlgorithm OID into pk_type
|
* \brief Translate PublicKeyAlgorithm OID into pk_type
|
||||||
@@ -456,7 +487,7 @@ int mbedtls_oid_get_attr_short_name(const mbedtls_asn1_buf *oid, const char **sh
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||||
*/
|
*/
|
||||||
int mbedtls_oid_get_pk_alg(const mbedtls_asn1_buf *oid, mbedtls_pk_type_t *pk_alg);
|
int mbedtls_oid_get_pk_alg( const mbedtls_asn1_buf *oid, mbedtls_pk_type_t *pk_alg );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Translate pk_type into PublicKeyAlgorithm OID
|
* \brief Translate pk_type into PublicKeyAlgorithm OID
|
||||||
@@ -467,8 +498,8 @@ int mbedtls_oid_get_pk_alg(const mbedtls_asn1_buf *oid, mbedtls_pk_type_t *pk_al
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||||
*/
|
*/
|
||||||
int mbedtls_oid_get_oid_by_pk_alg(mbedtls_pk_type_t pk_alg,
|
int mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_type_t pk_alg,
|
||||||
const char **oid, size_t *olen);
|
const char **oid, size_t *olen );
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECP_C)
|
#if defined(MBEDTLS_ECP_C)
|
||||||
/**
|
/**
|
||||||
@@ -479,7 +510,7 @@ int mbedtls_oid_get_oid_by_pk_alg(mbedtls_pk_type_t pk_alg,
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||||
*/
|
*/
|
||||||
int mbedtls_oid_get_ec_grp(const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *grp_id);
|
int mbedtls_oid_get_ec_grp( const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *grp_id );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Translate EC group identifier into NamedCurve OID
|
* \brief Translate EC group identifier into NamedCurve OID
|
||||||
@@ -490,8 +521,8 @@ int mbedtls_oid_get_ec_grp(const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *gr
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||||
*/
|
*/
|
||||||
int mbedtls_oid_get_oid_by_ec_grp(mbedtls_ecp_group_id grp_id,
|
int mbedtls_oid_get_oid_by_ec_grp( mbedtls_ecp_group_id grp_id,
|
||||||
const char **oid, size_t *olen);
|
const char **oid, size_t *olen );
|
||||||
#endif /* MBEDTLS_ECP_C */
|
#endif /* MBEDTLS_ECP_C */
|
||||||
|
|
||||||
#if defined(MBEDTLS_MD_C)
|
#if defined(MBEDTLS_MD_C)
|
||||||
@@ -504,8 +535,8 @@ int mbedtls_oid_get_oid_by_ec_grp(mbedtls_ecp_group_id grp_id,
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||||
*/
|
*/
|
||||||
int mbedtls_oid_get_sig_alg(const mbedtls_asn1_buf *oid,
|
int mbedtls_oid_get_sig_alg( const mbedtls_asn1_buf *oid,
|
||||||
mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg);
|
mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Translate SignatureAlgorithm OID into description
|
* \brief Translate SignatureAlgorithm OID into description
|
||||||
@@ -515,7 +546,7 @@ int mbedtls_oid_get_sig_alg(const mbedtls_asn1_buf *oid,
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||||
*/
|
*/
|
||||||
int mbedtls_oid_get_sig_alg_desc(const mbedtls_asn1_buf *oid, const char **desc);
|
int mbedtls_oid_get_sig_alg_desc( const mbedtls_asn1_buf *oid, const char **desc );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Translate md_type and pk_type into SignatureAlgorithm OID
|
* \brief Translate md_type and pk_type into SignatureAlgorithm OID
|
||||||
@@ -527,8 +558,8 @@ int mbedtls_oid_get_sig_alg_desc(const mbedtls_asn1_buf *oid, const char **desc)
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||||
*/
|
*/
|
||||||
int mbedtls_oid_get_oid_by_sig_alg(mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
|
int mbedtls_oid_get_oid_by_sig_alg( mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
|
||||||
const char **oid, size_t *olen);
|
const char **oid, size_t *olen );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Translate hash algorithm OID into md_type
|
* \brief Translate hash algorithm OID into md_type
|
||||||
@@ -538,7 +569,7 @@ int mbedtls_oid_get_oid_by_sig_alg(mbedtls_pk_type_t pk_alg, mbedtls_md_type_t m
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||||
*/
|
*/
|
||||||
int mbedtls_oid_get_md_alg(const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg);
|
int mbedtls_oid_get_md_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Translate hmac algorithm OID into md_type
|
* \brief Translate hmac algorithm OID into md_type
|
||||||
@@ -548,7 +579,7 @@ int mbedtls_oid_get_md_alg(const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_al
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||||
*/
|
*/
|
||||||
int mbedtls_oid_get_md_hmac(const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_hmac);
|
int mbedtls_oid_get_md_hmac( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_hmac );
|
||||||
#endif /* MBEDTLS_MD_C */
|
#endif /* MBEDTLS_MD_C */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -559,7 +590,17 @@ int mbedtls_oid_get_md_hmac(const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_h
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
* \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);
|
int mbedtls_oid_get_extended_key_usage( const mbedtls_asn1_buf *oid, const char **desc );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Translate certificate policies OID into description
|
||||||
|
*
|
||||||
|
* \param oid OID to use
|
||||||
|
* \param desc place to store string pointer
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||||
|
*/
|
||||||
|
int mbedtls_oid_get_certificate_policies( const mbedtls_asn1_buf *oid, const char **desc );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Translate md_type into hash algorithm OID
|
* \brief Translate md_type into hash algorithm OID
|
||||||
@@ -570,7 +611,7 @@ int mbedtls_oid_get_extended_key_usage(const mbedtls_asn1_buf *oid, const char *
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||||
*/
|
*/
|
||||||
int mbedtls_oid_get_oid_by_md(mbedtls_md_type_t md_alg, const char **oid, size_t *olen);
|
int mbedtls_oid_get_oid_by_md( mbedtls_md_type_t md_alg, const char **oid, size_t *olen );
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_C)
|
#if defined(MBEDTLS_CIPHER_C)
|
||||||
/**
|
/**
|
||||||
@@ -581,7 +622,7 @@ int mbedtls_oid_get_oid_by_md(mbedtls_md_type_t md_alg, const char **oid, size_t
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||||
*/
|
*/
|
||||||
int mbedtls_oid_get_cipher_alg(const mbedtls_asn1_buf *oid, mbedtls_cipher_type_t *cipher_alg);
|
int mbedtls_oid_get_cipher_alg( const mbedtls_asn1_buf *oid, mbedtls_cipher_type_t *cipher_alg );
|
||||||
#endif /* MBEDTLS_CIPHER_C */
|
#endif /* MBEDTLS_CIPHER_C */
|
||||||
|
|
||||||
#if defined(MBEDTLS_PKCS12_C)
|
#if defined(MBEDTLS_PKCS12_C)
|
||||||
@@ -595,8 +636,8 @@ int mbedtls_oid_get_cipher_alg(const mbedtls_asn1_buf *oid, mbedtls_cipher_type_
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||||
*/
|
*/
|
||||||
int mbedtls_oid_get_pkcs12_pbe_alg(const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg,
|
int mbedtls_oid_get_pkcs12_pbe_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg,
|
||||||
mbedtls_cipher_type_t *cipher_alg);
|
mbedtls_cipher_type_t *cipher_alg );
|
||||||
#endif /* MBEDTLS_PKCS12_C */
|
#endif /* MBEDTLS_PKCS12_C */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
164
common/mbedtls/padlock.c
Normal file
164
common/mbedtls/padlock.c
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
* VIA PadLock support functions
|
||||||
|
*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* 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 implementation is based on the VIA PadLock Programming Guide:
|
||||||
|
*
|
||||||
|
* http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/
|
||||||
|
* programming_guide.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PADLOCK_C)
|
||||||
|
|
||||||
|
#include "mbedtls/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 1f \n\t"
|
||||||
|
"movl $0xC0000001, %%eax \n\t"
|
||||||
|
"cpuid \n\t"
|
||||||
|
"1: \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 */
|
||||||
124
common/mbedtls/padlock.h
Normal file
124
common/mbedtls/padlock.h
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
/**
|
||||||
|
* \file padlock.h
|
||||||
|
*
|
||||||
|
* \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 The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef MBEDTLS_PADLOCK_H
|
||||||
|
#define MBEDTLS_PADLOCK_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mbedtls/aes.h"
|
||||||
|
|
||||||
|
#define MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED -0x0030 /**< Input data should be aligned. */
|
||||||
|
|
||||||
|
#if defined(__has_feature)
|
||||||
|
#if __has_feature(address_sanitizer)
|
||||||
|
#define MBEDTLS_HAVE_ASAN
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Some versions of ASan result in errors about not enough registers */
|
||||||
|
#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && defined(__i386__) && \
|
||||||
|
!defined(MBEDTLS_HAVE_ASAN)
|
||||||
|
|
||||||
|
#ifndef MBEDTLS_HAVE_X86
|
||||||
|
#define MBEDTLS_HAVE_X86
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define MBEDTLS_PADLOCK_RNG 0x000C
|
||||||
|
#define MBEDTLS_PADLOCK_ACE 0x00C0
|
||||||
|
#define MBEDTLS_PADLOCK_PHE 0x0C00
|
||||||
|
#define MBEDTLS_PADLOCK_PMM 0x3000
|
||||||
|
|
||||||
|
#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.
|
||||||
|
*
|
||||||
|
* \param feature The feature to detect
|
||||||
|
*
|
||||||
|
* \return 1 if CPU has support for the feature, 0 otherwise
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* \param ctx AES context
|
||||||
|
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
|
||||||
|
* \param input 16-byte input block
|
||||||
|
* \param output 16-byte output block
|
||||||
|
*
|
||||||
|
* \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] );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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.
|
||||||
|
*
|
||||||
|
* \param ctx AES context
|
||||||
|
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
|
||||||
|
* \param length length of the input data
|
||||||
|
* \param iv initialization vector (updated after use)
|
||||||
|
* \param input buffer holding the input data
|
||||||
|
* \param output buffer holding the output data
|
||||||
|
*
|
||||||
|
* \return 0 if 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 );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAVE_X86 */
|
||||||
|
|
||||||
|
#endif /* padlock.h */
|
||||||
@@ -1,31 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* Privacy Enhanced Mail (PEM) decoding
|
* Privacy Enhanced Mail (PEM) decoding
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#include "common.h"
|
||||||
#include "mbedtls/config.h"
|
|
||||||
#else
|
|
||||||
#include MBEDTLS_CONFIG_FILE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
|
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
|
||||||
|
|
||||||
@@ -36,6 +28,7 @@
|
|||||||
#include "mbedtls/md5.h"
|
#include "mbedtls/md5.h"
|
||||||
#include "mbedtls/cipher.h"
|
#include "mbedtls/cipher.h"
|
||||||
#include "mbedtls/platform_util.h"
|
#include "mbedtls/platform_util.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -48,8 +41,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||||
void mbedtls_pem_init(mbedtls_pem_context *ctx) {
|
void mbedtls_pem_init( mbedtls_pem_context *ctx )
|
||||||
memset(ctx, 0, sizeof(mbedtls_pem_context));
|
{
|
||||||
|
memset( ctx, 0, sizeof( mbedtls_pem_context ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \
|
#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \
|
||||||
@@ -57,136 +51,141 @@ void mbedtls_pem_init(mbedtls_pem_context *ctx) {
|
|||||||
/*
|
/*
|
||||||
* Read a 16-byte hex string and convert it to binary
|
* Read a 16-byte hex string and convert it to binary
|
||||||
*/
|
*/
|
||||||
static int pem_get_iv(const unsigned char *s, unsigned char *iv,
|
static int pem_get_iv( const unsigned char *s, unsigned char *iv,
|
||||||
size_t iv_len) {
|
size_t iv_len )
|
||||||
|
{
|
||||||
size_t i, j, k;
|
size_t i, j, k;
|
||||||
|
|
||||||
memset(iv, 0, iv_len);
|
memset( iv, 0, iv_len );
|
||||||
|
|
||||||
for (i = 0; i < iv_len * 2; i++, s++) {
|
for( i = 0; i < iv_len * 2; i++, s++ )
|
||||||
if (*s >= '0' && *s <= '9') j = *s - '0';
|
{
|
||||||
else if (*s >= 'A' && *s <= 'F') j = *s - '7';
|
if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
|
||||||
else if (*s >= 'a' && *s <= 'f') j = *s - 'W';
|
if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
|
||||||
else
|
if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
|
||||||
return (MBEDTLS_ERR_PEM_INVALID_ENC_IV);
|
return( MBEDTLS_ERR_PEM_INVALID_ENC_IV );
|
||||||
|
|
||||||
k = ((i & 1) != 0) ? j : j << 4;
|
k = ( ( i & 1 ) != 0 ) ? j : j << 4;
|
||||||
|
|
||||||
iv[i >> 1] = (unsigned char)(iv[i >> 1] | k);
|
iv[i >> 1] = (unsigned char)( iv[i >> 1] | k );
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pem_pbkdf1(unsigned char *key, size_t keylen,
|
static int pem_pbkdf1( unsigned char *key, size_t keylen,
|
||||||
unsigned char *iv,
|
unsigned char *iv,
|
||||||
const unsigned char *pwd, size_t pwdlen) {
|
const unsigned char *pwd, size_t pwdlen )
|
||||||
|
{
|
||||||
mbedtls_md5_context md5_ctx;
|
mbedtls_md5_context md5_ctx;
|
||||||
unsigned char md5sum[16];
|
unsigned char md5sum[16];
|
||||||
size_t use_len;
|
size_t use_len;
|
||||||
int ret;
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
mbedtls_md5_init(&md5_ctx);
|
mbedtls_md5_init( &md5_ctx );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* key[ 0..15] = MD5(pwd || IV)
|
* key[ 0..15] = MD5(pwd || IV)
|
||||||
*/
|
*/
|
||||||
if ((ret = mbedtls_md5_starts_ret(&md5_ctx)) != 0)
|
if( ( ret = mbedtls_md5_starts_ret( &md5_ctx ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
if ((ret = mbedtls_md5_update_ret(&md5_ctx, pwd, pwdlen)) != 0)
|
if( ( ret = mbedtls_md5_update_ret( &md5_ctx, pwd, pwdlen ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
if ((ret = mbedtls_md5_update_ret(&md5_ctx, iv, 8)) != 0)
|
if( ( ret = mbedtls_md5_update_ret( &md5_ctx, iv, 8 ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
if ((ret = mbedtls_md5_finish_ret(&md5_ctx, md5sum)) != 0)
|
if( ( ret = mbedtls_md5_finish_ret( &md5_ctx, md5sum ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (keylen <= 16) {
|
if( keylen <= 16 )
|
||||||
memcpy(key, md5sum, keylen);
|
{
|
||||||
|
memcpy( key, md5sum, keylen );
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(key, md5sum, 16);
|
memcpy( key, md5sum, 16 );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* key[16..23] = MD5(key[ 0..15] || pwd || IV])
|
* key[16..23] = MD5(key[ 0..15] || pwd || IV])
|
||||||
*/
|
*/
|
||||||
if ((ret = mbedtls_md5_starts_ret(&md5_ctx)) != 0)
|
if( ( ret = mbedtls_md5_starts_ret( &md5_ctx ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
if ((ret = mbedtls_md5_update_ret(&md5_ctx, md5sum, 16)) != 0)
|
if( ( ret = mbedtls_md5_update_ret( &md5_ctx, md5sum, 16 ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
if ((ret = mbedtls_md5_update_ret(&md5_ctx, pwd, pwdlen)) != 0)
|
if( ( ret = mbedtls_md5_update_ret( &md5_ctx, pwd, pwdlen ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
if ((ret = mbedtls_md5_update_ret(&md5_ctx, iv, 8)) != 0)
|
if( ( ret = mbedtls_md5_update_ret( &md5_ctx, iv, 8 ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
if ((ret = mbedtls_md5_finish_ret(&md5_ctx, md5sum)) != 0)
|
if( ( ret = mbedtls_md5_finish_ret( &md5_ctx, md5sum ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
use_len = 16;
|
use_len = 16;
|
||||||
if (keylen < 32)
|
if( keylen < 32 )
|
||||||
use_len = keylen - 16;
|
use_len = keylen - 16;
|
||||||
|
|
||||||
memcpy(key + 16, md5sum, use_len);
|
memcpy( key + 16, md5sum, use_len );
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
mbedtls_md5_free(&md5_ctx);
|
mbedtls_md5_free( &md5_ctx );
|
||||||
mbedtls_platform_zeroize(md5sum, 16);
|
mbedtls_platform_zeroize( md5sum, 16 );
|
||||||
|
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MBEDTLS_DES_C)
|
#if defined(MBEDTLS_DES_C)
|
||||||
/*
|
/*
|
||||||
* Decrypt with DES-CBC, using PBKDF1 for key derivation
|
* Decrypt with DES-CBC, using PBKDF1 for key derivation
|
||||||
*/
|
*/
|
||||||
static int pem_des_decrypt(unsigned char des_iv[8],
|
static int pem_des_decrypt( unsigned char des_iv[8],
|
||||||
unsigned char *buf, size_t buflen,
|
unsigned char *buf, size_t buflen,
|
||||||
const unsigned char *pwd, size_t pwdlen) {
|
const unsigned char *pwd, size_t pwdlen )
|
||||||
|
{
|
||||||
mbedtls_des_context des_ctx;
|
mbedtls_des_context des_ctx;
|
||||||
unsigned char des_key[8];
|
unsigned char des_key[8];
|
||||||
int ret;
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
mbedtls_des_init(&des_ctx);
|
mbedtls_des_init( &des_ctx );
|
||||||
|
|
||||||
if ((ret = pem_pbkdf1(des_key, 8, des_iv, pwd, pwdlen)) != 0)
|
if( ( ret = pem_pbkdf1( des_key, 8, des_iv, pwd, pwdlen ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if ((ret = mbedtls_des_setkey_dec(&des_ctx, des_key)) != 0)
|
if( ( ret = mbedtls_des_setkey_dec( &des_ctx, des_key ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
ret = mbedtls_des_crypt_cbc(&des_ctx, MBEDTLS_DES_DECRYPT, buflen,
|
ret = mbedtls_des_crypt_cbc( &des_ctx, MBEDTLS_DES_DECRYPT, buflen,
|
||||||
des_iv, buf, buf);
|
des_iv, buf, buf );
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
mbedtls_des_free(&des_ctx);
|
mbedtls_des_free( &des_ctx );
|
||||||
mbedtls_platform_zeroize(des_key, 8);
|
mbedtls_platform_zeroize( des_key, 8 );
|
||||||
|
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decrypt with 3DES-CBC, using PBKDF1 for key derivation
|
* Decrypt with 3DES-CBC, using PBKDF1 for key derivation
|
||||||
*/
|
*/
|
||||||
static int pem_des3_decrypt(unsigned char des3_iv[8],
|
static int pem_des3_decrypt( unsigned char des3_iv[8],
|
||||||
unsigned char *buf, size_t buflen,
|
unsigned char *buf, size_t buflen,
|
||||||
const unsigned char *pwd, size_t pwdlen) {
|
const unsigned char *pwd, size_t pwdlen )
|
||||||
|
{
|
||||||
mbedtls_des3_context des3_ctx;
|
mbedtls_des3_context des3_ctx;
|
||||||
unsigned char des3_key[24];
|
unsigned char des3_key[24];
|
||||||
int ret;
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
mbedtls_des3_init(&des3_ctx);
|
mbedtls_des3_init( &des3_ctx );
|
||||||
|
|
||||||
if ((ret = pem_pbkdf1(des3_key, 24, des3_iv, pwd, pwdlen)) != 0)
|
if( ( ret = pem_pbkdf1( des3_key, 24, des3_iv, pwd, pwdlen ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if ((ret = mbedtls_des3_set3key_dec(&des3_ctx, des3_key)) != 0)
|
if( ( ret = mbedtls_des3_set3key_dec( &des3_ctx, des3_key ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
ret = mbedtls_des3_crypt_cbc(&des3_ctx, MBEDTLS_DES_DECRYPT, buflen,
|
ret = mbedtls_des3_crypt_cbc( &des3_ctx, MBEDTLS_DES_DECRYPT, buflen,
|
||||||
des3_iv, buf, buf);
|
des3_iv, buf, buf );
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
mbedtls_des3_free(&des3_ctx);
|
mbedtls_des3_free( &des3_ctx );
|
||||||
mbedtls_platform_zeroize(des3_key, 24);
|
mbedtls_platform_zeroize( des3_key, 24 );
|
||||||
|
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_DES_C */
|
#endif /* MBEDTLS_DES_C */
|
||||||
|
|
||||||
@@ -194,37 +193,39 @@ exit:
|
|||||||
/*
|
/*
|
||||||
* Decrypt with AES-XXX-CBC, using PBKDF1 for key derivation
|
* Decrypt with AES-XXX-CBC, using PBKDF1 for key derivation
|
||||||
*/
|
*/
|
||||||
static int pem_aes_decrypt(unsigned char aes_iv[16], unsigned int keylen,
|
static int pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen,
|
||||||
unsigned char *buf, size_t buflen,
|
unsigned char *buf, size_t buflen,
|
||||||
const unsigned char *pwd, size_t pwdlen) {
|
const unsigned char *pwd, size_t pwdlen )
|
||||||
|
{
|
||||||
mbedtls_aes_context aes_ctx;
|
mbedtls_aes_context aes_ctx;
|
||||||
unsigned char aes_key[32];
|
unsigned char aes_key[32];
|
||||||
int ret;
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
mbedtls_aes_init(&aes_ctx);
|
mbedtls_aes_init( &aes_ctx );
|
||||||
|
|
||||||
if ((ret = pem_pbkdf1(aes_key, keylen, aes_iv, pwd, pwdlen)) != 0)
|
if( ( ret = pem_pbkdf1( aes_key, keylen, aes_iv, pwd, pwdlen ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if ((ret = mbedtls_aes_setkey_dec(&aes_ctx, aes_key, keylen * 8)) != 0)
|
if( ( ret = mbedtls_aes_setkey_dec( &aes_ctx, aes_key, keylen * 8 ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
ret = mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_DECRYPT, buflen,
|
ret = mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_DECRYPT, buflen,
|
||||||
aes_iv, buf, buf);
|
aes_iv, buf, buf );
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
mbedtls_aes_free(&aes_ctx);
|
mbedtls_aes_free( &aes_ctx );
|
||||||
mbedtls_platform_zeroize(aes_key, keylen);
|
mbedtls_platform_zeroize( aes_key, keylen );
|
||||||
|
|
||||||
return (ret);
|
return( ret );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_AES_C */
|
#endif /* MBEDTLS_AES_C */
|
||||||
|
|
||||||
#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
|
#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
|
||||||
( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
|
( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
|
||||||
|
|
||||||
int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const char *footer,
|
int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const char *footer,
|
||||||
const unsigned char *data, const unsigned char *pwd,
|
const unsigned char *data, const unsigned char *pwd,
|
||||||
size_t pwdlen, size_t *use_len) {
|
size_t pwdlen, size_t *use_len )
|
||||||
|
{
|
||||||
int ret, enc;
|
int ret, enc;
|
||||||
size_t len;
|
size_t len;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
@@ -239,145 +240,154 @@ int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const
|
|||||||
#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
|
#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
|
||||||
( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
|
( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
|
||||||
|
|
||||||
if (ctx == NULL)
|
if( ctx == NULL )
|
||||||
return (MBEDTLS_ERR_PEM_BAD_INPUT_DATA);
|
return( MBEDTLS_ERR_PEM_BAD_INPUT_DATA );
|
||||||
|
|
||||||
s1 = (unsigned char *) strstr((const char *) data, header);
|
s1 = (unsigned char *) strstr( (const char *) data, header );
|
||||||
|
|
||||||
if (s1 == NULL)
|
if( s1 == NULL )
|
||||||
return (MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT);
|
return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT );
|
||||||
|
|
||||||
s2 = (unsigned char *) strstr((const char *) data, footer);
|
s2 = (unsigned char *) strstr( (const char *) data, footer );
|
||||||
|
|
||||||
if (s2 == NULL || s2 <= s1)
|
if( s2 == NULL || s2 <= s1 )
|
||||||
return (MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT);
|
return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT );
|
||||||
|
|
||||||
s1 += strlen(header);
|
s1 += strlen( header );
|
||||||
if (*s1 == ' ') s1++;
|
if( *s1 == ' ' ) s1++;
|
||||||
if (*s1 == '\r') s1++;
|
if( *s1 == '\r' ) s1++;
|
||||||
if (*s1 == '\n') s1++;
|
if( *s1 == '\n' ) s1++;
|
||||||
else return (MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT);
|
else return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT );
|
||||||
|
|
||||||
end = s2;
|
end = s2;
|
||||||
end += strlen(footer);
|
end += strlen( footer );
|
||||||
if (*end == ' ') end++;
|
if( *end == ' ' ) end++;
|
||||||
if (*end == '\r') end++;
|
if( *end == '\r' ) end++;
|
||||||
if (*end == '\n') end++;
|
if( *end == '\n' ) end++;
|
||||||
*use_len = end - data;
|
*use_len = end - data;
|
||||||
|
|
||||||
enc = 0;
|
enc = 0;
|
||||||
|
|
||||||
if (s2 - s1 >= 22 && memcmp(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) && \
|
#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \
|
||||||
( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
|
( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
|
||||||
enc++;
|
enc++;
|
||||||
|
|
||||||
s1 += 22;
|
s1 += 22;
|
||||||
if (*s1 == '\r') s1++;
|
if( *s1 == '\r' ) s1++;
|
||||||
if (*s1 == '\n') s1++;
|
if( *s1 == '\n' ) s1++;
|
||||||
else return (MBEDTLS_ERR_PEM_INVALID_DATA);
|
else return( MBEDTLS_ERR_PEM_INVALID_DATA );
|
||||||
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_DES_C)
|
#if defined(MBEDTLS_DES_C)
|
||||||
if (s2 - s1 >= 23 && memcmp(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;
|
enc_alg = MBEDTLS_CIPHER_DES_EDE3_CBC;
|
||||||
|
|
||||||
s1 += 23;
|
s1 += 23;
|
||||||
if (s2 - s1 < 16 || pem_get_iv(s1, pem_iv, 8) != 0)
|
if( s2 - s1 < 16 || pem_get_iv( s1, pem_iv, 8 ) != 0 )
|
||||||
return (MBEDTLS_ERR_PEM_INVALID_ENC_IV);
|
return( MBEDTLS_ERR_PEM_INVALID_ENC_IV );
|
||||||
|
|
||||||
s1 += 16;
|
s1 += 16;
|
||||||
} else if (s2 - s1 >= 18 && memcmp(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;
|
enc_alg = MBEDTLS_CIPHER_DES_CBC;
|
||||||
|
|
||||||
s1 += 18;
|
s1 += 18;
|
||||||
if (s2 - s1 < 16 || pem_get_iv(s1, pem_iv, 8) != 0)
|
if( s2 - s1 < 16 || pem_get_iv( s1, pem_iv, 8) != 0 )
|
||||||
return (MBEDTLS_ERR_PEM_INVALID_ENC_IV);
|
return( MBEDTLS_ERR_PEM_INVALID_ENC_IV );
|
||||||
|
|
||||||
s1 += 16;
|
s1 += 16;
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_DES_C */
|
#endif /* MBEDTLS_DES_C */
|
||||||
|
|
||||||
#if defined(MBEDTLS_AES_C)
|
#if defined(MBEDTLS_AES_C)
|
||||||
if (s2 - s1 >= 14 && memcmp(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);
|
if( s2 - s1 < 22 )
|
||||||
else if (memcmp(s1, "DEK-Info: AES-128-CBC,", 22) == 0)
|
return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG );
|
||||||
|
else if( memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 )
|
||||||
enc_alg = MBEDTLS_CIPHER_AES_128_CBC;
|
enc_alg = MBEDTLS_CIPHER_AES_128_CBC;
|
||||||
else if (memcmp(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;
|
enc_alg = MBEDTLS_CIPHER_AES_192_CBC;
|
||||||
else if (memcmp(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;
|
enc_alg = MBEDTLS_CIPHER_AES_256_CBC;
|
||||||
else
|
else
|
||||||
return (MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG);
|
return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG );
|
||||||
|
|
||||||
s1 += 22;
|
s1 += 22;
|
||||||
if (s2 - s1 < 32 || pem_get_iv(s1, pem_iv, 16) != 0)
|
if( s2 - s1 < 32 || pem_get_iv( s1, pem_iv, 16 ) != 0 )
|
||||||
return (MBEDTLS_ERR_PEM_INVALID_ENC_IV);
|
return( MBEDTLS_ERR_PEM_INVALID_ENC_IV );
|
||||||
|
|
||||||
s1 += 32;
|
s1 += 32;
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_AES_C */
|
#endif /* MBEDTLS_AES_C */
|
||||||
|
|
||||||
if (enc_alg == MBEDTLS_CIPHER_NONE)
|
if( enc_alg == MBEDTLS_CIPHER_NONE )
|
||||||
return (MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG);
|
return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG );
|
||||||
|
|
||||||
if (*s1 == '\r') s1++;
|
if( *s1 == '\r' ) s1++;
|
||||||
if (*s1 == '\n') s1++;
|
if( *s1 == '\n' ) s1++;
|
||||||
else return (MBEDTLS_ERR_PEM_INVALID_DATA);
|
else return( MBEDTLS_ERR_PEM_INVALID_DATA );
|
||||||
#else
|
#else
|
||||||
return (MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE);
|
return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE );
|
||||||
#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
|
#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
|
||||||
( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
|
( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s1 >= s2)
|
if( s1 >= s2 )
|
||||||
return (MBEDTLS_ERR_PEM_INVALID_DATA);
|
return( MBEDTLS_ERR_PEM_INVALID_DATA );
|
||||||
|
|
||||||
ret = mbedtls_base64_decode(NULL, 0, &len, s1, s2 - s1);
|
ret = mbedtls_base64_decode( NULL, 0, &len, s1, s2 - s1 );
|
||||||
|
|
||||||
if (ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER)
|
if( ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER )
|
||||||
return (MBEDTLS_ERR_PEM_INVALID_DATA + ret);
|
return( MBEDTLS_ERR_PEM_INVALID_DATA + ret );
|
||||||
|
|
||||||
if ((buf = mbedtls_calloc(1, len)) == NULL)
|
if( ( buf = mbedtls_calloc( 1, len ) ) == NULL )
|
||||||
return (MBEDTLS_ERR_PEM_ALLOC_FAILED);
|
return( MBEDTLS_ERR_PEM_ALLOC_FAILED );
|
||||||
|
|
||||||
if ((ret = mbedtls_base64_decode(buf, len, &len, s1, s2 - s1)) != 0) {
|
if( ( ret = mbedtls_base64_decode( buf, len, &len, s1, s2 - s1 ) ) != 0 )
|
||||||
mbedtls_platform_zeroize(buf, len);
|
{
|
||||||
mbedtls_free(buf);
|
mbedtls_platform_zeroize( buf, len );
|
||||||
return (MBEDTLS_ERR_PEM_INVALID_DATA + ret);
|
mbedtls_free( buf );
|
||||||
|
return( MBEDTLS_ERR_PEM_INVALID_DATA + ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enc != 0) {
|
if( enc != 0 )
|
||||||
|
{
|
||||||
#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \
|
#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \
|
||||||
( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
|
( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
|
||||||
if (pwd == NULL) {
|
if( pwd == NULL )
|
||||||
mbedtls_platform_zeroize(buf, len);
|
{
|
||||||
mbedtls_free(buf);
|
mbedtls_platform_zeroize( buf, len );
|
||||||
return (MBEDTLS_ERR_PEM_PASSWORD_REQUIRED);
|
mbedtls_free( buf );
|
||||||
|
return( MBEDTLS_ERR_PEM_PASSWORD_REQUIRED );
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
#if defined(MBEDTLS_DES_C)
|
#if defined(MBEDTLS_DES_C)
|
||||||
if (enc_alg == MBEDTLS_CIPHER_DES_EDE3_CBC)
|
if( enc_alg == MBEDTLS_CIPHER_DES_EDE3_CBC )
|
||||||
ret = pem_des3_decrypt(pem_iv, buf, len, pwd, pwdlen);
|
ret = pem_des3_decrypt( pem_iv, buf, len, pwd, pwdlen );
|
||||||
else if (enc_alg == MBEDTLS_CIPHER_DES_CBC)
|
else if( enc_alg == MBEDTLS_CIPHER_DES_CBC )
|
||||||
ret = pem_des_decrypt(pem_iv, buf, len, pwd, pwdlen);
|
ret = pem_des_decrypt( pem_iv, buf, len, pwd, pwdlen );
|
||||||
#endif /* MBEDTLS_DES_C */
|
#endif /* MBEDTLS_DES_C */
|
||||||
|
|
||||||
#if defined(MBEDTLS_AES_C)
|
#if defined(MBEDTLS_AES_C)
|
||||||
if (enc_alg == MBEDTLS_CIPHER_AES_128_CBC)
|
if( enc_alg == MBEDTLS_CIPHER_AES_128_CBC )
|
||||||
ret = pem_aes_decrypt(pem_iv, 16, buf, len, pwd, pwdlen);
|
ret = pem_aes_decrypt( pem_iv, 16, buf, len, pwd, pwdlen );
|
||||||
else if (enc_alg == MBEDTLS_CIPHER_AES_192_CBC)
|
else if( enc_alg == MBEDTLS_CIPHER_AES_192_CBC )
|
||||||
ret = pem_aes_decrypt(pem_iv, 24, buf, len, pwd, pwdlen);
|
ret = pem_aes_decrypt( pem_iv, 24, buf, len, pwd, pwdlen );
|
||||||
else if (enc_alg == MBEDTLS_CIPHER_AES_256_CBC)
|
else if( enc_alg == MBEDTLS_CIPHER_AES_256_CBC )
|
||||||
ret = pem_aes_decrypt(pem_iv, 32, buf, len, pwd, pwdlen);
|
ret = pem_aes_decrypt( pem_iv, 32, buf, len, pwd, pwdlen );
|
||||||
#endif /* MBEDTLS_AES_C */
|
#endif /* MBEDTLS_AES_C */
|
||||||
|
|
||||||
if (ret != 0) {
|
if( ret != 0 )
|
||||||
mbedtls_free(buf);
|
{
|
||||||
return (ret);
|
mbedtls_free( buf );
|
||||||
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -386,15 +396,16 @@ int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const
|
|||||||
*
|
*
|
||||||
* Use that as a heuristic to try to detect password mismatches.
|
* Use that as a heuristic to try to detect password mismatches.
|
||||||
*/
|
*/
|
||||||
if (len <= 2 || buf[0] != 0x30 || buf[1] > 0x83) {
|
if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 )
|
||||||
mbedtls_platform_zeroize(buf, len);
|
{
|
||||||
mbedtls_free(buf);
|
mbedtls_platform_zeroize( buf, len );
|
||||||
return (MBEDTLS_ERR_PEM_PASSWORD_MISMATCH);
|
mbedtls_free( buf );
|
||||||
|
return( MBEDTLS_ERR_PEM_PASSWORD_MISMATCH );
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
mbedtls_platform_zeroize(buf, len);
|
mbedtls_platform_zeroize( buf, len );
|
||||||
mbedtls_free(buf);
|
mbedtls_free( buf );
|
||||||
return (MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE);
|
return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE );
|
||||||
#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
|
#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
|
||||||
( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
|
( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
|
||||||
}
|
}
|
||||||
@@ -402,66 +413,77 @@ int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const
|
|||||||
ctx->buf = buf;
|
ctx->buf = buf;
|
||||||
ctx->buflen = len;
|
ctx->buflen = len;
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void mbedtls_pem_free(mbedtls_pem_context *ctx) {
|
void mbedtls_pem_free( mbedtls_pem_context *ctx )
|
||||||
if (ctx->buf != NULL)
|
{
|
||||||
mbedtls_platform_zeroize(ctx->buf, ctx->buflen);
|
if ( ctx->buf != NULL )
|
||||||
mbedtls_free(ctx->buf);
|
{
|
||||||
mbedtls_free(ctx->info);
|
mbedtls_platform_zeroize( ctx->buf, ctx->buflen );
|
||||||
|
mbedtls_free( ctx->buf );
|
||||||
|
}
|
||||||
|
mbedtls_free( ctx->info );
|
||||||
|
|
||||||
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pem_context));
|
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pem_context ) );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_PEM_PARSE_C */
|
#endif /* MBEDTLS_PEM_PARSE_C */
|
||||||
|
|
||||||
#if defined(MBEDTLS_PEM_WRITE_C)
|
#if defined(MBEDTLS_PEM_WRITE_C)
|
||||||
int mbedtls_pem_write_buffer(const char *header, const char *footer,
|
int mbedtls_pem_write_buffer( const char *header, const char *footer,
|
||||||
const unsigned char *der_data, size_t der_len,
|
const unsigned char *der_data, size_t der_len,
|
||||||
unsigned char *buf, size_t buf_len, size_t *olen) {
|
unsigned char *buf, size_t buf_len, size_t *olen )
|
||||||
int ret;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
unsigned char *encode_buf = NULL, *c, *p = buf;
|
unsigned char *encode_buf = NULL, *c, *p = buf;
|
||||||
size_t len = 0, use_len, add_len = 0;
|
size_t len = 0, use_len, add_len = 0;
|
||||||
|
|
||||||
mbedtls_base64_encode(NULL, 0, &use_len, der_data, der_len);
|
mbedtls_base64_encode( NULL, 0, &use_len, der_data, der_len );
|
||||||
add_len = strlen(header) + strlen(footer) + (use_len / 64) + 1;
|
add_len = strlen( header ) + strlen( footer ) + ( use_len / 64 ) + 1;
|
||||||
|
|
||||||
if (use_len + add_len > buf_len) {
|
if( use_len + add_len > buf_len )
|
||||||
|
{
|
||||||
*olen = use_len + add_len;
|
*olen = use_len + add_len;
|
||||||
return (MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL);
|
return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_len != 0 &&
|
if( use_len != 0 &&
|
||||||
((encode_buf = mbedtls_calloc(1, use_len)) == NULL))
|
( ( encode_buf = mbedtls_calloc( 1, use_len ) ) == NULL ) )
|
||||||
return (MBEDTLS_ERR_PEM_ALLOC_FAILED);
|
return( MBEDTLS_ERR_PEM_ALLOC_FAILED );
|
||||||
|
|
||||||
if ((ret = mbedtls_base64_encode(encode_buf, use_len, &use_len, der_data,
|
if( ( ret = mbedtls_base64_encode( encode_buf, use_len, &use_len, der_data,
|
||||||
der_len)) != 0) {
|
der_len ) ) != 0 )
|
||||||
mbedtls_free(encode_buf);
|
{
|
||||||
return (ret);
|
mbedtls_free( encode_buf );
|
||||||
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(p, header, strlen(header));
|
memcpy( p, header, strlen( header ) );
|
||||||
p += strlen(header);
|
p += strlen( header );
|
||||||
c = encode_buf;
|
c = encode_buf;
|
||||||
|
|
||||||
while (use_len) {
|
while( use_len )
|
||||||
len = (use_len > 64) ? 64 : use_len;
|
{
|
||||||
memcpy(p, c, len);
|
len = ( use_len > 64 ) ? 64 : use_len;
|
||||||
|
memcpy( p, c, len );
|
||||||
use_len -= len;
|
use_len -= len;
|
||||||
p += len;
|
p += len;
|
||||||
c += len;
|
c += len;
|
||||||
*p++ = '\n';
|
*p++ = '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(p, footer, strlen(footer));
|
memcpy( p, footer, strlen( footer ) );
|
||||||
p += strlen(footer);
|
p += strlen( footer );
|
||||||
|
|
||||||
*p++ = '\0';
|
*p++ = '\0';
|
||||||
*olen = p - buf;
|
*olen = p - buf;
|
||||||
|
|
||||||
mbedtls_free(encode_buf);
|
/* Clean any remaining data previously written to the buffer */
|
||||||
return (0);
|
memset( buf + *olen, 0, buf_len - *olen );
|
||||||
|
|
||||||
|
mbedtls_free( encode_buf );
|
||||||
|
return( 0 );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_PEM_WRITE_C */
|
#endif /* MBEDTLS_PEM_WRITE_C */
|
||||||
#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */
|
#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */
|
||||||
|
|
||||||
|
|||||||
@@ -4,28 +4,30 @@
|
|||||||
* \brief Privacy Enhanced Mail (PEM) decoding
|
* \brief Privacy Enhanced Mail (PEM) decoding
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef MBEDTLS_PEM_H
|
#ifndef MBEDTLS_PEM_H
|
||||||
#define MBEDTLS_PEM_H
|
#define MBEDTLS_PEM_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,7 +55,8 @@ extern "C" {
|
|||||||
/**
|
/**
|
||||||
* \brief PEM context structure
|
* \brief PEM context structure
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_pem_context {
|
typedef struct mbedtls_pem_context
|
||||||
|
{
|
||||||
unsigned char *buf; /*!< buffer for decoded data */
|
unsigned char *buf; /*!< buffer for decoded data */
|
||||||
size_t buflen; /*!< length of the buffer */
|
size_t buflen; /*!< length of the buffer */
|
||||||
unsigned char *info; /*!< buffer for extra header information */
|
unsigned char *info; /*!< buffer for extra header information */
|
||||||
@@ -65,7 +68,7 @@ mbedtls_pem_context;
|
|||||||
*
|
*
|
||||||
* \param ctx context to be initialized
|
* \param ctx context to be initialized
|
||||||
*/
|
*/
|
||||||
void mbedtls_pem_init(mbedtls_pem_context *ctx);
|
void mbedtls_pem_init( mbedtls_pem_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Read a buffer for PEM information and store the resulting
|
* \brief Read a buffer for PEM information and store the resulting
|
||||||
@@ -89,17 +92,17 @@ void mbedtls_pem_init(mbedtls_pem_context *ctx);
|
|||||||
*
|
*
|
||||||
* \return 0 on success, or a specific PEM error code
|
* \return 0 on success, or a specific PEM error code
|
||||||
*/
|
*/
|
||||||
int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const char *footer,
|
int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const char *footer,
|
||||||
const unsigned char *data,
|
const unsigned char *data,
|
||||||
const unsigned char *pwd,
|
const unsigned char *pwd,
|
||||||
size_t pwdlen, size_t *use_len);
|
size_t pwdlen, size_t *use_len );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief PEM context memory freeing
|
* \brief PEM context memory freeing
|
||||||
*
|
*
|
||||||
* \param ctx context to be freed
|
* \param ctx context to be freed
|
||||||
*/
|
*/
|
||||||
void mbedtls_pem_free(mbedtls_pem_context *ctx);
|
void mbedtls_pem_free( mbedtls_pem_context *ctx );
|
||||||
#endif /* MBEDTLS_PEM_PARSE_C */
|
#endif /* MBEDTLS_PEM_PARSE_C */
|
||||||
|
|
||||||
#if defined(MBEDTLS_PEM_WRITE_C)
|
#if defined(MBEDTLS_PEM_WRITE_C)
|
||||||
@@ -107,21 +110,31 @@ void mbedtls_pem_free(mbedtls_pem_context *ctx);
|
|||||||
* \brief Write a buffer of PEM information from a DER encoded
|
* \brief Write a buffer of PEM information from a DER encoded
|
||||||
* buffer.
|
* buffer.
|
||||||
*
|
*
|
||||||
* \param header header string to write
|
* \param header The header string to write.
|
||||||
* \param footer footer string to write
|
* \param footer The footer string to write.
|
||||||
* \param der_data DER data to write
|
* \param der_data The DER data to encode.
|
||||||
* \param der_len length of the DER data
|
* \param der_len The length of the DER data \p der_data in Bytes.
|
||||||
* \param buf buffer to write to
|
* \param buf The buffer to write to.
|
||||||
* \param buf_len length of output buffer
|
* \param buf_len The length of the output buffer \p buf in Bytes.
|
||||||
* \param olen total length written / required (if buf_len is not enough)
|
* \param olen The address at which to store the total length written
|
||||||
|
* or required (if \p buf_len is not enough).
|
||||||
*
|
*
|
||||||
* \return 0 on success, or a specific PEM or BASE64 error code. On
|
* \note You may pass \c NULL for \p buf and \c 0 for \p buf_len
|
||||||
* MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL olen is the required
|
* to request the length of the resulting PEM buffer in
|
||||||
* size.
|
* `*olen`.
|
||||||
|
*
|
||||||
|
* \note This function may be called with overlapping \p der_data
|
||||||
|
* and \p buf buffers.
|
||||||
|
*
|
||||||
|
* \return \c 0 on success.
|
||||||
|
* \return #MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL if \p buf isn't large
|
||||||
|
* enough to hold the PEM buffer. In this case, `*olen` holds
|
||||||
|
* the required minimum size of \p buf.
|
||||||
|
* \return Another PEM or BASE64 error code on other kinds of failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_pem_write_buffer(const char *header, const char *footer,
|
int mbedtls_pem_write_buffer( const char *header, const char *footer,
|
||||||
const unsigned char *der_data, size_t der_len,
|
const unsigned char *der_data, size_t der_len,
|
||||||
unsigned char *buf, size_t buf_len, size_t *olen);
|
unsigned char *buf, size_t buf_len, size_t *olen );
|
||||||
#endif /* MBEDTLS_PEM_WRITE_C */
|
#endif /* MBEDTLS_PEM_WRITE_C */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -1,37 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
* Public Key abstraction layer
|
* Public Key abstraction layer
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#include "common.h"
|
||||||
#include "mbedtls/config.h"
|
|
||||||
#else
|
|
||||||
#include MBEDTLS_CONFIG_FILE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_PK_C)
|
#if defined(MBEDTLS_PK_C)
|
||||||
#include "mbedtls/pk.h"
|
#include "mbedtls/pk.h"
|
||||||
#include "mbedtls/pk_internal.h"
|
#include "mbedtls/pk_internal.h"
|
||||||
|
|
||||||
#include "mbedtls/platform_util.h"
|
#include "mbedtls/platform_util.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
#if defined(MBEDTLS_RSA_C)
|
#if defined(MBEDTLS_RSA_C)
|
||||||
#include "mbedtls/rsa.h"
|
#include "mbedtls/rsa.h"
|
||||||
@@ -43,15 +36,25 @@
|
|||||||
#include "mbedtls/ecdsa.h"
|
#include "mbedtls/ecdsa.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||||
|
#include "mbedtls/psa_util.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* Parameter validation macros based on platform_util.h */
|
||||||
|
#define PK_VALIDATE_RET( cond ) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
|
||||||
|
#define PK_VALIDATE( cond ) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialise a mbedtls_pk_context
|
* Initialise a mbedtls_pk_context
|
||||||
*/
|
*/
|
||||||
void mbedtls_pk_init(mbedtls_pk_context *ctx) {
|
void mbedtls_pk_init( mbedtls_pk_context *ctx )
|
||||||
if (ctx == NULL)
|
{
|
||||||
return;
|
PK_VALIDATE( ctx != NULL );
|
||||||
|
|
||||||
ctx->pk_info = NULL;
|
ctx->pk_info = NULL;
|
||||||
ctx->pk_ctx = NULL;
|
ctx->pk_ctx = NULL;
|
||||||
@@ -60,71 +63,143 @@ void mbedtls_pk_init(mbedtls_pk_context *ctx) {
|
|||||||
/*
|
/*
|
||||||
* Free (the components of) a mbedtls_pk_context
|
* Free (the components of) a mbedtls_pk_context
|
||||||
*/
|
*/
|
||||||
void mbedtls_pk_free(mbedtls_pk_context *ctx) {
|
void mbedtls_pk_free( mbedtls_pk_context *ctx )
|
||||||
if (ctx == NULL || ctx->pk_info == NULL)
|
{
|
||||||
|
if( ctx == NULL )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ctx->pk_info->ctx_free_func(ctx->pk_ctx);
|
if ( ctx->pk_info != NULL )
|
||||||
|
ctx->pk_info->ctx_free_func( ctx->pk_ctx );
|
||||||
|
|
||||||
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pk_context));
|
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
/*
|
||||||
|
* Initialize a restart context
|
||||||
|
*/
|
||||||
|
void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx )
|
||||||
|
{
|
||||||
|
PK_VALIDATE( ctx != NULL );
|
||||||
|
ctx->pk_info = NULL;
|
||||||
|
ctx->rs_ctx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free the components of a restart context
|
||||||
|
*/
|
||||||
|
void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx )
|
||||||
|
{
|
||||||
|
if( ctx == NULL || ctx->pk_info == NULL ||
|
||||||
|
ctx->pk_info->rs_free_func == NULL )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->pk_info->rs_free_func( ctx->rs_ctx );
|
||||||
|
|
||||||
|
ctx->pk_info = NULL;
|
||||||
|
ctx->rs_ctx = NULL;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get pk_info structure from type
|
* Get pk_info structure from type
|
||||||
*/
|
*/
|
||||||
const mbedtls_pk_info_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 )
|
||||||
switch (pk_type) {
|
{
|
||||||
|
switch( pk_type ) {
|
||||||
#if defined(MBEDTLS_RSA_C)
|
#if defined(MBEDTLS_RSA_C)
|
||||||
case MBEDTLS_PK_RSA:
|
case MBEDTLS_PK_RSA:
|
||||||
return (&mbedtls_rsa_info);
|
return( &mbedtls_rsa_info );
|
||||||
#endif
|
#endif
|
||||||
#if defined(MBEDTLS_ECP_C)
|
#if defined(MBEDTLS_ECP_C)
|
||||||
case MBEDTLS_PK_ECKEY:
|
case MBEDTLS_PK_ECKEY:
|
||||||
return (&mbedtls_eckey_info);
|
return( &mbedtls_eckey_info );
|
||||||
case MBEDTLS_PK_ECKEY_DH:
|
case MBEDTLS_PK_ECKEY_DH:
|
||||||
return (&mbedtls_eckeydh_info);
|
return( &mbedtls_eckeydh_info );
|
||||||
#endif
|
#endif
|
||||||
#if defined(MBEDTLS_ECDSA_C)
|
#if defined(MBEDTLS_ECDSA_C)
|
||||||
case MBEDTLS_PK_ECDSA:
|
case MBEDTLS_PK_ECDSA:
|
||||||
return (&mbedtls_ecdsa_info);
|
return( &mbedtls_ecdsa_info );
|
||||||
#endif
|
#endif
|
||||||
/* MBEDTLS_PK_RSA_ALT omitted on purpose */
|
/* MBEDTLS_PK_RSA_ALT omitted on purpose */
|
||||||
default:
|
default:
|
||||||
return (NULL);
|
return( NULL );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialise context
|
* Initialise context
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info) {
|
int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
|
||||||
if (ctx == NULL || info == NULL || ctx->pk_info != NULL)
|
{
|
||||||
return (MBEDTLS_ERR_PK_BAD_INPUT_DATA);
|
PK_VALIDATE_RET( ctx != NULL );
|
||||||
|
if( info == NULL || ctx->pk_info != NULL )
|
||||||
|
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||||
|
|
||||||
if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL)
|
if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
|
||||||
return (MBEDTLS_ERR_PK_ALLOC_FAILED);
|
return( MBEDTLS_ERR_PK_ALLOC_FAILED );
|
||||||
|
|
||||||
ctx->pk_info = info;
|
ctx->pk_info = info;
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||||
|
/*
|
||||||
|
* Initialise a PSA-wrapping context
|
||||||
|
*/
|
||||||
|
int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx,
|
||||||
|
const psa_key_id_t key )
|
||||||
|
{
|
||||||
|
const mbedtls_pk_info_t * const info = &mbedtls_pk_opaque_info;
|
||||||
|
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||||
|
psa_key_id_t *pk_ctx;
|
||||||
|
psa_key_type_t type;
|
||||||
|
|
||||||
|
if( ctx == NULL || ctx->pk_info != NULL )
|
||||||
|
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
if( PSA_SUCCESS != psa_get_key_attributes( key, &attributes ) )
|
||||||
|
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||||
|
type = psa_get_key_type( &attributes );
|
||||||
|
psa_reset_key_attributes( &attributes );
|
||||||
|
|
||||||
|
/* Current implementation of can_do() relies on this. */
|
||||||
|
if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
|
||||||
|
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) ;
|
||||||
|
|
||||||
|
if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
|
||||||
|
return( MBEDTLS_ERR_PK_ALLOC_FAILED );
|
||||||
|
|
||||||
|
ctx->pk_info = info;
|
||||||
|
|
||||||
|
pk_ctx = (psa_key_id_t *) ctx->pk_ctx;
|
||||||
|
*pk_ctx = key;
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||||
|
|
||||||
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
|
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
|
||||||
/*
|
/*
|
||||||
* Initialize an RSA-alt context
|
* Initialize an RSA-alt context
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_setup_rsa_alt(mbedtls_pk_context *ctx, void *key,
|
int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
|
||||||
mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
|
mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
|
||||||
mbedtls_pk_rsa_alt_sign_func sign_func,
|
mbedtls_pk_rsa_alt_sign_func sign_func,
|
||||||
mbedtls_pk_rsa_alt_key_len_func key_len_func) {
|
mbedtls_pk_rsa_alt_key_len_func key_len_func )
|
||||||
|
{
|
||||||
mbedtls_rsa_alt_context *rsa_alt;
|
mbedtls_rsa_alt_context *rsa_alt;
|
||||||
const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
|
const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
|
||||||
|
|
||||||
if (ctx == NULL || ctx->pk_info != NULL)
|
PK_VALIDATE_RET( ctx != NULL );
|
||||||
return (MBEDTLS_ERR_PK_BAD_INPUT_DATA);
|
if( ctx->pk_info != NULL )
|
||||||
|
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||||
|
|
||||||
if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL)
|
if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
|
||||||
return (MBEDTLS_ERR_PK_ALLOC_FAILED);
|
return( MBEDTLS_ERR_PK_ALLOC_FAILED );
|
||||||
|
|
||||||
ctx->pk_info = info;
|
ctx->pk_info = info;
|
||||||
|
|
||||||
@@ -135,225 +210,430 @@ int mbedtls_pk_setup_rsa_alt(mbedtls_pk_context *ctx, void *key,
|
|||||||
rsa_alt->sign_func = sign_func;
|
rsa_alt->sign_func = sign_func;
|
||||||
rsa_alt->key_len_func = key_len_func;
|
rsa_alt->key_len_func = key_len_func;
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
|
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tell if a PK can do the operations of the given type
|
* Tell if a PK can do the operations of the given type
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type) {
|
int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type )
|
||||||
/* null or NONE context can't do anything */
|
{
|
||||||
if (ctx == NULL || ctx->pk_info == NULL)
|
/* A context with null pk_info is not set up yet and can't do anything.
|
||||||
return (0);
|
* For backward compatibility, also accept NULL instead of a context
|
||||||
|
* pointer. */
|
||||||
|
if( ctx == NULL || ctx->pk_info == NULL )
|
||||||
|
return( 0 );
|
||||||
|
|
||||||
return (ctx->pk_info->can_do(type));
|
return( ctx->pk_info->can_do( type ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper for mbedtls_pk_sign and mbedtls_pk_verify
|
* Helper for mbedtls_pk_sign and mbedtls_pk_verify
|
||||||
*/
|
*/
|
||||||
static inline int pk_hashlen_helper(mbedtls_md_type_t md_alg, size_t *hash_len) {
|
static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len )
|
||||||
|
{
|
||||||
const mbedtls_md_info_t *md_info;
|
const mbedtls_md_info_t *md_info;
|
||||||
|
|
||||||
if (*hash_len != 0)
|
if( *hash_len != 0 )
|
||||||
return (0);
|
return( 0 );
|
||||||
|
|
||||||
if ((md_info = mbedtls_md_info_from_type(md_alg)) == NULL)
|
if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
|
||||||
return (-1);
|
return( -1 );
|
||||||
|
|
||||||
*hash_len = mbedtls_md_get_size(md_info);
|
*hash_len = mbedtls_md_get_size( md_info );
|
||||||
return (0);
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
/*
|
||||||
|
* Helper to set up a restart context if needed
|
||||||
|
*/
|
||||||
|
static int pk_restart_setup( mbedtls_pk_restart_ctx *ctx,
|
||||||
|
const mbedtls_pk_info_t *info )
|
||||||
|
{
|
||||||
|
/* Don't do anything if already set up or invalid */
|
||||||
|
if( ctx == NULL || ctx->pk_info != NULL )
|
||||||
|
return( 0 );
|
||||||
|
|
||||||
|
/* Should never happen when we're called */
|
||||||
|
if( info->rs_alloc_func == NULL || info->rs_free_func == NULL )
|
||||||
|
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
if( ( ctx->rs_ctx = info->rs_alloc_func() ) == NULL )
|
||||||
|
return( MBEDTLS_ERR_PK_ALLOC_FAILED );
|
||||||
|
|
||||||
|
ctx->pk_info = info;
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify a signature (restartable)
|
||||||
|
*/
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
PK_VALIDATE_RET( ctx != NULL );
|
||||||
|
PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
|
||||||
|
hash != NULL );
|
||||||
|
PK_VALIDATE_RET( sig != NULL );
|
||||||
|
|
||||||
|
if( ctx->pk_info == NULL ||
|
||||||
|
pk_hashlen_helper( md_alg, &hash_len ) != 0 )
|
||||||
|
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
/* optimization: use non-restartable version if restart disabled */
|
||||||
|
if( rs_ctx != NULL &&
|
||||||
|
mbedtls_ecp_restart_is_enabled() &&
|
||||||
|
ctx->pk_info->verify_rs_func != NULL )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
|
if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
ret = ctx->pk_info->verify_rs_func( ctx->pk_ctx,
|
||||||
|
md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx );
|
||||||
|
|
||||||
|
if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
|
||||||
|
mbedtls_pk_restart_free( rs_ctx );
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
|
||||||
|
(void) rs_ctx;
|
||||||
|
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
|
||||||
|
|
||||||
|
if( ctx->pk_info->verify_func == NULL )
|
||||||
|
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
|
||||||
|
|
||||||
|
return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len,
|
||||||
|
sig, sig_len ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Verify a signature
|
* Verify a signature
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
|
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 *hash, size_t hash_len,
|
||||||
const unsigned char *sig, size_t sig_len) {
|
const unsigned char *sig, size_t sig_len )
|
||||||
if (ctx == NULL || ctx->pk_info == NULL ||
|
{
|
||||||
pk_hashlen_helper(md_alg, &hash_len) != 0)
|
return( mbedtls_pk_verify_restartable( ctx, md_alg, hash, hash_len,
|
||||||
return (MBEDTLS_ERR_PK_BAD_INPUT_DATA);
|
sig, sig_len, NULL ) );
|
||||||
|
|
||||||
if (ctx->pk_info->verify_func == NULL)
|
|
||||||
return (MBEDTLS_ERR_PK_TYPE_MISMATCH);
|
|
||||||
|
|
||||||
return (ctx->pk_info->verify_func(ctx->pk_ctx, md_alg, hash, hash_len,
|
|
||||||
sig, sig_len));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Verify a signature with options
|
* Verify a signature with options
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options,
|
int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
|
||||||
mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
|
mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
|
||||||
const unsigned char *hash, size_t hash_len,
|
const unsigned char *hash, size_t hash_len,
|
||||||
const unsigned char *sig, size_t sig_len) {
|
const unsigned char *sig, size_t sig_len )
|
||||||
if (ctx == NULL || ctx->pk_info == NULL)
|
{
|
||||||
return (MBEDTLS_ERR_PK_BAD_INPUT_DATA);
|
PK_VALIDATE_RET( ctx != NULL );
|
||||||
|
PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
|
||||||
|
hash != NULL );
|
||||||
|
PK_VALIDATE_RET( sig != NULL );
|
||||||
|
|
||||||
if (! mbedtls_pk_can_do(ctx, type))
|
if( ctx->pk_info == NULL )
|
||||||
return (MBEDTLS_ERR_PK_TYPE_MISMATCH);
|
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||||
|
|
||||||
if (type == MBEDTLS_PK_RSASSA_PSS) {
|
if( ! mbedtls_pk_can_do( ctx, type ) )
|
||||||
|
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
|
||||||
|
|
||||||
|
if( type == MBEDTLS_PK_RSASSA_PSS )
|
||||||
|
{
|
||||||
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
|
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
|
||||||
int ret;
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
const mbedtls_pk_rsassa_pss_options *pss_opts;
|
const mbedtls_pk_rsassa_pss_options *pss_opts;
|
||||||
|
|
||||||
#if SIZE_MAX > UINT_MAX
|
#if SIZE_MAX > UINT_MAX
|
||||||
if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len)
|
if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
|
||||||
return (MBEDTLS_ERR_PK_BAD_INPUT_DATA);
|
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||||
#endif /* SIZE_MAX > UINT_MAX */
|
#endif /* SIZE_MAX > UINT_MAX */
|
||||||
|
|
||||||
if (options == NULL)
|
if( options == NULL )
|
||||||
return (MBEDTLS_ERR_PK_BAD_INPUT_DATA);
|
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||||
|
|
||||||
pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
|
pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
|
||||||
|
|
||||||
if (sig_len < mbedtls_pk_get_len(ctx))
|
if( sig_len < mbedtls_pk_get_len( ctx ) )
|
||||||
return (MBEDTLS_ERR_RSA_VERIFY_FAILED);
|
return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
|
||||||
|
|
||||||
ret = mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_pk_rsa(*ctx),
|
ret = mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_pk_rsa( *ctx ),
|
||||||
NULL, NULL, MBEDTLS_RSA_PUBLIC,
|
NULL, NULL, MBEDTLS_RSA_PUBLIC,
|
||||||
md_alg, (unsigned int) hash_len, hash,
|
md_alg, (unsigned int) hash_len, hash,
|
||||||
pss_opts->mgf1_hash_id,
|
pss_opts->mgf1_hash_id,
|
||||||
pss_opts->expected_salt_len,
|
pss_opts->expected_salt_len,
|
||||||
sig);
|
sig );
|
||||||
if (ret != 0)
|
if( ret != 0 )
|
||||||
return (ret);
|
return( ret );
|
||||||
|
|
||||||
if (sig_len > mbedtls_pk_get_len(ctx))
|
if( sig_len > mbedtls_pk_get_len( ctx ) )
|
||||||
return (MBEDTLS_ERR_PK_SIG_LEN_MISMATCH);
|
return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
|
||||||
|
|
||||||
return (0);
|
return( 0 );
|
||||||
#else
|
#else
|
||||||
return (MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE);
|
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
|
||||||
#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
|
#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* General case: no options */
|
/* General case: no options */
|
||||||
if (options != NULL)
|
if( options != NULL )
|
||||||
return (MBEDTLS_ERR_PK_BAD_INPUT_DATA);
|
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||||
|
|
||||||
return (mbedtls_pk_verify(ctx, md_alg, hash, hash_len, sig, sig_len));
|
return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make a signature (restartable)
|
||||||
|
*/
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
PK_VALIDATE_RET( ctx != NULL );
|
||||||
|
PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
|
||||||
|
hash != NULL );
|
||||||
|
PK_VALIDATE_RET( sig != NULL );
|
||||||
|
|
||||||
|
if( ctx->pk_info == NULL ||
|
||||||
|
pk_hashlen_helper( md_alg, &hash_len ) != 0 )
|
||||||
|
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
/* optimization: use non-restartable version if restart disabled */
|
||||||
|
if( rs_ctx != NULL &&
|
||||||
|
mbedtls_ecp_restart_is_enabled() &&
|
||||||
|
ctx->pk_info->sign_rs_func != NULL )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
|
if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
ret = ctx->pk_info->sign_rs_func( ctx->pk_ctx, md_alg,
|
||||||
|
hash, hash_len, sig, sig_len, f_rng, p_rng, rs_ctx->rs_ctx );
|
||||||
|
|
||||||
|
if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
|
||||||
|
mbedtls_pk_restart_free( rs_ctx );
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
|
||||||
|
(void) rs_ctx;
|
||||||
|
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
|
||||||
|
|
||||||
|
if( ctx->pk_info->sign_func == NULL )
|
||||||
|
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
|
||||||
|
|
||||||
|
return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len,
|
||||||
|
sig, sig_len, f_rng, p_rng ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make a signature
|
* Make a signature
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
|
int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
|
||||||
const unsigned char *hash, size_t hash_len,
|
const unsigned char *hash, size_t hash_len,
|
||||||
unsigned char *sig, size_t *sig_len,
|
unsigned char *sig, size_t *sig_len,
|
||||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) {
|
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||||
if (ctx == NULL || ctx->pk_info == NULL ||
|
{
|
||||||
pk_hashlen_helper(md_alg, &hash_len) != 0)
|
return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len,
|
||||||
return (MBEDTLS_ERR_PK_BAD_INPUT_DATA);
|
sig, sig_len, f_rng, p_rng, NULL ) );
|
||||||
|
|
||||||
if (ctx->pk_info->sign_func == NULL)
|
|
||||||
return (MBEDTLS_ERR_PK_TYPE_MISMATCH);
|
|
||||||
|
|
||||||
return (ctx->pk_info->sign_func(ctx->pk_ctx, md_alg, hash, hash_len,
|
|
||||||
sig, sig_len, f_rng, p_rng));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decrypt message
|
* Decrypt message
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_decrypt(mbedtls_pk_context *ctx,
|
int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
|
||||||
const unsigned char *input, size_t ilen,
|
const unsigned char *input, size_t ilen,
|
||||||
unsigned char *output, size_t *olen, size_t osize,
|
unsigned char *output, size_t *olen, size_t osize,
|
||||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) {
|
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||||
if (ctx == NULL || ctx->pk_info == NULL)
|
{
|
||||||
return (MBEDTLS_ERR_PK_BAD_INPUT_DATA);
|
PK_VALIDATE_RET( ctx != NULL );
|
||||||
|
PK_VALIDATE_RET( input != NULL || ilen == 0 );
|
||||||
|
PK_VALIDATE_RET( output != NULL || osize == 0 );
|
||||||
|
PK_VALIDATE_RET( olen != NULL );
|
||||||
|
|
||||||
if (ctx->pk_info->decrypt_func == NULL)
|
if( ctx->pk_info == NULL )
|
||||||
return (MBEDTLS_ERR_PK_TYPE_MISMATCH);
|
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||||
|
|
||||||
return (ctx->pk_info->decrypt_func(ctx->pk_ctx, input, ilen,
|
if( ctx->pk_info->decrypt_func == NULL )
|
||||||
output, olen, osize, f_rng, p_rng));
|
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
|
||||||
|
|
||||||
|
return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen,
|
||||||
|
output, olen, osize, f_rng, p_rng ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Encrypt message
|
* Encrypt message
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_encrypt(mbedtls_pk_context *ctx,
|
int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
|
||||||
const unsigned char *input, size_t ilen,
|
const unsigned char *input, size_t ilen,
|
||||||
unsigned char *output, size_t *olen, size_t osize,
|
unsigned char *output, size_t *olen, size_t osize,
|
||||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) {
|
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||||
if (ctx == NULL || ctx->pk_info == NULL)
|
{
|
||||||
return (MBEDTLS_ERR_PK_BAD_INPUT_DATA);
|
PK_VALIDATE_RET( ctx != NULL );
|
||||||
|
PK_VALIDATE_RET( input != NULL || ilen == 0 );
|
||||||
|
PK_VALIDATE_RET( output != NULL || osize == 0 );
|
||||||
|
PK_VALIDATE_RET( olen != NULL );
|
||||||
|
|
||||||
if (ctx->pk_info->encrypt_func == NULL)
|
if( ctx->pk_info == NULL )
|
||||||
return (MBEDTLS_ERR_PK_TYPE_MISMATCH);
|
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||||
|
|
||||||
return (ctx->pk_info->encrypt_func(ctx->pk_ctx, input, ilen,
|
if( ctx->pk_info->encrypt_func == NULL )
|
||||||
output, olen, osize, f_rng, p_rng));
|
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
|
||||||
|
|
||||||
|
return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen,
|
||||||
|
output, olen, osize, f_rng, p_rng ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check public-private key pair
|
* Check public-private key pair
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_check_pair(const mbedtls_pk_context *pub, const mbedtls_pk_context *prv) {
|
int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv )
|
||||||
if (pub == NULL || pub->pk_info == NULL ||
|
{
|
||||||
prv == NULL || prv->pk_info == NULL ||
|
PK_VALIDATE_RET( pub != NULL );
|
||||||
prv->pk_info->check_pair_func == NULL) {
|
PK_VALIDATE_RET( prv != NULL );
|
||||||
return (MBEDTLS_ERR_PK_BAD_INPUT_DATA);
|
|
||||||
|
if( pub->pk_info == NULL ||
|
||||||
|
prv->pk_info == NULL )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prv->pk_info->type == MBEDTLS_PK_RSA_ALT) {
|
if( prv->pk_info->check_pair_func == NULL )
|
||||||
if (pub->pk_info->type != MBEDTLS_PK_RSA)
|
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
|
||||||
return (MBEDTLS_ERR_PK_TYPE_MISMATCH);
|
|
||||||
} else {
|
if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT )
|
||||||
if (pub->pk_info != prv->pk_info)
|
{
|
||||||
return (MBEDTLS_ERR_PK_TYPE_MISMATCH);
|
if( pub->pk_info->type != MBEDTLS_PK_RSA )
|
||||||
|
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( pub->pk_info != prv->pk_info )
|
||||||
|
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
|
||||||
}
|
}
|
||||||
|
|
||||||
return (prv->pk_info->check_pair_func(pub->pk_ctx, prv->pk_ctx));
|
return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get key size in bits
|
* Get key size in bits
|
||||||
*/
|
*/
|
||||||
size_t mbedtls_pk_get_bitlen(const mbedtls_pk_context *ctx) {
|
size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx )
|
||||||
if (ctx == NULL || ctx->pk_info == NULL)
|
{
|
||||||
return (0);
|
/* For backward compatibility, accept NULL or a context that
|
||||||
|
* isn't set up yet, and return a fake value that should be safe. */
|
||||||
|
if( ctx == NULL || ctx->pk_info == NULL )
|
||||||
|
return( 0 );
|
||||||
|
|
||||||
return (ctx->pk_info->get_bitlen(ctx->pk_ctx));
|
return( ctx->pk_info->get_bitlen( ctx->pk_ctx ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Export debug information
|
* Export debug information
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_debug(const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items) {
|
int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items )
|
||||||
if (ctx == NULL || ctx->pk_info == NULL)
|
{
|
||||||
return (MBEDTLS_ERR_PK_BAD_INPUT_DATA);
|
PK_VALIDATE_RET( ctx != NULL );
|
||||||
|
if( ctx->pk_info == NULL )
|
||||||
|
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||||
|
|
||||||
if (ctx->pk_info->debug_func == NULL)
|
if( ctx->pk_info->debug_func == NULL )
|
||||||
return (MBEDTLS_ERR_PK_TYPE_MISMATCH);
|
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
|
||||||
|
|
||||||
ctx->pk_info->debug_func(ctx->pk_ctx, items);
|
ctx->pk_info->debug_func( ctx->pk_ctx, items );
|
||||||
return (0);
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access the PK type name
|
* Access the PK type name
|
||||||
*/
|
*/
|
||||||
const char *mbedtls_pk_get_name(const mbedtls_pk_context *ctx) {
|
const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx )
|
||||||
if (ctx == NULL || ctx->pk_info == NULL)
|
{
|
||||||
return ("invalid PK");
|
if( ctx == NULL || ctx->pk_info == NULL )
|
||||||
|
return( "invalid PK" );
|
||||||
|
|
||||||
return (ctx->pk_info->name);
|
return( ctx->pk_info->name );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access the PK type
|
* Access the PK type
|
||||||
*/
|
*/
|
||||||
mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx) {
|
mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx )
|
||||||
if (ctx == NULL || ctx->pk_info == NULL)
|
{
|
||||||
return (MBEDTLS_PK_NONE);
|
if( ctx == NULL || ctx->pk_info == NULL )
|
||||||
|
return( MBEDTLS_PK_NONE );
|
||||||
|
|
||||||
return (ctx->pk_info->type);
|
return( ctx->pk_info->type );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||||
|
/*
|
||||||
|
* Load the key to a PSA key slot,
|
||||||
|
* then turn the PK context into a wrapper for that key slot.
|
||||||
|
*
|
||||||
|
* Currently only works for EC private keys.
|
||||||
|
*/
|
||||||
|
int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
|
||||||
|
psa_key_id_t *key,
|
||||||
|
psa_algorithm_t hash_alg )
|
||||||
|
{
|
||||||
|
#if !defined(MBEDTLS_ECP_C)
|
||||||
|
((void) pk);
|
||||||
|
((void) key);
|
||||||
|
((void) hash_alg);
|
||||||
|
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
|
||||||
|
#else
|
||||||
|
const mbedtls_ecp_keypair *ec;
|
||||||
|
unsigned char d[MBEDTLS_ECP_MAX_BYTES];
|
||||||
|
size_t d_len;
|
||||||
|
psa_ecc_family_t curve_id;
|
||||||
|
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||||
|
psa_key_type_t key_type;
|
||||||
|
size_t bits;
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
|
/* export the private key material in the format PSA wants */
|
||||||
|
if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_ECKEY )
|
||||||
|
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
|
||||||
|
|
||||||
|
ec = mbedtls_pk_ec( *pk );
|
||||||
|
d_len = ( ec->grp.nbits + 7 ) / 8;
|
||||||
|
if( ( ret = mbedtls_mpi_write_binary( &ec->d, d, d_len ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
curve_id = mbedtls_ecc_group_to_psa( ec->grp.id, &bits );
|
||||||
|
key_type = PSA_KEY_TYPE_ECC_KEY_PAIR( curve_id );
|
||||||
|
|
||||||
|
/* prepare the key attributes */
|
||||||
|
psa_set_key_type( &attributes, key_type );
|
||||||
|
psa_set_key_bits( &attributes, bits );
|
||||||
|
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH );
|
||||||
|
psa_set_key_algorithm( &attributes, PSA_ALG_ECDSA(hash_alg) );
|
||||||
|
|
||||||
|
/* import private key into PSA */
|
||||||
|
if( PSA_SUCCESS != psa_import_key( &attributes, d, d_len, key ) )
|
||||||
|
return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
|
||||||
|
|
||||||
|
/* make PK context wrap the key slot */
|
||||||
|
mbedtls_pk_free( pk );
|
||||||
|
mbedtls_pk_init( pk );
|
||||||
|
|
||||||
|
return( mbedtls_pk_setup_opaque( pk, *key ) );
|
||||||
|
#endif /* MBEDTLS_ECP_C */
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||||
#endif /* MBEDTLS_PK_C */
|
#endif /* MBEDTLS_PK_C */
|
||||||
|
|||||||
@@ -4,47 +4,47 @@
|
|||||||
* \brief Public Key abstraction layer
|
* \brief Public Key abstraction layer
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright The Mbed TLS Contributors
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* it under the terms of the GNU General Public License as published by
|
* not use this file except in compliance with the License.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* You may obtain a copy of the License at
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* See the License for the specific language governing permissions and
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MBEDTLS_PK_H
|
#ifndef MBEDTLS_PK_H
|
||||||
#define MBEDTLS_PK_H
|
#define MBEDTLS_PK_H
|
||||||
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
#include "config.h"
|
#include "mbedtls/config.h"
|
||||||
#else
|
#else
|
||||||
#include MBEDTLS_CONFIG_FILE
|
#include MBEDTLS_CONFIG_FILE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "md.h"
|
#include "mbedtls/md.h"
|
||||||
|
|
||||||
#if defined(MBEDTLS_RSA_C)
|
#if defined(MBEDTLS_RSA_C)
|
||||||
#include "rsa.h"
|
#include "mbedtls/rsa.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECP_C)
|
#if defined(MBEDTLS_ECP_C)
|
||||||
#include "ecp.h"
|
#include "mbedtls/ecp.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECDSA_C)
|
#if defined(MBEDTLS_ECDSA_C)
|
||||||
#include "ecdsa.h"
|
#include "mbedtls/ecdsa.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||||
|
#include "psa/crypto.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
|
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
|
||||||
@@ -66,6 +66,8 @@
|
|||||||
#define MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE -0x3A00 /**< Elliptic curve is unsupported (only NIST curves are supported). */
|
#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_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. */
|
#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. */
|
#define MBEDTLS_ERR_PK_HW_ACCEL_FAILED -0x3880 /**< PK hardware accelerator failed. */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -76,29 +78,84 @@ extern "C" {
|
|||||||
* \brief Public key types
|
* \brief Public key types
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
MBEDTLS_PK_NONE = 0,
|
MBEDTLS_PK_NONE=0,
|
||||||
MBEDTLS_PK_RSA,
|
MBEDTLS_PK_RSA,
|
||||||
MBEDTLS_PK_ECKEY,
|
MBEDTLS_PK_ECKEY,
|
||||||
MBEDTLS_PK_ECKEY_DH,
|
MBEDTLS_PK_ECKEY_DH,
|
||||||
MBEDTLS_PK_ECDSA,
|
MBEDTLS_PK_ECDSA,
|
||||||
MBEDTLS_PK_RSA_ALT,
|
MBEDTLS_PK_RSA_ALT,
|
||||||
MBEDTLS_PK_RSASSA_PSS,
|
MBEDTLS_PK_RSASSA_PSS,
|
||||||
|
MBEDTLS_PK_OPAQUE,
|
||||||
} mbedtls_pk_type_t;
|
} mbedtls_pk_type_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Options for RSASSA-PSS signature verification.
|
* \brief Options for RSASSA-PSS signature verification.
|
||||||
* See \c mbedtls_rsa_rsassa_pss_verify_ext()
|
* See \c mbedtls_rsa_rsassa_pss_verify_ext()
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_pk_rsassa_pss_options {
|
typedef struct mbedtls_pk_rsassa_pss_options
|
||||||
|
{
|
||||||
mbedtls_md_type_t mgf1_hash_id;
|
mbedtls_md_type_t mgf1_hash_id;
|
||||||
int expected_salt_len;
|
int expected_salt_len;
|
||||||
|
|
||||||
} mbedtls_pk_rsassa_pss_options;
|
} mbedtls_pk_rsassa_pss_options;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Maximum size of a signature made by mbedtls_pk_sign().
|
||||||
|
*/
|
||||||
|
/* We need to set MBEDTLS_PK_SIGNATURE_MAX_SIZE to the maximum signature
|
||||||
|
* size among the supported signature types. Do it by starting at 0,
|
||||||
|
* then incrementally increasing to be large enough for each supported
|
||||||
|
* signature mechanism.
|
||||||
|
*
|
||||||
|
* The resulting value can be 0, for example if MBEDTLS_ECDH_C is enabled
|
||||||
|
* (which allows the pk module to be included) but neither MBEDTLS_ECDSA_C
|
||||||
|
* nor MBEDTLS_RSA_C nor any opaque signature mechanism (PSA or RSA_ALT).
|
||||||
|
*/
|
||||||
|
#define MBEDTLS_PK_SIGNATURE_MAX_SIZE 0
|
||||||
|
|
||||||
|
#if ( defined(MBEDTLS_RSA_C) || defined(MBEDTLS_PK_RSA_ALT_SUPPORT) ) && \
|
||||||
|
MBEDTLS_MPI_MAX_SIZE > MBEDTLS_PK_SIGNATURE_MAX_SIZE
|
||||||
|
/* For RSA, the signature can be as large as the bignum module allows.
|
||||||
|
* For RSA_ALT, the signature size is not necessarily tied to what the
|
||||||
|
* bignum module can do, but in the absence of any specific setting,
|
||||||
|
* we use that (rsa_alt_sign_wrap in pk_wrap will check). */
|
||||||
|
#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE
|
||||||
|
#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDSA_C) && \
|
||||||
|
MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_PK_SIGNATURE_MAX_SIZE
|
||||||
|
/* For ECDSA, the ecdsa module exports a constant for the maximum
|
||||||
|
* signature size. */
|
||||||
|
#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE
|
||||||
|
#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||||
|
#if PSA_SIGNATURE_MAX_SIZE > MBEDTLS_PK_SIGNATURE_MAX_SIZE
|
||||||
|
/* PSA_SIGNATURE_MAX_SIZE is the maximum size of a signature made
|
||||||
|
* through the PSA API in the PSA representation. */
|
||||||
|
#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE
|
||||||
|
#define MBEDTLS_PK_SIGNATURE_MAX_SIZE PSA_SIGNATURE_MAX_SIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE + 11 > MBEDTLS_PK_SIGNATURE_MAX_SIZE
|
||||||
|
/* The Mbed TLS representation is different for ECDSA signatures:
|
||||||
|
* PSA uses the raw concatenation of r and s,
|
||||||
|
* whereas Mbed TLS uses the ASN.1 representation (SEQUENCE of two INTEGERs).
|
||||||
|
* Add the overhead of ASN.1: up to (1+2) + 2 * (1+2+1) for the
|
||||||
|
* types, lengths (represented by up to 2 bytes), and potential leading
|
||||||
|
* zeros of the INTEGERs and the SEQUENCE. */
|
||||||
|
#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE
|
||||||
|
#define MBEDTLS_PK_SIGNATURE_MAX_SIZE ( PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE + 11 )
|
||||||
|
#endif
|
||||||
|
#endif /* defined(MBEDTLS_USE_PSA_CRYPTO) */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Types for interfacing with the debug module
|
* \brief Types for interfacing with the debug module
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum
|
||||||
|
{
|
||||||
MBEDTLS_PK_DEBUG_NONE = 0,
|
MBEDTLS_PK_DEBUG_NONE = 0,
|
||||||
MBEDTLS_PK_DEBUG_MPI,
|
MBEDTLS_PK_DEBUG_MPI,
|
||||||
MBEDTLS_PK_DEBUG_ECP,
|
MBEDTLS_PK_DEBUG_ECP,
|
||||||
@@ -107,7 +164,8 @@ typedef enum {
|
|||||||
/**
|
/**
|
||||||
* \brief Item to send to the debug module
|
* \brief Item to send to the debug module
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_pk_debug_item {
|
typedef struct mbedtls_pk_debug_item
|
||||||
|
{
|
||||||
mbedtls_pk_debug_type type;
|
mbedtls_pk_debug_type type;
|
||||||
const char *name;
|
const char *name;
|
||||||
void *value;
|
void *value;
|
||||||
@@ -124,11 +182,26 @@ typedef struct mbedtls_pk_info_t mbedtls_pk_info_t;
|
|||||||
/**
|
/**
|
||||||
* \brief Public key container
|
* \brief Public key container
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_pk_context {
|
typedef struct mbedtls_pk_context
|
||||||
const mbedtls_pk_info_t *pk_info; /**< Public key informations */
|
{
|
||||||
void *pk_ctx; /**< Underlying public key context */
|
const mbedtls_pk_info_t * pk_info; /**< Public key information */
|
||||||
|
void * pk_ctx; /**< Underlying public key context */
|
||||||
} mbedtls_pk_context;
|
} mbedtls_pk_context;
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
/**
|
||||||
|
* \brief Context for resuming operations
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const mbedtls_pk_info_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 */
|
||||||
|
|
||||||
#if defined(MBEDTLS_RSA_C)
|
#if defined(MBEDTLS_RSA_C)
|
||||||
/**
|
/**
|
||||||
* Quick access to an RSA context inside a PK context.
|
* Quick access to an RSA context inside a PK context.
|
||||||
@@ -136,8 +209,9 @@ typedef struct mbedtls_pk_context {
|
|||||||
* \warning You must make sure the PK context actually holds an RSA context
|
* \warning You must make sure the PK context actually holds an RSA context
|
||||||
* before using this function!
|
* before using this function!
|
||||||
*/
|
*/
|
||||||
static inline mbedtls_rsa_context *mbedtls_pk_rsa(const mbedtls_pk_context pk) {
|
static inline mbedtls_rsa_context *mbedtls_pk_rsa( const mbedtls_pk_context pk )
|
||||||
return ((mbedtls_rsa_context *)(pk).pk_ctx);
|
{
|
||||||
|
return( (mbedtls_rsa_context *) (pk).pk_ctx );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_RSA_C */
|
#endif /* MBEDTLS_RSA_C */
|
||||||
|
|
||||||
@@ -148,8 +222,9 @@ static inline mbedtls_rsa_context *mbedtls_pk_rsa(const mbedtls_pk_context pk) {
|
|||||||
* \warning You must make sure the PK context actually holds an EC context
|
* \warning You must make sure the PK context actually holds an EC context
|
||||||
* before using this function!
|
* before using this function!
|
||||||
*/
|
*/
|
||||||
static inline mbedtls_ecp_keypair *mbedtls_pk_ec(const mbedtls_pk_context pk) {
|
static inline mbedtls_ecp_keypair *mbedtls_pk_ec( const mbedtls_pk_context pk )
|
||||||
return ((mbedtls_ecp_keypair *)(pk).pk_ctx);
|
{
|
||||||
|
return( (mbedtls_ecp_keypair *) (pk).pk_ctx );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_ECP_C */
|
#endif /* MBEDTLS_ECP_C */
|
||||||
|
|
||||||
@@ -157,14 +232,14 @@ static inline mbedtls_ecp_keypair *mbedtls_pk_ec(const mbedtls_pk_context pk) {
|
|||||||
/**
|
/**
|
||||||
* \brief Types for RSA-alt abstraction
|
* \brief Types for RSA-alt abstraction
|
||||||
*/
|
*/
|
||||||
typedef int (*mbedtls_pk_rsa_alt_decrypt_func)(void *ctx, int mode, size_t *olen,
|
typedef int (*mbedtls_pk_rsa_alt_decrypt_func)( void *ctx, int mode, size_t *olen,
|
||||||
const unsigned char *input, unsigned char *output,
|
const unsigned char *input, unsigned char *output,
|
||||||
size_t output_max_len);
|
size_t output_max_len );
|
||||||
typedef int (*mbedtls_pk_rsa_alt_sign_func)(void *ctx,
|
typedef int (*mbedtls_pk_rsa_alt_sign_func)( void *ctx,
|
||||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
|
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
|
||||||
int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,
|
int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,
|
||||||
const unsigned char *hash, unsigned char *sig);
|
const unsigned char *hash, unsigned char *sig );
|
||||||
typedef size_t (*mbedtls_pk_rsa_alt_key_len_func)(void *ctx);
|
typedef size_t (*mbedtls_pk_rsa_alt_key_len_func)( void *ctx );
|
||||||
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
|
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -174,23 +249,53 @@ 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.
|
* \return The PK info associated with the type or NULL if not found.
|
||||||
*/
|
*/
|
||||||
const mbedtls_pk_info_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)
|
* \brief Initialize a #mbedtls_pk_context (as NONE).
|
||||||
|
*
|
||||||
|
* \param ctx The context to initialize.
|
||||||
|
* This must not be \c NULL.
|
||||||
*/
|
*/
|
||||||
void mbedtls_pk_init(mbedtls_pk_context *ctx);
|
void mbedtls_pk_init( mbedtls_pk_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Free a mbedtls_pk_context
|
* \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.
|
||||||
|
*
|
||||||
|
* \note For contexts that have been set up with
|
||||||
|
* mbedtls_pk_setup_opaque(), this does not free the underlying
|
||||||
|
* PSA key and you still need to call psa_destroy_key()
|
||||||
|
* independently if you want to destroy that key.
|
||||||
*/
|
*/
|
||||||
void mbedtls_pk_free(mbedtls_pk_context *ctx);
|
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
|
* \brief Initialize a PK context with the information given
|
||||||
* and allocates the type-specific PK subcontext.
|
* and allocates the type-specific PK subcontext.
|
||||||
*
|
*
|
||||||
* \param ctx Context to initialize. Must be empty (type NONE).
|
* \param ctx Context to initialize. It must not have been set
|
||||||
|
* up yet (type #MBEDTLS_PK_NONE).
|
||||||
* \param info Information to use
|
* \param info Information to use
|
||||||
*
|
*
|
||||||
* \return 0 on success,
|
* \return 0 on success,
|
||||||
@@ -200,13 +305,47 @@ void mbedtls_pk_free(mbedtls_pk_context *ctx);
|
|||||||
* \note For contexts holding an RSA-alt key, use
|
* \note For contexts holding an RSA-alt key, use
|
||||||
* \c mbedtls_pk_setup_rsa_alt() instead.
|
* \c mbedtls_pk_setup_rsa_alt() instead.
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info);
|
int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||||
|
/**
|
||||||
|
* \brief Initialize a PK context to wrap a PSA key.
|
||||||
|
*
|
||||||
|
* \note This function replaces mbedtls_pk_setup() for contexts
|
||||||
|
* that wrap a (possibly opaque) PSA key instead of
|
||||||
|
* storing and manipulating the key material directly.
|
||||||
|
*
|
||||||
|
* \param ctx The context to initialize. It must be empty (type NONE).
|
||||||
|
* \param key The PSA key to wrap, which must hold an ECC key pair
|
||||||
|
* (see notes below).
|
||||||
|
*
|
||||||
|
* \note The wrapped key must remain valid as long as the
|
||||||
|
* wrapping PK context is in use, that is at least between
|
||||||
|
* the point this function is called and the point
|
||||||
|
* mbedtls_pk_free() is called on this context. The wrapped
|
||||||
|
* key might then be independently used or destroyed.
|
||||||
|
*
|
||||||
|
* \note This function is currently only available for ECC key
|
||||||
|
* pairs (that is, ECC keys containing private key material).
|
||||||
|
* Support for other key types may be added later.
|
||||||
|
*
|
||||||
|
* \return \c 0 on success.
|
||||||
|
* \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input
|
||||||
|
* (context already used, invalid key identifier).
|
||||||
|
* \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the key is not an
|
||||||
|
* ECC key pair.
|
||||||
|
* \return #MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure.
|
||||||
|
*/
|
||||||
|
int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx,
|
||||||
|
const psa_key_id_t key );
|
||||||
|
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||||
|
|
||||||
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
|
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
|
||||||
/**
|
/**
|
||||||
* \brief Initialize an RSA-alt context
|
* \brief Initialize an RSA-alt context
|
||||||
*
|
*
|
||||||
* \param ctx Context to initialize. Must be empty (type NONE).
|
* \param ctx Context to initialize. It must not have been set
|
||||||
|
* up yet (type #MBEDTLS_PK_NONE).
|
||||||
* \param key RSA key pointer
|
* \param key RSA key pointer
|
||||||
* \param decrypt_func Decryption function
|
* \param decrypt_func Decryption function
|
||||||
* \param sign_func Signing function
|
* \param sign_func Signing function
|
||||||
@@ -217,46 +356,51 @@ int mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info);
|
|||||||
*
|
*
|
||||||
* \note This function replaces \c mbedtls_pk_setup() for RSA-alt.
|
* \note This function replaces \c mbedtls_pk_setup() for RSA-alt.
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_setup_rsa_alt(mbedtls_pk_context *ctx, void *key,
|
int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
|
||||||
mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
|
mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
|
||||||
mbedtls_pk_rsa_alt_sign_func sign_func,
|
mbedtls_pk_rsa_alt_sign_func sign_func,
|
||||||
mbedtls_pk_rsa_alt_key_len_func key_len_func);
|
mbedtls_pk_rsa_alt_key_len_func key_len_func );
|
||||||
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
|
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Get the size in bits of the underlying key
|
* \brief Get the size in bits of the underlying key
|
||||||
*
|
*
|
||||||
* \param ctx Context to use
|
* \param ctx The context to query. It must have been initialized.
|
||||||
*
|
*
|
||||||
* \return Key size in bits, or 0 on error
|
* \return Key size in bits, or 0 on error
|
||||||
*/
|
*/
|
||||||
size_t mbedtls_pk_get_bitlen(const mbedtls_pk_context *ctx);
|
size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Get the length in bytes of the underlying key
|
* \brief Get the length in bytes of the underlying key
|
||||||
* \param ctx Context to use
|
*
|
||||||
|
* \param ctx The context to query. It must have been initialized.
|
||||||
*
|
*
|
||||||
* \return Key length in bytes, or 0 on error
|
* \return Key length in bytes, or 0 on error
|
||||||
*/
|
*/
|
||||||
static inline size_t mbedtls_pk_get_len(const mbedtls_pk_context *ctx) {
|
static inline size_t mbedtls_pk_get_len( const mbedtls_pk_context *ctx )
|
||||||
return ((mbedtls_pk_get_bitlen(ctx) + 7) / 8);
|
{
|
||||||
|
return( ( mbedtls_pk_get_bitlen( ctx ) + 7 ) / 8 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Tell if a context can do the operation given by type
|
* \brief Tell if a context can do the operation given by type
|
||||||
*
|
*
|
||||||
* \param ctx Context to test
|
* \param ctx The context to query. It must have been initialized.
|
||||||
* \param type Target type
|
* \param type The desired type.
|
||||||
*
|
*
|
||||||
* \return 0 if context can't do the operations,
|
* \return 1 if the context can do operations on the given type.
|
||||||
* 1 otherwise.
|
* \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().
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type);
|
int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Verify signature (including padding if relevant).
|
* \brief Verify signature (including padding if relevant).
|
||||||
*
|
*
|
||||||
* \param ctx PK context to use
|
* \param ctx The PK context to use. It must have been set up.
|
||||||
* \param md_alg Hash algorithm used (see notes)
|
* \param md_alg Hash algorithm used (see notes)
|
||||||
* \param hash Hash of the message to sign
|
* \param hash Hash of the message to sign
|
||||||
* \param hash_len Hash length or 0 (see notes)
|
* \param hash_len Hash length or 0 (see notes)
|
||||||
@@ -277,9 +421,35 @@ int mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type);
|
|||||||
*
|
*
|
||||||
* \note md_alg may be MBEDTLS_MD_NONE, only if hash_len != 0
|
* \note md_alg may be MBEDTLS_MD_NONE, only if hash_len != 0
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
|
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 *hash, size_t hash_len,
|
||||||
const unsigned char *sig, size_t sig_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.
|
* \brief Verify signature, with options.
|
||||||
@@ -287,7 +457,7 @@ int mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
|
|||||||
*
|
*
|
||||||
* \param type Signature type (inc. possible padding type) to verify
|
* \param type Signature type (inc. possible padding type) to verify
|
||||||
* \param options Pointer to type-specific options, or NULL
|
* \param options Pointer to type-specific options, or NULL
|
||||||
* \param ctx PK context to use
|
* \param ctx The PK context to use. It must have been set up.
|
||||||
* \param md_alg Hash algorithm used (see notes)
|
* \param md_alg Hash algorithm used (see notes)
|
||||||
* \param hash Hash of the message to sign
|
* \param hash Hash of the message to sign
|
||||||
* \param hash_len Hash length or 0 (see notes)
|
* \param hash_len Hash length or 0 (see notes)
|
||||||
@@ -310,20 +480,26 @@ int mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
|
|||||||
* to a mbedtls_pk_rsassa_pss_options structure,
|
* to a mbedtls_pk_rsassa_pss_options structure,
|
||||||
* otherwise it must be NULL.
|
* otherwise it must be NULL.
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options,
|
int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
|
||||||
mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
|
mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
|
||||||
const unsigned char *hash, size_t hash_len,
|
const unsigned char *hash, size_t hash_len,
|
||||||
const unsigned char *sig, size_t sig_len);
|
const unsigned char *sig, size_t sig_len );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Make signature, including padding if relevant.
|
* \brief Make signature, including padding if relevant.
|
||||||
*
|
*
|
||||||
* \param ctx PK context to use - must hold a private key
|
* \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 md_alg Hash algorithm used (see notes)
|
||||||
* \param hash Hash of the message to sign
|
* \param hash Hash of the message to sign
|
||||||
* \param hash_len Hash length or 0 (see notes)
|
* \param hash_len Hash length or 0 (see notes)
|
||||||
* \param sig Place to write the signature
|
* \param sig Place to write the signature.
|
||||||
* \param sig_len Number of bytes written
|
* It must have enough room for the signature.
|
||||||
|
* #MBEDTLS_PK_SIGNATURE_MAX_SIZE is always enough.
|
||||||
|
* You may use a smaller buffer if it is large enough
|
||||||
|
* given the key type.
|
||||||
|
* \param sig_len On successful return,
|
||||||
|
* the number of bytes written to \p sig.
|
||||||
* \param f_rng RNG function
|
* \param f_rng RNG function
|
||||||
* \param p_rng RNG parameter
|
* \param p_rng RNG parameter
|
||||||
*
|
*
|
||||||
@@ -339,15 +515,51 @@ 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.
|
* \note For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0.
|
||||||
* For ECDSA, md_alg may never be MBEDTLS_MD_NONE.
|
* For ECDSA, md_alg may never be MBEDTLS_MD_NONE.
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
|
int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
|
||||||
const unsigned char *hash, size_t hash_len,
|
const unsigned char *hash, size_t hash_len,
|
||||||
unsigned char *sig, size_t *sig_len,
|
unsigned char *sig, size_t *sig_len,
|
||||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
|
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().
|
||||||
|
*
|
||||||
|
* \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 for mbedtls_pk_sign())
|
||||||
|
* \param hash Hash of the message to sign
|
||||||
|
* \param hash_len Hash length or 0 (see notes for mbedtls_pk_sign())
|
||||||
|
* \param sig Place to write the signature.
|
||||||
|
* It must have enough room for the signature.
|
||||||
|
* #MBEDTLS_PK_SIGNATURE_MAX_SIZE is always enough.
|
||||||
|
* You may use a smaller buffer if it is large enough
|
||||||
|
* given the key type.
|
||||||
|
* \param sig_len On successful return,
|
||||||
|
* the number of bytes written to \p sig.
|
||||||
|
* \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().
|
||||||
|
* \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).
|
* \brief Decrypt message (including padding if relevant).
|
||||||
*
|
*
|
||||||
* \param ctx PK context to use - must hold a private key
|
* \param ctx The PK context to use. It must have been set up
|
||||||
|
* with a private key.
|
||||||
* \param input Input to decrypt
|
* \param input Input to decrypt
|
||||||
* \param ilen Input size
|
* \param ilen Input size
|
||||||
* \param output Decrypted output
|
* \param output Decrypted output
|
||||||
@@ -360,15 +572,15 @@ int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
|
|||||||
*
|
*
|
||||||
* \return 0 on success, or a specific error code.
|
* \return 0 on success, or a specific error code.
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_decrypt(mbedtls_pk_context *ctx,
|
int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
|
||||||
const unsigned char *input, size_t ilen,
|
const unsigned char *input, size_t ilen,
|
||||||
unsigned char *output, size_t *olen, size_t osize,
|
unsigned char *output, size_t *olen, size_t osize,
|
||||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
|
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Encrypt message (including padding if relevant).
|
* \brief Encrypt message (including padding if relevant).
|
||||||
*
|
*
|
||||||
* \param ctx PK context to use
|
* \param ctx The PK context to use. It must have been set up.
|
||||||
* \param input Message to encrypt
|
* \param input Message to encrypt
|
||||||
* \param ilen Message size
|
* \param ilen Message size
|
||||||
* \param output Encrypted output
|
* \param output Encrypted output
|
||||||
@@ -381,10 +593,10 @@ int mbedtls_pk_decrypt(mbedtls_pk_context *ctx,
|
|||||||
*
|
*
|
||||||
* \return 0 on success, or a specific error code.
|
* \return 0 on success, or a specific error code.
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_encrypt(mbedtls_pk_context *ctx,
|
int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
|
||||||
const unsigned char *input, size_t ilen,
|
const unsigned char *input, size_t ilen,
|
||||||
unsigned char *output, size_t *olen, size_t osize,
|
unsigned char *output, size_t *olen, size_t osize,
|
||||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
|
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Check if a public-private pair of keys matches.
|
* \brief Check if a public-private pair of keys matches.
|
||||||
@@ -392,49 +604,64 @@ int mbedtls_pk_encrypt(mbedtls_pk_context *ctx,
|
|||||||
* \param pub Context holding a public key.
|
* \param pub Context holding a public key.
|
||||||
* \param prv Context holding a private (and public) key.
|
* \param prv Context holding a private (and public) key.
|
||||||
*
|
*
|
||||||
* \return 0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA
|
* \return \c 0 on success (keys were checked and match each other).
|
||||||
|
* \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the keys could not
|
||||||
|
* be checked - in that case they may or may not match.
|
||||||
|
* \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA if a context is invalid.
|
||||||
|
* \return Another non-zero value if the keys do not match.
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_check_pair(const mbedtls_pk_context *pub, const mbedtls_pk_context *prv);
|
int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Export debug information
|
* \brief Export debug information
|
||||||
*
|
*
|
||||||
* \param ctx Context to use
|
* \param ctx The PK context to use. It must have been initialized.
|
||||||
* \param items Place to write debug items
|
* \param items Place to write debug items
|
||||||
*
|
*
|
||||||
* \return 0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA
|
* \return 0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_debug(const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items);
|
int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Access the type name
|
* \brief Access the type name
|
||||||
*
|
*
|
||||||
* \param ctx Context to use
|
* \param ctx The PK context to use. It must have been initialized.
|
||||||
*
|
*
|
||||||
* \return Type name on success, or "invalid PK"
|
* \return Type name on success, or "invalid PK"
|
||||||
*/
|
*/
|
||||||
const char *mbedtls_pk_get_name(const mbedtls_pk_context *ctx);
|
const char * mbedtls_pk_get_name( const mbedtls_pk_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Get the key type
|
* \brief Get the key type
|
||||||
*
|
*
|
||||||
* \param ctx Context to use
|
* \param ctx The PK context to use. It must have been initialized.
|
||||||
*
|
*
|
||||||
* \return Type on success, or MBEDTLS_PK_NONE
|
* \return Type on success.
|
||||||
|
* \return #MBEDTLS_PK_NONE for a context that has not been set up.
|
||||||
*/
|
*/
|
||||||
mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx);
|
mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx );
|
||||||
|
|
||||||
#if defined(MBEDTLS_PK_PARSE_C)
|
#if defined(MBEDTLS_PK_PARSE_C)
|
||||||
/** \ingroup pk_module */
|
/** \ingroup pk_module */
|
||||||
/**
|
/**
|
||||||
* \brief Parse a private key in PEM or DER format
|
* \brief Parse a private key in PEM or DER format
|
||||||
*
|
*
|
||||||
* \param ctx key to be initialized
|
* \param ctx The PK context to fill. It must have been initialized
|
||||||
* \param key input buffer
|
* but not set up.
|
||||||
* \param keylen size of the buffer
|
* \param key Input buffer to parse.
|
||||||
* (including the terminating null byte for PEM data)
|
* The buffer must contain the input exactly, with no
|
||||||
* \param pwd password for decryption (optional)
|
* extra trailing material. For PEM, the buffer must
|
||||||
* \param pwdlen size of the password
|
* 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.
|
||||||
*
|
*
|
||||||
* \note On entry, ctx must be empty, either freshly initialised
|
* \note On entry, ctx must be empty, either freshly initialised
|
||||||
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
|
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
|
||||||
@@ -444,18 +671,23 @@ mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx);
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or a specific PK or PEM error code
|
* \return 0 if successful, or a specific PK or PEM error code
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_parse_key(mbedtls_pk_context *ctx,
|
int mbedtls_pk_parse_key( mbedtls_pk_context *ctx,
|
||||||
const unsigned char *key, size_t keylen,
|
const unsigned char *key, size_t keylen,
|
||||||
const unsigned char *pwd, size_t pwdlen);
|
const unsigned char *pwd, size_t pwdlen );
|
||||||
|
|
||||||
/** \ingroup pk_module */
|
/** \ingroup pk_module */
|
||||||
/**
|
/**
|
||||||
* \brief Parse a public key in PEM or DER format
|
* \brief Parse a public key in PEM or DER format
|
||||||
*
|
*
|
||||||
* \param ctx key to be initialized
|
* \param ctx The PK context to fill. It must have been initialized
|
||||||
* \param key input buffer
|
* but not set up.
|
||||||
* \param keylen size of the buffer
|
* \param key Input buffer to parse.
|
||||||
* (including the terminating null byte for PEM data)
|
* 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`.
|
||||||
*
|
*
|
||||||
* \note On entry, ctx must be empty, either freshly initialised
|
* \note On entry, ctx must be empty, either freshly initialised
|
||||||
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
|
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
|
||||||
@@ -465,17 +697,22 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *ctx,
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or a specific PK or PEM error code
|
* \return 0 if successful, or a specific PK or PEM error code
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_parse_public_key(mbedtls_pk_context *ctx,
|
int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
|
||||||
const unsigned char *key, size_t keylen);
|
const unsigned char *key, size_t keylen );
|
||||||
|
|
||||||
#if defined(MBEDTLS_FS_IO)
|
#if defined(MBEDTLS_FS_IO)
|
||||||
/** \ingroup pk_module */
|
/** \ingroup pk_module */
|
||||||
/**
|
/**
|
||||||
* \brief Load and parse a private key
|
* \brief Load and parse a private key
|
||||||
*
|
*
|
||||||
* \param ctx key to be initialized
|
* \param ctx The PK context to fill. It must have been initialized
|
||||||
|
* but not set up.
|
||||||
* \param path filename to read the private key from
|
* \param path filename to read the private key from
|
||||||
* \param password password to decrypt the file (can be NULL)
|
* \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.
|
||||||
*
|
*
|
||||||
* \note On entry, ctx must be empty, either freshly initialised
|
* \note On entry, ctx must be empty, either freshly initialised
|
||||||
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
|
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
|
||||||
@@ -485,14 +722,15 @@ int mbedtls_pk_parse_public_key(mbedtls_pk_context *ctx,
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or a specific PK or PEM error code
|
* \return 0 if successful, or a specific PK or PEM error code
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_parse_keyfile(mbedtls_pk_context *ctx,
|
int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
|
||||||
const char *path, const char *password);
|
const char *path, const char *password );
|
||||||
|
|
||||||
/** \ingroup pk_module */
|
/** \ingroup pk_module */
|
||||||
/**
|
/**
|
||||||
* \brief Load and parse a public key
|
* \brief Load and parse a public key
|
||||||
*
|
*
|
||||||
* \param ctx key to be initialized
|
* \param ctx The PK context to fill. It must have been initialized
|
||||||
|
* but not set up.
|
||||||
* \param path filename to read the public key from
|
* \param path filename to read the public key from
|
||||||
*
|
*
|
||||||
* \note On entry, ctx must be empty, either freshly initialised
|
* \note On entry, ctx must be empty, either freshly initialised
|
||||||
@@ -504,7 +742,7 @@ int mbedtls_pk_parse_keyfile(mbedtls_pk_context *ctx,
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or a specific PK or PEM error code
|
* \return 0 if successful, or a specific PK or PEM error code
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_parse_public_keyfile(mbedtls_pk_context *ctx, const char *path);
|
int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path );
|
||||||
#endif /* MBEDTLS_FS_IO */
|
#endif /* MBEDTLS_FS_IO */
|
||||||
#endif /* MBEDTLS_PK_PARSE_C */
|
#endif /* MBEDTLS_PK_PARSE_C */
|
||||||
|
|
||||||
@@ -515,14 +753,14 @@ int mbedtls_pk_parse_public_keyfile(mbedtls_pk_context *ctx, const char *path);
|
|||||||
* return value to determine where you should start
|
* return value to determine where you should start
|
||||||
* using the buffer
|
* using the buffer
|
||||||
*
|
*
|
||||||
* \param ctx private to write away
|
* \param ctx PK context which must contain a valid private key.
|
||||||
* \param buf buffer to write to
|
* \param buf buffer to write to
|
||||||
* \param size size of the buffer
|
* \param size size of the buffer
|
||||||
*
|
*
|
||||||
* \return length of data written if successful, or a specific
|
* \return length of data written if successful, or a specific
|
||||||
* error code
|
* error code
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_write_key_der(mbedtls_pk_context *ctx, unsigned char *buf, size_t size);
|
int mbedtls_pk_write_key_der( mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Write a public key to a SubjectPublicKeyInfo DER structure
|
* \brief Write a public key to a SubjectPublicKeyInfo DER structure
|
||||||
@@ -530,37 +768,39 @@ int mbedtls_pk_write_key_der(mbedtls_pk_context *ctx, unsigned char *buf, size_t
|
|||||||
* return value to determine where you should start
|
* return value to determine where you should start
|
||||||
* using the buffer
|
* using the buffer
|
||||||
*
|
*
|
||||||
* \param ctx public key to write away
|
* \param ctx PK context which must contain a valid public or private key.
|
||||||
* \param buf buffer to write to
|
* \param buf buffer to write to
|
||||||
* \param size size of the buffer
|
* \param size size of the buffer
|
||||||
*
|
*
|
||||||
* \return length of data written if successful, or a specific
|
* \return length of data written if successful, or a specific
|
||||||
* error code
|
* error code
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_write_pubkey_der(mbedtls_pk_context *ctx, unsigned char *buf, size_t size);
|
int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
|
||||||
|
|
||||||
#if defined(MBEDTLS_PEM_WRITE_C)
|
#if defined(MBEDTLS_PEM_WRITE_C)
|
||||||
/**
|
/**
|
||||||
* \brief Write a public key to a PEM string
|
* \brief Write a public key to a PEM string
|
||||||
*
|
*
|
||||||
* \param ctx public key to write away
|
* \param ctx PK context which must contain a valid public or private key.
|
||||||
* \param buf buffer to write to
|
* \param buf Buffer to write to. The output includes a
|
||||||
* \param size size of the buffer
|
* terminating null byte.
|
||||||
|
* \param size Size of the buffer in bytes.
|
||||||
*
|
*
|
||||||
* \return 0 if successful, or a specific error code
|
* \return 0 if successful, or a specific error code
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_write_pubkey_pem(mbedtls_pk_context *ctx, unsigned char *buf, size_t size);
|
int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Write a private key to a PKCS#1 or SEC1 PEM string
|
* \brief Write a private key to a PKCS#1 or SEC1 PEM string
|
||||||
*
|
*
|
||||||
* \param ctx private to write away
|
* \param ctx PK context which must contain a valid private key.
|
||||||
* \param buf buffer to write to
|
* \param buf Buffer to write to. The output includes a
|
||||||
* \param size size of the buffer
|
* terminating null byte.
|
||||||
|
* \param size Size of the buffer in bytes.
|
||||||
*
|
*
|
||||||
* \return 0 if successful, or a specific error code
|
* \return 0 if successful, or a specific error code
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_write_key_pem(mbedtls_pk_context *ctx, unsigned char *buf, size_t size);
|
int mbedtls_pk_write_key_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
|
||||||
#endif /* MBEDTLS_PEM_WRITE_C */
|
#endif /* MBEDTLS_PEM_WRITE_C */
|
||||||
#endif /* MBEDTLS_PK_WRITE_C */
|
#endif /* MBEDTLS_PK_WRITE_C */
|
||||||
|
|
||||||
@@ -575,12 +815,13 @@ int mbedtls_pk_write_key_pem(mbedtls_pk_context *ctx, unsigned char *buf, size_t
|
|||||||
*
|
*
|
||||||
* \param p the position in the ASN.1 data
|
* \param p the position in the ASN.1 data
|
||||||
* \param end end of the buffer
|
* \param end end of the buffer
|
||||||
* \param pk the key to fill
|
* \param pk The PK context to fill. It must have been initialized
|
||||||
|
* but not set up.
|
||||||
*
|
*
|
||||||
* \return 0 if successful, or a specific PK error code
|
* \return 0 if successful, or a specific PK error code
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end,
|
int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
|
||||||
mbedtls_pk_context *pk);
|
mbedtls_pk_context *pk );
|
||||||
#endif /* MBEDTLS_PK_PARSE_C */
|
#endif /* MBEDTLS_PK_PARSE_C */
|
||||||
|
|
||||||
#if defined(MBEDTLS_PK_WRITE_C)
|
#if defined(MBEDTLS_PK_WRITE_C)
|
||||||
@@ -590,12 +831,12 @@ int mbedtls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end,
|
|||||||
*
|
*
|
||||||
* \param p reference to current position pointer
|
* \param p reference to current position pointer
|
||||||
* \param start start of the buffer (for bounds-checking)
|
* \param start start of the buffer (for bounds-checking)
|
||||||
* \param key public key to write away
|
* \param key PK context which must contain a valid public or private key.
|
||||||
*
|
*
|
||||||
* \return the length written or a negative error code
|
* \return the length written or a negative error code
|
||||||
*/
|
*/
|
||||||
int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start,
|
int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
|
||||||
const mbedtls_pk_context *key);
|
const mbedtls_pk_context *key );
|
||||||
#endif /* MBEDTLS_PK_WRITE_C */
|
#endif /* MBEDTLS_PK_WRITE_C */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -603,9 +844,35 @@ int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start,
|
|||||||
* know you do.
|
* know you do.
|
||||||
*/
|
*/
|
||||||
#if defined(MBEDTLS_FS_IO)
|
#if defined(MBEDTLS_FS_IO)
|
||||||
int mbedtls_pk_load_file(const char *path, unsigned char **buf, size_t *n);
|
int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||||
|
/**
|
||||||
|
* \brief Turn an EC key into an opaque one.
|
||||||
|
*
|
||||||
|
* \warning This is a temporary utility function for tests. It might
|
||||||
|
* change or be removed at any time without notice.
|
||||||
|
*
|
||||||
|
* \note Only ECDSA keys are supported so far. Signing with the
|
||||||
|
* specified hash is the only allowed use of that key.
|
||||||
|
*
|
||||||
|
* \param pk Input: the EC key to import to a PSA key.
|
||||||
|
* Output: a PK context wrapping that PSA key.
|
||||||
|
* \param key Output: a PSA key identifier.
|
||||||
|
* It's the caller's responsibility to call
|
||||||
|
* psa_destroy_key() on that key identifier after calling
|
||||||
|
* mbedtls_pk_free() on the PK context.
|
||||||
|
* \param hash_alg The hash algorithm to allow for use with that key.
|
||||||
|
*
|
||||||
|
* \return \c 0 if successful.
|
||||||
|
* \return An Mbed TLS error code otherwise.
|
||||||
|
*/
|
||||||
|
int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
|
||||||
|
psa_key_id_t *key,
|
||||||
|
psa_algorithm_t hash_alg );
|
||||||
|
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user