Add polarssl
This commit is contained in:
parent
03ef25bda5
commit
19db92c0c8
12 changed files with 7125 additions and 0 deletions
|
@ -6,7 +6,9 @@
|
||||||
|
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
|
|
||||||
|
#include "core/loader/crypto.h"
|
||||||
#include "core/loader/ncch.h"
|
#include "core/loader/ncch.h"
|
||||||
|
#include "core/loader/polarssl/aes.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/mem_map.h"
|
#include "core/mem_map.h"
|
||||||
|
|
||||||
|
@ -17,6 +19,9 @@ namespace Loader {
|
||||||
|
|
||||||
static const int kMaxSections = 8; ///< Maximum number of sections (files) in an ExeFs
|
static const int kMaxSections = 8; ///< Maximum number of sections (files) in an ExeFs
|
||||||
static const int kBlockSize = 0x200; ///< Size of ExeFS blocks (in bytes)
|
static const int kBlockSize = 0x200; ///< Size of ExeFS blocks (in bytes)
|
||||||
|
ctr_aes_context ctx;
|
||||||
|
aes_context aes;
|
||||||
|
u8 ncch_key[0x10];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the decompressed size of an LZSS compressed ExeFS file
|
* Get the decompressed size of an LZSS compressed ExeFS file
|
||||||
|
@ -104,6 +109,7 @@ AppLoader_NCCH::AppLoader_NCCH(const std::string& filename) {
|
||||||
this->filename = filename;
|
this->filename = filename;
|
||||||
is_loaded = false;
|
is_loaded = false;
|
||||||
is_compressed = false;
|
is_compressed = false;
|
||||||
|
is_encrypted = false;
|
||||||
entry_point = 0;
|
entry_point = 0;
|
||||||
ncch_offset = 0;
|
ncch_offset = 0;
|
||||||
exefs_offset = 0;
|
exefs_offset = 0;
|
||||||
|
@ -226,6 +232,42 @@ ResultStatus AppLoader_NCCH::Load() {
|
||||||
INFO_LOG(LOADER, "Code compressed: %s", is_compressed ? "yes" : "no");
|
INFO_LOG(LOADER, "Code compressed: %s", is_compressed ? "yes" : "no");
|
||||||
INFO_LOG(LOADER, "Entry point: 0x%08X", entry_point);
|
INFO_LOG(LOADER, "Entry point: 0x%08X", entry_point);
|
||||||
|
|
||||||
|
if (!memcmp(exheader_header.arm11_system_local_caps.program_id, ncch_header.program_id, 8)) {
|
||||||
|
// program id's match, so it's probably not encrypted
|
||||||
|
is_encrypted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (ncch_header.flags[7] & 4) {
|
||||||
|
is_encrypted = false; // not encrypted
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (ncch_header.flags[7] & 1) {
|
||||||
|
if (programid_is_system(ncch_header.program_id)) {
|
||||||
|
// fixed system key
|
||||||
|
#ifdef NYUU_DEC
|
||||||
|
Nyuu_getkey(NINKEY_TYPE_FIX, &ncch_header, ncch_key);
|
||||||
|
#else
|
||||||
|
is_encrypted = true;
|
||||||
|
WARN_LOG(LOADER, "Fixed system key(s) not included in Citra");
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
// null key
|
||||||
|
is_encrypted = true;
|
||||||
|
memset(ncch_key, 0, 0x10);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// secure key (cannot decrypt!)
|
||||||
|
is_encrypted = true;
|
||||||
|
#ifdef NYUU_DEC
|
||||||
|
Nyuu_getkey(NINKEY_TYPE_SEC, &ncch_header, ncch_key);
|
||||||
|
#else
|
||||||
|
WARN_LOG(LOADER, "Secure key(s) are not included in Citra");
|
||||||
|
#endif
|
||||||
|
} if (is_encrypted) {
|
||||||
|
ncch_extract_prepare(&ctx, &ncch_header, NCCHTYPE_EXHEADER, ncch_key);
|
||||||
|
//ctr_crypt_counter(&ctx, &exheader_header, &exheader_header, sizeof(ExHeader_Header)); // Get this shit to compile and work at the same time (need help)
|
||||||
|
}
|
||||||
|
|
||||||
// Read ExeFS...
|
// Read ExeFS...
|
||||||
|
|
||||||
exefs_offset = ncch_header.exefs_offset * kBlockSize;
|
exefs_offset = ncch_header.exefs_offset * kBlockSize;
|
||||||
|
@ -234,9 +276,15 @@ ResultStatus AppLoader_NCCH::Load() {
|
||||||
INFO_LOG(LOADER, "ExeFS offset: 0x%08X", exefs_offset);
|
INFO_LOG(LOADER, "ExeFS offset: 0x%08X", exefs_offset);
|
||||||
INFO_LOG(LOADER, "ExeFS size: 0x%08X", exefs_size);
|
INFO_LOG(LOADER, "ExeFS size: 0x%08X", exefs_size);
|
||||||
|
|
||||||
|
|
||||||
file.Seek(exefs_offset + ncch_offset, 0);
|
file.Seek(exefs_offset + ncch_offset, 0);
|
||||||
file.ReadBytes(&exefs_header, sizeof(ExeFs_Header));
|
file.ReadBytes(&exefs_header, sizeof(ExeFs_Header));
|
||||||
|
|
||||||
|
if (is_encrypted) {
|
||||||
|
ncch_extract_prepare(&ctx, &ncch_header, NCCHTYPE_EXEFS, ncch_key);
|
||||||
|
//ctr_crypt_counter(&ctx, &exefs_header, &exefs_header, sizeof(ExeFs_Header)); // Get this shit to compile and work at the same time (need help)
|
||||||
|
}
|
||||||
|
|
||||||
is_loaded = true; // Set state to loaded
|
is_loaded = true; // Set state to loaded
|
||||||
|
|
||||||
LoadExec(); // Load the executable into memory for booting
|
LoadExec(); // Load the executable into memory for booting
|
||||||
|
|
1164
src/core/loader/polarssl/aes.c
Normal file
1164
src/core/loader/polarssl/aes.c
Normal file
File diff suppressed because it is too large
Load diff
139
src/core/loader/polarssl/aes.h
Normal file
139
src/core/loader/polarssl/aes.h
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
/**
|
||||||
|
* \file aes.h
|
||||||
|
*
|
||||||
|
* 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_AES_H
|
||||||
|
#define POLARSSL_AES_H
|
||||||
|
|
||||||
|
#define AES_ENCRYPT 1
|
||||||
|
#define AES_DECRYPT 0
|
||||||
|
|
||||||
|
#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH -0x0800
|
||||||
|
#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH -0x0810
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief AES context structure
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int nr; /*!< number of rounds */
|
||||||
|
unsigned long *rk; /*!< AES round keys */
|
||||||
|
unsigned long buf[68]; /*!< unaligned data */
|
||||||
|
}
|
||||||
|
aes_context;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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, 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, 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] );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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,
|
||||||
|
int length,
|
||||||
|
unsigned char iv[16],
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief AES-CFB128 buffer encryption/decryption.
|
||||||
|
*
|
||||||
|
* \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,
|
||||||
|
int length,
|
||||||
|
int *iv_off,
|
||||||
|
unsigned char iv[16],
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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 */
|
2038
src/core/loader/polarssl/bignum.c
Normal file
2038
src/core/loader/polarssl/bignum.c
Normal file
File diff suppressed because it is too large
Load diff
533
src/core/loader/polarssl/bignum.h
Normal file
533
src/core/loader/polarssl/bignum.h
Normal file
|
@ -0,0 +1,533 @@
|
||||||
|
/**
|
||||||
|
* \file bignum.h
|
||||||
|
*
|
||||||
|
* 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_BIGNUM_H
|
||||||
|
#define POLARSSL_BIGNUM_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define POLARSSL_ERR_MPI_FILE_IO_ERROR 0x0002
|
||||||
|
#define POLARSSL_ERR_MPI_BAD_INPUT_DATA 0x0004
|
||||||
|
#define POLARSSL_ERR_MPI_INVALID_CHARACTER 0x0006
|
||||||
|
#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL 0x0008
|
||||||
|
#define POLARSSL_ERR_MPI_NEGATIVE_VALUE 0x000A
|
||||||
|
#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO 0x000C
|
||||||
|
#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE 0x000E
|
||||||
|
|
||||||
|
#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define the base integer type, architecture-wise
|
||||||
|
*/
|
||||||
|
#if defined(POLARSSL_HAVE_INT8)
|
||||||
|
typedef unsigned char t_int;
|
||||||
|
typedef unsigned short t_dbl;
|
||||||
|
#else
|
||||||
|
#if defined(POLARSSL_HAVE_INT16)
|
||||||
|
typedef unsigned short t_int;
|
||||||
|
typedef unsigned long t_dbl;
|
||||||
|
#else
|
||||||
|
typedef unsigned long t_int;
|
||||||
|
#if defined(_MSC_VER) && defined(_M_IX86)
|
||||||
|
typedef unsigned __int64 t_dbl;
|
||||||
|
#else
|
||||||
|
#if defined(__amd64__) || defined(__x86_64__) || \
|
||||||
|
defined(__ppc64__) || defined(__powerpc64__) || \
|
||||||
|
defined(__ia64__) || defined(__alpha__)
|
||||||
|
typedef unsigned int t_dbl __attribute__((mode(TI)));
|
||||||
|
#else
|
||||||
|
#if defined(POLARSSL_HAVE_LONGLONG)
|
||||||
|
typedef unsigned long long t_dbl;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MPI structure
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int s; /*!< integer sign */
|
||||||
|
int n; /*!< total # of limbs */
|
||||||
|
t_int *p; /*!< pointer to limbs */
|
||||||
|
}
|
||||||
|
mpi;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initialize one or more mpi
|
||||||
|
*/
|
||||||
|
void mpi_init( mpi *X, ... );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Unallocate one or more mpi
|
||||||
|
*/
|
||||||
|
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,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_grow( mpi *X, int nblimbs );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Copy the contents of Y into X
|
||||||
|
*
|
||||||
|
* \param X Destination MPI
|
||||||
|
* \param Y Source MPI
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 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,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_lset( mpi *X, int z );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return the number of least significant bits
|
||||||
|
*
|
||||||
|
* \param X MPI to use
|
||||||
|
*/
|
||||||
|
int mpi_lsb( const mpi *X );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return the number of most significant bits
|
||||||
|
*
|
||||||
|
* \param X MPI to use
|
||||||
|
*/
|
||||||
|
int mpi_msb( const mpi *X );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return the total size in bytes
|
||||||
|
*
|
||||||
|
* \param X MPI to use
|
||||||
|
*/
|
||||||
|
int 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 an 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 an 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, int *slen );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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, or an 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 an 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 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_read_binary( mpi *X, const unsigned char *buf, int 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, int buflen );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Left-shift: X <<= count
|
||||||
|
*
|
||||||
|
* \param X MPI to shift
|
||||||
|
* \param count Amount to shift
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_shift_l( mpi *X, int count );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Right-shift: X >>= count
|
||||||
|
*
|
||||||
|
* \param X MPI to shift
|
||||||
|
* \param count Amount to shift
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_shift_r( mpi *X, int 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, int 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,
|
||||||
|
* 1 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,
|
||||||
|
* 1 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,
|
||||||
|
* 1 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,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_add_int( mpi *X, const mpi *A, int 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,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_sub_int( mpi *X, const mpi *A, int 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,
|
||||||
|
* 1 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,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_mul_int( mpi *X, const mpi *A, t_int 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,
|
||||||
|
* 1 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,
|
||||||
|
* 1 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, int 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,
|
||||||
|
* 1 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_int
|
||||||
|
* \param A Left-hand MPI
|
||||||
|
* \param b Integer to divide by
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 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_int *r, const mpi *A, int 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,
|
||||||
|
* 1 if memory allocation failed,
|
||||||
|
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even
|
||||||
|
*
|
||||||
|
* \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 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,
|
||||||
|
* 1 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,
|
||||||
|
* 1 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),
|
||||||
|
* 1 if memory allocation failed,
|
||||||
|
* POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
|
||||||
|
*/
|
||||||
|
int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Prime number generation
|
||||||
|
*
|
||||||
|
* \param X Destination MPI
|
||||||
|
* \param nbits Required size of X in 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),
|
||||||
|
* 1 if memory allocation failed,
|
||||||
|
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
|
||||||
|
*/
|
||||||
|
int mpi_gen_prime( mpi *X, int nbits, int dh_flag,
|
||||||
|
int (*f_rng)(void *), 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 */
|
736
src/core/loader/polarssl/bn_mul.h
Normal file
736
src/core/loader/polarssl/bn_mul.h
Normal file
|
@ -0,0 +1,736 @@
|
||||||
|
/**
|
||||||
|
* \file bn_mul.h
|
||||||
|
*
|
||||||
|
* 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 "core/loader/polarssl/config.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__)
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
asm( "ld %0, %%o0 " :: "m" (s)); \
|
||||||
|
asm( "ld %0, %%o1 " :: "m" (d)); \
|
||||||
|
asm( "ld %0, %%o2 " :: "m" (c)); \
|
||||||
|
asm( "ld %0, %%o3 " :: "m" (b));
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
asm( "ld [%o0], %o4 " ); \
|
||||||
|
asm( "inc 4, %o0 " ); \
|
||||||
|
asm( "ld [%o1], %o5 " ); \
|
||||||
|
asm( "umul %o3, %o4, %o4 " ); \
|
||||||
|
asm( "addcc %o4, %o2, %o4 " ); \
|
||||||
|
asm( "rd %y, %g1 " ); \
|
||||||
|
asm( "addx %g1, 0, %g1 " ); \
|
||||||
|
asm( "addcc %o4, %o5, %o4 " ); \
|
||||||
|
asm( "st %o4, [%o1] " ); \
|
||||||
|
asm( "addx %g1, 0, %o2 " ); \
|
||||||
|
asm( "inc 4, %o1 " );
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
asm( "st %%o2, %0 " : "=m" (c)); \
|
||||||
|
asm( "st %%o1, %0 " : "=m" (d)); \
|
||||||
|
asm( "st %%o0, %0 " : "=m" (s) :: \
|
||||||
|
"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__)
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
asm( "ldr r0, %0 " :: "m" (s)); \
|
||||||
|
asm( "ldr r1, %0 " :: "m" (d)); \
|
||||||
|
asm( "ldr r2, %0 " :: "m" (c)); \
|
||||||
|
asm( "ldr r3, %0 " :: "m" (b));
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
asm( "ldr r4, [r0], #4 " ); \
|
||||||
|
asm( "mov r5, #0 " ); \
|
||||||
|
asm( "ldr r6, [r1] " ); \
|
||||||
|
asm( "umlal r2, r5, r3, r4 " ); \
|
||||||
|
asm( "adds r7, r6, r2 " ); \
|
||||||
|
asm( "adc r2, r5, #0 " ); \
|
||||||
|
asm( "str r7, [r1], #4 " );
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
asm( "str r2, %0 " : "=m" (c)); \
|
||||||
|
asm( "str r1, %0 " : "=m" (d)); \
|
||||||
|
asm( "str r0, %0 " : "=m" (s) :: \
|
||||||
|
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" );
|
||||||
|
|
||||||
|
#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_LONGLONG)
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
{ \
|
||||||
|
t_dbl r; \
|
||||||
|
t_int r0, r1;
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
r = *(s++) * (t_dbl) 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_int s0, s1, b0, b1; \
|
||||||
|
t_int 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 */
|
336
src/core/loader/polarssl/config.h
Normal file
336
src/core/loader/polarssl/config.h
Normal file
|
@ -0,0 +1,336 @@
|
||||||
|
/**
|
||||||
|
* \file config.h
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* This set of compile-time options may be used to enable
|
||||||
|
* or disable features selectively, and reduce the global
|
||||||
|
* memory footprint.
|
||||||
|
*/
|
||||||
|
#ifndef POLARSSL_CONFIG_H
|
||||||
|
#define POLARSSL_CONFIG_H
|
||||||
|
|
||||||
|
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||||
|
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uncomment if native integers are 8-bit wide.
|
||||||
|
*
|
||||||
|
#define POLARSSL_HAVE_INT8
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uncomment if native integers are 16-bit wide.
|
||||||
|
*
|
||||||
|
#define POLARSSL_HAVE_INT16
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uncomment if the compiler supports long long.
|
||||||
|
*
|
||||||
|
#define POLARSSL_HAVE_LONGLONG
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uncomment to enable the use of assembly code.
|
||||||
|
*
|
||||||
|
* Requires support for asm() in compiler.
|
||||||
|
*
|
||||||
|
* Used in:
|
||||||
|
* library/timing.c
|
||||||
|
* library/padlock.c
|
||||||
|
* include/polarssl/bn_mul.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
//#define POLARSSL_HAVE_ASM
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uncomment if the CPU supports SSE2 (IA-32 specific).
|
||||||
|
*
|
||||||
|
#define POLARSSL_HAVE_SSE2
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable all SSL/TLS debugging messages.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_DEBUG_MSG
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable the checkup functions (*_self_test).
|
||||||
|
*/
|
||||||
|
//#define POLARSSL_SELF_TEST
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable run-time version information functions
|
||||||
|
*/
|
||||||
|
#define POLARSSL_VERSION_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable the prime-number generation code.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_GENPRIME
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uncomment this macro to store the AES tables in ROM.
|
||||||
|
*
|
||||||
|
#define POLARSSL_AES_ROM_TABLES
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/aes.c
|
||||||
|
* Caller: library/ssl_tls.c
|
||||||
|
*
|
||||||
|
* This module enables the following ciphersuites:
|
||||||
|
* SSL_RSA_AES_128_SHA
|
||||||
|
* SSL_RSA_AES_256_SHA
|
||||||
|
* SSL_EDH_RSA_AES_256_SHA
|
||||||
|
*/
|
||||||
|
#define POLARSSL_AES_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/arc4.c
|
||||||
|
* Caller: library/ssl_tls.c
|
||||||
|
*
|
||||||
|
* This module enables the following ciphersuites:
|
||||||
|
* SSL_RSA_RC4_128_MD5
|
||||||
|
* SSL_RSA_RC4_128_SHA
|
||||||
|
*/
|
||||||
|
#define POLARSSL_ARC4_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/base64.c
|
||||||
|
* Caller: library/x509parse.c
|
||||||
|
*
|
||||||
|
* This module is required for X.509 support.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_BASE64_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/bignum.c
|
||||||
|
* Caller: library/dhm.c
|
||||||
|
* library/rsa.c
|
||||||
|
* library/ssl_tls.c
|
||||||
|
* library/x509parse.c
|
||||||
|
*
|
||||||
|
* This module is required for RSA and DHM support.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_BIGNUM_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/camellia.c
|
||||||
|
* Caller: library/ssl_tls.c
|
||||||
|
*
|
||||||
|
* This module enabled the following cipher suites:
|
||||||
|
* SSL_RSA_CAMELLIA_128_SHA
|
||||||
|
* SSL_RSA_CAMELLIA_256_SHA
|
||||||
|
* SSL_EDH_RSA_CAMELLIA_256_SHA
|
||||||
|
*/
|
||||||
|
#define POLARSSL_CAMELLIA_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/certs.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module is used for testing (ssl_client/server).
|
||||||
|
*/
|
||||||
|
#define POLARSSL_CERTS_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/debug.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
* library/ssl_tls.c
|
||||||
|
*
|
||||||
|
* This module provides debugging functions.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_DEBUG_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/des.c
|
||||||
|
* Caller: library/ssl_tls.c
|
||||||
|
*
|
||||||
|
* This module enables the following ciphersuites:
|
||||||
|
* SSL_RSA_DES_168_SHA
|
||||||
|
* SSL_EDH_RSA_DES_168_SHA
|
||||||
|
*/
|
||||||
|
#define POLARSSL_DES_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/dhm.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
*
|
||||||
|
* This module enables the following ciphersuites:
|
||||||
|
* SSL_EDH_RSA_DES_168_SHA
|
||||||
|
* SSL_EDH_RSA_AES_256_SHA
|
||||||
|
* SSL_EDH_RSA_CAMELLIA_256_SHA
|
||||||
|
*/
|
||||||
|
#define POLARSSL_DHM_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/havege.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module enables the HAVEGE random number generator.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_HAVEGE_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/md2.c
|
||||||
|
* Caller: library/x509parse.c
|
||||||
|
*
|
||||||
|
* Uncomment to enable support for (rare) MD2-signed X.509 certs.
|
||||||
|
*
|
||||||
|
#define POLARSSL_MD2_C
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/md4.c
|
||||||
|
* Caller: library/x509parse.c
|
||||||
|
*
|
||||||
|
* Uncomment to enable support for (rare) MD4-signed X.509 certs.
|
||||||
|
*
|
||||||
|
#define POLARSSL_MD4_C
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/md5.c
|
||||||
|
* Caller: library/ssl_tls.c
|
||||||
|
* library/x509parse.c
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS and X.509.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_MD5_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/net.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module provides TCP/IP networking routines.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_NET_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/padlock.c
|
||||||
|
* Caller: library/aes.c
|
||||||
|
*
|
||||||
|
* This modules adds support for the VIA PadLock on x86.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_PADLOCK_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/rsa.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
* library/ssl_tls.c
|
||||||
|
* library/x509.c
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS and MD5-signed certificates.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_RSA_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/sha1.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
* library/ssl_tls.c
|
||||||
|
* library/x509parse.c
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS and SHA1-signed certificates.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SHA1_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/sha2.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module adds support for SHA-224 and SHA-256.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SHA2_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/sha4.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module adds support for SHA-384 and SHA-512.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SHA4_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/ssl_cli.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS client support.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SSL_CLI_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/ssl_srv.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS server support.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SSL_SRV_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/ssl_tls.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SSL_TLS_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/timing.c
|
||||||
|
* Caller: library/havege.c
|
||||||
|
*
|
||||||
|
* This module is used by the HAVEGE random number generator.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_TIMING_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/x509parse.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
* library/ssl_tls.c
|
||||||
|
*
|
||||||
|
* This module is required for X.509 certificate parsing.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_X509_PARSE_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/x509_write.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module is required for X.509 certificate writing.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_X509_WRITE_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/xtea.c
|
||||||
|
* Caller:
|
||||||
|
*/
|
||||||
|
#define POLARSSL_XTEA_C
|
||||||
|
|
||||||
|
#endif /* config.h */
|
98
src/core/loader/polarssl/padlock.h
Normal file
98
src/core/loader/polarssl/padlock.h
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
/**
|
||||||
|
* \file padlock.h
|
||||||
|
*
|
||||||
|
* 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_PADLOCK_H
|
||||||
|
#define POLARSSL_PADLOCK_H
|
||||||
|
|
||||||
|
#include "core/loader/polarssl/aes.h"
|
||||||
|
|
||||||
|
#if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && defined(__i386__)
|
||||||
|
|
||||||
|
#ifndef POLARSSL_HAVE_X86
|
||||||
|
#define POLARSSL_HAVE_X86
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PADLOCK_RNG 0x000C
|
||||||
|
#define PADLOCK_ACE 0x00C0
|
||||||
|
#define PADLOCK_PHE 0x0C00
|
||||||
|
#define PADLOCK_PMM 0x3000
|
||||||
|
|
||||||
|
#define PADLOCK_ALIGN16(x) (unsigned long *) (16 + ((long) x & ~15))
|
||||||
|
|
||||||
|
#define POLARSSL_ERR_PADLOCK_DATA_MISALIGNED -0x08E0
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief PadLock detection routine
|
||||||
|
*
|
||||||
|
* \param The feature to detect
|
||||||
|
*
|
||||||
|
* \return 1 if CPU has support for the feature, 0 otherwise
|
||||||
|
*/
|
||||||
|
int padlock_supports( int feature );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief PadLock AES-ECB block en(de)cryption
|
||||||
|
*
|
||||||
|
* \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 success, 1 if operation failed
|
||||||
|
*/
|
||||||
|
int padlock_xcryptecb( aes_context *ctx,
|
||||||
|
int mode,
|
||||||
|
const unsigned char input[16],
|
||||||
|
unsigned char output[16] );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief PadLock AES-CBC buffer en(de)cryption
|
||||||
|
*
|
||||||
|
* \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 success, 1 if operation failed
|
||||||
|
*/
|
||||||
|
int padlock_xcryptcbc( aes_context *ctx,
|
||||||
|
int mode,
|
||||||
|
int length,
|
||||||
|
unsigned char iv[16],
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAVE_X86 */
|
||||||
|
|
||||||
|
#endif /* padlock.h */
|
823
src/core/loader/polarssl/rsa.c
Normal file
823
src/core/loader/polarssl/rsa.c
Normal file
|
@ -0,0 +1,823 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
|
||||||
|
*
|
||||||
|
* http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
|
||||||
|
* http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "core/loader/polarssl/config.h"
|
||||||
|
|
||||||
|
#if defined(POLARSSL_RSA_C)
|
||||||
|
|
||||||
|
#include "core/loader/polarssl/rsa.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize an RSA context
|
||||||
|
*/
|
||||||
|
void rsa_init( rsa_context *ctx,
|
||||||
|
int padding,
|
||||||
|
int hash_id )
|
||||||
|
{
|
||||||
|
memset( ctx, 0, sizeof( rsa_context ) );
|
||||||
|
|
||||||
|
ctx->padding = padding;
|
||||||
|
ctx->hash_id = hash_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(POLARSSL_GENPRIME)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate an RSA keypair
|
||||||
|
*/
|
||||||
|
int rsa_gen_key( rsa_context *ctx,
|
||||||
|
int (*f_rng)(void *),
|
||||||
|
void *p_rng,
|
||||||
|
int nbits, int exponent )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
mpi P1, Q1, H, G;
|
||||||
|
|
||||||
|
if( f_rng == NULL || nbits < 128 || exponent < 3 )
|
||||||
|
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
mpi_init( &P1, &Q1, &H, &G, NULL );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* find primes P and Q with Q < P so that:
|
||||||
|
* GCD( E, (P-1)*(Q-1) ) == 1
|
||||||
|
*/
|
||||||
|
MPI_CHK( mpi_lset( &ctx->E, exponent ) );
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0,
|
||||||
|
f_rng, p_rng ) );
|
||||||
|
|
||||||
|
MPI_CHK( mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0,
|
||||||
|
f_rng, p_rng ) );
|
||||||
|
|
||||||
|
if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
|
||||||
|
mpi_swap( &ctx->P, &ctx->Q );
|
||||||
|
|
||||||
|
if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MPI_CHK( mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
|
||||||
|
if( mpi_msb( &ctx->N ) != nbits )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
|
||||||
|
MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
|
||||||
|
MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
|
||||||
|
MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
|
||||||
|
}
|
||||||
|
while( mpi_cmp_int( &G, 1 ) != 0 );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* D = E^-1 mod ((P-1)*(Q-1))
|
||||||
|
* DP = D mod (P - 1)
|
||||||
|
* DQ = D mod (Q - 1)
|
||||||
|
* QP = Q^-1 mod P
|
||||||
|
*/
|
||||||
|
MPI_CHK( mpi_inv_mod( &ctx->D , &ctx->E, &H ) );
|
||||||
|
MPI_CHK( mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) );
|
||||||
|
MPI_CHK( mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) );
|
||||||
|
MPI_CHK( mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) );
|
||||||
|
|
||||||
|
ctx->len = ( mpi_msb( &ctx->N ) + 7 ) >> 3;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
mpi_free( &G, &H, &Q1, &P1, NULL );
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
{
|
||||||
|
rsa_free( ctx );
|
||||||
|
return( POLARSSL_ERR_RSA_KEY_GEN_FAILED | ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check a public RSA key
|
||||||
|
*/
|
||||||
|
int rsa_check_pubkey( const rsa_context *ctx )
|
||||||
|
{
|
||||||
|
if( !ctx->N.p || !ctx->E.p )
|
||||||
|
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
|
||||||
|
|
||||||
|
if( ( ctx->N.p[0] & 1 ) == 0 ||
|
||||||
|
( ctx->E.p[0] & 1 ) == 0 )
|
||||||
|
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
|
||||||
|
|
||||||
|
if( mpi_msb( &ctx->N ) < 128 ||
|
||||||
|
mpi_msb( &ctx->N ) > 4096 )
|
||||||
|
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
|
||||||
|
|
||||||
|
if( mpi_msb( &ctx->E ) < 2 ||
|
||||||
|
mpi_msb( &ctx->E ) > 64 )
|
||||||
|
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check a private RSA key
|
||||||
|
*/
|
||||||
|
int rsa_check_privkey( const rsa_context *ctx )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2;
|
||||||
|
|
||||||
|
if( ( ret = rsa_check_pubkey( ctx ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
if( !ctx->P.p || !ctx->Q.p || !ctx->D.p )
|
||||||
|
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
|
||||||
|
|
||||||
|
mpi_init( &PQ, &DE, &P1, &Q1, &H, &I, &G, &G2, &L1, &L2, NULL );
|
||||||
|
|
||||||
|
MPI_CHK( mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) );
|
||||||
|
MPI_CHK( mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) );
|
||||||
|
MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
|
||||||
|
MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
|
||||||
|
MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
|
||||||
|
MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
|
||||||
|
|
||||||
|
MPI_CHK( mpi_gcd( &G2, &P1, &Q1 ) );
|
||||||
|
MPI_CHK( mpi_div_mpi( &L1, &L2, &H, &G2 ) );
|
||||||
|
MPI_CHK( mpi_mod_mpi( &I, &DE, &L1 ) );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for a valid PKCS1v2 private key
|
||||||
|
*/
|
||||||
|
if( mpi_cmp_mpi( &PQ, &ctx->N ) == 0 &&
|
||||||
|
mpi_cmp_int( &L2, 0 ) == 0 &&
|
||||||
|
mpi_cmp_int( &I, 1 ) == 0 &&
|
||||||
|
mpi_cmp_int( &G, 1 ) == 0 )
|
||||||
|
{
|
||||||
|
mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL );
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL );
|
||||||
|
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED | ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do an RSA public key operation
|
||||||
|
*/
|
||||||
|
int rsa_public( rsa_context *ctx,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output )
|
||||||
|
{
|
||||||
|
int ret, olen;
|
||||||
|
mpi T;
|
||||||
|
|
||||||
|
mpi_init( &T, NULL );
|
||||||
|
|
||||||
|
MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
|
||||||
|
|
||||||
|
if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
|
||||||
|
{
|
||||||
|
mpi_free( &T, NULL );
|
||||||
|
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
olen = ctx->len;
|
||||||
|
MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
|
||||||
|
MPI_CHK( mpi_write_binary( &T, output, olen ) );
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
mpi_free( &T, NULL );
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
return( POLARSSL_ERR_RSA_PUBLIC_FAILED | ret );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do an RSA private key operation
|
||||||
|
*/
|
||||||
|
int rsa_private( rsa_context *ctx,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output )
|
||||||
|
{
|
||||||
|
int ret, olen;
|
||||||
|
mpi T, T1, T2;
|
||||||
|
|
||||||
|
mpi_init( &T, &T1, &T2, NULL );
|
||||||
|
|
||||||
|
MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
|
||||||
|
|
||||||
|
if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
|
||||||
|
{
|
||||||
|
mpi_free( &T, NULL );
|
||||||
|
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* faster decryption using the CRT
|
||||||
|
*
|
||||||
|
* T1 = input ^ dP mod P
|
||||||
|
* T2 = input ^ dQ mod Q
|
||||||
|
*/
|
||||||
|
MPI_CHK( mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) );
|
||||||
|
MPI_CHK( mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* T = (T1 - T2) * (Q^-1 mod P) mod P
|
||||||
|
*/
|
||||||
|
MPI_CHK( mpi_sub_mpi( &T, &T1, &T2 ) );
|
||||||
|
MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->QP ) );
|
||||||
|
MPI_CHK( mpi_mod_mpi( &T, &T1, &ctx->P ) );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* output = T2 + T * Q
|
||||||
|
*/
|
||||||
|
MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->Q ) );
|
||||||
|
MPI_CHK( mpi_add_mpi( &T, &T2, &T1 ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
olen = ctx->len;
|
||||||
|
MPI_CHK( mpi_write_binary( &T, output, olen ) );
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
mpi_free( &T, &T1, &T2, NULL );
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
return( POLARSSL_ERR_RSA_PRIVATE_FAILED | ret );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the message padding, then do an RSA operation
|
||||||
|
*/
|
||||||
|
int rsa_pkcs1_encrypt( rsa_context *ctx,
|
||||||
|
int (*f_rng)(void *),
|
||||||
|
void *p_rng,
|
||||||
|
int mode, int ilen,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output )
|
||||||
|
{
|
||||||
|
int nb_pad, olen;
|
||||||
|
unsigned char *p = output;
|
||||||
|
|
||||||
|
olen = ctx->len;
|
||||||
|
|
||||||
|
switch( ctx->padding )
|
||||||
|
{
|
||||||
|
case RSA_PKCS_V15:
|
||||||
|
|
||||||
|
if( ilen < 0 || olen < ilen + 11 || f_rng == NULL )
|
||||||
|
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
nb_pad = olen - 3 - ilen;
|
||||||
|
|
||||||
|
*p++ = 0;
|
||||||
|
*p++ = RSA_CRYPT;
|
||||||
|
|
||||||
|
while( nb_pad-- > 0 )
|
||||||
|
{
|
||||||
|
int rng_dl = 100;
|
||||||
|
|
||||||
|
do {
|
||||||
|
*p = (unsigned char) f_rng( p_rng );
|
||||||
|
} while( *p == 0 && --rng_dl );
|
||||||
|
|
||||||
|
// Check if RNG failed to generate data
|
||||||
|
//
|
||||||
|
if( rng_dl == 0 )
|
||||||
|
return POLARSSL_ERR_RSA_RNG_FAILED;
|
||||||
|
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
*p++ = 0;
|
||||||
|
memcpy( p, input, ilen );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( ( mode == RSA_PUBLIC )
|
||||||
|
? rsa_public( ctx, output, output )
|
||||||
|
: rsa_private( ctx, output, output ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do an RSA operation, then remove the message padding
|
||||||
|
*/
|
||||||
|
int rsa_pkcs1_decrypt( rsa_context *ctx,
|
||||||
|
int mode, int *olen,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output,
|
||||||
|
int output_max_len)
|
||||||
|
{
|
||||||
|
int ret, ilen;
|
||||||
|
unsigned char *p;
|
||||||
|
unsigned char buf[1024];
|
||||||
|
|
||||||
|
ilen = ctx->len;
|
||||||
|
|
||||||
|
if( ilen < 16 || ilen > (int) sizeof( buf ) )
|
||||||
|
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
ret = ( mode == RSA_PUBLIC )
|
||||||
|
? rsa_public( ctx, input, buf )
|
||||||
|
: rsa_private( ctx, input, buf );
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
p = buf;
|
||||||
|
|
||||||
|
switch( ctx->padding )
|
||||||
|
{
|
||||||
|
case RSA_PKCS_V15:
|
||||||
|
|
||||||
|
if( *p++ != 0 || *p++ != RSA_CRYPT )
|
||||||
|
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||||
|
|
||||||
|
while( *p != 0 )
|
||||||
|
{
|
||||||
|
if( p >= buf + ilen - 1 )
|
||||||
|
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ilen - (int)(p - buf) > output_max_len)
|
||||||
|
return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );
|
||||||
|
|
||||||
|
*olen = ilen - (int)(p - buf);
|
||||||
|
memcpy( output, p, *olen );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do an RSA operation to sign the message digest
|
||||||
|
*/
|
||||||
|
int rsa_pkcs1_sign( rsa_context *ctx,
|
||||||
|
int mode,
|
||||||
|
int hash_id,
|
||||||
|
int hashlen,
|
||||||
|
const unsigned char *hash,
|
||||||
|
unsigned char *sig )
|
||||||
|
{
|
||||||
|
int nb_pad, olen;
|
||||||
|
unsigned char *p = sig;
|
||||||
|
|
||||||
|
olen = ctx->len;
|
||||||
|
|
||||||
|
switch( ctx->padding )
|
||||||
|
{
|
||||||
|
case RSA_PKCS_V15:
|
||||||
|
|
||||||
|
switch( hash_id )
|
||||||
|
{
|
||||||
|
case SIG_RSA_RAW:
|
||||||
|
nb_pad = olen - 3 - hashlen;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIG_RSA_MD2:
|
||||||
|
case SIG_RSA_MD4:
|
||||||
|
case SIG_RSA_MD5:
|
||||||
|
nb_pad = olen - 3 - 34;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA1:
|
||||||
|
nb_pad = olen - 3 - 35;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA224:
|
||||||
|
nb_pad = olen - 3 - 47;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA256:
|
||||||
|
nb_pad = olen - 3 - 51;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA384:
|
||||||
|
nb_pad = olen - 3 - 67;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA512:
|
||||||
|
nb_pad = olen - 3 - 83;
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( nb_pad < 8 )
|
||||||
|
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
*p++ = 0;
|
||||||
|
*p++ = RSA_SIGN;
|
||||||
|
memset( p, 0xFF, nb_pad );
|
||||||
|
p += nb_pad;
|
||||||
|
*p++ = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( hash_id )
|
||||||
|
{
|
||||||
|
case SIG_RSA_RAW:
|
||||||
|
memcpy( p, hash, hashlen );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIG_RSA_MD2:
|
||||||
|
memcpy( p, ASN1_HASH_MDX, 18 );
|
||||||
|
memcpy( p + 18, hash, 16 );
|
||||||
|
p[13] = 2; break;
|
||||||
|
|
||||||
|
case SIG_RSA_MD4:
|
||||||
|
memcpy( p, ASN1_HASH_MDX, 18 );
|
||||||
|
memcpy( p + 18, hash, 16 );
|
||||||
|
p[13] = 4; break;
|
||||||
|
|
||||||
|
case SIG_RSA_MD5:
|
||||||
|
memcpy( p, ASN1_HASH_MDX, 18 );
|
||||||
|
memcpy( p + 18, hash, 16 );
|
||||||
|
p[13] = 5; break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA1:
|
||||||
|
memcpy( p, ASN1_HASH_SHA1, 15 );
|
||||||
|
memcpy( p + 15, hash, 20 );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA224:
|
||||||
|
memcpy( p, ASN1_HASH_SHA2X, 19 );
|
||||||
|
memcpy( p + 19, hash, 28 );
|
||||||
|
p[1] += 28; p[14] = 4; p[18] += 28; break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA256:
|
||||||
|
memcpy( p, ASN1_HASH_SHA2X, 19 );
|
||||||
|
memcpy( p + 19, hash, 32 );
|
||||||
|
p[1] += 32; p[14] = 1; p[18] += 32; break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA384:
|
||||||
|
memcpy( p, ASN1_HASH_SHA2X, 19 );
|
||||||
|
memcpy( p + 19, hash, 48 );
|
||||||
|
p[1] += 48; p[14] = 2; p[18] += 48; break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA512:
|
||||||
|
memcpy( p, ASN1_HASH_SHA2X, 19 );
|
||||||
|
memcpy( p + 19, hash, 64 );
|
||||||
|
p[1] += 64; p[14] = 3; p[18] += 64; break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( ( mode == RSA_PUBLIC )
|
||||||
|
? rsa_public( ctx, sig, sig )
|
||||||
|
: rsa_private( ctx, sig, sig ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do an RSA operation and check the message digest
|
||||||
|
*/
|
||||||
|
int rsa_pkcs1_verify( rsa_context *ctx,
|
||||||
|
int mode,
|
||||||
|
int hash_id,
|
||||||
|
int hashlen,
|
||||||
|
const unsigned char *hash,
|
||||||
|
unsigned char *sig )
|
||||||
|
{
|
||||||
|
int ret, len, siglen;
|
||||||
|
unsigned char *p, c;
|
||||||
|
unsigned char buf[1024];
|
||||||
|
|
||||||
|
siglen = ctx->len;
|
||||||
|
|
||||||
|
if( siglen < 16 || siglen > (int) sizeof( buf ) )
|
||||||
|
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
ret = ( mode == RSA_PUBLIC )
|
||||||
|
? rsa_public( ctx, sig, buf )
|
||||||
|
: rsa_private( ctx, sig, buf );
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
p = buf;
|
||||||
|
|
||||||
|
switch( ctx->padding )
|
||||||
|
{
|
||||||
|
case RSA_PKCS_V15:
|
||||||
|
|
||||||
|
if( *p++ != 0 || *p++ != RSA_SIGN )
|
||||||
|
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||||
|
|
||||||
|
while( *p != 0 )
|
||||||
|
{
|
||||||
|
if( p >= buf + siglen - 1 || *p != 0xFF )
|
||||||
|
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||||
|
}
|
||||||
|
|
||||||
|
len = siglen - (int)( p - buf );
|
||||||
|
|
||||||
|
if( len == 34 )
|
||||||
|
{
|
||||||
|
c = p[13];
|
||||||
|
p[13] = 0;
|
||||||
|
|
||||||
|
if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
|
||||||
|
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||||
|
|
||||||
|
if( ( c == 2 && hash_id == SIG_RSA_MD2 ) ||
|
||||||
|
( c == 4 && hash_id == SIG_RSA_MD4 ) ||
|
||||||
|
( c == 5 && hash_id == SIG_RSA_MD5 ) )
|
||||||
|
{
|
||||||
|
if( memcmp( p + 18, hash, 16 ) == 0 )
|
||||||
|
return( 0 );
|
||||||
|
else
|
||||||
|
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( len == 35 && hash_id == SIG_RSA_SHA1 )
|
||||||
|
{
|
||||||
|
if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
|
||||||
|
memcmp( p + 15, hash, 20 ) == 0 )
|
||||||
|
return( 0 );
|
||||||
|
else
|
||||||
|
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||||
|
}
|
||||||
|
if( ( len == 19 + 28 && p[14] == 4 && hash_id == SIG_RSA_SHA224 ) ||
|
||||||
|
( len == 19 + 32 && p[14] == 1 && hash_id == SIG_RSA_SHA256 ) ||
|
||||||
|
( len == 19 + 48 && p[14] == 2 && hash_id == SIG_RSA_SHA384 ) ||
|
||||||
|
( len == 19 + 64 && p[14] == 3 && hash_id == SIG_RSA_SHA512 ) )
|
||||||
|
{
|
||||||
|
c = p[1] - 17;
|
||||||
|
p[1] = 17;
|
||||||
|
p[14] = 0;
|
||||||
|
|
||||||
|
if( p[18] == c &&
|
||||||
|
memcmp( p, ASN1_HASH_SHA2X, 18 ) == 0 &&
|
||||||
|
memcmp( p + 19, hash, c ) == 0 )
|
||||||
|
return( 0 );
|
||||||
|
else
|
||||||
|
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( len == hashlen && hash_id == SIG_RSA_RAW )
|
||||||
|
{
|
||||||
|
if( memcmp( p, hash, hashlen ) == 0 )
|
||||||
|
return( 0 );
|
||||||
|
else
|
||||||
|
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free the components of an RSA key
|
||||||
|
*/
|
||||||
|
void rsa_free( rsa_context *ctx )
|
||||||
|
{
|
||||||
|
mpi_free( &ctx->RQ, &ctx->RP, &ctx->RN,
|
||||||
|
&ctx->QP, &ctx->DQ, &ctx->DP,
|
||||||
|
&ctx->Q, &ctx->P, &ctx->D,
|
||||||
|
&ctx->E, &ctx->N, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(POLARSSL_SELF_TEST)
|
||||||
|
|
||||||
|
#include "polarssl/sha1.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Example RSA-1024 keypair, for test purposes
|
||||||
|
*/
|
||||||
|
#define KEY_LEN 128
|
||||||
|
|
||||||
|
#define RSA_N "9292758453063D803DD603D5E777D788" \
|
||||||
|
"8ED1D5BF35786190FA2F23EBC0848AEA" \
|
||||||
|
"DDA92CA6C3D80B32C4D109BE0F36D6AE" \
|
||||||
|
"7130B9CED7ACDF54CFC7555AC14EEBAB" \
|
||||||
|
"93A89813FBF3C4F8066D2D800F7C38A8" \
|
||||||
|
"1AE31942917403FF4946B0A83D3D3E05" \
|
||||||
|
"EE57C6F5F5606FB5D4BC6CD34EE0801A" \
|
||||||
|
"5E94BB77B07507233A0BC7BAC8F90F79"
|
||||||
|
|
||||||
|
#define RSA_E "10001"
|
||||||
|
|
||||||
|
#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
|
||||||
|
"66CA472BC44D253102F8B4A9D3BFA750" \
|
||||||
|
"91386C0077937FE33FA3252D28855837" \
|
||||||
|
"AE1B484A8A9A45F7EE8C0C634F99E8CD" \
|
||||||
|
"DF79C5CE07EE72C7F123142198164234" \
|
||||||
|
"CABB724CF78B8173B9F880FC86322407" \
|
||||||
|
"AF1FEDFDDE2BEB674CA15F3E81A1521E" \
|
||||||
|
"071513A1E85B5DFA031F21ECAE91A34D"
|
||||||
|
|
||||||
|
#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
|
||||||
|
"2C01CAD19EA484A87EA4377637E75500" \
|
||||||
|
"FCB2005C5C7DD6EC4AC023CDA285D796" \
|
||||||
|
"C3D9E75E1EFC42488BB4F1D13AC30A57"
|
||||||
|
|
||||||
|
#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
|
||||||
|
"E211C2B9E5DB1ED0BF61D0D9899620F4" \
|
||||||
|
"910E4168387E3C30AA1E00C339A79508" \
|
||||||
|
"8452DD96A9A5EA5D9DCA68DA636032AF"
|
||||||
|
|
||||||
|
#define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \
|
||||||
|
"3C94D22288ACD763FD8E5600ED4A702D" \
|
||||||
|
"F84198A5F06C2E72236AE490C93F07F8" \
|
||||||
|
"3CC559CD27BC2D1CA488811730BB5725"
|
||||||
|
|
||||||
|
#define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \
|
||||||
|
"D8AAEA56749EA28623272E4F7D0592AF" \
|
||||||
|
"7C1F1313CAC9471B5C523BFE592F517B" \
|
||||||
|
"407A1BD76C164B93DA2D32A383E58357"
|
||||||
|
|
||||||
|
#define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \
|
||||||
|
"F38D18D2B2F0E2DD275AA977E2BF4411" \
|
||||||
|
"F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
|
||||||
|
"A74206CEC169D74BF5A8C50D6F48EA08"
|
||||||
|
|
||||||
|
#define PT_LEN 24
|
||||||
|
#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
|
||||||
|
"\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
|
||||||
|
|
||||||
|
static int myrand( void *rng_state )
|
||||||
|
{
|
||||||
|
if( rng_state != NULL )
|
||||||
|
rng_state = NULL;
|
||||||
|
|
||||||
|
return( rand() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checkup routine
|
||||||
|
*/
|
||||||
|
int rsa_self_test( int verbose )
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
rsa_context rsa;
|
||||||
|
unsigned char sha1sum[20];
|
||||||
|
unsigned char rsa_plaintext[PT_LEN];
|
||||||
|
unsigned char rsa_decrypted[PT_LEN];
|
||||||
|
unsigned char rsa_ciphertext[KEY_LEN];
|
||||||
|
|
||||||
|
rsa_init( &rsa, RSA_PKCS_V15, 0 );
|
||||||
|
|
||||||
|
rsa.len = KEY_LEN;
|
||||||
|
mpi_read_string( &rsa.N , 16, RSA_N );
|
||||||
|
mpi_read_string( &rsa.E , 16, RSA_E );
|
||||||
|
mpi_read_string( &rsa.D , 16, RSA_D );
|
||||||
|
mpi_read_string( &rsa.P , 16, RSA_P );
|
||||||
|
mpi_read_string( &rsa.Q , 16, RSA_Q );
|
||||||
|
mpi_read_string( &rsa.DP, 16, RSA_DP );
|
||||||
|
mpi_read_string( &rsa.DQ, 16, RSA_DQ );
|
||||||
|
mpi_read_string( &rsa.QP, 16, RSA_QP );
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( " RSA key validation: " );
|
||||||
|
|
||||||
|
if( rsa_check_pubkey( &rsa ) != 0 ||
|
||||||
|
rsa_check_privkey( &rsa ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "failed\n" );
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "passed\n PKCS#1 encryption : " );
|
||||||
|
|
||||||
|
memcpy( rsa_plaintext, RSA_PT, PT_LEN );
|
||||||
|
|
||||||
|
if( rsa_pkcs1_encrypt( &rsa, &myrand, NULL, RSA_PUBLIC, PT_LEN,
|
||||||
|
rsa_plaintext, rsa_ciphertext ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "failed\n" );
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "passed\n PKCS#1 decryption : " );
|
||||||
|
|
||||||
|
if( rsa_pkcs1_decrypt( &rsa, RSA_PRIVATE, &len,
|
||||||
|
rsa_ciphertext, rsa_decrypted,
|
||||||
|
sizeof(rsa_decrypted) ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "failed\n" );
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "failed\n" );
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "passed\n PKCS#1 data sign : " );
|
||||||
|
|
||||||
|
sha1( rsa_plaintext, PT_LEN, sha1sum );
|
||||||
|
|
||||||
|
if( rsa_pkcs1_sign( &rsa, RSA_PRIVATE, SIG_RSA_SHA1, 20,
|
||||||
|
sha1sum, rsa_ciphertext ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "failed\n" );
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "passed\n PKCS#1 sig. verify: " );
|
||||||
|
|
||||||
|
if( rsa_pkcs1_verify( &rsa, RSA_PUBLIC, SIG_RSA_SHA1, 20,
|
||||||
|
sha1sum, rsa_ciphertext ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "failed\n" );
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "passed\n\n" );
|
||||||
|
|
||||||
|
rsa_free( &rsa );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
353
src/core/loader/polarssl/rsa.h
Normal file
353
src/core/loader/polarssl/rsa.h
Normal file
|
@ -0,0 +1,353 @@
|
||||||
|
/**
|
||||||
|
* \file rsa.h
|
||||||
|
*
|
||||||
|
* 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 "core/loader/polarssl/bignum.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RSA Error codes
|
||||||
|
*/
|
||||||
|
#define POLARSSL_ERR_RSA_BAD_INPUT_DATA -0x0400
|
||||||
|
#define POLARSSL_ERR_RSA_INVALID_PADDING -0x0410
|
||||||
|
#define POLARSSL_ERR_RSA_KEY_GEN_FAILED -0x0420
|
||||||
|
#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED -0x0430
|
||||||
|
#define POLARSSL_ERR_RSA_PUBLIC_FAILED -0x0440
|
||||||
|
#define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x0450
|
||||||
|
#define POLARSSL_ERR_RSA_VERIFY_FAILED -0x0460
|
||||||
|
#define POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE -0x0470
|
||||||
|
#define POLARSSL_ERR_RSA_RNG_FAILED -0x0480
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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_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 */
|
||||||
|
int 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; /*!< 1.5 or OAEP/PSS */
|
||||||
|
int hash_id; /*!< hash identifier */
|
||||||
|
}
|
||||||
|
rsa_context;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initialize an RSA context
|
||||||
|
*
|
||||||
|
* \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.
|
||||||
|
*
|
||||||
|
* \note Currently, RSA_PKCS_V21 padding
|
||||||
|
* is not supported.
|
||||||
|
*/
|
||||||
|
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 *),
|
||||||
|
void *p_rng,
|
||||||
|
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 Add the message padding, then do an RSA operation
|
||||||
|
*
|
||||||
|
* \param ctx RSA context
|
||||||
|
* \param f_rng RNG function
|
||||||
|
* \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 *),
|
||||||
|
void *p_rng,
|
||||||
|
int mode, int ilen,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Do an RSA operation, then remove the message padding
|
||||||
|
*
|
||||||
|
* \param ctx RSA context
|
||||||
|
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||||
|
* \param input buffer holding the encrypted data
|
||||||
|
* \param output buffer that will hold the plaintext
|
||||||
|
* \param olen will contain the plaintext length
|
||||||
|
* \param output_max_len maximum length of the output buffer
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or an 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, int *olen,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output,
|
||||||
|
int output_max_len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Do a private RSA to sign a message digest
|
||||||
|
*
|
||||||
|
* \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_pkcs1_sign( rsa_context *ctx,
|
||||||
|
int mode,
|
||||||
|
int hash_id,
|
||||||
|
int hashlen,
|
||||||
|
const unsigned char *hash,
|
||||||
|
unsigned char *sig );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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).
|
||||||
|
*/
|
||||||
|
int rsa_pkcs1_verify( rsa_context *ctx,
|
||||||
|
int mode,
|
||||||
|
int hash_id,
|
||||||
|
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 */
|
702
src/core/loader/polarssl/sha2.c
Normal file
702
src/core/loader/polarssl/sha2.c
Normal file
|
@ -0,0 +1,702 @@
|
||||||
|
/*
|
||||||
|
* FIPS-180-2 compliant SHA-256 implementation
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
|
||||||
|
*
|
||||||
|
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "core/loader/polarssl/config.h"
|
||||||
|
|
||||||
|
#if defined(POLARSSL_SHA2_C)
|
||||||
|
|
||||||
|
#include "core/loader/polarssl/sha2.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 32-bit integer manipulation macros (big endian)
|
||||||
|
*/
|
||||||
|
#ifndef GET_ULONG_BE
|
||||||
|
#define GET_ULONG_BE(n,b,i) \
|
||||||
|
{ \
|
||||||
|
(n) = ( (unsigned long) (b)[(i) ] << 24 ) \
|
||||||
|
| ( (unsigned long) (b)[(i) + 1] << 16 ) \
|
||||||
|
| ( (unsigned long) (b)[(i) + 2] << 8 ) \
|
||||||
|
| ( (unsigned long) (b)[(i) + 3] ); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PUT_ULONG_BE
|
||||||
|
#define PUT_ULONG_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
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 context setup
|
||||||
|
*/
|
||||||
|
void sha2_starts( sha2_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sha2_process( sha2_context *ctx, const unsigned char data[64] )
|
||||||
|
{
|
||||||
|
unsigned long temp1, temp2, W[64];
|
||||||
|
unsigned long A, B, C, D, E, F, G, H;
|
||||||
|
|
||||||
|
GET_ULONG_BE( W[ 0], data, 0 );
|
||||||
|
GET_ULONG_BE( W[ 1], data, 4 );
|
||||||
|
GET_ULONG_BE( W[ 2], data, 8 );
|
||||||
|
GET_ULONG_BE( W[ 3], data, 12 );
|
||||||
|
GET_ULONG_BE( W[ 4], data, 16 );
|
||||||
|
GET_ULONG_BE( W[ 5], data, 20 );
|
||||||
|
GET_ULONG_BE( W[ 6], data, 24 );
|
||||||
|
GET_ULONG_BE( W[ 7], data, 28 );
|
||||||
|
GET_ULONG_BE( W[ 8], data, 32 );
|
||||||
|
GET_ULONG_BE( W[ 9], data, 36 );
|
||||||
|
GET_ULONG_BE( W[10], data, 40 );
|
||||||
|
GET_ULONG_BE( W[11], data, 44 );
|
||||||
|
GET_ULONG_BE( W[12], data, 48 );
|
||||||
|
GET_ULONG_BE( W[13], data, 52 );
|
||||||
|
GET_ULONG_BE( W[14], data, 56 );
|
||||||
|
GET_ULONG_BE( W[15], data, 60 );
|
||||||
|
|
||||||
|
#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; \
|
||||||
|
}
|
||||||
|
|
||||||
|
A = ctx->state[0];
|
||||||
|
B = ctx->state[1];
|
||||||
|
C = ctx->state[2];
|
||||||
|
D = ctx->state[3];
|
||||||
|
E = ctx->state[4];
|
||||||
|
F = ctx->state[5];
|
||||||
|
G = ctx->state[6];
|
||||||
|
H = ctx->state[7];
|
||||||
|
|
||||||
|
P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 );
|
||||||
|
P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 );
|
||||||
|
P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF );
|
||||||
|
P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 );
|
||||||
|
P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B );
|
||||||
|
P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 );
|
||||||
|
P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 );
|
||||||
|
P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 );
|
||||||
|
P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 );
|
||||||
|
P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 );
|
||||||
|
P( G, H, A, B, C, D, E, F, W[10], 0x243185BE );
|
||||||
|
P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 );
|
||||||
|
P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 );
|
||||||
|
P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE );
|
||||||
|
P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 );
|
||||||
|
P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 );
|
||||||
|
P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 );
|
||||||
|
P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 );
|
||||||
|
P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 );
|
||||||
|
P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC );
|
||||||
|
P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F );
|
||||||
|
P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA );
|
||||||
|
P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC );
|
||||||
|
P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA );
|
||||||
|
P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 );
|
||||||
|
P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D );
|
||||||
|
P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 );
|
||||||
|
P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 );
|
||||||
|
P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 );
|
||||||
|
P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 );
|
||||||
|
P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 );
|
||||||
|
P( B, C, D, E, F, G, H, A, R(31), 0x14292967 );
|
||||||
|
P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 );
|
||||||
|
P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 );
|
||||||
|
P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC );
|
||||||
|
P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 );
|
||||||
|
P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 );
|
||||||
|
P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB );
|
||||||
|
P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E );
|
||||||
|
P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 );
|
||||||
|
P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 );
|
||||||
|
P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B );
|
||||||
|
P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 );
|
||||||
|
P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 );
|
||||||
|
P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 );
|
||||||
|
P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 );
|
||||||
|
P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 );
|
||||||
|
P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 );
|
||||||
|
P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 );
|
||||||
|
P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 );
|
||||||
|
P( G, H, A, B, C, D, E, F, R(50), 0x2748774C );
|
||||||
|
P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 );
|
||||||
|
P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 );
|
||||||
|
P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A );
|
||||||
|
P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F );
|
||||||
|
P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 );
|
||||||
|
P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE );
|
||||||
|
P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F );
|
||||||
|
P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 );
|
||||||
|
P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 );
|
||||||
|
P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA );
|
||||||
|
P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB );
|
||||||
|
P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 );
|
||||||
|
P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 );
|
||||||
|
|
||||||
|
ctx->state[0] += A;
|
||||||
|
ctx->state[1] += B;
|
||||||
|
ctx->state[2] += C;
|
||||||
|
ctx->state[3] += D;
|
||||||
|
ctx->state[4] += E;
|
||||||
|
ctx->state[5] += F;
|
||||||
|
ctx->state[6] += G;
|
||||||
|
ctx->state[7] += H;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 process buffer
|
||||||
|
*/
|
||||||
|
void sha2_update( sha2_context *ctx, const unsigned char *input, int ilen )
|
||||||
|
{
|
||||||
|
int fill;
|
||||||
|
unsigned long left;
|
||||||
|
|
||||||
|
if( ilen <= 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
left = ctx->total[0] & 0x3F;
|
||||||
|
fill = 64 - left;
|
||||||
|
|
||||||
|
ctx->total[0] += ilen;
|
||||||
|
ctx->total[0] &= 0xFFFFFFFF;
|
||||||
|
|
||||||
|
if( ctx->total[0] < (unsigned long) ilen )
|
||||||
|
ctx->total[1]++;
|
||||||
|
|
||||||
|
if( left && ilen >= fill )
|
||||||
|
{
|
||||||
|
memcpy( (void *) (ctx->buffer + left),
|
||||||
|
(void *) input, fill );
|
||||||
|
sha2_process( ctx, ctx->buffer );
|
||||||
|
input += fill;
|
||||||
|
ilen -= fill;
|
||||||
|
left = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( ilen >= 64 )
|
||||||
|
{
|
||||||
|
sha2_process( ctx, input );
|
||||||
|
input += 64;
|
||||||
|
ilen -= 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ilen > 0 )
|
||||||
|
{
|
||||||
|
memcpy( (void *) (ctx->buffer + left),
|
||||||
|
(void *) input, ilen );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const unsigned char sha2_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 sha2_finish( sha2_context *ctx, unsigned char output[32] )
|
||||||
|
{
|
||||||
|
unsigned long last, padn;
|
||||||
|
unsigned long high, low;
|
||||||
|
unsigned char msglen[8];
|
||||||
|
|
||||||
|
high = ( ctx->total[0] >> 29 )
|
||||||
|
| ( ctx->total[1] << 3 );
|
||||||
|
low = ( ctx->total[0] << 3 );
|
||||||
|
|
||||||
|
PUT_ULONG_BE( high, msglen, 0 );
|
||||||
|
PUT_ULONG_BE( low, msglen, 4 );
|
||||||
|
|
||||||
|
last = ctx->total[0] & 0x3F;
|
||||||
|
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
|
||||||
|
|
||||||
|
sha2_update( ctx, (unsigned char *) sha2_padding, padn );
|
||||||
|
sha2_update( ctx, msglen, 8 );
|
||||||
|
|
||||||
|
PUT_ULONG_BE( ctx->state[0], output, 0 );
|
||||||
|
PUT_ULONG_BE( ctx->state[1], output, 4 );
|
||||||
|
PUT_ULONG_BE( ctx->state[2], output, 8 );
|
||||||
|
PUT_ULONG_BE( ctx->state[3], output, 12 );
|
||||||
|
PUT_ULONG_BE( ctx->state[4], output, 16 );
|
||||||
|
PUT_ULONG_BE( ctx->state[5], output, 20 );
|
||||||
|
PUT_ULONG_BE( ctx->state[6], output, 24 );
|
||||||
|
|
||||||
|
if( ctx->is224 == 0 )
|
||||||
|
PUT_ULONG_BE( ctx->state[7], output, 28 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* output = SHA-256( input buffer )
|
||||||
|
*/
|
||||||
|
void sha2( const unsigned char *input, int ilen,
|
||||||
|
unsigned char output[32], int is224 )
|
||||||
|
{
|
||||||
|
sha2_context ctx;
|
||||||
|
|
||||||
|
sha2_starts( &ctx, is224 );
|
||||||
|
sha2_update( &ctx, input, ilen );
|
||||||
|
sha2_finish( &ctx, output );
|
||||||
|
|
||||||
|
memset( &ctx, 0, sizeof( sha2_context ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* output = SHA-256( file contents )
|
||||||
|
*/
|
||||||
|
int sha2_file( const char *path, unsigned char output[32], int is224 )
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
size_t n;
|
||||||
|
sha2_context ctx;
|
||||||
|
unsigned char buf[1024];
|
||||||
|
|
||||||
|
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||||
|
return( 1 );
|
||||||
|
|
||||||
|
sha2_starts( &ctx, is224 );
|
||||||
|
|
||||||
|
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
|
||||||
|
sha2_update( &ctx, buf, (int) n );
|
||||||
|
|
||||||
|
sha2_finish( &ctx, output );
|
||||||
|
|
||||||
|
memset( &ctx, 0, sizeof( sha2_context ) );
|
||||||
|
|
||||||
|
if( ferror( f ) != 0 )
|
||||||
|
{
|
||||||
|
fclose( f );
|
||||||
|
return( 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose( f );
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 HMAC context setup
|
||||||
|
*/
|
||||||
|
void sha2_hmac_starts( sha2_context *ctx, const unsigned char *key, int keylen,
|
||||||
|
int is224 )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char sum[32];
|
||||||
|
|
||||||
|
if( keylen > 64 )
|
||||||
|
{
|
||||||
|
sha2( key, keylen, sum, is224 );
|
||||||
|
keylen = ( is224 ) ? 28 : 32;
|
||||||
|
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] );
|
||||||
|
}
|
||||||
|
|
||||||
|
sha2_starts( ctx, is224 );
|
||||||
|
sha2_update( ctx, ctx->ipad, 64 );
|
||||||
|
|
||||||
|
memset( sum, 0, sizeof( sum ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 HMAC process buffer
|
||||||
|
*/
|
||||||
|
void sha2_hmac_update( sha2_context *ctx, const unsigned char *input, int ilen )
|
||||||
|
{
|
||||||
|
sha2_update( ctx, input, ilen );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 HMAC final digest
|
||||||
|
*/
|
||||||
|
void sha2_hmac_finish( sha2_context *ctx, unsigned char output[32] )
|
||||||
|
{
|
||||||
|
int is224, hlen;
|
||||||
|
unsigned char tmpbuf[32];
|
||||||
|
|
||||||
|
is224 = ctx->is224;
|
||||||
|
hlen = ( is224 == 0 ) ? 32 : 28;
|
||||||
|
|
||||||
|
sha2_finish( ctx, tmpbuf );
|
||||||
|
sha2_starts( ctx, is224 );
|
||||||
|
sha2_update( ctx, ctx->opad, 64 );
|
||||||
|
sha2_update( ctx, tmpbuf, hlen );
|
||||||
|
sha2_finish( ctx, output );
|
||||||
|
|
||||||
|
memset( tmpbuf, 0, sizeof( tmpbuf ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 HMAC context reset
|
||||||
|
*/
|
||||||
|
void sha2_hmac_reset( sha2_context *ctx )
|
||||||
|
{
|
||||||
|
sha2_starts( ctx, ctx->is224 );
|
||||||
|
sha2_update( ctx, ctx->ipad, 64 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* output = HMAC-SHA-256( hmac key, input buffer )
|
||||||
|
*/
|
||||||
|
void sha2_hmac( const unsigned char *key, int keylen,
|
||||||
|
const unsigned char *input, int ilen,
|
||||||
|
unsigned char output[32], int is224 )
|
||||||
|
{
|
||||||
|
sha2_context ctx;
|
||||||
|
|
||||||
|
sha2_hmac_starts( &ctx, key, keylen, is224 );
|
||||||
|
sha2_hmac_update( &ctx, input, ilen );
|
||||||
|
sha2_hmac_finish( &ctx, output );
|
||||||
|
|
||||||
|
memset( &ctx, 0, sizeof( sha2_context ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(POLARSSL_SELF_TEST)
|
||||||
|
/*
|
||||||
|
* FIPS-180-2 test vectors
|
||||||
|
*/
|
||||||
|
static unsigned char sha2_test_buf[3][57] =
|
||||||
|
{
|
||||||
|
{ "abc" },
|
||||||
|
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
|
||||||
|
{ "" }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int sha2_test_buflen[3] =
|
||||||
|
{
|
||||||
|
3, 56, 1000
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char sha2_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 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RFC 4231 test vectors
|
||||||
|
*/
|
||||||
|
static unsigned char sha2_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 131 times */
|
||||||
|
{ "" }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int sha2_hmac_test_keylen[7] =
|
||||||
|
{
|
||||||
|
20, 4, 20, 25, 20, 131, 131
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char sha2_hmac_test_buf[7][153] =
|
||||||
|
{
|
||||||
|
{ "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" },
|
||||||
|
{ "This is a test using a larger than block-size key "
|
||||||
|
"and a larger than block-size data. The key needs to "
|
||||||
|
"be hashed before being used by the HMAC algorithm." }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int sha2_hmac_test_buflen[7] =
|
||||||
|
{
|
||||||
|
8, 28, 50, 50, 20, 54, 152
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char sha2_hmac_test_sum[14][32] =
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* HMAC-SHA-224 test vectors
|
||||||
|
*/
|
||||||
|
{ 0x89, 0x6F, 0xB1, 0x12, 0x8A, 0xBB, 0xDF, 0x19,
|
||||||
|
0x68, 0x32, 0x10, 0x7C, 0xD4, 0x9D, 0xF3, 0x3F,
|
||||||
|
0x47, 0xB4, 0xB1, 0x16, 0x99, 0x12, 0xBA, 0x4F,
|
||||||
|
0x53, 0x68, 0x4B, 0x22 },
|
||||||
|
{ 0xA3, 0x0E, 0x01, 0x09, 0x8B, 0xC6, 0xDB, 0xBF,
|
||||||
|
0x45, 0x69, 0x0F, 0x3A, 0x7E, 0x9E, 0x6D, 0x0F,
|
||||||
|
0x8B, 0xBE, 0xA2, 0xA3, 0x9E, 0x61, 0x48, 0x00,
|
||||||
|
0x8F, 0xD0, 0x5E, 0x44 },
|
||||||
|
{ 0x7F, 0xB3, 0xCB, 0x35, 0x88, 0xC6, 0xC1, 0xF6,
|
||||||
|
0xFF, 0xA9, 0x69, 0x4D, 0x7D, 0x6A, 0xD2, 0x64,
|
||||||
|
0x93, 0x65, 0xB0, 0xC1, 0xF6, 0x5D, 0x69, 0xD1,
|
||||||
|
0xEC, 0x83, 0x33, 0xEA },
|
||||||
|
{ 0x6C, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3C, 0xAC,
|
||||||
|
0x6A, 0x2A, 0xBC, 0x1B, 0xB3, 0x82, 0x62, 0x7C,
|
||||||
|
0xEC, 0x6A, 0x90, 0xD8, 0x6E, 0xFC, 0x01, 0x2D,
|
||||||
|
0xE7, 0xAF, 0xEC, 0x5A },
|
||||||
|
{ 0x0E, 0x2A, 0xEA, 0x68, 0xA9, 0x0C, 0x8D, 0x37,
|
||||||
|
0xC9, 0x88, 0xBC, 0xDB, 0x9F, 0xCA, 0x6F, 0xA8 },
|
||||||
|
{ 0x95, 0xE9, 0xA0, 0xDB, 0x96, 0x20, 0x95, 0xAD,
|
||||||
|
0xAE, 0xBE, 0x9B, 0x2D, 0x6F, 0x0D, 0xBC, 0xE2,
|
||||||
|
0xD4, 0x99, 0xF1, 0x12, 0xF2, 0xD2, 0xB7, 0x27,
|
||||||
|
0x3F, 0xA6, 0x87, 0x0E },
|
||||||
|
{ 0x3A, 0x85, 0x41, 0x66, 0xAC, 0x5D, 0x9F, 0x02,
|
||||||
|
0x3F, 0x54, 0xD5, 0x17, 0xD0, 0xB3, 0x9D, 0xBD,
|
||||||
|
0x94, 0x67, 0x70, 0xDB, 0x9C, 0x2B, 0x95, 0xC9,
|
||||||
|
0xF6, 0xF5, 0x65, 0xD1 },
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HMAC-SHA-256 test vectors
|
||||||
|
*/
|
||||||
|
{ 0xB0, 0x34, 0x4C, 0x61, 0xD8, 0xDB, 0x38, 0x53,
|
||||||
|
0x5C, 0xA8, 0xAF, 0xCE, 0xAF, 0x0B, 0xF1, 0x2B,
|
||||||
|
0x88, 0x1D, 0xC2, 0x00, 0xC9, 0x83, 0x3D, 0xA7,
|
||||||
|
0x26, 0xE9, 0x37, 0x6C, 0x2E, 0x32, 0xCF, 0xF7 },
|
||||||
|
{ 0x5B, 0xDC, 0xC1, 0x46, 0xBF, 0x60, 0x75, 0x4E,
|
||||||
|
0x6A, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xC7,
|
||||||
|
0x5A, 0x00, 0x3F, 0x08, 0x9D, 0x27, 0x39, 0x83,
|
||||||
|
0x9D, 0xEC, 0x58, 0xB9, 0x64, 0xEC, 0x38, 0x43 },
|
||||||
|
{ 0x77, 0x3E, 0xA9, 0x1E, 0x36, 0x80, 0x0E, 0x46,
|
||||||
|
0x85, 0x4D, 0xB8, 0xEB, 0xD0, 0x91, 0x81, 0xA7,
|
||||||
|
0x29, 0x59, 0x09, 0x8B, 0x3E, 0xF8, 0xC1, 0x22,
|
||||||
|
0xD9, 0x63, 0x55, 0x14, 0xCE, 0xD5, 0x65, 0xFE },
|
||||||
|
{ 0x82, 0x55, 0x8A, 0x38, 0x9A, 0x44, 0x3C, 0x0E,
|
||||||
|
0xA4, 0xCC, 0x81, 0x98, 0x99, 0xF2, 0x08, 0x3A,
|
||||||
|
0x85, 0xF0, 0xFA, 0xA3, 0xE5, 0x78, 0xF8, 0x07,
|
||||||
|
0x7A, 0x2E, 0x3F, 0xF4, 0x67, 0x29, 0x66, 0x5B },
|
||||||
|
{ 0xA3, 0xB6, 0x16, 0x74, 0x73, 0x10, 0x0E, 0xE0,
|
||||||
|
0x6E, 0x0C, 0x79, 0x6C, 0x29, 0x55, 0x55, 0x2B },
|
||||||
|
{ 0x60, 0xE4, 0x31, 0x59, 0x1E, 0xE0, 0xB6, 0x7F,
|
||||||
|
0x0D, 0x8A, 0x26, 0xAA, 0xCB, 0xF5, 0xB7, 0x7F,
|
||||||
|
0x8E, 0x0B, 0xC6, 0x21, 0x37, 0x28, 0xC5, 0x14,
|
||||||
|
0x05, 0x46, 0x04, 0x0F, 0x0E, 0xE3, 0x7F, 0x54 },
|
||||||
|
{ 0x9B, 0x09, 0xFF, 0xA7, 0x1B, 0x94, 0x2F, 0xCB,
|
||||||
|
0x27, 0x63, 0x5F, 0xBC, 0xD5, 0xB0, 0xE9, 0x44,
|
||||||
|
0xBF, 0xDC, 0x63, 0x64, 0x4F, 0x07, 0x13, 0x93,
|
||||||
|
0x8A, 0x7F, 0x51, 0x53, 0x5C, 0x3A, 0x35, 0xE2 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checkup routine
|
||||||
|
*/
|
||||||
|
int sha2_self_test( int verbose )
|
||||||
|
{
|
||||||
|
int i, j, k, buflen;
|
||||||
|
unsigned char buf[1024];
|
||||||
|
unsigned char sha2sum[32];
|
||||||
|
sha2_context ctx;
|
||||||
|
|
||||||
|
for( i = 0; i < 6; i++ )
|
||||||
|
{
|
||||||
|
j = i % 3;
|
||||||
|
k = i < 3;
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
|
||||||
|
|
||||||
|
sha2_starts( &ctx, k );
|
||||||
|
|
||||||
|
if( j == 2 )
|
||||||
|
{
|
||||||
|
memset( buf, 'a', buflen = 1000 );
|
||||||
|
|
||||||
|
for( j = 0; j < 1000; j++ )
|
||||||
|
sha2_update( &ctx, buf, buflen );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sha2_update( &ctx, sha2_test_buf[j],
|
||||||
|
sha2_test_buflen[j] );
|
||||||
|
|
||||||
|
sha2_finish( &ctx, sha2sum );
|
||||||
|
|
||||||
|
if( memcmp( sha2sum, sha2_test_sum[i], 32 - k * 4 ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "failed\n" );
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "passed\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "\n" );
|
||||||
|
|
||||||
|
for( i = 0; i < 14; i++ )
|
||||||
|
{
|
||||||
|
j = i % 7;
|
||||||
|
k = i < 7;
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( " HMAC-SHA-%d test #%d: ", 256 - k * 32, j + 1 );
|
||||||
|
|
||||||
|
if( j == 5 || j == 6 )
|
||||||
|
{
|
||||||
|
memset( buf, '\xAA', buflen = 131 );
|
||||||
|
sha2_hmac_starts( &ctx, buf, buflen, k );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sha2_hmac_starts( &ctx, sha2_hmac_test_key[j],
|
||||||
|
sha2_hmac_test_keylen[j], k );
|
||||||
|
|
||||||
|
sha2_hmac_update( &ctx, sha2_hmac_test_buf[j],
|
||||||
|
sha2_hmac_test_buflen[j] );
|
||||||
|
|
||||||
|
sha2_hmac_finish( &ctx, sha2sum );
|
||||||
|
|
||||||
|
buflen = ( j == 4 ) ? 16 : 32 - k * 4;
|
||||||
|
|
||||||
|
if( memcmp( sha2sum, sha2_hmac_test_sum[i], buflen ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "failed\n" );
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "passed\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "\n" );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
155
src/core/loader/polarssl/sha2.h
Normal file
155
src/core/loader/polarssl/sha2.h
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
/**
|
||||||
|
* \file sha2.h
|
||||||
|
*
|
||||||
|
* 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_SHA2_H
|
||||||
|
#define POLARSSL_SHA2_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief SHA-256 context structure
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned long total[2]; /*!< number of bytes processed */
|
||||||
|
unsigned long state[8]; /*!< 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 */
|
||||||
|
int is224; /*!< 0 => SHA-256, else SHA-224 */
|
||||||
|
}
|
||||||
|
sha2_context;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief SHA-256 context setup
|
||||||
|
*
|
||||||
|
* \param ctx context to be initialized
|
||||||
|
* \param is224 0 = use SHA256, 1 = use SHA224
|
||||||
|
*/
|
||||||
|
void sha2_starts( sha2_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 sha2_update( sha2_context *ctx, const unsigned char *input, int ilen );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief SHA-256 final digest
|
||||||
|
*
|
||||||
|
* \param ctx SHA-256 context
|
||||||
|
* \param output SHA-224/256 checksum result
|
||||||
|
*/
|
||||||
|
void sha2_finish( sha2_context *ctx, unsigned char output[32] );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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 sha2( const unsigned char *input, int ilen,
|
||||||
|
unsigned char output[32], int is224 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Output = SHA-256( file contents )
|
||||||
|
*
|
||||||
|
* \param path input file name
|
||||||
|
* \param output SHA-224/256 checksum result
|
||||||
|
* \param is224 0 = use SHA256, 1 = use SHA224
|
||||||
|
*
|
||||||
|
* \return 0 if successful, 1 if fopen failed,
|
||||||
|
* or 2 if fread failed
|
||||||
|
*/
|
||||||
|
int sha2_file( const char *path, unsigned char output[32], int is224 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief SHA-256 HMAC context setup
|
||||||
|
*
|
||||||
|
* \param ctx HMAC context to be initialized
|
||||||
|
* \param key HMAC secret key
|
||||||
|
* \param keylen length of the HMAC key
|
||||||
|
* \param is224 0 = use SHA256, 1 = use SHA224
|
||||||
|
*/
|
||||||
|
void sha2_hmac_starts( sha2_context *ctx, const unsigned char *key, int keylen,
|
||||||
|
int is224 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief SHA-256 HMAC process buffer
|
||||||
|
*
|
||||||
|
* \param ctx HMAC context
|
||||||
|
* \param input buffer holding the data
|
||||||
|
* \param ilen length of the input data
|
||||||
|
*/
|
||||||
|
void sha2_hmac_update( sha2_context *ctx, const unsigned char *input, int ilen );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief SHA-256 HMAC final digest
|
||||||
|
*
|
||||||
|
* \param ctx HMAC context
|
||||||
|
* \param output SHA-224/256 HMAC checksum result
|
||||||
|
*/
|
||||||
|
void sha2_hmac_finish( sha2_context *ctx, unsigned char output[32] );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief SHA-256 HMAC context reset
|
||||||
|
*
|
||||||
|
* \param ctx HMAC context to be reset
|
||||||
|
*/
|
||||||
|
void sha2_hmac_reset( sha2_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Output = HMAC-SHA-256( 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-224/256 result
|
||||||
|
* \param is224 0 = use SHA256, 1 = use SHA224
|
||||||
|
*/
|
||||||
|
void sha2_hmac( const unsigned char *key, int keylen,
|
||||||
|
const unsigned char *input, int ilen,
|
||||||
|
unsigned char output[32], int is224 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Checkup routine
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or 1 if the test failed
|
||||||
|
*/
|
||||||
|
int sha2_self_test( int verbose );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* sha2.h */
|
Loading…
Reference in a new issue