add: cryptolibs needed in emv,

moved aes, des into here.
This commit is contained in:
iceman1001 2017-12-24 10:21:28 +01:00
parent 1deb171573
commit 5d55807f37
14 changed files with 12405 additions and 0 deletions

1454
common/polarssl/aes.c Normal file

File diff suppressed because it is too large Load diff

256
common/polarssl/aes.h Normal file
View file

@ -0,0 +1,256 @@
/**
* \file aes.h
*
* \brief AES block cipher
*
* Copyright (C) 2006-2014, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* 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.
*/
#ifndef POLARSSL_AES_H
#define POLARSSL_AES_H
#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl_config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif
#include <string.h>
#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
#include <basetsd.h>
typedef UINT32 uint32_t;
#else
#include <inttypes.h>
#endif
/* padlock.c and aesni.c rely on these values! */
#define AES_ENCRYPT 1
#define AES_DECRYPT 0
#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
#if !defined(POLARSSL_AES_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief AES context structure
*
* \note buf is able to hold 32 extra bytes, which can be used:
* - for alignment purposes if VIA padlock is used, and/or
* - to simplify key expansion in the 256-bit case by
* generating an extra round key
*/
typedef struct
{
int nr; /*!< number of rounds */
uint32_t *rk; /*!< AES round keys */
uint32_t buf[68]; /*!< unaligned data */
}
aes_context;
/**
* \brief Initialize AES context
*
* \param ctx AES context to be initialized
*/
void aes_init( aes_context *ctx );
/**
* \brief Clear AES context
*
* \param ctx AES context to be cleared
*/
void aes_free( aes_context *ctx );
/**
* \brief AES key schedule (encryption)
*
* \param ctx AES context to be initialized
* \param key encryption key
* \param keysize must be 128, 192 or 256
*
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
*/
int aes_setkey_enc( aes_context *ctx, const unsigned char *key,
unsigned int keysize );
/**
* \brief AES key schedule (decryption)
*
* \param ctx AES context to be initialized
* \param key decryption key
* \param keysize must be 128, 192 or 256
*
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
*/
int aes_setkey_dec( aes_context *ctx, const unsigned char *key,
unsigned int keysize );
/**
* \brief AES-ECB block encryption/decryption
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return 0 if successful
*/
int aes_crypt_ecb( aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
#if defined(POLARSSL_CIPHER_MODE_CBC)
/**
* \brief AES-CBC buffer encryption/decryption
* Length should be a multiple of the block
* size (16 bytes)
*
* \param ctx AES context
* \param mode AES_ENCRYPT or 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 successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH
*/
int aes_crypt_cbc( aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#endif /* POLARSSL_CIPHER_MODE_CBC */
#if defined(POLARSSL_CIPHER_MODE_CFB)
/**
* \brief AES-CFB128 buffer encryption/decryption.
*
* Note: Due to the nature of CFB you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param length length of the input data
* \param iv_off offset in IV (updated after use)
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful
*/
int aes_crypt_cfb128( aes_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
/**
* \brief AES-CFB8 buffer encryption/decryption.
*
* Note: Due to the nature of CFB you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
*
* \param ctx AES context
* \param mode AES_ENCRYPT or 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 successful
*/
int aes_crypt_cfb8( aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#endif /*POLARSSL_CIPHER_MODE_CFB */
#if defined(POLARSSL_CIPHER_MODE_CTR)
/**
* \brief AES-CTR buffer encryption/decryption
*
* Warning: You have to keep the maximum use of your counter in mind!
*
* Note: Due to the nature of CTR you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
*
* \param ctx AES context
* \param length The length of the data
* \param nc_off The offset in the current stream_block (for resuming
* within current cipher stream). The offset pointer to
* should be 0 at the start of a stream.
* \param nonce_counter The 128-bit nonce and counter.
* \param stream_block The saved stream-block for resuming. Is overwritten
* by the function.
* \param input The input data stream
* \param output The output data stream
*
* \return 0 if successful
*/
int aes_crypt_ctr( aes_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[16],
unsigned char stream_block[16],
const unsigned char *input,
unsigned char *output );
#endif /* POLARSSL_CIPHER_MODE_CTR */
#ifdef __cplusplus
}
#endif
#else /* POLARSSL_AES_ALT */
#include "aes_alt.h"
#endif /* POLARSSL_AES_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int aes_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* aes.h */

2143
common/polarssl/bignum.c Normal file

File diff suppressed because it is too large Load diff

685
common/polarssl/bignum.h Normal file
View file

@ -0,0 +1,685 @@
/**
* \file bignum.h
*
* \brief Multi-precision integer library
*
* Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* 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.
*/
#ifndef POLARSSL_BIGNUM_H
#define POLARSSL_BIGNUM_H
#include <stdio.h>
#include <string.h>
#include "polarssl_config.h"
#ifdef _MSC_VER
#include <basetsd.h>
#if (_MSC_VER <= 1200)
typedef signed short int16_t;
typedef unsigned short uint16_t;
#else
typedef INT16 int16_t;
typedef UINT16 uint16_t;
#endif
typedef INT32 int32_t;
typedef INT64 int64_t;
typedef UINT32 uint32_t;
typedef UINT64 uint64_t;
#else
#include <inttypes.h>
#endif
#define POLARSSL_ERR_MPI_FILE_IO_ERROR -0x0002 /**< An error occurred while reading from or writing to a file. */
#define POLARSSL_ERR_MPI_BAD_INPUT_DATA -0x0004 /**< Bad input parameters to function. */
#define POLARSSL_ERR_MPI_INVALID_CHARACTER -0x0006 /**< There is an invalid character in the digit string. */
#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL -0x0008 /**< The buffer is too small to write to. */
#define POLARSSL_ERR_MPI_NEGATIVE_VALUE -0x000A /**< The input arguments are negative or result in illegal output. */
#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO -0x000C /**< The input argument for division is zero, which is not allowed. */
#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */
#define POLARSSL_ERR_MPI_MALLOC_FAILED -0x0010 /**< Memory allocation failed. */
#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
/*
* Maximum size MPIs are allowed to grow to in number of limbs.
*/
#define POLARSSL_MPI_MAX_LIMBS 10000
#if !defined(POLARSSL_CONFIG_OPTIONS)
/*
* Maximum window size used for modular exponentiation. Default: 6
* Minimum value: 1. Maximum value: 6.
*
* Result is an array of ( 2 << POLARSSL_MPI_WINDOW_SIZE ) MPIs used
* for the sliding window calculation. (So 64 by default)
*
* Reduction in size, reduces speed.
*/
#define POLARSSL_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */
/*
* Maximum size of MPIs allowed in bits and bytes for user-MPIs.
* ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits )
*
* Note: Calculations can results temporarily in larger MPIs. So the number
* of limbs required (POLARSSL_MPI_MAX_LIMBS) is higher.
*/
#define POLARSSL_MPI_MAX_SIZE 512 /**< Maximum number of bytes for usable MPIs. */
#endif /* !POLARSSL_CONFIG_OPTIONS */
#define POLARSSL_MPI_MAX_BITS ( 8 * POLARSSL_MPI_MAX_SIZE ) /**< Maximum number of bits for usable MPIs. */
/*
* When reading from files with mpi_read_file() and writing to files with
* mpi_write_file() the buffer should have space
* for a (short) label, the MPI (in the provided radix), the newline
* characters and the '\0'.
*
* By default we assume at least a 10 char label, a minimum radix of 10
* (decimal) and a maximum of 4096 bit numbers (1234 decimal chars).
* Autosized at compile time for at least a 10 char label, a minimum radix
* of 10 (decimal) for a number of POLARSSL_MPI_MAX_BITS size.
*
* This used to be statically sized to 1250 for a maximum of 4096 bit
* numbers (1234 decimal chars).
*
* Calculate using the formula:
* POLARSSL_MPI_RW_BUFFER_SIZE = ceil(POLARSSL_MPI_MAX_BITS / ln(10) * ln(2)) +
* LabelSize + 6
*/
#define POLARSSL_MPI_MAX_BITS_SCALE100 ( 100 * POLARSSL_MPI_MAX_BITS )
#define LN_2_DIV_LN_10_SCALE100 332
#define POLARSSL_MPI_RW_BUFFER_SIZE ( ((POLARSSL_MPI_MAX_BITS_SCALE100 + LN_2_DIV_LN_10_SCALE100 - 1) / LN_2_DIV_LN_10_SCALE100) + 10 + 6 )
/*
* Define the base integer type, architecture-wise
*/
#if defined(POLARSSL_HAVE_INT8)
typedef signed char t_sint;
typedef unsigned char t_uint;
typedef uint16_t t_udbl;
#define POLARSSL_HAVE_UDBL
#else
#if defined(POLARSSL_HAVE_INT16)
typedef int16_t t_sint;
typedef uint16_t t_uint;
typedef uint32_t t_udbl;
#define POLARSSL_HAVE_UDBL
#else
#if ( defined(_MSC_VER) && defined(_M_AMD64) )
typedef int64_t t_sint;
typedef uint64_t t_uint;
#else
#if ( defined(__GNUC__) && ( \
defined(__amd64__) || defined(__x86_64__) || \
defined(__ppc64__) || defined(__powerpc64__) || \
defined(__ia64__) || defined(__alpha__) || \
(defined(__sparc__) && defined(__arch64__)) || \
defined(__s390x__) ) )
typedef int64_t t_sint;
typedef uint64_t t_uint;
typedef unsigned int t_udbl __attribute__((mode(TI)));
#define POLARSSL_HAVE_UDBL
#else
typedef int32_t t_sint;
typedef uint32_t t_uint;
#if ( defined(_MSC_VER) && defined(_M_IX86) )
typedef uint64_t t_udbl;
#define POLARSSL_HAVE_UDBL
#else
#if defined( POLARSSL_HAVE_LONGLONG )
typedef unsigned long long t_udbl;
#define POLARSSL_HAVE_UDBL
#endif
#endif
#endif
#endif
#endif /* POLARSSL_HAVE_INT16 */
#endif /* POLARSSL_HAVE_INT8 */
/**
* \brief MPI structure
*/
typedef struct
{
int s; /*!< integer sign */
size_t n; /*!< total # of limbs */
t_uint *p; /*!< pointer to limbs */
}
mpi;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Initialize one MPI
*
* \param X One MPI to initialize.
*/
void mpi_init( mpi *X );
/**
* \brief Unallocate one MPI
*
* \param X One MPI to unallocate.
*/
void mpi_free( mpi *X );
/**
* \brief Enlarge to the specified number of limbs
*
* \param X MPI to grow
* \param nblimbs The target number of limbs
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_grow( mpi *X, size_t nblimbs );
/**
* \brief Copy the contents of Y into X
*
* \param X Destination MPI
* \param Y Source MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_copy( mpi *X, const mpi *Y );
/**
* \brief Swap the contents of X and Y
*
* \param X First MPI value
* \param Y Second MPI value
*/
void mpi_swap( mpi *X, mpi *Y );
/**
* \brief Set value from integer
*
* \param X MPI to set
* \param z Value to use
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_lset( mpi *X, t_sint z );
/**
* \brief Get a specific bit from X
*
* \param X MPI to use
* \param pos Zero-based index of the bit in X
*
* \return Either a 0 or a 1
*/
int mpi_get_bit( const mpi *X, size_t pos );
/**
* \brief Set a bit of X to a specific value of 0 or 1
*
* \note Will grow X if necessary to set a bit to 1 in a not yet
* existing limb. Will not grow if bit should be set to 0
*
* \param X MPI to use
* \param pos Zero-based index of the bit in X
* \param val The value to set the bit to (0 or 1)
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if val is not 0 or 1
*/
int mpi_set_bit( mpi *X, size_t pos, unsigned char val );
/**
* \brief Return the number of zero-bits before the least significant
* '1' bit
*
* Note: Thus also the zero-based index of the least significant '1' bit
*
* \param X MPI to use
*/
size_t mpi_lsb( const mpi *X );
/**
* \brief Return the number of bits up to and including the most
* significant '1' bit'
*
* Note: Thus also the one-based index of the most significant '1' bit
*
* \param X MPI to use
*/
size_t mpi_msb( const mpi *X );
/**
* \brief Return the total size in bytes
*
* \param X MPI to use
*/
size_t mpi_size( const mpi *X );
/**
* \brief Import from an ASCII string
*
* \param X Destination MPI
* \param radix Input numeric base
* \param s Null-terminated string buffer
*
* \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code
*/
int mpi_read_string( mpi *X, int radix, const char *s );
/**
* \brief Export into an ASCII string
*
* \param X Source MPI
* \param radix Output numeric base
* \param s String buffer
* \param slen String buffer size
*
* \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code.
* *slen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* \note Call this function with *slen = 0 to obtain the
* minimum required buffer size in *slen.
*/
int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen );
#if defined(POLARSSL_FS_IO)
/**
* \brief Read X from an opened file
*
* \param X Destination MPI
* \param radix Input numeric base
* \param fin Input file handle
*
* \return 0 if successful, POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if
* the file read buffer is too small or a
* POLARSSL_ERR_MPI_XXX error code
*/
int mpi_read_file( mpi *X, int radix, FILE *fin );
/**
* \brief Write X into an opened file, or stdout if fout is NULL
*
* \param p Prefix, can be NULL
* \param X Source MPI
* \param radix Output numeric base
* \param fout Output file handle (can be NULL)
*
* \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code
*
* \note Set fout == NULL to print X on the console.
*/
int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout );
#endif /* POLARSSL_FS_IO */
/**
* \brief Import X from unsigned binary data, big endian
*
* \param X Destination MPI
* \param buf Input buffer
* \param buflen Input buffer size
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen );
/**
* \brief Export X into unsigned binary data, big endian
*
* \param X Source MPI
* \param buf Output buffer
* \param buflen Output buffer size
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
*/
int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen );
/**
* \brief Left-shift: X <<= count
*
* \param X MPI to shift
* \param count Amount to shift
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_shift_l( mpi *X, size_t count );
/**
* \brief Right-shift: X >>= count
*
* \param X MPI to shift
* \param count Amount to shift
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_shift_r( mpi *X, size_t count );
/**
* \brief Compare unsigned values
*
* \param X Left-hand MPI
* \param Y Right-hand MPI
*
* \return 1 if |X| is greater than |Y|,
* -1 if |X| is lesser than |Y| or
* 0 if |X| is equal to |Y|
*/
int mpi_cmp_abs( const mpi *X, const mpi *Y );
/**
* \brief Compare signed values
*
* \param X Left-hand MPI
* \param Y Right-hand MPI
*
* \return 1 if X is greater than Y,
* -1 if X is lesser than Y or
* 0 if X is equal to Y
*/
int mpi_cmp_mpi( const mpi *X, const mpi *Y );
/**
* \brief Compare signed values
*
* \param X Left-hand MPI
* \param z The integer value to compare to
*
* \return 1 if X is greater than z,
* -1 if X is lesser than z or
* 0 if X is equal to z
*/
int mpi_cmp_int( const mpi *X, t_sint z );
/**
* \brief Unsigned addition: X = |A| + |B|
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_add_abs( mpi *X, const mpi *A, const mpi *B );
/**
* \brief Unsigned substraction: X = |A| - |B|
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
*/
int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B );
/**
* \brief Signed addition: X = A + B
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B );
/**
* \brief Signed substraction: X = A - B
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B );
/**
* \brief Signed addition: X = A + b
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param b The integer value to add
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_add_int( mpi *X, const mpi *A, t_sint b );
/**
* \brief Signed substraction: X = A - b
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param b The integer value to subtract
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_sub_int( mpi *X, const mpi *A, t_sint b );
/**
* \brief Baseline multiplication: X = A * B
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B );
/**
* \brief Baseline multiplication: X = A * b
* Note: b is an unsigned integer type, thus
* Negative values of b are ignored.
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param b The integer value to multiply with
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_mul_int( mpi *X, const mpi *A, t_sint b );
/**
* \brief Division by mpi: A = Q * B + R
*
* \param Q Destination MPI for the quotient
* \param R Destination MPI for the rest value
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
*
* \note Either Q or R can be NULL.
*/
int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B );
/**
* \brief Division by int: A = Q * b + R
*
* \param Q Destination MPI for the quotient
* \param R Destination MPI for the rest value
* \param A Left-hand MPI
* \param b Integer to divide by
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
*
* \note Either Q or R can be NULL.
*/
int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b );
/**
* \brief Modulo: R = A mod B
*
* \param R Destination MPI for the rest value
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0,
* POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0
*/
int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B );
/**
* \brief Modulo: r = A mod b
*
* \param r Destination t_uint
* \param A Left-hand MPI
* \param b Integer to divide by
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0,
* POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0
*/
int mpi_mod_int( t_uint *r, const mpi *A, t_sint b );
/**
* \brief Sliding-window exponentiation: X = A^E mod N
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param E Exponent MPI
* \param N Modular MPI
* \param _RR Speed-up MPI used for recalculations
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even or if
* E is negative
*
* \note _RR is used to avoid re-computing R*R mod N across
* multiple calls, which speeds up things a bit. It can
* be set to NULL if the extra performance is unneeded.
*/
int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR );
/**
* \brief Fill an MPI X with size bytes of random
*
* \param X Destination MPI
* \param size Size in bytes
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_fill_random( mpi *X, size_t size,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Greatest common divisor: G = gcd(A, B)
*
* \param G Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_gcd( mpi *G, const mpi *A, const mpi *B );
/**
* \brief Modular inverse: X = A^-1 mod N
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param N Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
*/
int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N );
/**
* \brief Miller-Rabin primality test
*
* \param X MPI to check
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful (probably prime),
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
*/
int mpi_is_prime( mpi *X,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Prime number generation
*
* \param X Destination MPI
* \param nbits Required size of X in bits ( 3 <= nbits <= POLARSSL_MPI_MAX_BITS )
* \param dh_flag If 1, then (X-1)/2 will be prime too
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful (probably prime),
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
*/
int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mpi_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* bignum.h */

864
common/polarssl/bn_mul.h Normal file
View file

@ -0,0 +1,864 @@
/**
* \file bn_mul.h
*
* \brief Multi-precision integer library
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* 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.
*/
/*
* Multiply source vector [s] with b, add result
* to destination vector [d] and set carry c.
*
* Currently supports:
*
* . IA-32 (386+) . AMD64 / EM64T
* . IA-32 (SSE2) . Motorola 68000
* . PowerPC, 32-bit . MicroBlaze
* . PowerPC, 64-bit . TriCore
* . SPARC v8 . ARM v3+
* . Alpha . MIPS32
* . C, longlong . C, generic
*/
#ifndef POLARSSL_BN_MUL_H
#define POLARSSL_BN_MUL_H
#include "bignum.h"
#if defined(POLARSSL_HAVE_ASM)
#if defined(__GNUC__)
#if defined(__i386__)
#define MULADDC_INIT \
asm( " \
movl %%ebx, %0; \
movl %5, %%esi; \
movl %6, %%edi; \
movl %7, %%ecx; \
movl %8, %%ebx; \
"
#define MULADDC_CORE \
" \
lodsl; \
mull %%ebx; \
addl %%ecx, %%eax; \
adcl $0, %%edx; \
addl (%%edi), %%eax; \
adcl $0, %%edx; \
movl %%edx, %%ecx; \
stosl; \
"
#if defined(POLARSSL_HAVE_SSE2)
#define MULADDC_HUIT \
" \
movd %%ecx, %%mm1; \
movd %%ebx, %%mm0; \
movd (%%edi), %%mm3; \
paddq %%mm3, %%mm1; \
movd (%%esi), %%mm2; \
pmuludq %%mm0, %%mm2; \
movd 4(%%esi), %%mm4; \
pmuludq %%mm0, %%mm4; \
movd 8(%%esi), %%mm6; \
pmuludq %%mm0, %%mm6; \
movd 12(%%esi), %%mm7; \
pmuludq %%mm0, %%mm7; \
paddq %%mm2, %%mm1; \
movd 4(%%edi), %%mm3; \
paddq %%mm4, %%mm3; \
movd 8(%%edi), %%mm5; \
paddq %%mm6, %%mm5; \
movd 12(%%edi), %%mm4; \
paddq %%mm4, %%mm7; \
movd %%mm1, (%%edi); \
movd 16(%%esi), %%mm2; \
pmuludq %%mm0, %%mm2; \
psrlq $32, %%mm1; \
movd 20(%%esi), %%mm4; \
pmuludq %%mm0, %%mm4; \
paddq %%mm3, %%mm1; \
movd 24(%%esi), %%mm6; \
pmuludq %%mm0, %%mm6; \
movd %%mm1, 4(%%edi); \
psrlq $32, %%mm1; \
movd 28(%%esi), %%mm3; \
pmuludq %%mm0, %%mm3; \
paddq %%mm5, %%mm1; \
movd 16(%%edi), %%mm5; \
paddq %%mm5, %%mm2; \
movd %%mm1, 8(%%edi); \
psrlq $32, %%mm1; \
paddq %%mm7, %%mm1; \
movd 20(%%edi), %%mm5; \
paddq %%mm5, %%mm4; \
movd %%mm1, 12(%%edi); \
psrlq $32, %%mm1; \
paddq %%mm2, %%mm1; \
movd 24(%%edi), %%mm5; \
paddq %%mm5, %%mm6; \
movd %%mm1, 16(%%edi); \
psrlq $32, %%mm1; \
paddq %%mm4, %%mm1; \
movd 28(%%edi), %%mm5; \
paddq %%mm5, %%mm3; \
movd %%mm1, 20(%%edi); \
psrlq $32, %%mm1; \
paddq %%mm6, %%mm1; \
movd %%mm1, 24(%%edi); \
psrlq $32, %%mm1; \
paddq %%mm3, %%mm1; \
movd %%mm1, 28(%%edi); \
addl $32, %%edi; \
addl $32, %%esi; \
psrlq $32, %%mm1; \
movd %%mm1, %%ecx; \
"
#define MULADDC_STOP \
" \
emms; \
movl %4, %%ebx; \
movl %%ecx, %1; \
movl %%edi, %2; \
movl %%esi, %3; \
" \
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
: "eax", "ecx", "edx", "esi", "edi" \
);
#else
#define MULADDC_STOP \
" \
movl %4, %%ebx; \
movl %%ecx, %1; \
movl %%edi, %2; \
movl %%esi, %3; \
" \
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
: "eax", "ecx", "edx", "esi", "edi" \
);
#endif /* SSE2 */
#endif /* i386 */
#if defined(__amd64__) || defined (__x86_64__)
#define MULADDC_INIT \
asm( "movq %0, %%rsi " :: "m" (s)); \
asm( "movq %0, %%rdi " :: "m" (d)); \
asm( "movq %0, %%rcx " :: "m" (c)); \
asm( "movq %0, %%rbx " :: "m" (b)); \
asm( "xorq %r8, %r8 " );
#define MULADDC_CORE \
asm( "movq (%rsi),%rax " ); \
asm( "mulq %rbx " ); \
asm( "addq $8, %rsi " ); \
asm( "addq %rcx, %rax " ); \
asm( "movq %r8, %rcx " ); \
asm( "adcq $0, %rdx " ); \
asm( "nop " ); \
asm( "addq %rax, (%rdi) " ); \
asm( "adcq %rdx, %rcx " ); \
asm( "addq $8, %rdi " );
#define MULADDC_STOP \
asm( "movq %%rcx, %0 " : "=m" (c)); \
asm( "movq %%rdi, %0 " : "=m" (d)); \
asm( "movq %%rsi, %0 " : "=m" (s) :: \
"rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" );
#endif /* AMD64 */
#if defined(__mc68020__) || defined(__mcpu32__)
#define MULADDC_INIT \
asm( "movl %0, %%a2 " :: "m" (s)); \
asm( "movl %0, %%a3 " :: "m" (d)); \
asm( "movl %0, %%d3 " :: "m" (c)); \
asm( "movl %0, %%d2 " :: "m" (b)); \
asm( "moveq #0, %d0 " );
#define MULADDC_CORE \
asm( "movel %a2@+, %d1 " ); \
asm( "mulul %d2, %d4:%d1 " ); \
asm( "addl %d3, %d1 " ); \
asm( "addxl %d0, %d4 " ); \
asm( "moveq #0, %d3 " ); \
asm( "addl %d1, %a3@+ " ); \
asm( "addxl %d4, %d3 " );
#define MULADDC_STOP \
asm( "movl %%d3, %0 " : "=m" (c)); \
asm( "movl %%a3, %0 " : "=m" (d)); \
asm( "movl %%a2, %0 " : "=m" (s) :: \
"d0", "d1", "d2", "d3", "d4", "a2", "a3" );
#define MULADDC_HUIT \
asm( "movel %a2@+, %d1 " ); \
asm( "mulul %d2, %d4:%d1 " ); \
asm( "addxl %d3, %d1 " ); \
asm( "addxl %d0, %d4 " ); \
asm( "addl %d1, %a3@+ " ); \
asm( "movel %a2@+, %d1 " ); \
asm( "mulul %d2, %d3:%d1 " ); \
asm( "addxl %d4, %d1 " ); \
asm( "addxl %d0, %d3 " ); \
asm( "addl %d1, %a3@+ " ); \
asm( "movel %a2@+, %d1 " ); \
asm( "mulul %d2, %d4:%d1 " ); \
asm( "addxl %d3, %d1 " ); \
asm( "addxl %d0, %d4 " ); \
asm( "addl %d1, %a3@+ " ); \
asm( "movel %a2@+, %d1 " ); \
asm( "mulul %d2, %d3:%d1 " ); \
asm( "addxl %d4, %d1 " ); \
asm( "addxl %d0, %d3 " ); \
asm( "addl %d1, %a3@+ " ); \
asm( "movel %a2@+, %d1 " ); \
asm( "mulul %d2, %d4:%d1 " ); \
asm( "addxl %d3, %d1 " ); \
asm( "addxl %d0, %d4 " ); \
asm( "addl %d1, %a3@+ " ); \
asm( "movel %a2@+, %d1 " ); \
asm( "mulul %d2, %d3:%d1 " ); \
asm( "addxl %d4, %d1 " ); \
asm( "addxl %d0, %d3 " ); \
asm( "addl %d1, %a3@+ " ); \
asm( "movel %a2@+, %d1 " ); \
asm( "mulul %d2, %d4:%d1 " ); \
asm( "addxl %d3, %d1 " ); \
asm( "addxl %d0, %d4 " ); \
asm( "addl %d1, %a3@+ " ); \
asm( "movel %a2@+, %d1 " ); \
asm( "mulul %d2, %d3:%d1 " ); \
asm( "addxl %d4, %d1 " ); \
asm( "addxl %d0, %d3 " ); \
asm( "addl %d1, %a3@+ " ); \
asm( "addxl %d0, %d3 " );
#endif /* MC68000 */
#if defined(__powerpc__) || defined(__ppc__)
#if defined(__powerpc64__) || defined(__ppc64__)
#if defined(__MACH__) && defined(__APPLE__)
#define MULADDC_INIT \
asm( "ld r3, %0 " :: "m" (s)); \
asm( "ld r4, %0 " :: "m" (d)); \
asm( "ld r5, %0 " :: "m" (c)); \
asm( "ld r6, %0 " :: "m" (b)); \
asm( "addi r3, r3, -8 " ); \
asm( "addi r4, r4, -8 " ); \
asm( "addic r5, r5, 0 " );
#define MULADDC_CORE \
asm( "ldu r7, 8(r3) " ); \
asm( "mulld r8, r7, r6 " ); \
asm( "mulhdu r9, r7, r6 " ); \
asm( "adde r8, r8, r5 " ); \
asm( "ld r7, 8(r4) " ); \
asm( "addze r5, r9 " ); \
asm( "addc r8, r8, r7 " ); \
asm( "stdu r8, 8(r4) " );
#define MULADDC_STOP \
asm( "addze r5, r5 " ); \
asm( "addi r4, r4, 8 " ); \
asm( "addi r3, r3, 8 " ); \
asm( "std r5, %0 " : "=m" (c)); \
asm( "std r4, %0 " : "=m" (d)); \
asm( "std r3, %0 " : "=m" (s) :: \
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
#else
#define MULADDC_INIT \
asm( "ld %%r3, %0 " :: "m" (s)); \
asm( "ld %%r4, %0 " :: "m" (d)); \
asm( "ld %%r5, %0 " :: "m" (c)); \
asm( "ld %%r6, %0 " :: "m" (b)); \
asm( "addi %r3, %r3, -8 " ); \
asm( "addi %r4, %r4, -8 " ); \
asm( "addic %r5, %r5, 0 " );
#define MULADDC_CORE \
asm( "ldu %r7, 8(%r3) " ); \
asm( "mulld %r8, %r7, %r6 " ); \
asm( "mulhdu %r9, %r7, %r6 " ); \
asm( "adde %r8, %r8, %r5 " ); \
asm( "ld %r7, 8(%r4) " ); \
asm( "addze %r5, %r9 " ); \
asm( "addc %r8, %r8, %r7 " ); \
asm( "stdu %r8, 8(%r4) " );
#define MULADDC_STOP \
asm( "addze %r5, %r5 " ); \
asm( "addi %r4, %r4, 8 " ); \
asm( "addi %r3, %r3, 8 " ); \
asm( "std %%r5, %0 " : "=m" (c)); \
asm( "std %%r4, %0 " : "=m" (d)); \
asm( "std %%r3, %0 " : "=m" (s) :: \
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
#endif
#else /* PPC32 */
#if defined(__MACH__) && defined(__APPLE__)
#define MULADDC_INIT \
asm( "lwz r3, %0 " :: "m" (s)); \
asm( "lwz r4, %0 " :: "m" (d)); \
asm( "lwz r5, %0 " :: "m" (c)); \
asm( "lwz r6, %0 " :: "m" (b)); \
asm( "addi r3, r3, -4 " ); \
asm( "addi r4, r4, -4 " ); \
asm( "addic r5, r5, 0 " );
#define MULADDC_CORE \
asm( "lwzu r7, 4(r3) " ); \
asm( "mullw r8, r7, r6 " ); \
asm( "mulhwu r9, r7, r6 " ); \
asm( "adde r8, r8, r5 " ); \
asm( "lwz r7, 4(r4) " ); \
asm( "addze r5, r9 " ); \
asm( "addc r8, r8, r7 " ); \
asm( "stwu r8, 4(r4) " );
#define MULADDC_STOP \
asm( "addze r5, r5 " ); \
asm( "addi r4, r4, 4 " ); \
asm( "addi r3, r3, 4 " ); \
asm( "stw r5, %0 " : "=m" (c)); \
asm( "stw r4, %0 " : "=m" (d)); \
asm( "stw r3, %0 " : "=m" (s) :: \
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
#else
#define MULADDC_INIT \
asm( "lwz %%r3, %0 " :: "m" (s)); \
asm( "lwz %%r4, %0 " :: "m" (d)); \
asm( "lwz %%r5, %0 " :: "m" (c)); \
asm( "lwz %%r6, %0 " :: "m" (b)); \
asm( "addi %r3, %r3, -4 " ); \
asm( "addi %r4, %r4, -4 " ); \
asm( "addic %r5, %r5, 0 " );
#define MULADDC_CORE \
asm( "lwzu %r7, 4(%r3) " ); \
asm( "mullw %r8, %r7, %r6 " ); \
asm( "mulhwu %r9, %r7, %r6 " ); \
asm( "adde %r8, %r8, %r5 " ); \
asm( "lwz %r7, 4(%r4) " ); \
asm( "addze %r5, %r9 " ); \
asm( "addc %r8, %r8, %r7 " ); \
asm( "stwu %r8, 4(%r4) " );
#define MULADDC_STOP \
asm( "addze %r5, %r5 " ); \
asm( "addi %r4, %r4, 4 " ); \
asm( "addi %r3, %r3, 4 " ); \
asm( "stw %%r5, %0 " : "=m" (c)); \
asm( "stw %%r4, %0 " : "=m" (d)); \
asm( "stw %%r3, %0 " : "=m" (s) :: \
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
#endif
#endif /* PPC32 */
#endif /* PPC64 */
#if defined(__sparc__) && defined(__sparc64__)
#define MULADDC_INIT \
asm( \
" \
ldx %3, %%o0; \
ldx %4, %%o1; \
ld %5, %%o2; \
ld %6, %%o3; \
"
#define MULADDC_CORE \
" \
ld [%%o0], %%o4; \
inc 4, %%o0; \
ld [%%o1], %%o5; \
umul %%o3, %%o4, %%o4; \
addcc %%o4, %%o2, %%o4; \
rd %%y, %%g1; \
addx %%g1, 0, %%g1; \
addcc %%o4, %%o5, %%o4; \
st %%o4, [%%o1]; \
addx %%g1, 0, %%o2; \
inc 4, %%o1; \
"
#define MULADDC_STOP \
" \
st %%o2, %0; \
stx %%o1, %1; \
stx %%o0, %2; \
" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "g1", "o0", "o1", "o2", "o3", "o4", \
"o5" \
);
#endif /* SPARCv9 */
#if defined(__sparc__) && !defined(__sparc64__)
#define MULADDC_INIT \
asm( \
" \
ld %3, %%o0; \
ld %4, %%o1; \
ld %5, %%o2; \
ld %6, %%o3; \
"
#define MULADDC_CORE \
" \
ld [%%o0], %%o4; \
inc 4, %%o0; \
ld [%%o1], %%o5; \
umul %%o3, %%o4, %%o4; \
addcc %%o4, %%o2, %%o4; \
rd %%y, %%g1; \
addx %%g1, 0, %%g1; \
addcc %%o4, %%o5, %%o4; \
st %%o4, [%%o1]; \
addx %%g1, 0, %%o2; \
inc 4, %%o1; \
"
#define MULADDC_STOP \
" \
st %%o2, %0; \
st %%o1, %1; \
st %%o0, %2; \
" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "g1", "o0", "o1", "o2", "o3", "o4", \
"o5" \
);
#endif /* SPARCv8 */
#if defined(__microblaze__) || defined(microblaze)
#define MULADDC_INIT \
asm( "lwi r3, %0 " :: "m" (s)); \
asm( "lwi r4, %0 " :: "m" (d)); \
asm( "lwi r5, %0 " :: "m" (c)); \
asm( "lwi r6, %0 " :: "m" (b)); \
asm( "andi r7, r6, 0xffff" ); \
asm( "bsrli r6, r6, 16 " );
#define MULADDC_CORE \
asm( "lhui r8, r3, 0 " ); \
asm( "addi r3, r3, 2 " ); \
asm( "lhui r9, r3, 0 " ); \
asm( "addi r3, r3, 2 " ); \
asm( "mul r10, r9, r6 " ); \
asm( "mul r11, r8, r7 " ); \
asm( "mul r12, r9, r7 " ); \
asm( "mul r13, r8, r6 " ); \
asm( "bsrli r8, r10, 16 " ); \
asm( "bsrli r9, r11, 16 " ); \
asm( "add r13, r13, r8 " ); \
asm( "add r13, r13, r9 " ); \
asm( "bslli r10, r10, 16 " ); \
asm( "bslli r11, r11, 16 " ); \
asm( "add r12, r12, r10 " ); \
asm( "addc r13, r13, r0 " ); \
asm( "add r12, r12, r11 " ); \
asm( "addc r13, r13, r0 " ); \
asm( "lwi r10, r4, 0 " ); \
asm( "add r12, r12, r10 " ); \
asm( "addc r13, r13, r0 " ); \
asm( "add r12, r12, r5 " ); \
asm( "addc r5, r13, r0 " ); \
asm( "swi r12, r4, 0 " ); \
asm( "addi r4, r4, 4 " );
#define MULADDC_STOP \
asm( "swi r5, %0 " : "=m" (c)); \
asm( "swi r4, %0 " : "=m" (d)); \
asm( "swi r3, %0 " : "=m" (s) :: \
"r3", "r4" , "r5" , "r6" , "r7" , "r8" , \
"r9", "r10", "r11", "r12", "r13" );
#endif /* MicroBlaze */
#if defined(__tricore__)
#define MULADDC_INIT \
asm( "ld.a %%a2, %0 " :: "m" (s)); \
asm( "ld.a %%a3, %0 " :: "m" (d)); \
asm( "ld.w %%d4, %0 " :: "m" (c)); \
asm( "ld.w %%d1, %0 " :: "m" (b)); \
asm( "xor %d5, %d5 " );
#define MULADDC_CORE \
asm( "ld.w %d0, [%a2+] " ); \
asm( "madd.u %e2, %e4, %d0, %d1 " ); \
asm( "ld.w %d0, [%a3] " ); \
asm( "addx %d2, %d2, %d0 " ); \
asm( "addc %d3, %d3, 0 " ); \
asm( "mov %d4, %d3 " ); \
asm( "st.w [%a3+], %d2 " );
#define MULADDC_STOP \
asm( "st.w %0, %%d4 " : "=m" (c)); \
asm( "st.a %0, %%a3 " : "=m" (d)); \
asm( "st.a %0, %%a2 " : "=m" (s) :: \
"d0", "d1", "e2", "d4", "a2", "a3" );
#endif /* TriCore */
#if defined(__arm__)
#if defined(__thumb__) && !defined(__thumb2__)
#define MULADDC_INIT \
asm( \
" \
ldr r0, %3; \
ldr r1, %4; \
ldr r2, %5; \
ldr r3, %6; \
lsr r7, r3, #16; \
mov r9, r7; \
lsl r7, r3, #16; \
lsr r7, r7, #16; \
mov r8, r7; \
"
#define MULADDC_CORE \
" \
ldmia r0!, {r6}; \
lsr r7, r6, #16; \
lsl r6, r6, #16; \
lsr r6, r6, #16; \
mov r4, r8; \
mul r4, r6; \
mov r3, r9; \
mul r6, r3; \
mov r5, r9; \
mul r5, r7; \
mov r3, r8; \
mul r7, r3; \
lsr r3, r6, #16; \
add r5, r5, r3; \
lsr r3, r7, #16; \
add r5, r5, r3; \
add r4, r4, r2; \
mov r2, #0; \
adc r5, r2; \
lsl r3, r6, #16; \
add r4, r4, r3; \
adc r5, r2; \
lsl r3, r7, #16; \
add r4, r4, r3; \
adc r5, r2; \
ldr r3, [r1]; \
add r4, r4, r3; \
adc r2, r5; \
stmia r1!, {r4}; \
"
#define MULADDC_STOP \
" \
str r2, %0; \
str r1, %1; \
str r0, %2; \
" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r0", "r1", "r2", "r3", "r4", "r5", \
"r6", "r7", "r8", "r9", "cc" \
);
#else
#define MULADDC_INIT \
asm( \
" \
ldr r0, %3; \
ldr r1, %4; \
ldr r2, %5; \
ldr r3, %6; \
"
#define MULADDC_CORE \
" \
ldr r4, [r0], #4; \
mov r5, #0; \
ldr r6, [r1]; \
umlal r2, r5, r3, r4; \
adds r7, r6, r2; \
adc r2, r5, #0; \
str r7, [r1], #4; \
"
#define MULADDC_STOP \
" \
str r2, %0; \
str r1, %1; \
str r0, %2; \
" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r0", "r1", "r2", "r3", "r4", "r5", \
"r6", "r7", "cc" \
);
#endif /* Thumb */
#endif /* ARMv3 */
#if defined(__alpha__)
#define MULADDC_INIT \
asm( "ldq $1, %0 " :: "m" (s)); \
asm( "ldq $2, %0 " :: "m" (d)); \
asm( "ldq $3, %0 " :: "m" (c)); \
asm( "ldq $4, %0 " :: "m" (b));
#define MULADDC_CORE \
asm( "ldq $6, 0($1) " ); \
asm( "addq $1, 8, $1 " ); \
asm( "mulq $6, $4, $7 " ); \
asm( "umulh $6, $4, $6 " ); \
asm( "addq $7, $3, $7 " ); \
asm( "cmpult $7, $3, $3 " ); \
asm( "ldq $5, 0($2) " ); \
asm( "addq $7, $5, $7 " ); \
asm( "cmpult $7, $5, $5 " ); \
asm( "stq $7, 0($2) " ); \
asm( "addq $2, 8, $2 " ); \
asm( "addq $6, $3, $3 " ); \
asm( "addq $5, $3, $3 " );
#define MULADDC_STOP \
asm( "stq $3, %0 " : "=m" (c)); \
asm( "stq $2, %0 " : "=m" (d)); \
asm( "stq $1, %0 " : "=m" (s) :: \
"$1", "$2", "$3", "$4", "$5", "$6", "$7" );
#endif /* Alpha */
#if defined(__mips__)
#define MULADDC_INIT \
asm( "lw $10, %0 " :: "m" (s)); \
asm( "lw $11, %0 " :: "m" (d)); \
asm( "lw $12, %0 " :: "m" (c)); \
asm( "lw $13, %0 " :: "m" (b));
#define MULADDC_CORE \
asm( "lw $14, 0($10) " ); \
asm( "multu $13, $14 " ); \
asm( "addi $10, $10, 4 " ); \
asm( "mflo $14 " ); \
asm( "mfhi $9 " ); \
asm( "addu $14, $12, $14 " ); \
asm( "lw $15, 0($11) " ); \
asm( "sltu $12, $14, $12 " ); \
asm( "addu $15, $14, $15 " ); \
asm( "sltu $14, $15, $14 " ); \
asm( "addu $12, $12, $9 " ); \
asm( "sw $15, 0($11) " ); \
asm( "addu $12, $12, $14 " ); \
asm( "addi $11, $11, 4 " );
#define MULADDC_STOP \
asm( "sw $12, %0 " : "=m" (c)); \
asm( "sw $11, %0 " : "=m" (d)); \
asm( "sw $10, %0 " : "=m" (s) :: \
"$9", "$10", "$11", "$12", "$13", "$14", "$15" );
#endif /* MIPS */
#endif /* GNUC */
#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
#define MULADDC_INIT \
__asm mov esi, s \
__asm mov edi, d \
__asm mov ecx, c \
__asm mov ebx, b
#define MULADDC_CORE \
__asm lodsd \
__asm mul ebx \
__asm add eax, ecx \
__asm adc edx, 0 \
__asm add eax, [edi] \
__asm adc edx, 0 \
__asm mov ecx, edx \
__asm stosd
#if defined(POLARSSL_HAVE_SSE2)
#define EMIT __asm _emit
#define MULADDC_HUIT \
EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
EMIT 0x0F EMIT 0x6E EMIT 0x1F \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x6E EMIT 0x16 \
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
EMIT 0x0F EMIT 0x7E EMIT 0x0F \
EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x7E EMIT 0xC9
#define MULADDC_STOP \
EMIT 0x0F EMIT 0x77 \
__asm mov c, ecx \
__asm mov d, edi \
__asm mov s, esi \
#else
#define MULADDC_STOP \
__asm mov c, ecx \
__asm mov d, edi \
__asm mov s, esi \
#endif /* SSE2 */
#endif /* MSVC */
#endif /* POLARSSL_HAVE_ASM */
#if !defined(MULADDC_CORE)
#if defined(POLARSSL_HAVE_UDBL)
#define MULADDC_INIT \
{ \
t_udbl r; \
t_uint r0, r1;
#define MULADDC_CORE \
r = *(s++) * (t_udbl) b; \
r0 = r; \
r1 = r >> biL; \
r0 += c; r1 += (r0 < c); \
r0 += *d; r1 += (r0 < *d); \
c = r1; *(d++) = r0;
#define MULADDC_STOP \
}
#else
#define MULADDC_INIT \
{ \
t_uint s0, s1, b0, b1; \
t_uint r0, r1, rx, ry; \
b0 = ( b << biH ) >> biH; \
b1 = ( b >> biH );
#define MULADDC_CORE \
s0 = ( *s << biH ) >> biH; \
s1 = ( *s >> biH ); s++; \
rx = s0 * b1; r0 = s0 * b0; \
ry = s1 * b0; r1 = s1 * b1; \
r1 += ( rx >> biH ); \
r1 += ( ry >> biH ); \
rx <<= biH; ry <<= biH; \
r0 += rx; r1 += (r0 < rx); \
r0 += ry; r1 += (r0 < ry); \
r0 += c; r1 += (r0 < c); \
r0 += *d; r1 += (r0 < *d); \
c = r1; *(d++) = r0;
#define MULADDC_STOP \
}
#endif /* C (generic) */
#endif /* C (longlong) */
#endif /* bn_mul.h */

1014
common/polarssl/des.c Normal file

File diff suppressed because it is too large Load diff

281
common/polarssl/des.h Normal file
View file

@ -0,0 +1,281 @@
/**
* \file des.h
*
* \brief DES block cipher
*
* Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* 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.
*/
#ifndef POLARSSL_DES_H
#define POLARSSL_DES_H
//#include "config.h"
/**
* \def POLARSSL_CIPHER_MODE_CBC
*
* Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
*/
#define POLARSSL_CIPHER_MODE_CBC
#include <string.h>
#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
#include <basetsd.h>
typedef UINT32 uint32_t;
#else
#include <inttypes.h>
#endif
#define DES_ENCRYPT 1
#define DES_DECRYPT 0
#define POLARSSL_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */
#define DES_KEY_SIZE 8
#if !defined(POLARSSL_DES_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief DES context structure
*/
typedef struct
{
int mode; /*!< encrypt/decrypt */
uint32_t sk[32]; /*!< DES subkeys */
}
des_context;
/**
* \brief Triple-DES context structure
*/
typedef struct
{
int mode; /*!< encrypt/decrypt */
uint32_t sk[96]; /*!< 3DES subkeys */
}
des3_context;
/*
* Triple-DES key schedule (112-bit, encryption)
*/
int des3_set2key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] );
/*
* Triple-DES key schedule (112-bit, decryption)
*/
int des3_set2key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] );
/*
* Triple-DES key schedule (168-bit, encryption)
*/
int des3_set3key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] );
/*
* Triple-DES key schedule (168-bit, decryption)
*/
int des3_set3key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] );
/**
* \brief Set key parity on the given key to odd.
*
* DES keys are 56 bits long, but each byte is padded with
* a parity bit to allow verification.
*
* \param key 8-byte secret key
*/
void des_key_set_parity( unsigned char key[DES_KEY_SIZE] );
/**
* \brief Check that key parity on the given key is odd.
*
* DES keys are 56 bits long, but each byte is padded with
* a parity bit to allow verification.
*
* \param key 8-byte secret key
*
* \return 0 is parity was ok, 1 if parity was not correct.
*/
int des_key_check_key_parity( const unsigned char key[DES_KEY_SIZE] );
/**
* \brief Check that key is not a weak or semi-weak DES key
*
* \param key 8-byte secret key
*
* \return 0 if no weak key was found, 1 if a weak key was identified.
*/
int des_key_check_weak( const unsigned char key[DES_KEY_SIZE] );
/**
* \brief DES key schedule (56-bit, encryption)
*
* \param ctx DES context to be initialized
* \param key 8-byte secret key
*
* \return 0
*/
int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] );
/**
* \brief DES key schedule (56-bit, decryption)
*
* \param ctx DES context to be initialized
* \param key 8-byte secret key
*
* \return 0
*/
int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] );
/**
* \brief Triple-DES key schedule (112-bit, encryption)
*
* \param ctx 3DES context to be initialized
* \param key 16-byte secret key
*
* \return 0
*/
int des3_set2key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] );
/**
* \brief Triple-DES key schedule (112-bit, decryption)
*
* \param ctx 3DES context to be initialized
* \param key 16-byte secret key
*
* \return 0
*/
int des3_set2key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] );
/**
* \brief Triple-DES key schedule (168-bit, encryption)
*
* \param ctx 3DES context to be initialized
* \param key 24-byte secret key
*
* \return 0
*/
int des3_set3key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] );
/**
* \brief Triple-DES key schedule (168-bit, decryption)
*
* \param ctx 3DES context to be initialized
* \param key 24-byte secret key
*
* \return 0
*/
int des3_set3key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] );
/**
* \brief DES-ECB block encryption/decryption
*
* \param ctx DES context
* \param input 64-bit input block
* \param output 64-bit output block
*
* \return 0 if successful
*/
int des_crypt_ecb( des_context *ctx,
const unsigned char input[8],
unsigned char output[8] );
#if defined(POLARSSL_CIPHER_MODE_CBC)
/**
* \brief DES-CBC buffer encryption/decryption
*
* \param ctx DES context
* \param mode DES_ENCRYPT or DES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*/
int des_crypt_cbc( des_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output );
#endif /* POLARSSL_CIPHER_MODE_CBC */
/**
* \brief 3DES-ECB block encryption/decryption
*
* \param ctx 3DES context
* \param input 64-bit input block
* \param output 64-bit output block
*
* \return 0 if successful
*/
int des3_crypt_ecb( des3_context *ctx,
const unsigned char input[8],
unsigned char output[8] );
#if defined(POLARSSL_CIPHER_MODE_CBC)
/**
* \brief 3DES-CBC buffer encryption/decryption
*
* \param ctx 3DES context
* \param mode DES_ENCRYPT or DES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or POLARSSL_ERR_DES_INVALID_INPUT_LENGTH
*/
int des3_crypt_cbc( des3_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output );
#endif /* POLARSSL_CIPHER_MODE_CBC */
#ifdef __cplusplus
}
#endif
#else /* POLARSSL_DES_ALT */
#include "des_alt.h"
#endif /* POLARSSL_DES_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int des_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* des.h */

File diff suppressed because it is too large Load diff

1466
common/polarssl/rsa.c Normal file

File diff suppressed because it is too large Load diff

597
common/polarssl/rsa.h Normal file
View file

@ -0,0 +1,597 @@
/**
* \file rsa.h
*
* \brief The RSA public-key cryptosystem
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* 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.
*/
#ifndef POLARSSL_RSA_H
#define POLARSSL_RSA_H
#include "bignum.h"
/*
* RSA Error codes
*/
#define POLARSSL_ERR_RSA_BAD_INPUT_DATA -0x4080 /**< Bad input parameters to function. */
#define POLARSSL_ERR_RSA_INVALID_PADDING -0x4100 /**< Input data contains invalid padding and is rejected. */
#define POLARSSL_ERR_RSA_KEY_GEN_FAILED -0x4180 /**< Something failed during generation of a key. */
#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED -0x4200 /**< Key failed to pass the libraries validity check. */
#define POLARSSL_ERR_RSA_PUBLIC_FAILED -0x4280 /**< The public key operation failed. */
#define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x4300 /**< The private key operation failed. */
#define POLARSSL_ERR_RSA_VERIFY_FAILED -0x4380 /**< The PKCS#1 verification failed. */
#define POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE -0x4400 /**< The output buffer for decryption is not large enough. */
#define POLARSSL_ERR_RSA_RNG_FAILED -0x4480 /**< The random generator failed to generate non-zeros. */
/*
* PKCS#1 constants
*/
#define SIG_RSA_RAW 0
#define SIG_RSA_MD2 2
#define SIG_RSA_MD4 3
#define SIG_RSA_MD5 4
#define SIG_RSA_SHA1 5
#define SIG_RSA_SHA224 14
#define SIG_RSA_SHA256 11
#define SIG_RSA_SHA384 12
#define SIG_RSA_SHA512 13
#define RSA_PUBLIC 0
#define RSA_PRIVATE 1
#define RSA_PKCS_V15 0
#define RSA_PKCS_V21 1
#define RSA_SIGN 1
#define RSA_CRYPT 2
#define ASN1_STR_CONSTRUCTED_SEQUENCE "\x30"
#define ASN1_STR_NULL "\x05"
#define ASN1_STR_OID "\x06"
#define ASN1_STR_OCTET_STRING "\x04"
#define OID_DIGEST_ALG_MDX "\x2A\x86\x48\x86\xF7\x0D\x02\x00"
#define OID_HASH_ALG_SHA1 "\x2b\x0e\x03\x02\x1a"
#define OID_HASH_ALG_SHA2X "\x60\x86\x48\x01\x65\x03\x04\x02\x00"
#define OID_ISO_MEMBER_BODIES "\x2a"
#define OID_ISO_IDENTIFIED_ORG "\x2b"
/*
* ISO Member bodies OID parts
*/
#define OID_COUNTRY_US "\x86\x48"
#define OID_RSA_DATA_SECURITY "\x86\xf7\x0d"
/*
* ISO Identified organization OID parts
*/
#define OID_OIW_SECSIG_SHA1 "\x0e\x03\x02\x1a"
/*
* DigestInfo ::= SEQUENCE {
* digestAlgorithm DigestAlgorithmIdentifier,
* digest Digest }
*
* DigestAlgorithmIdentifier ::= AlgorithmIdentifier
*
* Digest ::= OCTET STRING
*/
#define ASN1_HASH_MDX \
( \
ASN1_STR_CONSTRUCTED_SEQUENCE "\x20" \
ASN1_STR_CONSTRUCTED_SEQUENCE "\x0C" \
ASN1_STR_OID "\x08" \
OID_DIGEST_ALG_MDX \
ASN1_STR_NULL "\x00" \
ASN1_STR_OCTET_STRING "\x10" \
)
#define ASN1_HASH_SHA1 \
ASN1_STR_CONSTRUCTED_SEQUENCE "\x21" \
ASN1_STR_CONSTRUCTED_SEQUENCE "\x09" \
ASN1_STR_OID "\x05" \
OID_HASH_ALG_SHA1 \
ASN1_STR_NULL "\x00" \
ASN1_STR_OCTET_STRING "\x14"
#define ASN1_HASH_SHA1_ALT \
ASN1_STR_CONSTRUCTED_SEQUENCE "\x1F" \
ASN1_STR_CONSTRUCTED_SEQUENCE "\x07" \
ASN1_STR_OID "\x05" \
OID_HASH_ALG_SHA1 \
ASN1_STR_OCTET_STRING "\x14"
#define ASN1_HASH_SHA2X \
ASN1_STR_CONSTRUCTED_SEQUENCE "\x11" \
ASN1_STR_CONSTRUCTED_SEQUENCE "\x0d" \
ASN1_STR_OID "\x09" \
OID_HASH_ALG_SHA2X \
ASN1_STR_NULL "\x00" \
ASN1_STR_OCTET_STRING "\x00"
/**
* \brief RSA context structure
*/
typedef struct
{
int ver; /*!< always 0 */
size_t len; /*!< size(N) in chars */
mpi N; /*!< public modulus */
mpi E; /*!< public exponent */
mpi D; /*!< private exponent */
mpi P; /*!< 1st prime factor */
mpi Q; /*!< 2nd prime factor */
mpi DP; /*!< D % (P - 1) */
mpi DQ; /*!< D % (Q - 1) */
mpi QP; /*!< 1 / (Q % P) */
mpi RN; /*!< cached R^2 mod N */
mpi RP; /*!< cached R^2 mod P */
mpi RQ; /*!< cached R^2 mod Q */
int padding; /*!< RSA_PKCS_V15 for 1.5 padding and
RSA_PKCS_v21 for OAEP/PSS */
int hash_id; /*!< Hash identifier of md_type_t as
specified in the md.h header file
for the EME-OAEP and EMSA-PSS
encoding */
}
rsa_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Initialize an RSA context
*
* Note: Set padding to RSA_PKCS_V21 for the RSAES-OAEP
* encryption scheme and the RSASSA-PSS signature scheme.
*
* \param ctx RSA context to be initialized
* \param padding RSA_PKCS_V15 or RSA_PKCS_V21
* \param hash_id RSA_PKCS_V21 hash identifier
*
* \note The hash_id parameter is actually ignored
* when using RSA_PKCS_V15 padding.
*/
void rsa_init( rsa_context *ctx,
int padding,
int hash_id);
/**
* \brief Generate an RSA keypair
*
* \param ctx RSA context that will hold the key
* \param f_rng RNG function
* \param p_rng RNG parameter
* \param nbits size of the public key in bits
* \param exponent public exponent (e.g., 65537)
*
* \note rsa_init() must be called beforehand to setup
* the RSA context.
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*/
int rsa_gen_key( rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
unsigned int nbits, int exponent );
/**
* \brief Check a public RSA key
*
* \param ctx RSA context to be checked
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*/
int rsa_check_pubkey( const rsa_context *ctx );
/**
* \brief Check a private RSA key
*
* \param ctx RSA context to be checked
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*/
int rsa_check_privkey( const rsa_context *ctx );
/**
* \brief Do an RSA public key operation
*
* \param ctx RSA context
* \param input input buffer
* \param output output buffer
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*
* \note This function does NOT take care of message
* padding. Also, be sure to set input[0] = 0 or assure that
* input is smaller than N.
*
* \note The input and output buffers must be large
* enough (eg. 128 bytes if RSA-1024 is used).
*/
int rsa_public( rsa_context *ctx,
const unsigned char *input,
unsigned char *output );
/**
* \brief Do an RSA private key operation
*
* \param ctx RSA context
* \param input input buffer
* \param output output buffer
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*
* \note The input and output buffers must be large
* enough (eg. 128 bytes if RSA-1024 is used).
*/
int rsa_private( rsa_context *ctx,
const unsigned char *input,
unsigned char *output );
/**
* \brief Generic wrapper to perform a PKCS#1 encryption using the
* mode from the context. Add the message padding, then do an
* RSA operation.
*
* \param ctx RSA context
* \param f_rng RNG function (Needed for padding and PKCS#1 v2.1 encoding)
* \param p_rng RNG parameter
* \param mode RSA_PUBLIC or RSA_PRIVATE
* \param ilen contains the plaintext length
* \param input buffer holding the data to be encrypted
* \param output buffer that will hold the ciphertext
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*
* \note The output buffer must be as large as the size
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
*/
int rsa_pkcs1_encrypt( rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
int mode, size_t ilen,
const unsigned char *input,
unsigned char *output );
/**
* \brief Perform a PKCS#1 v1.5 encryption (RSAES-PKCS1-v1_5-ENCRYPT)
*
* \param ctx RSA context
* \param f_rng RNG function (Needed for padding)
* \param p_rng RNG parameter
* \param mode RSA_PUBLIC or RSA_PRIVATE
* \param ilen contains the plaintext length
* \param input buffer holding the data to be encrypted
* \param output buffer that will hold the ciphertext
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*
* \note The output buffer must be as large as the size
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
*/
int rsa_rsaes_pkcs1_v15_encrypt( rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
int mode, size_t ilen,
const unsigned char *input,
unsigned char *output );
/**
* \brief Perform a PKCS#1 v2.1 OAEP encryption (RSAES-OAEP-ENCRYPT)
*
* \param ctx RSA context
* \param f_rng RNG function (Needed for padding and PKCS#1 v2.1 encoding)
* \param p_rng RNG parameter
* \param mode RSA_PUBLIC or RSA_PRIVATE
* \param label buffer holding the custom label to use
* \param label_len contains the label length
* \param ilen contains the plaintext length
* \param input buffer holding the data to be encrypted
* \param output buffer that will hold the ciphertext
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*
* \note The output buffer must be as large as the size
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
*/
int rsa_rsaes_oaep_encrypt( rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
int mode,
const unsigned char *label, size_t label_len,
size_t ilen,
const unsigned char *input,
unsigned char *output );
/**
* \brief Generic wrapper to perform a PKCS#1 decryption using the
* mode from the context. Do an RSA operation, then remove
* the message padding
*
* \param ctx RSA context
* \param mode RSA_PUBLIC or RSA_PRIVATE
* \param olen will contain the plaintext length
* \param input buffer holding the encrypted data
* \param output buffer that will hold the plaintext
* \param output_max_len maximum length of the output buffer
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*
* \note The output buffer must be as large as the size
* of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
* an error is thrown.
*/
int rsa_pkcs1_decrypt( rsa_context *ctx,
int mode, size_t *olen,
const unsigned char *input,
unsigned char *output,
size_t output_max_len );
/**
* \brief Perform a PKCS#1 v1.5 decryption (RSAES-PKCS1-v1_5-DECRYPT)
*
* \param ctx RSA context
* \param mode RSA_PUBLIC or RSA_PRIVATE
* \param olen will contain the plaintext length
* \param input buffer holding the encrypted data
* \param output buffer that will hold the plaintext
* \param output_max_len maximum length of the output buffer
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*
* \note The output buffer must be as large as the size
* of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
* an error is thrown.
*/
int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx,
int mode, size_t *olen,
const unsigned char *input,
unsigned char *output,
size_t output_max_len );
/**
* \brief Perform a PKCS#1 v2.1 OAEP decryption (RSAES-OAEP-DECRYPT)
*
* \param ctx RSA context
* \param mode RSA_PUBLIC or RSA_PRIVATE
* \param label buffer holding the custom label to use
* \param label_len contains the label length
* \param olen will contain the plaintext length
* \param input buffer holding the encrypted data
* \param output buffer that will hold the plaintext
* \param output_max_len maximum length of the output buffer
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*
* \note The output buffer must be as large as the size
* of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
* an error is thrown.
*/
int rsa_rsaes_oaep_decrypt( rsa_context *ctx,
int mode,
const unsigned char *label, size_t label_len,
size_t *olen,
const unsigned char *input,
unsigned char *output,
size_t output_max_len );
/**
* \brief Generic wrapper to perform a PKCS#1 signature using the
* mode from the context. Do a private RSA operation to sign
* a message digest
*
* \param ctx RSA context
* \param f_rng RNG function (Needed for PKCS#1 v2.1 encoding)
* \param p_rng RNG parameter
* \param mode RSA_PUBLIC or RSA_PRIVATE
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
* \param hashlen message digest length (for SIG_RSA_RAW only)
* \param hash buffer holding the message digest
* \param sig buffer that will hold the ciphertext
*
* \return 0 if the signing operation was successful,
* or an POLARSSL_ERR_RSA_XXX error code
*
* \note The "sig" buffer must be as large as the size
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
*
* \note In case of PKCS#1 v2.1 encoding keep in mind that
* the hash_id in the RSA context is the one used for the
* encoding. hash_id in the function call is the type of hash
* that is encoded. According to RFC 3447 it is advised to
* keep both hashes the same.
*/
int rsa_pkcs1_sign( rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
int mode,
int hash_id,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig );
/**
* \brief Perform a PKCS#1 v1.5 signature (RSASSA-PKCS1-v1_5-SIGN)
*
* \param ctx RSA context
* \param mode RSA_PUBLIC or RSA_PRIVATE
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
* \param hashlen message digest length (for SIG_RSA_RAW only)
* \param hash buffer holding the message digest
* \param sig buffer that will hold the ciphertext
*
* \return 0 if the signing operation was successful,
* or an POLARSSL_ERR_RSA_XXX error code
*
* \note The "sig" buffer must be as large as the size
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
*/
int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
int mode,
int hash_id,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig );
/**
* \brief Perform a PKCS#1 v2.1 PSS signature (RSASSA-PSS-SIGN)
*
* \param ctx RSA context
* \param f_rng RNG function (Needed for PKCS#1 v2.1 encoding)
* \param p_rng RNG parameter
* \param mode RSA_PUBLIC or RSA_PRIVATE
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
* \param hashlen message digest length (for SIG_RSA_RAW only)
* \param hash buffer holding the message digest
* \param sig buffer that will hold the ciphertext
*
* \return 0 if the signing operation was successful,
* or an POLARSSL_ERR_RSA_XXX error code
*
* \note The "sig" buffer must be as large as the size
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
*
* \note In case of PKCS#1 v2.1 encoding keep in mind that
* the hash_id in the RSA context is the one used for the
* encoding. hash_id in the function call is the type of hash
* that is encoded. According to RFC 3447 it is advised to
* keep both hashes the same.
*/
int rsa_rsassa_pss_sign( rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
int mode,
int hash_id,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig );
/**
* \brief Generic wrapper to perform a PKCS#1 verification using the
* mode from the context. Do a public RSA operation and check
* the message digest
*
* \param ctx points to an RSA public key
* \param mode RSA_PUBLIC or RSA_PRIVATE
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
* \param hashlen message digest length (for SIG_RSA_RAW only)
* \param hash buffer holding the message digest
* \param sig buffer holding the ciphertext
*
* \return 0 if the verify operation was successful,
* or an POLARSSL_ERR_RSA_XXX error code
*
* \note The "sig" buffer must be as large as the size
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
*
* \note In case of PKCS#1 v2.1 encoding keep in mind that
* the hash_id in the RSA context is the one used for the
* verification. hash_id in the function call is the type of hash
* that is verified. According to RFC 3447 it is advised to
* keep both hashes the same.
*/
int rsa_pkcs1_verify( rsa_context *ctx,
int mode,
int hash_id,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig );
/**
* \brief Perform a PKCS#1 v1.5 verification (RSASSA-PKCS1-v1_5-VERIFY)
*
* \param ctx points to an RSA public key
* \param mode RSA_PUBLIC or RSA_PRIVATE
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
* \param hashlen message digest length (for SIG_RSA_RAW only)
* \param hash buffer holding the message digest
* \param sig buffer holding the ciphertext
*
* \return 0 if the verify operation was successful,
* or an POLARSSL_ERR_RSA_XXX error code
*
* \note The "sig" buffer must be as large as the size
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
*/
int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx,
int mode,
int hash_id,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig );
/**
* \brief Perform a PKCS#1 v2.1 PSS verification (RSASSA-PSS-VERIFY)
* \brief Do a public RSA and check the message digest
*
* \param ctx points to an RSA public key
* \param mode RSA_PUBLIC or RSA_PRIVATE
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
* \param hashlen message digest length (for SIG_RSA_RAW only)
* \param hash buffer holding the message digest
* \param sig buffer holding the ciphertext
*
* \return 0 if the verify operation was successful,
* or an POLARSSL_ERR_RSA_XXX error code
*
* \note The "sig" buffer must be as large as the size
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
*
* \note In case of PKCS#1 v2.1 encoding keep in mind that
* the hash_id in the RSA context is the one used for the
* verification. hash_id in the function call is the type of hash
* that is verified. According to RFC 3447 it is advised to
* keep both hashes the same.
*/
int rsa_rsassa_pss_verify( rsa_context *ctx,
int mode,
int hash_id,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig );
/**
* \brief Free the components of an RSA key
*
* \param ctx RSA Context to free
*/
void rsa_free( rsa_context *ctx );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int rsa_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* rsa.h */

665
common/polarssl/sha1.c Normal file
View file

@ -0,0 +1,665 @@
/*
* FIPS-180-1 compliant SHA-1 implementation
*
* Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
*
* This file is part of mbed TLS (https://tls.mbed.org)
*
* 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.
*/
/*
* The SHA-1 standard was published by NIST in 1993.
*
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
*/
#if !defined(POLARSSL_CONFIG_FILE)
//#include "polarssl/config.h"
#define POLARSSL_SHA1_C
#else
#include POLARSSL_CONFIG_FILE
#endif
#if defined(POLARSSL_SHA1_C)
#include "sha1.h"
#include <string.h>
#if defined(POLARSSL_FS_IO)
#include <stdio.h>
#endif
#if defined(POLARSSL_SELF_TEST)
#if defined(POLARSSL_PLATFORM_C)
#include "polarssl/platform.h"
#else
#include <stdio.h>
#define polarssl_printf printf
#endif /* POLARSSL_PLATFORM_C */
#endif /* POLARSSL_SELF_TEST */
/* Implementation that should never be optimized out by the compiler */
static void polarssl_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
#if !defined(POLARSSL_SHA1_ALT)
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(n,b,i) \
{ \
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
| ( (uint32_t) (b)[(i) + 3] ); \
}
#endif
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
}
#endif
void sha1_init( sha1_context *ctx )
{
memset( ctx, 0, sizeof( sha1_context ) );
}
void sha1_free( sha1_context *ctx )
{
if( ctx == NULL )
return;
polarssl_zeroize( ctx, sizeof( sha1_context ) );
}
/*
* SHA-1 context setup
*/
void sha1_starts( sha1_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;
ctx->state[4] = 0xC3D2E1F0;
}
void sha1_process( sha1_context *ctx, const unsigned char data[64] )
{
uint32_t temp, W[16], A, B, C, D, E;
GET_UINT32_BE( W[ 0], data, 0 );
GET_UINT32_BE( W[ 1], data, 4 );
GET_UINT32_BE( W[ 2], data, 8 );
GET_UINT32_BE( W[ 3], data, 12 );
GET_UINT32_BE( W[ 4], data, 16 );
GET_UINT32_BE( W[ 5], data, 20 );
GET_UINT32_BE( W[ 6], data, 24 );
GET_UINT32_BE( W[ 7], data, 28 );
GET_UINT32_BE( W[ 8], data, 32 );
GET_UINT32_BE( W[ 9], data, 36 );
GET_UINT32_BE( W[10], data, 40 );
GET_UINT32_BE( W[11], data, 44 );
GET_UINT32_BE( W[12], data, 48 );
GET_UINT32_BE( W[13], data, 52 );
GET_UINT32_BE( W[14], data, 56 );
GET_UINT32_BE( W[15], data, 60 );
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define R(t) \
( \
temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \
W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \
( W[t & 0x0F] = S(temp,1) ) \
)
#define P(a,b,c,d,e,x) \
{ \
e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
}
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
E = ctx->state[4];
#define F(x,y,z) (z ^ (x & (y ^ z)))
#define K 0x5A827999
P( A, B, C, D, E, W[0] );
P( E, A, B, C, D, W[1] );
P( D, E, A, B, C, W[2] );
P( C, D, E, A, B, W[3] );
P( B, C, D, E, A, W[4] );
P( A, B, C, D, E, W[5] );
P( E, A, B, C, D, W[6] );
P( D, E, A, B, C, W[7] );
P( C, D, E, A, B, W[8] );
P( B, C, D, E, A, W[9] );
P( A, B, C, D, E, W[10] );
P( E, A, B, C, D, W[11] );
P( D, E, A, B, C, W[12] );
P( C, D, E, A, B, W[13] );
P( B, C, D, E, A, W[14] );
P( A, B, C, D, E, W[15] );
P( E, A, B, C, D, R(16) );
P( D, E, A, B, C, R(17) );
P( C, D, E, A, B, R(18) );
P( B, C, D, E, A, R(19) );
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0x6ED9EBA1
P( A, B, C, D, E, R(20) );
P( E, A, B, C, D, R(21) );
P( D, E, A, B, C, R(22) );
P( C, D, E, A, B, R(23) );
P( B, C, D, E, A, R(24) );
P( A, B, C, D, E, R(25) );
P( E, A, B, C, D, R(26) );
P( D, E, A, B, C, R(27) );
P( C, D, E, A, B, R(28) );
P( B, C, D, E, A, R(29) );
P( A, B, C, D, E, R(30) );
P( E, A, B, C, D, R(31) );
P( D, E, A, B, C, R(32) );
P( C, D, E, A, B, R(33) );
P( B, C, D, E, A, R(34) );
P( A, B, C, D, E, R(35) );
P( E, A, B, C, D, R(36) );
P( D, E, A, B, C, R(37) );
P( C, D, E, A, B, R(38) );
P( B, C, D, E, A, R(39) );
#undef K
#undef F
#define F(x,y,z) ((x & y) | (z & (x | y)))
#define K 0x8F1BBCDC
P( A, B, C, D, E, R(40) );
P( E, A, B, C, D, R(41) );
P( D, E, A, B, C, R(42) );
P( C, D, E, A, B, R(43) );
P( B, C, D, E, A, R(44) );
P( A, B, C, D, E, R(45) );
P( E, A, B, C, D, R(46) );
P( D, E, A, B, C, R(47) );
P( C, D, E, A, B, R(48) );
P( B, C, D, E, A, R(49) );
P( A, B, C, D, E, R(50) );
P( E, A, B, C, D, R(51) );
P( D, E, A, B, C, R(52) );
P( C, D, E, A, B, R(53) );
P( B, C, D, E, A, R(54) );
P( A, B, C, D, E, R(55) );
P( E, A, B, C, D, R(56) );
P( D, E, A, B, C, R(57) );
P( C, D, E, A, B, R(58) );
P( B, C, D, E, A, R(59) );
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0xCA62C1D6
P( A, B, C, D, E, R(60) );
P( E, A, B, C, D, R(61) );
P( D, E, A, B, C, R(62) );
P( C, D, E, A, B, R(63) );
P( B, C, D, E, A, R(64) );
P( A, B, C, D, E, R(65) );
P( E, A, B, C, D, R(66) );
P( D, E, A, B, C, R(67) );
P( C, D, E, A, B, R(68) );
P( B, C, D, E, A, R(69) );
P( A, B, C, D, E, R(70) );
P( E, A, B, C, D, R(71) );
P( D, E, A, B, C, R(72) );
P( C, D, E, A, B, R(73) );
P( B, C, D, E, A, R(74) );
P( A, B, C, D, E, R(75) );
P( E, A, B, C, D, R(76) );
P( D, E, A, B, C, R(77) );
P( C, D, E, A, B, R(78) );
P( B, C, D, E, A, R(79) );
#undef K
#undef F
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
ctx->state[4] += E;
}
/*
* SHA-1 process buffer
*/
void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen )
{
size_t fill;
uint32_t left;
if( ilen == 0 )
return;
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), input, fill );
sha1_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
}
while( ilen >= 64 )
{
sha1_process( ctx, input );
input += 64;
ilen -= 64;
}
if( ilen > 0 )
memcpy( (void *) (ctx->buffer + left), input, ilen );
}
static const unsigned char sha1_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
};
/*
* SHA-1 final digest
*/
void sha1_finish( sha1_context *ctx, unsigned char output[20] )
{
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_BE( high, msglen, 0 );
PUT_UINT32_BE( low, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
sha1_update( ctx, sha1_padding, padn );
sha1_update( ctx, msglen, 8 );
PUT_UINT32_BE( ctx->state[0], output, 0 );
PUT_UINT32_BE( ctx->state[1], output, 4 );
PUT_UINT32_BE( ctx->state[2], output, 8 );
PUT_UINT32_BE( ctx->state[3], output, 12 );
PUT_UINT32_BE( ctx->state[4], output, 16 );
}
#endif /* !POLARSSL_SHA1_ALT */
/*
* output = SHA-1( input buffer )
*/
void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] )
{
sha1_context ctx;
sha1_init( &ctx );
sha1_starts( &ctx );
sha1_update( &ctx, input, ilen );
sha1_finish( &ctx, output );
sha1_free( &ctx );
}
#if defined(POLARSSL_FS_IO)
/*
* output = SHA-1( file contents )
*/
int sha1_file( const char *path, unsigned char output[20] )
{
FILE *f;
size_t n;
sha1_context ctx;
unsigned char buf[1024];
if( ( f = fopen( path, "rb" ) ) == NULL )
return( POLARSSL_ERR_SHA1_FILE_IO_ERROR );
sha1_init( &ctx );
sha1_starts( &ctx );
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
sha1_update( &ctx, buf, n );
sha1_finish( &ctx, output );
sha1_free( &ctx );
if( ferror( f ) != 0 )
{
fclose( f );
return( POLARSSL_ERR_SHA1_FILE_IO_ERROR );
}
fclose( f );
return( 0 );
}
#endif /* POLARSSL_FS_IO */
/*
* SHA-1 HMAC context setup
*/
void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key,
size_t keylen )
{
size_t i;
unsigned char sum[20];
if( keylen > 64 )
{
sha1( key, keylen, sum );
keylen = 20;
key = sum;
}
memset( ctx->ipad, 0x36, 64 );
memset( ctx->opad, 0x5C, 64 );
for( i = 0; i < keylen; i++ )
{
ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
}
sha1_starts( ctx );
sha1_update( ctx, ctx->ipad, 64 );
polarssl_zeroize( sum, sizeof( sum ) );
}
/*
* SHA-1 HMAC process buffer
*/
void sha1_hmac_update( sha1_context *ctx, const unsigned char *input,
size_t ilen )
{
sha1_update( ctx, input, ilen );
}
/*
* SHA-1 HMAC final digest
*/
void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] )
{
unsigned char tmpbuf[20];
sha1_finish( ctx, tmpbuf );
sha1_starts( ctx );
sha1_update( ctx, ctx->opad, 64 );
sha1_update( ctx, tmpbuf, 20 );
sha1_finish( ctx, output );
polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
}
/*
* SHA1 HMAC context reset
*/
void sha1_hmac_reset( sha1_context *ctx )
{
sha1_starts( ctx );
sha1_update( ctx, ctx->ipad, 64 );
}
/*
* output = HMAC-SHA-1( hmac key, input buffer )
*/
void sha1_hmac( const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char output[20] )
{
sha1_context ctx;
sha1_init( &ctx );
sha1_hmac_starts( &ctx, key, keylen );
sha1_hmac_update( &ctx, input, ilen );
sha1_hmac_finish( &ctx, output );
sha1_free( &ctx );
}
#if defined(POLARSSL_SELF_TEST)
/*
* FIPS-180-1 test vectors
*/
static const unsigned char sha1_test_buf[3][57] =
{
{ "abc" },
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
{ "" }
};
static const int sha1_test_buflen[3] =
{
3, 56, 1000
};
static const unsigned char sha1_test_sum[3][20] =
{
{ 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
{ 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
};
/*
* RFC 2202 test vectors
*/
static const unsigned char sha1_hmac_test_key[7][26] =
{
{ "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
"\x0B\x0B\x0B\x0B" },
{ "Jefe" },
{ "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
"\xAA\xAA\xAA\xAA" },
{ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
{ "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
"\x0C\x0C\x0C\x0C" },
{ "" }, /* 0xAA 80 times */
{ "" }
};
static const int sha1_hmac_test_keylen[7] =
{
20, 4, 20, 25, 20, 80, 80
};
static const unsigned char sha1_hmac_test_buf[7][74] =
{
{ "Hi There" },
{ "what do ya want for nothing?" },
{ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
{ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
{ "Test With Truncation" },
{ "Test Using Larger Than Block-Size Key - Hash Key First" },
{ "Test Using Larger Than Block-Size Key and Larger"
" Than One Block-Size Data" }
};
static const int sha1_hmac_test_buflen[7] =
{
8, 28, 50, 50, 20, 54, 73
};
static const unsigned char sha1_hmac_test_sum[7][20] =
{
{ 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B,
0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 },
{ 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74,
0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 },
{ 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3,
0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 },
{ 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84,
0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA },
{ 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2,
0x7B, 0xE1 },
{ 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70,
0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 },
{ 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B,
0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 }
};
/*
* Checkup routine
*/
int sha1_self_test( int verbose )
{
int i, j, buflen, ret = 0;
unsigned char buf[1024];
unsigned char sha1sum[20];
sha1_context ctx;
sha1_init( &ctx );
/*
* SHA-1
*/
for( i = 0; i < 3; i++ )
{
if( verbose != 0 )
polarssl_printf( " SHA-1 test #%d: ", i + 1 );
sha1_starts( &ctx );
if( i == 2 )
{
memset( buf, 'a', buflen = 1000 );
for( j = 0; j < 1000; j++ )
sha1_update( &ctx, buf, buflen );
}
else
sha1_update( &ctx, sha1_test_buf[i],
sha1_test_buflen[i] );
sha1_finish( &ctx, sha1sum );
if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
{
if( verbose != 0 )
polarssl_printf( "failed\n" );
ret = 1;
goto exit;
}
if( verbose != 0 )
polarssl_printf( "passed\n" );
}
if( verbose != 0 )
polarssl_printf( "\n" );
for( i = 0; i < 7; i++ )
{
if( verbose != 0 )
polarssl_printf( " HMAC-SHA-1 test #%d: ", i + 1 );
if( i == 5 || i == 6 )
{
memset( buf, 0xAA, buflen = 80 );
sha1_hmac_starts( &ctx, buf, buflen );
}
else
sha1_hmac_starts( &ctx, sha1_hmac_test_key[i],
sha1_hmac_test_keylen[i] );
sha1_hmac_update( &ctx, sha1_hmac_test_buf[i],
sha1_hmac_test_buflen[i] );
sha1_hmac_finish( &ctx, sha1sum );
buflen = ( i == 4 ) ? 12 : 20;
if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 )
{
if( verbose != 0 )
polarssl_printf( "failed\n" );
ret = 1;
goto exit;
}
if( verbose != 0 )
polarssl_printf( "passed\n" );
}
if( verbose != 0 )
polarssl_printf( "\n" );
exit:
sha1_free( &ctx );
return( ret );
}
#endif /* POLARSSL_SELF_TEST */
#endif /* POLARSSL_SHA1_C */

213
common/polarssl/sha1.h Normal file
View file

@ -0,0 +1,213 @@
/**
* \file sha1.h
*
* \brief SHA-1 cryptographic hash function
*
* Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
*
* This file is part of mbed TLS (https://tls.mbed.org)
*
* 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.
*/
#ifndef POLARSSL_SHA1_H
#define POLARSSL_SHA1_H
#if !defined(POLARSSL_CONFIG_FILE)
//#include "config.h"
/**
* \def POLARSSL_SHA1_C
*
* Enable the SHA1 cryptographic hash algorithm.
*
* Module: library/sha1.c
* Caller: library/md.c
* library/ssl_cli.c
* library/ssl_srv.c
* library/ssl_tls.c
* library/x509write_crt.c
*
* This module is required for SSL/TLS and SHA1-signed certificates.
*/
#define POLARSSL_SHA1_C
#else
#include POLARSSL_CONFIG_FILE
#endif
#include <stddef.h>
#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
#include <basetsd.h>
typedef UINT32 uint32_t;
#else
#include <inttypes.h>
#endif
#define POLARSSL_ERR_SHA1_FILE_IO_ERROR -0x0076 /**< Read/write error in file. */
#if !defined(POLARSSL_SHA1_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief SHA-1 context structure
*/
typedef struct
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[5]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
unsigned char ipad[64]; /*!< HMAC: inner padding */
unsigned char opad[64]; /*!< HMAC: outer padding */
}
sha1_context;
/**
* \brief Initialize SHA-1 context
*
* \param ctx SHA-1 context to be initialized
*/
void sha1_init( sha1_context *ctx );
/**
* \brief Clear SHA-1 context
*
* \param ctx SHA-1 context to be cleared
*/
void sha1_free( sha1_context *ctx );
/**
* \brief SHA-1 context setup
*
* \param ctx context to be initialized
*/
void sha1_starts( sha1_context *ctx );
/**
* \brief SHA-1 process buffer
*
* \param ctx SHA-1 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen );
/**
* \brief SHA-1 final digest
*
* \param ctx SHA-1 context
* \param output SHA-1 checksum result
*/
void sha1_finish( sha1_context *ctx, unsigned char output[20] );
/* Internal use */
void sha1_process( sha1_context *ctx, const unsigned char data[64] );
#ifdef __cplusplus
}
#endif
#else /* POLARSSL_SHA1_ALT */
#include "sha1_alt.h"
#endif /* POLARSSL_SHA1_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Output = SHA-1( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output SHA-1 checksum result
*/
void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] );
/**
* \brief Output = SHA-1( file contents )
*
* \param path input file name
* \param output SHA-1 checksum result
*
* \return 0 if successful, or POLARSSL_ERR_SHA1_FILE_IO_ERROR
*/
int sha1_file( const char *path, unsigned char output[20] );
/**
* \brief SHA-1 HMAC context setup
*
* \param ctx HMAC context to be initialized
* \param key HMAC secret key
* \param keylen length of the HMAC key
*/
void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key,
size_t keylen );
/**
* \brief SHA-1 HMAC process buffer
*
* \param ctx HMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void sha1_hmac_update( sha1_context *ctx, const unsigned char *input,
size_t ilen );
/**
* \brief SHA-1 HMAC final digest
*
* \param ctx HMAC context
* \param output SHA-1 HMAC checksum result
*/
void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] );
/**
* \brief SHA-1 HMAC context reset
*
* \param ctx HMAC context to be reset
*/
void sha1_hmac_reset( sha1_context *ctx );
/**
* \brief Output = HMAC-SHA-1( hmac key, input buffer )
*
* \param key HMAC secret key
* \param keylen length of the HMAC key
* \param input buffer holding the data
* \param ilen length of the input data
* \param output HMAC-SHA-1 result
*/
void sha1_hmac( const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char output[20] );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int sha1_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* sha1.h */

446
common/polarssl/sha256.c Normal file
View file

@ -0,0 +1,446 @@
/*
* FIPS-180-2 compliant SHA-256 implementation
*
* Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
*
* This file is part of mbed TLS (https://tls.mbed.org)
*
* 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.
*/
/*
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
*
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
#if !defined(MBEDTLS_CONFIG_FILE)
//#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA256_C)
#include "mbedtls/sha256.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 */
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
#if !defined(MBEDTLS_SHA256_ALT)
/*
* 32-bit integer manipulation macros (big endian)
*/
#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
void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
}
void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
}
void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
const mbedtls_sha256_context *src )
{
*dst = *src;
}
/*
* SHA-256 context setup
*/
void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
if( is224 == 0 )
{
/* SHA-256 */
ctx->state[0] = 0x6A09E667;
ctx->state[1] = 0xBB67AE85;
ctx->state[2] = 0x3C6EF372;
ctx->state[3] = 0xA54FF53A;
ctx->state[4] = 0x510E527F;
ctx->state[5] = 0x9B05688C;
ctx->state[6] = 0x1F83D9AB;
ctx->state[7] = 0x5BE0CD19;
}
else
{
/* SHA-224 */
ctx->state[0] = 0xC1059ED8;
ctx->state[1] = 0x367CD507;
ctx->state[2] = 0x3070DD17;
ctx->state[3] = 0xF70E5939;
ctx->state[4] = 0xFFC00B31;
ctx->state[5] = 0x68581511;
ctx->state[6] = 0x64F98FA7;
ctx->state[7] = 0xBEFA4FA4;
}
ctx->is224 = is224;
}
#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
static const uint32_t K[] =
{
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
};
#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
#define F0(x,y,z) ((x & y) | (z & (x | y)))
#define F1(x,y,z) (z ^ (x & (y ^ z)))
#define R(t) \
( \
W[t] = S1(W[t - 2]) + W[t - 7] + \
S0(W[t - 15]) + W[t - 16] \
)
#define P(a,b,c,d,e,f,g,h,x,K) \
{ \
temp1 = h + S3(e) + F1(e,f,g) + K + x; \
temp2 = S2(a) + F0(a,b,c); \
d += temp1; h = temp1 + temp2; \
}
void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
{
uint32_t temp1, temp2, W[64];
uint32_t A[8];
unsigned int i;
for( i = 0; i < 8; i++ )
A[i] = ctx->state[i];
#if defined(MBEDTLS_SHA256_SMALLER)
for( i = 0; i < 64; i++ )
{
if( i < 16 )
GET_UINT32_BE( W[i], data, 4 * i );
else
R( i );
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
}
#else /* MBEDTLS_SHA256_SMALLER */
for( i = 0; i < 16; i++ )
GET_UINT32_BE( W[i], data, 4 * i );
for( i = 0; i < 16; i += 8 )
{
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
}
for( i = 16; i < 64; i += 8 )
{
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
}
#endif /* MBEDTLS_SHA256_SMALLER */
for( i = 0; i < 8; i++ )
ctx->state[i] += A[i];
}
#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
/*
* SHA-256 process buffer
*/
void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,
size_t ilen )
{
size_t fill;
uint32_t left;
if( ilen == 0 )
return;
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), input, fill );
mbedtls_sha256_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
}
while( ilen >= 64 )
{
mbedtls_sha256_process( ctx, input );
input += 64;
ilen -= 64;
}
if( ilen > 0 )
memcpy( (void *) (ctx->buffer + left), input, ilen );
}
static const unsigned char sha256_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
};
/*
* SHA-256 final digest
*/
void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] )
{
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_BE( high, msglen, 0 );
PUT_UINT32_BE( low, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
mbedtls_sha256_update( ctx, sha256_padding, padn );
mbedtls_sha256_update( ctx, msglen, 8 );
PUT_UINT32_BE( ctx->state[0], output, 0 );
PUT_UINT32_BE( ctx->state[1], output, 4 );
PUT_UINT32_BE( ctx->state[2], output, 8 );
PUT_UINT32_BE( ctx->state[3], output, 12 );
PUT_UINT32_BE( ctx->state[4], output, 16 );
PUT_UINT32_BE( ctx->state[5], output, 20 );
PUT_UINT32_BE( ctx->state[6], output, 24 );
if( ctx->is224 == 0 )
PUT_UINT32_BE( ctx->state[7], output, 28 );
}
#endif /* !MBEDTLS_SHA256_ALT */
/*
* output = SHA-256( input buffer )
*/
void mbedtls_sha256( const unsigned char *input, size_t ilen,
unsigned char output[32], int is224 )
{
mbedtls_sha256_context ctx;
mbedtls_sha256_init( &ctx );
mbedtls_sha256_starts( &ctx, is224 );
mbedtls_sha256_update( &ctx, input, ilen );
mbedtls_sha256_finish( &ctx, output );
mbedtls_sha256_free( &ctx );
}
#if defined(MBEDTLS_SELF_TEST)
/*
* FIPS-180-2 test vectors
*/
static const unsigned char sha256_test_buf[3][57] =
{
{ "abc" },
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
{ "" }
};
static const int sha256_test_buflen[3] =
{
3, 56, 1000
};
static const unsigned char sha256_test_sum[6][32] =
{
/*
* SHA-224 test vectors
*/
{ 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
0xE3, 0x6C, 0x9D, 0xA7 },
{ 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
0x52, 0x52, 0x25, 0x25 },
{ 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
0x4E, 0xE7, 0xAD, 0x67 },
/*
* SHA-256 test vectors
*/
{ 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
{ 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
{ 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
};
/*
* Checkup routine
*/
int mbedtls_sha256_self_test( int verbose )
{
int i, j, k, buflen, ret = 0;
unsigned char buf[1024];
unsigned char sha256sum[32];
mbedtls_sha256_context ctx;
mbedtls_sha256_init( &ctx );
for( i = 0; i < 6; i++ )
{
j = i % 3;
k = i < 3;
if( verbose != 0 )
mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
mbedtls_sha256_starts( &ctx, k );
if( j == 2 )
{
memset( buf, 'a', buflen = 1000 );
for( j = 0; j < 1000; j++ )
mbedtls_sha256_update( &ctx, buf, buflen );
}
else
mbedtls_sha256_update( &ctx, sha256_test_buf[j],
sha256_test_buflen[j] );
mbedtls_sha256_finish( &ctx, sha256sum );
if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit;
}
if( verbose != 0 )
mbedtls_printf( "passed\n" );
}
if( verbose != 0 )
mbedtls_printf( "\n" );
exit:
mbedtls_sha256_free( &ctx );
return( ret );
}
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_SHA256_C */

142
common/polarssl/sha256.h Normal file
View file

@ -0,0 +1,142 @@
/**
* \file mbedtls_sha256.h
*
* \brief SHA-224 and SHA-256 cryptographic hash function
*
* Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
*
* This file is part of mbed TLS (https://tls.mbed.org)
*
* 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.
*/
#ifndef MBEDTLS_SHA256_H
#define MBEDTLS_SHA256_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#if !defined(MBEDTLS_SHA256_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief SHA-256 context structure
*/
typedef struct
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[8]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
int is224; /*!< 0 => SHA-256, else SHA-224 */
}
mbedtls_sha256_context;
/**
* \brief Initialize SHA-256 context
*
* \param ctx SHA-256 context to be initialized
*/
void mbedtls_sha256_init( mbedtls_sha256_context *ctx );
/**
* \brief Clear SHA-256 context
*
* \param ctx SHA-256 context to be cleared
*/
void mbedtls_sha256_free( mbedtls_sha256_context *ctx );
/**
* \brief Clone (the state of) a SHA-256 context
*
* \param dst The destination context
* \param src The context to be cloned
*/
void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
const mbedtls_sha256_context *src );
/**
* \brief SHA-256 context setup
*
* \param ctx context to be initialized
* \param is224 0 = use SHA256, 1 = use SHA224
*/
void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 );
/**
* \brief SHA-256 process buffer
*
* \param ctx SHA-256 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,
size_t ilen );
/**
* \brief SHA-256 final digest
*
* \param ctx SHA-256 context
* \param output SHA-224/256 checksum result
*/
void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] );
/* Internal use */
void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] );
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_SHA256_ALT */
#include "sha256_alt.h"
#endif /* MBEDTLS_SHA256_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Output = SHA-256( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output SHA-224/256 checksum result
* \param is224 0 = use SHA256, 1 = use SHA224
*/
void mbedtls_sha256( const unsigned char *input, size_t ilen,
unsigned char output[32], int is224 );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_sha256_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* mbedtls_sha256.h */